opencli-adapter-author

Original🇨🇳 Chinese
Translated

This guide applies when writing an OpenCLI adapter for a new site or adding a new command to an existing site. It provides end-to-end guidance from initial reconnaissance, field decoding, adapter coding to verification. Replaces opencli-oneshot / opencli-explorer / opencli-browser / opencli-usage.

30installs
Added on

NPX Install

npx skill4agent add jackwener/opencli opencli-adapter-author

SKILL.md Content (Chinese)

View Translation Comparison →

opencli-adapter-author

You are an agent tasked with writing an adapter for a site. The goal of this skill: Complete the closed loop from scratch to passing
opencli browser verify
within 30 minutes
.
Use existing tools throughout the process:
opencli browser *
/
opencli doctor
/
opencli browser init
/
opencli browser verify
. No new commands are required.

Pre-work: Confirm Your Starting Point

First, take a quick self-assessment using
coverage-matrix.md
with three questions:
  1. Can the data be viewed in the browser? (No → Resolve authentication first)
  2. Is the data in HTTP/JSON/HTML format? (No → Out of this skill's scope)
  3. Is real-time push required? (Yes → Find the corresponding HTTP interface for the data; abandon if none exists)
Proceed only if all three answers are yes.

Top-level Decision Tree

START
┌──────────────────────────┐
│ Is opencli doctor passing? │── no ──→ Fix the bridge (follow prompts in doctor output)
└──────────────────────────┘
  │ yes
┌────────────────────────────────────────────────────┐
│ Read site memory:                                  │
│   1. ~/.opencli/sites/<site>/endpoints.json         │
│   2. ~/.opencli/sites/<site>/notes.md               │
│   3. references/site-memory/<site>.md               │
└────────────────────────────────────────────────────┘
  │ If endpoint + fields are found → Jump directly to [Endpoint Verification] (do not jump to write adapter! Memory may be outdated)
  │ If not found → Continue
┌──────────────────────────┐
│ Site Reconnaissance (site-recon)    │  → Pattern A/B/C/D/E
└──────────────────────────┘
┌──────────────────────────┐
│ API Discovery (api-discovery)│  §1 network → §2 state → §3 bundle → §4 token → §5 intercept
└──────────────────────────┘
  │ Obtain candidate endpoints
┌────────────────────────────────────────────┐
│ Direct fetch to verify endpoint (run even if memory hits)│── 401/403 ──→ Return to §4 to troubleshoot token
│ Non-empty data + 200 status                              │── Empty/HTML ──→ Return to site-recon and switch Pattern
│ Is the value in memory still valid?                     │── Site updated ──→ Mark old endpoint, return to api-discovery
└────────────────────────────────────────────┘
  │ OK
┌───────────────────────────────────────┐
│ Field Decoding (spot-check field-map in memory too)│  Self-explanatory → Use directly / Known code → field-conventions / Unknown → decode-playbook
│ Compare one known field with the value visible on the webpage to confirm no misalignment     │
└───────────────────────────────────────┘
┌──────────────────────────┐
│ Design columns (output)    │  Follow naming / type / order in output-design.md
└──────────────────────────┘
┌──────────────────────────┐
│ opencli browser init      │  Generate skeleton file ~/.opencli/clis/<site>/<name>.js
│ Copy the most similar neighbor adapter    │
│ Modify name / URL / field mapping in three places  │
└──────────────────────────┘
┌──────────────────────────┐
│ opencli browser verify    │── Failed ──→ Use autofix skill, return to corresponding step
└──────────────────────────┘
  │ Success
┌──────────────────────────┐
│ Cross-check fields with visible webpage values   │── Incorrect values ──→ Return to field decoding
└──────────────────────────┘
  │ Values match
┌──────────────────────────┐
│ Write back to ~/.opencli/sites/   │  endpoints / field-map / notes / fixtures
└──────────────────────────┘
DONE

Runbook (Check off step by step)

[ ] 1. opencli doctor returns "Everything looks good"
[ ] 2. Read site memory:
       [ ] Does ~/.opencli/sites/<site>/endpoints.json exist? Does it contain the desired endpoint?
       [ ] Does references/site-memory/<site>.md exist? Check the "Known endpoints" section
       [ ] If hit: **Jump to Step 5 (Endpoint Verification) + Step 7 (Field Check)**; do not jump directly to Step 9 to write adapter
       [ ] If memory was written over 30 days ago (check `verified_at`) → Treat as expired, follow cold start steps Step 3 → 4
[ ] 3. Reconnaissance (site-recon.md):
       [ ] opencli browser open <url>
       [ ] opencli browser wait time 3
       [ ] opencli browser network
       [ ] Determine Pattern (A / B / C / D / E)
[ ] 4. API Discovery (api-discovery.md) select section based on Pattern:
       [ ] Pattern A → Read §1 network in detail
       [ ] Pattern B → Extract §2 state + §1 deep data
       [ ] Pattern C → Search §3 bundle / script src
       [ ] Pattern D → Check §4 token source + fallback to §5
       [ ] Pattern E → Find HTTP polling interface; use §5 only if not found
[ ] 5. Direct fetch to verify candidate endpoint:
       [ ] Returns 200 status
       [ ] Response contains target data (not HTML / ads)
[ ] 6. Determine authentication strategy: Bare fetch works → PUBLIC; Requires cookie → COOKIE; Requires header → HEADER; Cannot obtain signature → INTERCEPT
[ ] 7. Field Decoding:
       [ ] Self-explanatory → Use key directly
       [ ] Known code → Look up in field-conventions.md
       [ ] Unknown code → Follow field-decode-playbook.md (sort key comparison / structure difference / constant check)
[ ] 8. Design columns (output-design.md):
       [ ] Naming uses camelCase and aligns with neighbor adapters
       [ ] Type / unit / percentage format is clear
       [ ] Order: Identification columns → Business figures → metadata
[ ] 9. Write adapter (adapter-template.md):
       [ ] opencli browser init <site>/<name>
       [ ] Find the most similar adapter for the same site or type, copy it over
       [ ] Modify name / URL / field mapping
[ ] 10. opencli browser verify <site>/<name>
[ ] 11. Cross-check field values with visible webpage values (don't just rely on "Adapter works!")
[ ] 12. Write back to site memory (**After passing verify + cross-check matches**, see schema in `references/site-memory.md`):
        [ ] `endpoints.json`: Use the short name of the endpoint as the key, value = `{url, method, params.{required,optional}, response, verified_at: YYYY-MM-DD, notes}`
        [ ] `field-map.json`: Only append new codes. Key = field code, value = `{meaning, verified_at: YYYY-MM-DD, source}`; **Do not overwrite existing keys**, align with webpage values first if there's a conflict before writing
        [ ] `notes.md`: Append a section `## YYYY-MM-DD by <agent/user>` at the top, documenting new pitfalls / conclusions encountered during this adapter writing process
        [ ] `fixtures/<cmd>-<YYYYMMDDHHMM>.json`: Save a complete response sample of this endpoint (remove cookies / tokens / user private fields first), for subsequent regression / field comparison

Fallback Paths (Where to jump if stuck at a step)

Stuck atPhenomenonJump to
Step 4 API Discovery
network
is empty,
__INITIAL_STATE__
is also empty
§3 bundle to search baseURL
Cannot find baseURL in bundle§5 intercept
Step 5 Endpoint Verification401 / 403 status§4 token troubleshooting
200 status but response is HTMLReturn to Step 3 to re-judge Pattern
200 status but
data: []
is empty
Wrong parameters passed / interface updated, return to §1 to check real request headers in network
Step 7 Field DecodingCannot deduce via sort key comparison§3 structure difference in field-decode-playbook.md
Still cannot deduceOutput raw data first, iterate after adapter runs
Step 10 Verify FailedMissing
fltt
/ Wrong field mapping
Use autofix skill
A column is always
null
Wrong field path, return to Step 7
Step 11 Incorrect Values10000x differenceInconsistent units ("ten thousand" vs "yuan")
Percentage is 100x smallerResponse is already
0.025
, do not multiply by 100

Reference Files

FileWhen to refer to it
references/coverage-matrix.md
Self-assess "whether within scope" before starting
references/site-recon.md
Determine site type in Step 3
references/api-discovery.md
Find endpoints in Step 4
references/field-conventions.md
Look up known field codes in Step 7
references/field-decode-playbook.md
When fields are not in the dictionary in Step 7
references/output-design.md
Naming / type / order in Step 8
references/adapter-template.md
File structure + live example
convertible.js
in Step 9
references/site-memory.md
Overview: Two-layer structure of in-repo seeds + local
~/.opencli/sites/
references/site-memory/<site>.md
Read site public knowledge in Step 2 (eastmoney / xueqiu / bilibili / tonghuashun are already covered)

Key Conventions

  • Adapters only import
    @jackwener/opencli/registry
    +
    @jackwener/opencli/errors
    , no third-party dependencies
  • The
    columns
    array must exactly align with the keys (including order) of the object returned by
    func
  • Throw
    CliError('CODE', 'msg')
    or
    AuthRequiredError(domain)
    for known failures, do not silently
    return []
  • Use
    ~/.opencli/clis/<site>/<name>.js
    for private adapters (no build required); copy to
    clis/<site>/<name>.js
    only when submitting a PR
  • Site memory write-back each cycle: No memory → Use skill → Generate memory → Next time takes 5 minutes

Stuck?

  • Diagnosis:
    opencli doctor
    → Check
    notes.md
    → Search autofix skill
  • Field decoding: Complete all three sections in
    field-decode-playbook.md
    → Output raw data first and iterate
  • Cannot find endpoint: Use §5 intercept in api-discovery as fallback
Do not guess. If you guess wrong, verify may pass but the data will be incorrect, and users will only notice when they see garbled content.