opencli-repair

Diagnose and fix broken OpenCLI adapters when websites change. Use when an opencli command fails with SELECTOR, EMPTY_RESULT, API_ERROR, or PAGE_CHANGED…

INSTALLATION
npx skills add https://github.com/jackwener/opencli --skill opencli-repair
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

$27

Step 1: Collect Diagnostic Context

Run the failing command with diagnostic mode enabled:

OPENCLI_DIAGNOSTIC=1 opencli <site> <command> [args...] 2>diagnostic.json

This outputs a RepairContext JSON between ___OPENCLI_DIAGNOSTIC___ markers in stderr:

{

  "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"

}

Parse it:

# Extract JSON between markers from stderr output

cat diagnostic.json | sed -n '/___OPENCLI_DIAGNOSTIC___/{n;p;}'

Step 2: Analyze the Failure

Read the diagnostic context and the adapter source. Classify the root cause:

Error Code

Likely Cause

Repair Strategy

SELECTOR

DOM restructured, class/id renamed

Explore current DOM → find new selector

EMPTY_RESULT

API response schema changed, or data moved

Check network → find new response path

API_ERROR

Endpoint URL changed, new params required

Discover new API via network intercept

AUTH_REQUIRED

Login flow changed, cookies expired

Walk login flow with operate

TIMEOUT

Page loads differently, spinner/lazy-load

Add/update wait conditions

PAGE_CHANGED

Major redesign

May need full adapter rewrite

Key questions to answer:

  • What is the adapter trying to do? (Read the source field)
  • What did the page look like when it failed? (Read the snapshot field)
  • What network requests happened? (Read networkRequests)
  • What's the gap between what the adapter expects and what the page provides?

Step 3: Explore the Current Website

Use opencli operate to inspect the live website. Never use the broken adapter — it will just fail again.

DOM changed (SELECTOR errors)

# Open the page and inspect current DOM

opencli operate open https://example.com/target-page &#x26;&#x26; opencli operate state

# Look for elements that match the adapter's intent

# Compare the snapshot with what the adapter expects

API changed (API_ERROR, EMPTY_RESULT)

# Open page with network interceptor, then trigger the action manually

opencli operate open https://example.com/target-page &#x26;&#x26; opencli operate state

# Interact to trigger API calls

opencli operate click <N> &#x26;&#x26; opencli operate network

# Inspect specific API response

opencli operate network --detail <index>

Auth changed (AUTH_REQUIRED)

# Check current auth state

opencli operate open https://example.com &#x26;&#x26; opencli operate state

# If login page: inspect the login form

opencli operate state  # Look for login form fields

Step 4: Patch the Adapter

Read the adapter source file and make targeted fixes:

# Read the adapter

cat <sourcePath from diagnostic>

Common Fixes

Selector update:

// Before: page.evaluate('document.querySelector(".old-class")...')

// After:  page.evaluate('document.querySelector(".new-class")...')

API endpoint change:

// Before: const resp = await page.evaluate(`fetch('/api/v1/old-endpoint')...`)

// After:  const resp = await page.evaluate(`fetch('/api/v2/new-endpoint')...`)

Response schema change:

// Before: const items = data.results

// After:  const items = data.data.items  // API now nests under "data"

Wait condition update:

// Before: await page.waitForSelector('.loading-spinner', { hidden: true })

// After:  await page.waitForSelector('[data-loaded="true"]')

Rules for Patching

  • Make minimal changes — fix only what's broken, don't refactor
  • Keep the same output structurecolumns and return format must stay compatible
  • Prefer API over DOM scraping — if you discover a JSON API during exploration, switch to it
  • **Use @jackwener/opencli/* imports only** — never add third-party package imports
  • Test after patching — run the command again to verify

Step 5: Verify the Fix

# Run the command normally (without diagnostic mode)

opencli <site> <command> [args...]

If it still fails, go back to Step 3 and explore further. If the website has fundamentally changed (major redesign, removed feature), report that the adapter needs a full rewrite.

When to Give Up

Not all failures are repairable with a quick patch:

  • Site requires CAPTCHA — can't automate this
  • Feature completely removed — the data no longer exists
  • Major redesign — needs full adapter rewrite via opencli-explorer skill
  • Rate limited / IP blocked — not an adapter issue

In these cases, clearly communicate the situation to the user rather than making futile patches.

Example Repair Session

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 operate open https://www.zhihu.com/hot &#x26;&#x26; opencli operate state

   → Confirms new class name ".HotItem" with child ".HotItem-content"

5. AI patches: Edit clis/zhihu/hot.ts — replace ".HotList-item" with ".HotItem"

6. AI verifies: opencli zhihu hot

   → Success: returns hot topics
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card