Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Interact with social/content sites (Bilibili, Twitter/X, Zhihu, YouTube, Reddit, HN) using Chrome's login session via CLI.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
SKILL.md
1---2name: qiaomu-opencli-autofix3description: Automatically fix broken OpenCLI adapters when commands fail. Load this skill when an opencli command fails — it guides you through diagnosing the failure via OPENCLI_DIAGNOSTIC, patching the adapter, and retrying. Works with any AI agent.4author: joeseesun5upstream: jackwener/opencli6allowed-tools: Bash(opencli:*), Read, Edit, Write7---89# OpenCLI AutoFix — Automatic Adapter Self-Repair1011When an `opencli` command fails because a website changed its DOM, API, or response schema, **automatically diagnose, fix the adapter, and retry** — don't just report the error.1213## Safety Boundaries1415**Before starting any repair, check these hard stops:**1617- **`AUTH_REQUIRED`** (exit code 77) — **STOP.** Do not modify code. Tell the user to log into the site in Chrome.18- **`BROWSER_CONNECT`** (exit code 69) — **STOP.** Do not modify code. Tell the user to run `opencli doctor`.19- **CAPTCHA / rate limiting** — **STOP.** Not an adapter issue.2021**Scope constraint:**22- **Only modify the file at `RepairContext.adapter.sourcePath`** — this is the authoritative adapter location (may be `clis/<site>/` in repo or `~/.opencli/clis/<site>/` for npm installs)23- **Never modify** `src/`, `extension/`, `tests/`, `package.json`, or `tsconfig.json`2425**Retry budget:** Max **3 repair rounds** per failure. If 3 rounds of diagnose → fix → retry don't resolve it, stop and report what was tried.2627## Prerequisites2829```bash30opencli doctor # Verify extension + daemon connectivity31```3233## When to Use This Skill3435Use when `opencli <site> <command>` fails with repairable errors:36- **SELECTOR** — element not found (DOM changed)37- **EMPTY_RESULT** — no data returned (API response changed)38- **API_ERROR** / **NETWORK** — endpoint moved or broke39- **PAGE_CHANGED** — page structure no longer matches40- **COMMAND_EXEC** — runtime error in adapter logic41- **TIMEOUT** — page loads differently, adapter waits for wrong thing4243## Before Entering Repair: "Empty" ≠ "Broken"4445`EMPTY_RESULT` — and sometimes a structurally-valid `SELECTOR` that returns nothing — is often **not an adapter bug**. Platforms actively degrade results under anti-scrape heuristics, and a "not found" response from the site doesn't mean the content is actually missing. Rule this out **before** committing to a repair round:4647- **Retry with an alternative query or entry point.** If `opencli xiaohongshu search "X"` returns 0 but `opencli xiaohongshu search "X 攻略"` returns 20, the adapter is fine — the platform was shaping results for the first query.48- **Spot-check in a normal Chrome tab.** If the data is visible in the user's own browser but the adapter comes back empty, the issue is usually authentication state, rate limiting, or a soft block — not a code bug. The fix is `opencli doctor` / re-login, not editing source.49- **Look for soft 404s.** Sites like xiaohongshu / weibo / douyin return HTTP 200 with an empty payload instead of a real 404 when an item is hidden or deleted. The snapshot will look structurally correct. A retry 2-3 seconds later often distinguishes "temporarily hidden" from "actually gone".50- **"0 results" from a search is an answer.** If the adapter successfully reached the search endpoint, got an HTTP 200, and the platform returned `results: []`, that is a valid answer — report it to the user as "no matches for this query" rather than patching the adapter.5152Only proceed to Step 1 if the empty/selector-missing result is **reproducible across retries and alternative entry points**. Otherwise you're patching a working adapter to chase noise, and the patched version will break the next working path.5354## Step 1: Collect Diagnostic Context5556Run the failing command with diagnostic mode enabled:5758```bash59OPENCLI_DIAGNOSTIC=1 opencli <site> <command> [args...] 2>diagnostic.json60```6162This outputs a `RepairContext` JSON between `___OPENCLI_DIAGNOSTIC___` markers in stderr:6364```json65{66"error": {67"code": "SELECTOR",68"message": "Could not find element: .old-selector",69"hint": "The page UI may have changed."70},71"adapter": {72"site": "example",73"command": "example/search",74"sourcePath": "/path/to/clis/example/search.ts",75"source": "// full adapter source code"76},77"page": {78"url": "https://example.com/search",79"snapshot": "// DOM snapshot with [N] indices",80"networkRequests": [],81"consoleErrors": []82},83"timestamp": "2025-01-01T00:00:00.000Z"84}85```8687**Parse it:**88```bash89# Extract JSON between markers from stderr output90cat diagnostic.json | sed -n '/___OPENCLI_DIAGNOSTIC___/{n;p;}'91```9293## Step 2: Analyze the Failure9495Read the diagnostic context and the adapter source. Classify the root cause:9697| Error Code | Likely Cause | Repair Strategy |98|-----------|-------------|-----------------|99| SELECTOR | DOM restructured, class/id renamed | Explore current DOM → find new selector |100| EMPTY_RESULT | API response schema changed, or data moved | Check network → find new response path |101| API_ERROR | Endpoint URL changed, new params required | Discover new API via network intercept |102| AUTH_REQUIRED | Login flow changed, cookies expired | **STOP** — tell user to log in, do not modify code |103| TIMEOUT | Page loads differently, spinner/lazy-load | Add/update wait conditions |104| PAGE_CHANGED | Major redesign | May need full adapter rewrite |105106**Key questions to answer:**1071. What is the adapter trying to do? (Read the `source` field)1082. What did the page look like when it failed? (Read the `snapshot` field)1093. What network requests happened? (Read `networkRequests`)1104. What's the gap between what the adapter expects and what the page provides?111112## Step 3: Explore the Current Website113114Use `opencli browser` to inspect the live website. **Never use the broken adapter** — it will just fail again.115116### DOM changed (SELECTOR errors)117118```bash119# Open the page and inspect current DOM120opencli browser open https://example.com/target-page && opencli browser state121122# Look for elements that match the adapter's intent123# Compare the snapshot with what the adapter expects124```125126### API changed (API_ERROR, EMPTY_RESULT)127128```bash129# Open page with network interceptor, then trigger the action manually130opencli browser open https://example.com/target-page && opencli browser state131132# Interact to trigger API calls133opencli browser click <N> && opencli browser network134135# Inspect specific API response136opencli browser network --detail <index>137```138139## Step 4: Patch the Adapter140141Read the adapter source file at the path from `RepairContext.adapter.sourcePath` and make targeted fixes. This path is authoritative — it may be in the repo (`clis/`) or user-local (`~/.opencli/clis/`).142143```bash144# Read the adapter (use the exact path from diagnostic)145cat <RepairContext.adapter.sourcePath>146```147148### Common Fixes149150**Selector update:**151```typescript152// Before: page.evaluate('document.querySelector(".old-class")...')153// After: page.evaluate('document.querySelector(".new-class")...')154```155156**API endpoint change:**157```typescript158// Before: const resp = await page.evaluate(`fetch('/api/v1/old-endpoint')...`)159// After: const resp = await page.evaluate(`fetch('/api/v2/new-endpoint')...`)160```161162**Response schema change:**163```typescript164// Before: const items = data.results165// After: const items = data.data.items // API now nests under "data"166```167168**Wait condition update:**169```typescript170// Before: await page.waitForSelector('.loading-spinner', { hidden: true })171// After: await page.waitForSelector('[data-loaded="true"]')172```173174### Rules for Patching1751761. **Make minimal changes** — fix only what's broken, don't refactor1772. **Keep the same output structure** — `columns` and return format must stay compatible1783. **Prefer API over DOM scraping** — if you discover a JSON API during exploration, switch to it1794. **Use `@jackwener/opencli/*` imports only** — never add third-party package imports1805. **Test after patching** — run the command again to verify181182## Step 5: Verify the Fix183184```bash185# Run the command normally (without diagnostic mode)186opencli <site> <command> [args...]187```188189If it still fails, go back to Step 1 and collect fresh diagnostics. You have a budget of **3 repair rounds** (diagnose → fix → retry). If the same error persists after a fix, try a different approach. After 3 rounds, stop and report what was tried.190191## When to Stop192193**Hard stops (do not modify code):**194- **AUTH_REQUIRED / BROWSER_CONNECT** — environment issue, not adapter bug195- **Site requires CAPTCHA** — can't automate this196- **Rate limited / IP blocked** — not an adapter issue197198**Soft stops (report after attempting):**199- **3 repair rounds exhausted** — stop, report what was tried and what failed200- **Feature completely removed** — the data no longer exists201- **Major redesign** — needs full adapter rewrite via `opencli-explorer` skill202203In all stop cases, clearly communicate the situation to the user rather than making futile patches.204205## Example Repair Session206207```2081. User runs: opencli zhihu hot209→ Fails: SELECTOR "Could not find element: .HotList-item"2102112. AI runs: OPENCLI_DIAGNOSTIC=1 opencli zhihu hot 2>diag.json212→ Gets RepairContext with DOM snapshot showing page loaded2132143. AI reads diagnostic: snapshot shows the page loaded but uses ".HotItem" instead of ".HotList-item"2152164. AI explores: opencli browser open https://www.zhihu.com/hot && opencli browser state217→ Confirms new class name ".HotItem" with child ".HotItem-content"2182195. AI patches: Edit adapter at RepairContext.adapter.sourcePath — replace ".HotList-item" with ".HotItem"2202216. AI verifies: opencli zhihu hot222→ Success: returns hot topics223```224