关于 opencli-autofix
用于在网站变化导致 OpenCLI 命令失败时修复适配器的技能。它依据保留的失败跟踪诊断并修改适配器,设有严格的安全边界,并要求验证修复结果。
主要功能
- 01依据保留跟踪诊断故障
- 02检查当前页面与网络活动
- 03仅修改跟踪指定的适配器文件
- 04最多进行三轮修复
- 05验证修复后再提交问题
适用场景
- 01网站改版后修复选择器
- 02适配器适配 API 变化
- 03排查空结果或超时
- 04向上游报告已验证的适配器偏差
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jackwener/ opencli --skill opencli-autofix安装后在 Claude Code 中输入/opencli-autofix确认已加载。
详细介绍
OpenCLI AutoFix — 自动适配器自修复
当 opencli 命令因网站的 DOM、API 或响应结构变化而失败时,自动诊断、修复适配器并重试,而不是仅仅报告错误。
安全边界
在开始任何修复前,先检查以下硬性停止条件:
AUTH_REQUIRED(退出码 77)—停止。 不要修改代码。告知用户在 Chrome 中登录该网站。BROWSER_CONNECT(退出码 69)—停止。 不要修改代码。告知用户运行opencli doctor。- 验证码 / 速率限制—停止。 这不是适配器问题。
范围约束:
- 只修改 trace
summary.md前置元数据中adapterSourcePath指向的文件——这是权威的适配器位置(可能是仓库中的clis/<site>/,也可能是 npm 安装时的~/.opencli/clis/<site>/) - 禁止修改
src/、extension/、tests/、package.json或tsconfig.json
重试预算: 每次失败最多进行 3 轮修复。如果 3 轮「诊断 → 修复 → 重试」仍未解决,则停止并报告已尝试的内容。
前置条件
opencli doctor # Verify extension + daemon connectivity
何时使用此 Skill
当 opencli <site> <command> 因可修复的错误而失败时使用:
- SELECTOR——元素未找到(DOM 已变化)
- EMPTY_RESULT——未返回数据(API 响应已变化)
- API_ERROR / NETWORK——端点已迁移或损坏
- PAGE_CHANGED——页面结构不再匹配
- COMMAND_EXEC——适配器逻辑中的运行时错误
- TIMEOUT——页面加载方式不同,适配器等待了错误的内容
进入修复前:「空结果」≠「已损坏」
EMPTY_RESULT——以及有时结构上有效但返回为空的 SELECTOR——通常不是适配器的 bug。平台会在反爬启发式策略下主动降低结果质量,网站返回的「未找到」并不意味着内容真的不存在。在决定进行一轮修复之前,请先排除以下情况:
- 使用替代查询或入口重试。 如果
opencli xiaohongshu search "X"返回 0 条,但opencli xiaohongshu search "X 攻略"返回 20 条,说明适配器没有问题——只是平台对第一个查询做了结果调整。 - 在普通 Chrome 标签页中抽查。 如果数据在用户自己的浏览器中可见,但适配器返回为空,问题通常出在登录状态、速率限制或软封锁上,而非代码缺陷。解决办法是运行
opencli doctor/ 重新登录,而不是编辑源码。 - 留意软 404。 xiaohongshu / weibo / douyin 等网站在内容被隐藏或删除时,会返回 HTTP 200 加空数据,而不是真正的 404。快照看起来结构完全正常。间隔 2–3 秒重试,通常能区分「暂时隐藏」与「确实已删除」。
- 搜索返回「0 条结果」本身就是一个答案。 如果适配器成功请求了搜索接口,得到 HTTP 200,且平台返回
results: [],这是一个有效的结论——应向用户报告「该查询无匹配结果」,而不是去修补适配器。
只有当空结果或选择器缺失的情况在多次重试和替代入口下都可复现时,才继续进行第 1 步。否则,你就是在为了追逐噪声而修补一个正常工作的适配器,而修补后的版本可能会破坏下一条正常路径。
第 1 步:收集 Trace 上下文
启用失败时保留 trace 的方式运行失败的命令:
opencli <site> <command> [args...] --trace retain-on-failure 2>trace-error.yaml
失败时,stderr 包含常规错误信封以及一个简短的 trace 块:
ok: false
error:
code: SELECTOR
message: "Could not find element: .old-selector"
trace:
schemaVersion: 1
opencliVersion: "..."
traceId: "..."
dir: "/path/to/.opencli/profiles/default/traces/..."
summaryPath: "/path/to/.opencli/profiles/default/traces/.../summary.md"
receiptPath: "/path/to/.opencli/profiles/default/traces/.../receipt.json"
先阅读 summaryPath。它是面向 LLM 的入口,包含前置元数据:
---
schemaVersion: 1
opencliVersion: "..."
traceId: "..."
status: failure
site: "example"
command: "example/search"
adapterSourcePath: "/path/to/clis/example/search.js"
errorCode: "SELECTOR"
errorMessage: "Could not find element: .old-selector"
---
产物目录包含:
summary.md # start here
receipt.json # machine-readable trace receipt
trace.jsonl # full redacted timeline
network.jsonl # redacted network events
console.jsonl # redacted console events
state/ # final snapshots when available
screenshots/ # final screenshots when available
如果你将 stderr 重定向到了文件,请读取该文件并复制其中的 trace.summaryPath。
不要要求用户使用旧版诊断环境变量重新运行。Trace 才是修复所依据的证据路径。
Step 2: 分析故障
阅读 trace 摘要和适配器源码,判断根本原因:
| 错误码 | 可能原因 | 修复策略 |
|---|---|---|
| SELECTOR | DOM 结构变化,class/id 被重命名 | 检查当前 DOM → 找到新选择器 |
| EMPTY_RESULT | API 响应结构变化,或数据位置迁移 | 检查网络请求 → 找到新的响应路径 |
| API_ERROR | 端点 URL 变化,或需要新参数 | 通过网络拦截发现新 API |
| AUTH_REQUIRED | 登录流程变化,Cookie 过期 | 停止:告知用户登录,不要修改代码 |
| TIMEOUT | 页面加载方式变化,出现加载动画或懒加载 | 添加或更新等待条件 |
| PAGE_CHANGED | 页面大改版 | 可能需要完全重写适配器 |
需要回答的关键问题:
- 适配器想要做什么?(阅读
adapterSourcePath处的文件) - 失败时页面是什么样子?(阅读
summary.md,必要时再读state/) - 发生了哪些网络请求?(阅读
summary.md中的Failed Network,必要时再读network.jsonl) - 适配器的预期与页面实际提供的内容之间存在什么差距?
Step 3: 探查当前网站
使用 opencli browser 检查线上网站。切勿使用已损坏的适配器,否则只会再次失败。
DOM 变化(SELECTOR 错误)
# Open the page and inspect current DOM
opencli browser --session research open https://example.com/target-page && opencli browser --session research state
# Look for elements that match the adapter's intent
# Compare the snapshot with what the adapter expects
API 变化(API_ERROR、EMPTY_RESULT)
# Open page with network interceptor, then trigger the action manually
opencli browser --session research open https://example.com/target-page && opencli browser --session research state
# Interact to trigger API calls
opencli browser --session research click <N> && opencli browser --session research network
# Narrow to the request you care about by the fields its body should have
opencli browser --session research network --filter author,text,likes
# Inspect specific API response (key is the `key` field from the default JSON output)
opencli browser --session research network --detail <key>
Step 4: 修补适配器
读取 trace 摘要 front matter 中 adapterSourcePath 指定的适配器源文件,并进行有针对性的修复。该路径为权威来源,它可能位于仓库(clis/)中,也可能位于用户本地(~/.opencli/clis/)中。
请对 summary.md front matter 中的准确路径使用 Read 工具。
常见修复
更新选择器:
// Before: page.evaluate('document.querySelector(".old-class")...')
// After: page.evaluate('document.querySelector(".new-class")...')
API 端点变化:
// Before: const resp = await page.evaluate(`fetch('/api/v1/old-endpoint')...`)
// After: const resp = await page.evaluate(`fetch('/api/v2/new-endpoint')...`)
响应结构变化:
// Before: const items = data.results
// After: const items = data.data.items // API now nests under "data"
更新等待条件:
// Before: await page.wait({ selector: '.loading-spinner', hidden: true })
// After: await page.wait({ selector: '[data-loaded="true"]' })
修补规则
- 做最小化修改:只修复出错的部分,不要重构
- 保持相同的输出结构:
columns和返回格式必须保持兼容 - 优先使用 API 而非 DOM 抓取:如果在探查中发现了 JSON API,就切换过去
- 只使用
@jackwener/opencli/*导入:绝不添加第三方包导入 - 修补后测试:重新运行命令以验证
- 切勿放宽
verify/<cmd>.json夹具来掩盖失败。patterns、notEmpty、mustNotContain、mustBeTruthy规则失败,说明适配器输出有误。应收紧适配器,使其产出正确的值,而不是放宽夹具去接受错误的值。修复过程中唯一合理的修改夹具的理由,是网站本身结构发生了变化(例如 URL 格式迁移),此时应更新夹具,并在~/.opencli/sites/<site>/notes.md中记录该变更。否则,修改夹具就是在掩盖一个静默的正确性回归。
Step 5: 验证修复
# Run the command normally
opencli <site> <command> [args...]
如果仍然失败,请返回 Step 1 并重新收集 trace。你的修复预算为 3 轮(trace → 修复 → 重试)。如果修复后同样的错误仍然存在,请尝试不同的方法。3 轮之后,停止并报告已尝试的内容。
第 6 步:提交上游 Issue
如果重试通过,说明本地适配器已经与上游产生偏差。请提交一个 GitHub Issue,以便修复回流到 jackwener/OpenCLI。
以下情况不要提交:
AUTH_REQUIRED、BROWSER_CONNECT、ARGUMENT、CONFIG:属于环境或用法问题,不是适配器缺陷- 验证码或速率限制:无法在上游修复
- 你实际无法修复的失败(已用尽 3 轮修复)
只有在本地修复已验证后才提交:必须先让重试通过。
操作步骤:
- 根据你已有的追踪摘要准备 Issue 内容:
- 标题:
[autofix] <site>/<command>: <error_code>(例如[autofix] zhihu/hot: SELECTOR) - 正文(使用以下模板):
- 标题:
## Summary
OpenCLI autofix repaired this adapter locally, and the retry passed.
## Adapter
- Site: `<site>`
- Command: `<command>`
- OpenCLI version: `<version from opencli --version>`
## Original failure
- Error code: `<error_code>`
~~~
<error_message>
~~~
## Local fix summary
~~~
<1-2 sentence description of what you changed and why>
~~~
_Issue filed by OpenCLI autofix after a verified local repair._
-
提交前先征求用户同意。 向用户展示标题和正文草稿。只有在用户确认后才继续。
-
如果用户同意且
gh auth status检查通过:
gh issue create --repo jackwener/OpenCLI \
--title "[autofix] <site>/<command>: <error_code>" \
--body "<the body above>"
如果未安装 gh 或尚未完成认证,请告知用户并跳过,不要报错中止。
何时停止
硬性停止(不要修改代码):
- AUTH_REQUIRED / BROWSER_CONNECT:环境问题,不是适配器缺陷
- 站点要求验证码:无法自动化处理
- 被速率限制 / IP 被封:不属于适配器问题
软性停止(尝试后再报告):
- 已用尽 3 轮修复:停止,报告已尝试的操作和失败原因
- 功能已被完全移除:数据已不存在
- 重大改版:需要通过
opencli-adapter-authorSkill 完整重写适配器
在所有停止情形下,都应向用户清楚说明情况,而不是做无效的补丁。
修复会话示例
1. User runs: opencli zhihu hot
→ Fails: SELECTOR "Could not find element: .HotList-item"
2. AI runs: opencli zhihu hot --trace retain-on-failure 2>trace-error.yaml
→ Gets trace summary with final state and failed action evidence
3. AI reads summary/state: page loaded but uses ".HotItem" instead of ".HotList-item"
4. AI explores: opencli browser --session research open https://www.zhihu.com/hot && opencli browser --session research state
→ Confirms new class name ".HotItem" with child ".HotItem-content"
5. AI patches: Edit adapter at `adapterSourcePath` — replace ".HotList-item" with ".HotItem"
6. AI verifies: opencli zhihu hot
→ Success: returns hot topics
7. AI prepares upstream issue draft, shows it to the user
8. User approves → AI runs: gh issue create --repo jackwener/OpenCLI --title "[autofix] zhihu/hot: SELECTOR" --body "..."