关于 qiaomu-opencli-autofix
qiaomu-opencli-autofix 是用于诊断和修复 OpenCLI 适配器的 Agent 技能,适用于网站变化导致命令失效的情况。它依据诊断信息,仅修改适配器源文件,最多重试三轮,并遵守停止条件。
主要功能
- 01分析诊断上下文
- 02调查 DOM 和 API 变化
- 03定向修补适配器
- 04验证修复后的命令
- 05最多三轮重试
- 06登录与限流停止规则
适用场景
- 01页面改版后修复选择器
- 02适配 API 变更
- 03区分空结果与适配器故障
- 04登录或限流问题时安全停止
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ joeseesun/ qiaomu-opencli-skills --skill qiaomu-opencli-autofix安装后在 Claude Code 中输入/qiaomu-opencli-autofix确认已加载。
详细介绍
OpenCLI 自动修复 — 自动修复适配器
当 opencli 命令因网站更改了 DOM、API 或响应架构而失败时,自动诊断、修复适配器并重试,不要只报告错误。
安全边界
开始任何修复前,请检查以下硬性停止条件:
AUTH_REQUIRED(退出代码 77)— 停止。 不要修改代码。告知用户在 Chrome 中登录该网站。BROWSER_CONNECT(退出代码 69)— 停止。 不要修改代码。告知用户运行opencli doctor。- CAPTCHA / 速率限制 — 停止。 这不是适配器问题。
范围限制:
- 仅修改
RepairContext.adapter.sourcePath指定的文件 — 这是适配器的权威位置(可能位于仓库中的clis/<site>/,也可能是 npm 安装中的~/.opencli/clis/<site>/) - 绝不要修改
src/、extension/、tests/、package.json或tsconfig.json
重试预算: 每次故障最多进行 3 轮修复。如果经过 3 轮诊断 → 修复 → 重试后仍未解决,请停止并报告尝试过的操作。
前提条件
opencli doctor # Verify extension + daemon connectivity
何时使用此技能
当 opencli <site> <command> 因可修复的错误而失败时使用:
- SELECTOR — 找不到元素(DOM 已更改)
- EMPTY_RESULT — 未返回数据(API 响应已更改)
- API_ERROR / NETWORK — 端点已迁移或出现故障
- PAGE_CHANGED — 页面结构不再匹配
- COMMAND_EXEC — 适配器逻辑发生运行时错误
- TIMEOUT — 页面加载方式已更改,适配器等待的目标不正确
开始修复前:“空”≠“坏”
EMPTY_RESULT — 有时也包括结构有效但未返回任何结果的 SELECTOR — 通常不是适配器错误。平台会主动根据反爬启发式规则降低结果质量;网站返回“未找到”并不意味着内容确实不存在。在开始修复前,先排除以下情况:
- 使用其他查询或入口重试。 如果
opencli xiaohongshu search "X"返回 0 条结果,但opencli xiaohongshu search "X 攻略"返回 20 条,说明适配器没有问题——平台针对第一个查询调整了结果。 - 在普通 Chrome 标签页中抽查。 如果用户自己的浏览器中能看到数据,但适配器返回空结果,问题通常出在身份验证状态、速率限制或软封锁上,而不是代码错误。应使用
opencli doctor/ 重新登录解决,而不是编辑源代码。 - 留意软 404。 小红书 / weibo / douyin 等网站在内容被隐藏或删除时,会返回 HTTP 200 和空载荷,而不是真正的 404。快照看起来在结构上仍然正确。等待 2–3 秒后重试,通常可以区分“暂时隐藏”和“确已消失”。
- 搜索返回“0 条结果”本身就是一种答案。 如果适配器成功访问搜索端点、收到 HTTP 200,且平台返回了
results: [],这就是有效答案——应向用户报告“此查询没有匹配项”,而不是修补适配器。
只有在多次重试和尝试其他入口后,空结果或找不到选择器的情况仍然可以复现时,才继续执行步骤 1。否则,你是在为了追逐噪声而修改一个正常工作的适配器,而修改后的版本会破坏下一个正常路径。
步骤 1:收集诊断上下文
启用诊断模式运行失败的命令:
OPENCLI_DIAGNOSTIC=1 opencli <site> <command> [args...] 2>diagnostic.json
这会在 stderr 中的 ___OPENCLI_DIAGNOSTIC___ 标记之间输出 RepairContext JSON:
{
"error": {
"code": "SELECTOR",
"message": "Could not find element: .old-selector",
"hint": "The page UI may have changed."
},
"adapter": {
"site": "example",
"command": "example/search",
"sourcePath": "/path/to/clis/example/search.ts",
"source": "// full adapter source code"
},
"page": {
"url": "https://example.com/search",
"snapshot": "// DOM snapshot with [N] indices",
"networkRequests": [],
"consoleErrors": []
},
"timestamp": "2025-01-01T00:00:00.000Z"
}
解析它:
# Extract JSON between markers from stderr output
cat diagnostic.json | sed -n '/___OPENCLI_DIAGNOSTIC___/{n;p;}'
第 2 步:分析故障
阅读诊断上下文和适配器源码,判断根本原因:
| 错误代码 | 可能原因 | 修复策略 |
|---|---|---|
| SELECTOR | DOM 结构调整,class/id 改名 | 探索当前 DOM → 查找新的选择器 |
| EMPTY_RESULT | API 响应架构变更,或数据已迁移 | 检查网络 → 查找新的响应路径 |
| API_ERROR | Endpoint URL 已更改,需要新的参数 | 通过网络拦截发现新的 API |
| AUTH_REQUIRED | 登录流程已更改,Cookie 已过期 | 停止 — 告知用户登录,不要修改代码 |
| TIMEOUT | 页面加载方式不同,出现加载指示器/延迟加载 | 添加/更新等待条件 |
| PAGE_CHANGED | 页面进行了重大重新设计 | 可能需要完整重写适配器 |
需要回答的关键问题:
- 适配器要做什么?(读取
source字段) - 失败时页面是什么样的?(读取
snapshot字段) - 发生了哪些网络请求?(读取
networkRequests) - 适配器的预期与页面实际提供的内容之间有什么差异?
第 3 步:探索当前网站
使用 opencli browser 检查当前网站。切勿使用已损坏的适配器 — 它只会再次失败。
DOM 已更改(SELECTOR 错误)
# Open the page and inspect current DOM
opencli browser open https://example.com/target-page && opencli browser 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 open https://example.com/target-page && opencli browser state
# Interact to trigger API calls
opencli browser click <N> && opencli browser network
# Inspect specific API response
opencli browser network --detail <index>
第 4 步:修补适配器
读取 RepairContext.adapter.sourcePath 指定路径下的适配器源文件,并进行有针对性的修复。此路径具有权威性 — 文件可能位于仓库(clis/)中,也可能位于用户本地(~/.opencli/clis/)。
# Read the adapter (use the exact path from diagnostic)
cat <RepairContext.adapter.sourcePath>
常见修复
更新选择器:
// Before: page.evaluate('document.querySelector(".old-class")...')
// After: page.evaluate('document.querySelector(".new-class")...')
更改 API endpoint:
// 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.waitForSelector('.loading-spinner', { hidden: true })
// After: await page.waitForSelector('[data-loaded="true"]')
修补规则
- 尽量少改动 — 只修复出错的部分,不要重构
- 保持相同的输出结构 —
columns和返回格式必须保持兼容 - 优先使用 API,而不是抓取 DOM — 如果探索时发现 JSON API,请改用它
- 只使用
@jackwener/opencli/*导入 — 切勿添加第三方包导入 - 修补后进行测试 — 再次运行命令以验证
第 5 步:验证修复
# Run the command normally (without diagnostic mode)
opencli <site> <command> [args...]
如果仍然失败,请返回第 1 步并收集最新诊断信息。最多可进行 3 轮修复(诊断 → 修复 → 重试)。如果修复后仍出现相同错误,请尝试其他方法。完成 3 轮后,停止并报告已尝试的操作。
何时停止
必须停止(不要修改代码):
- AUTH_REQUIRED / BROWSER_CONNECT — 环境问题,不是适配器错误
- 网站要求 CAPTCHA — 无法自动处理
- 受到速率限制 / IP 被封锁 — 不是适配器问题
可尝试后停止(尝试后报告):
- 3 轮修复已用尽 — 停止并报告已尝试的操作及失败之处
- 功能已完全移除 — 数据已不复存在
- 重大重新设计 — 需要通过
opencli-explorerskill 完整重写适配器
遇到上述任何停止情况时,都应向用户清楚说明情况,而不是进行无效修补。
修复会话示例
1. User runs: opencli zhihu hot
→ Fails: SELECTOR "Could not find element: .HotList-item"
2. AI runs: OPENCLI_DIAGNOSTIC=1 opencli zhihu hot 2>diag.json
→ Gets RepairContext with DOM snapshot showing page loaded
3. AI reads diagnostic: snapshot shows the page loaded but uses ".HotItem" instead of ".HotList-item"
4. AI explores: opencli browser open https://www.zhihu.com/hot && opencli browser state
→ Confirms new class name ".HotItem" with child ".HotItem-content"
5. AI patches: Edit adapter at RepairContext.adapter.sourcePath — replace ".HotList-item" with ".HotItem"
6. AI verifies: opencli zhihu hot
→ Success: returns hot topics