.fyi
SkillsMCPPluginsSubagents

Browse by category

DevOps & CI/CD SkillsProductivity & Workflow SkillsOther SkillsProduct & Project Management SkillsDocumentation & Knowledge SkillsCode Review & Refactor SkillsBackend & APIs SkillsAgent Meta & Communication SkillsResearch SkillsSecurity SkillsUX UI & Design SkillsTesting & QA SkillsSee all →

Every Claude Code skill, MCP server, plugin and subagent in one directory. Searchable, comparable, and one command from installed. Live stats from GitHub, npm and PyPI.

We're on Product HuntYour agent's app storeCheck it out →
Agent SkillsMCP ServersPluginsSubagentsCoding Agents
CollectionsOfficial publishersGlossaryFAQBlogSearchSavedFeedback
PrivacyTermsllms.txtSitemap

made with ♥ · © 2026 aaaa.fyi

Independent project · real data from public registries

…/opencli/opencli-adapter-author
home/skills/jackwener/opencli/opencli-adapter-author
jackwener avatar

opencli-adapter-author

byjackwener· 9 skills

Installs

13k

Stars

27k

Forks

2.7k

Category

Debugging

View on GitHub

TL;DR

Use when writing an OpenCLI adapter for a new site or adding a new command to an existing site. Guides end-to-end from first recon through field decoding, adapter coding, and verify. Replaces opencli-oneshot / opencli-explorer. For ad-hoc browser driving (no adapter), see opencli-browser instead; for a top-level orientation to opencli, see opencli-usage.

How to install opencli-adapter-author?

jackwener/opencli/opencli-adapter-author
$npx -y skills add jackwener/opencli --skill opencli-adapter-author

Installs into the current project.

›Prefer a prompt? Paste this to your agent

Use this skill

Run `npx skills use "https://github.com/jackwener/opencli" --skill "jackwener/opencli/opencli-adapter-author"` and follow the generated skill instructions now. Read its complete output, redirecting it to a temporary file first if necessary. Resolve relative paths from the supporting-files directory it provides.

Use the whole pack

Use the skills in "https://github.com/jackwener/opencli" that are relevant to the current task. Run `npx skills add "https://github.com/jackwener/opencli"` and select the relevant skills, then follow their instructions.

Files · 1

View on GitHub
SKILL.md
1# opencli-adapter-author
2 
3你是要给一个站点写 adapter 的 agent。这份 skill 目标:**从零到通过 `opencli browser verify` 的 30 分钟内闭环**。
4 
5全程用现有工具:`opencli browser *` / `opencli doctor` / `opencli browser init` / `opencli browser verify`。没有新命令。
6 
7调试浏览器型 adapter 时,优先直接带上 `--trace on --keep-tab true --window foreground`。`--trace on` 每轮都落 trace artifact,`summary.md` 是失败/成功复盘入口;`--keep-tab true --window foreground` 让 tab lease 保留且浏览器窗口在前台,方便核对最终页面状态。
8 
9---
10 
11## 前置:看你落在哪
12 
13先拿 `coverage-matrix.md` 快速自测。三个问题:
14 
151. 数据在浏览器里看得到吗?(否 → 先解决鉴权)
162. 数据是 HTTP/JSON/HTML 吗?(否 → 不在 skill 范围)
173. 需要实时推送吗?(是 → 找同数据 HTTP 接口;没有就放弃)
18 
19三个都 yes 继续。
20 
21---
22 
23## 顶层决策树
24 
25**先定 strategy,再写 adapter。** 每次进入 Step 3/4 后、写代码前,必须产出一段 strategy note。没有这段 note,不要开始写 `clis/<site>/<name>.js`。
26 
27核心判断不是 "API 比 DOM 高级",而是 **数据源有没有外部契约**。实测维护成本显示:公开/官方接口最稳;UI/DOM 语义通常也有用户可见契约;站内未文档化 XHR/GraphQL/signature endpoint 最容易漂。不要为了 "API-first" 把稳定的 UI/DOM 实现盲目迁到无契约内部接口。
28 
29```md
30Strategy: PUBLIC_API | COOKIE_API | PAGE_FETCH | INTERCEPT | DOM_STATE | UI_SELECTOR
31Contract: stable | visible-ui | internal-unstable
32Evidence:
33- observed request/state: <endpoint / state global / UI-only signal>
34- auth source: <none / browser cookie / csrf from meta / localStorage / page runtime>
35- replay result: <status + content-type + non-empty sample shape>
36 
37If Strategy is PAGE_FETCH or INTERCEPT:
38- why PUBLIC_API / COOKIE_API are unavailable:
39- why UI_SELECTOR / DOM_STATE are not safer:
40- why the maintenance cost is acceptable:
41```
42 
43Strategy classes:
44 
45| Strategy | 契约级别 | 用在什么时候 | 证据要求 |
46|---|---|---|---|
47| `PUBLIC_API` | stable | 不需要登录,Node-side `fetch` 直接拿到目标数据 | 200 + JSON/HTML 含目标数据,不是埋点/广告 |
48| `COOKIE_API` | stable | Node-side `fetch` + `page.getCookies()` / header helper 能拿数据 | cookie/CSRF 来源清楚,replay 非空 |
49| `UI_SELECTOR` | visible-ui | publish/upload/click/表单,或页面语义比内部接口更稳 | selector 有语义锚点;错误路径是 typed error |
50| `DOM_STATE` | visible-ui | 数据在 hydration state / bootstrap JSON / SSR HTML 里 | state key / script JSON / HTML 结构明确 |
51| `PAGE_FETCH` | internal-unstable | 只能在页面上下文 `fetch` 才能复用 same-origin/session/runtime | `opencli browser eval fetch(...)` 非空;必须解释为什么避不开内部接口 |
52| `INTERCEPT` | internal-unstable | 请求签名复杂,但页面自己能自然发出请求 | 触发 UI 后能截到目标 response;必须解释为什么 UI/DOM 不够 |
53 
54选择规则:优先 `PUBLIC_API` / `COOKIE_API`。如果 UI/DOM 语义稳定,不要强行升级到 `PAGE_FETCH` / `INTERCEPT`。只有公开/官方接口不可用、UI/DOM 无法表达目标数据或操作时,才承担无契约内部接口的维护成本。
55 
56实测:`PAGE_FETCH` / `INTERCEPT` 的 fix 频率约为 `PUBLIC_API` 的 7-8 倍,`UI_SELECTOR` 跟 `COOKIE_API` 同档。详细 ladder 推导、`api_candidates` 证据怎么填、booking #1680 等反例见 [`references/strategy-selection.md`](./references/strategy-selection.md)。
57 
58边界:只复用页面自己已经合法获得的数据/能力。不教破解签名、不绕验证码/风控/访问控制;遇到不可复用签名(如必须由页面 runtime 生成且不能安全抽象)就降级到 `UI_SELECTOR` / `DOM_STATE` / `INTERCEPT`。
59 
60```
61START
62 │
63 ▼
64┌──────────────────────────┐
65│ opencli doctor 通? │── no ──→ 修桥接(doctor 输出里的提示)
66└──────────────────────────┘
67 │ yes
68 ▼
69┌────────────────────────────────────────────────────┐
70│ 读站点记忆: │
71│ 1. ~/.opencli/sites/<site>/endpoints.json │
72│ 2. ~/.opencli/sites/<site>/notes.md │
73│ 3. references/site-memory/<site>.md │
74└────────────────────────────────────────────────────┘
75 │ 命中 endpoint + 字段 → 直接跳到【endpoint 验证】(不跳写 adapter!memory 可能过期)
76 │ 没命中 → 继续
77 ▼
78┌──────────────────────────┐
79│ 站点侦察(site-recon) │ → Pattern A/B/C/D/E
80└──────────────────────────┘
81 │
82 ▼
83┌──────────────────────────┐
84│ API 发现(api-discovery)│ §1 network → §2 state → §3 bundle → §4 token → §5 intercept
85└──────────────────────────┘
86 │ 拿到候选 endpoint
87 ▼
88┌────────────────────────────────────────────┐
89│ 直接 fetch 验证 endpoint(memory 命中也要跑)│── 401/403 ──→ 回到 §4 排 token
90│ 数据非空 + 200 │── 空/HTML ──→ 回到 site-recon 换 Pattern
91│ memory 里的值还活着吗? │── 站点换版 ──→ 标记旧 endpoint,回 api-discovery
92└────────────────────────────────────────────┘
93 │ OK
94 ▼
95┌───────────────────────────────────────┐
96│ 字段解码(memory 里的 field-map 也要抽查)│ 自解释 → 直接 / 已知代号 → field-conventions / 未知 → decode-playbook
97│ 比一条已知字段和网页肉眼值,确认没错位 │
98└───────────────────────────────────────┘
99 │
100 ▼
101┌──────────────────────────┐
102│ 设计 columns (output) │ 对照 output-design.md 的命名 / 类型 / 顺序
103└──────────────────────────┘
104 │
105 ▼
106┌──────────────────────────┐
107│ opencli browser init │ 生成 ~/.opencli/clis/<site>/<name>.js 骨架
108│ 复制最像的邻居 adapter │
109│ 改 name / URL / 映射三处 │
110└──────────────────────────┘
111 │
112 ▼
113┌──────────────────────────┐
114│ opencli browser verify │── 失败 ──→ autofix skill,用 --trace retain-on-failure 回对应步骤
115└──────────────────────────┘
116 │ 成功
117 ▼
118┌──────────────────────────┐
119│ 字段 vs 网页肉眼对一遍 │── 数值不对 ──→ 回字段解码
120└──────────────────────────┘
121 │ 对得上
122 ▼
123┌──────────────────────────┐
124│ 回写 ~/.opencli/sites/ │ endpoints / field-map / notes / fixtures
125└──────────────────────────┘
126 │
127 ▼
128DONE
129```
130 
131---
132 
133## Runbook(一步一步勾选)
134 
135```
136[ ] 1. opencli doctor 返回 "Everything looks good"
137[ ] 2. 读站点记忆:
138 [ ] ~/.opencli/sites/<site>/endpoints.json 存在?里面有想要的 endpoint?
139 [ ] references/site-memory/<site>.md 存在?看"已知 endpoint"节
140 [ ] 命中后:**跳到第 5(endpoint 验证) + 第 7(字段核对)**,不能直接跳第 9 写 adapter
141 [ ] memory 写入超过 30 天(看 `verified_at`)→ 当作过期,按冷启动走 Step 3 → 4
142[ ] 3. 侦察(site-recon.md):
143 [ ] **首选**:`opencli browser analyze <url>` 一步拿 pattern + 反爬 + 最近 adapter + next step
144 [ ] `analyze` 结论模糊时再手跑:`open` → `wait time 2` (或 `wait xhr <regex>`) → `network`
145 [ ] 定 Pattern(A / B / C / D / E)
146[ ] 4. API 发现(api-discovery.md)按 Pattern 选 §:
147 [ ] Pattern A → §1 network 精读
148 [ ] Pattern B → §2 state 抽取 + §1 深层数据
149 [ ] Pattern C → §3 bundle / script src 搜索
150 [ ] Pattern D → §4 token 来源 + 降级 §5
151 [ ] Pattern E → 找 HTTP 轮询接口;找不到才 §5
152[ ] 5. 直接 fetch 候选 endpoint 验证:
153 [ ] 返回 200
154 [ ] 响应含目标数据(不是 HTML / 广告)
155[ ] 6. 写 strategy note(写代码前的强制产物):
156 [ ] 从 `PUBLIC_API / COOKIE_API / PAGE_FETCH / INTERCEPT / DOM_STATE / UI_SELECTOR` 选一个
157 [ ] 填 Contract:`stable / visible-ui / internal-unstable`
158 [ ] 填 Evidence:observed request/state、auth source、replay result
159 [ ] 如果选 `PAGE_FETCH` / `INTERCEPT`,必须解释为什么 `PUBLIC_API` / `COOKIE_API` / `UI_SELECTOR` / `DOM_STATE` 都不适合
160 [ ] 如果选 `UI_SELECTOR` / `DOM_STATE`,不需要为 "为什么不是 API" 过度辩护;只要说明语义锚点和 typed error 路径
161[ ] 7. 字段解码:
162 [ ] 自解释 → 直接用 key
163 [ ] 已知代号 → field-conventions.md 查表
164 [ ] 未知代号 → field-decode-playbook.md(排序键对比 / 结构差分 / 常量排查)
165[ ] 8. 设计 columns(output-design.md):
166 [ ] 命名 camelCase 且对齐邻居 adapter
167 [ ] 类型 / 单位 / 百分比格式清楚
168 [ ] 顺序:识别列 → 业务数字 → metadata
169[ ] 9. 写 adapter(adapter-template.md):
170 [ ] opencli browser init <site>/<name>
171 [ ] 找同站点或同类型最像的 adapter,cp 过来
172 [ ] 改 name / URL / 字段映射
173[ ] 10. opencli browser verify <site>/<name>
174 [ ] 首轮通过后立刻 `--write-fixture` 生成 `~/.opencli/sites/<site>/verify/<cmd>.json` 种子
175 [ ] 手改种子:加 `patterns`(URL / 日期 / ID 格式)+ `notEmpty`(核心字段)+ 收紧 `rowCount`
176 [ ] 再跑一次 `opencli browser verify <site>/<name>`,确认 ✓ matches fixture
177[ ] 11. 字段值 vs 网页肉眼比对(别只看 "Adapter works!")
178[ ] 12. 回写站点记忆(**verify 通过 + 肉眼比对对得上之后**,schema 见 `references/site-memory.md`):
179 [ ] `endpoints.json`:以 endpoint 的短名为 key,value = `{url, method, params.{required,optional}, response, verified_at: YYYY-MM-DD, notes}`
180 [ ] `field-map.json`:只追加新代号。key = 字段代号,value = `{meaning, verified_at: YYYY-MM-DD, source}`;**已存在的 key 不要覆盖**,有冲突先和网页肉眼值对齐再写
181 [ ] `notes.md`:顶部追加一段 `## YYYY-MM-DD by <agent/user>`,写本次写 adapter 时遇到的新坑 / 新结论
182 [ ] `verify/<cmd>.json`:**必填。** `opencli browser verify` 的期望值(args / rowCount / columns / types / patterns / notEmpty),Step 10 已经让你生成了,这里只是 checklist
183 [ ] `fixtures/<cmd>-<YYYYMMDDHHMM>.json`:存一份该 endpoint 的完整响应样本(去掉 cookie / token / 用户私有字段再存),给后续字段对比 / 离线 replay 用
184 [ ] 调试过程中如果在 repo / adapter 目录 dump 过临时文件(`.dbg-*.html` / `raw-*.json` / 等),**在 commit 前清干净**——这些本来就该落在 `~/.opencli/sites/<site>/fixtures/` 或 `/tmp/`
185```
186 
187---
188 
189## 降级路径(某步卡住跳到哪)
190 
191| 卡在 | 现象 | 跳去 |
192|------|------|-----|
193| Step 4 API 发现 | `network` 空,`__INITIAL_STATE__` 也空 | §3 bundle 搜 baseURL |
194| | bundle 搜不到 baseURL | §5 intercept |
195| Step 5 endpoint 验证 | 401 / 403 | §4 token 排查 |
196| | 200 但响应是 HTML | 回 Step 3 换 Pattern 判断 |
197| | 200 但 `data: []` 空 | 参数传错 / 接口换版,回 §1 看 network 里真实请求头 |
198| Step 7 字段解码 | 排序键对比推不出 | field-decode-playbook.md §3 结构差分 |
199| | 还推不出 | 先输出 raw,adapter 跑起来再迭代 |
200| Step 10 verify 失败 | `fltt` 漏了 / 字段映射错 | autofix skill;复现命令加 `--trace retain-on-failure` |
201| | 某列永远是 `null` | 字段路径错了,回 Step 7 |
202| Step 10 verify fixture mismatch | `[pattern]` row[i] 报错 | 先肉眼比对网页值;值对 → 是 fixture pattern 太严,放宽;值不对 → 字段映射错 |
203| | `[column] missing column "X"` | 实际 response 没这列(站点改版 or args 影响);重新 `--update-fixture` 或修 adapter |
204| | `[type]` actual null / undefined | 字段提取失败,回 Step 7 重抽;临时 fallback 用 union type `string\|null` 只有在语义真的可空时用 |
205| Step 11 数值不对 | 差 10000 倍 | 单位不统一("万" vs "元") |
206| | 百分比小 100 倍 | 响应已是 `0.025`,不要 × 100 |
207 
208---
209 
210## 参考文件
211 
212| 文件 | 什么时候翻 |
213|------|----------|
214| `references/coverage-matrix.md` | 动手前做"是否在范围内"自测 |
215| `references/site-recon.md` | Step 3 定站点类型 |
216| `references/api-discovery.md` | Step 4 找 endpoint |
217| `references/strategy-selection.md` | Step 6 填 strategy note 之前:契约模型 + 实测 fix 频率 + `api_candidates` 证据用法 + 反例 |
218| `references/field-conventions.md` | Step 7 查已知字段代号 |
219| `references/field-decode-playbook.md` | Step 7 字段不在词典时 |
220| `references/output-design.md` | Step 8 命名 / 类型 / 顺序 |
221| `references/adapter-template.md` | Step 9 文件结构 + 活例子 `convertible.js` |
222| `references/site-memory.md` | 总览:in-repo 种子 + 本地 `~/.opencli/sites/` 的两层结构 |
223| `references/site-memory/<site>.md` | Step 2 读站点公共知识(eastmoney / xueqiu / bilibili / tonghuashun 已铺) |
224| `references/success-rate-pitfalls.md` | Step 7 / 11 踩坑前翻:11 种"verify 能过但数据是错的"静默失败(含 aria-label locale-dependence) |
225| `references/jsdom-fixture-pattern.md` | 当 adapter 走 `page.evaluate` 内 DOM 抽取、且 mocked-evaluate 单测漏 silent bug 时——把 HTML 冻进 `clis/<site>/__fixtures__/` 用 JSDOM 跑(含 fixture 创建 mandatory `awk 'NF>0'` 收紧 + reverse-validate 纪律) |
226| `references/typed-errors.md` | 写 `func` 主体之前必读:5 类 typed error 落点表(ArgumentError / EmptyResultError / CommandExecutionError / AuthRequiredError / TimeoutError)+ 三大 silent anti-pattern(silent-clamp / sentinel-row / generic CliError)的反例修法 |
227 
228---
229 
230## 关键约定
231 
232- adapter 只引 `@jackwener/opencli/registry` + `@jackwener/opencli/errors`,不用第三方
233- `columns` 数组和 `func` 返回对象 keys 完全对齐(含顺序)
234- **中间解析对象 key 不能跟 `columns` 任一项重叠**(否则 silent-column-drop audit 误判,PR #1329 R1 真踩过;改成专属命名 + push row 时 destructure aliasing)
235- **`browser:` field 决定 func 签名**:`browser:false → (args)`,`browser:true → (page, args)`。搞反时 `args` 实际是 debug flag,所有外部参数 silent fallback 到 default(PR #1329 upstream 之前 8 个 non-browser adapter 全踩过这个)
236- 已知失败按 [`references/typed-errors.md`](./references/typed-errors.md) 5-classification 抛对应 typed error;**不要** silent `return []`,**不要** silent `return [{sentinel}]`,**不要** `Math.max/min` silent clamp 外部参数
237- 写私人 adapter 用 `~/.opencli/clis/<site>/<name>.js`(免 build);要提 PR 才 copy 到 `clis/<site>/<name>.js`
238- 站点记忆每轮回写:没记忆 → 用 skill → 产生记忆 → 下次变 5 分钟
239- **调试过程中的原始 dump / 抓包 / HTML 样本只能落在 `~/.opencli/sites/<site>/fixtures/` 或 `/tmp/`。严禁在 repo 根目录、`clis/<site>/` 或当前工作目录留 `.dbg-*.html / raw-*.json / sample.*` 这类临时文件**(PR diff 会带上去,别人 review 时很烦)。
240- **JSDOM unit-test fixture(`clis/<site>/__fixtures__/<command>.html`)是上面那条的例外**——它是有意 commit 进 repo 的 review artifact,不是临时 dump。但因此 quality bar 要更高:必须按 `references/jsdom-fixture-pattern.md` 的 5 步做完(含 mandatory `awk 'NF>0'` 空白行收紧),并 reverse-validate 一道证明 regression guard 真能挂。
241 
242---
243 
244## 卡住了
245 
246- 诊断类:`opencli doctor` → 看 `notes.md` → 搜 autofix skill
247- 字段解码类:`field-decode-playbook.md` 全三节走完 → 先输出 raw 迭代
248- endpoint 找不到:api-discovery §5 intercept 兜底
249 
250不要猜。猜错了 verify 能通过但数据是错的,用户看到乱码才发现。

Security

Review

  • Gen Agent Trust Hubpass
  • Socketpass
  • Snykwarn

Preview

jackwener/openclijackwener/opencli

$ npx -y skills add jackwener/opencli --skill opencli-adapter-author

▸ installing to .claude/skills…

✓ opencli-adapter-author ready

Repojackwener/opencli
TypeSkills
CategoryDebugging
ForDeveloper
UpdatedJul 2026
License—
First seenJul 27, 2026

Tags

Skill

Related

6 picks
Type
  1. microsoft avatarazure-diagnosticsDebug Azure production issues on Azure using AppLens, Azure Monitor, resource health, and safe triage.SkillsJul 2026485k1.3k
  2. microsoft avatarappinsights-instrumentationGuidance for instrumenting webapps with Azure Application Insights. Provides telemetry patterns, SDK setup, and configuration references.SkillsJul 2026483k1.3k
  3. mattpocock avatardiagnosing-bugsDiagnosis loop for hard bugs and performance regressions. Use when the user says "diagnose"/"debug this", or reports something broken/throwing/failing/slow.SkillsJul 2026263k189k
  4. obra avatarsystematic-debuggingUse when encountering any bug, test failure, or unexpected behavior, before proposing fixesSkillsJul 2026205k261k
  5. lllllllama avatarsafe-debugRigor Debug / Rigor Audit skill for deep learning research work.SkillsJul 2026176k512
  6. samber avatargolang-error-handlingIdiomatic Golang error handling — creation, wrapping with %w, errors.Is/As, errors.Join, custom error types, sentinel errors, panic/recover, the single…SkillsJul 202636k2.7k