Install
$ agentstack add skill-mxyhi-ok-skills-opencli-autofix ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
OpenCLI AutoFix — Automatic Adapter Self-Repair
When 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.
Safety Boundaries
Before starting any repair, check these hard stops:
AUTH_REQUIRED(exit code 77) — STOP. Do not modify code. Tell the user to log into the site in Chrome.BROWSER_CONNECT(exit code 69) — STOP. Do not modify code. Tell the user to runopencli doctor.- CAPTCHA / rate limiting — STOP. Not an adapter issue.
Scope constraint:
- Only modify the file at
adapterSourcePathin the tracesummary.mdfront matter — this is the authoritative adapter location (may beclis//in repo or~/.opencli/clis//for npm installs) - Never modify
src/,extension/,tests/,package.json, ortsconfig.json
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.
Prerequisites
opencli doctor # Verify extension + daemon connectivity
When to Use This Skill
Use when opencli fails with repairable errors:
- SELECTOR — element not found (DOM changed)
- EMPTY_RESULT — no data returned (API response changed)
- API_ERROR / NETWORK — endpoint moved or broke
- PAGE_CHANGED — page structure no longer matches
- COMMAND_EXEC — runtime error in adapter logic
- TIMEOUT — page loads differently, adapter waits for wrong thing
Before Entering Repair: "Empty" ≠ "Broken"
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:
- Retry with an alternative query or entry point. If
opencli xiaohongshu search "X"returns 0 butopencli xiaohongshu search "X 攻略"returns 20, the adapter is fine — the platform was shaping results for the first query. - 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. - 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".
- "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.
Only 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.
Step 1: Collect Trace Context
Run the failing command with failure-retained trace enabled:
opencli [args...] --trace retain-on-failure 2>trace-error.yaml
On failure, stderr contains the normal error envelope plus a small trace block:
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"
Read summaryPath first. It is the LLM-oriented entry point and includes front matter:
---
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"
---
The artifact directory contains:
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
If you redirected stderr to a file, read that file and copy trace.summaryPath.
Do not ask the user to rerun with legacy diagnostic env vars. Trace is the repair evidence path.
Step 2: Analyze the Failure
Read the trace summary 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 | | EMPTYRESULT | API response schema changed, or data moved | Check network → find new response path | | APIERROR | Endpoint URL changed, new params required | Discover new API via network intercept | | AUTHREQUIRED | Login flow changed, cookies expired | STOP — tell user to log in, do not modify code | | TIMEOUT | Page loads differently, spinner/lazy-load | Add/update wait conditions | | PAGECHANGED | Major redesign | May need full adapter rewrite |
Key questions to answer:
- What is the adapter trying to do? (Read the file at
adapterSourcePath) - What did the page look like when it failed? (Read
summary.md, thenstate/if needed) - What network requests happened? (Read
Failed Networkinsummary.md, thennetwork.jsonlif needed) - What's the gap between what the adapter expects and what the page provides?
Step 3: Explore the Current Website
Use opencli browser 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 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 changed (APIERROR, EMPTYRESULT)
# 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 && opencli browser network
# Narrow to the request you care about by the fields its body should have
opencli browser network --filter author,text,likes
# Inspect specific API response (key is the `key` field from the default JSON output)
opencli browser network --detail
Step 4: Patch the Adapter
Read the adapter source file at adapterSourcePath from the trace summary front matter and make targeted fixes. This path is authoritative — it may be in the repo (clis/) or user-local (~/.opencli/clis/).
Use the Read tool on the exact path from summary.md front matter.
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.wait({ selector: '.loading-spinner', hidden: true })
// After: await page.wait({ selector: '[data-loaded="true"]' })
Rules for Patching
- Make minimal changes — fix only what's broken, don't refactor
- Keep the same output structure —
columnsand 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
- Never relax
verify/.jsonfixtures to silence a failure. A failingpatterns/notEmpty/mustNotContain/mustBeTruthyrule means the adapter's output is broken. Tighten the adapter so it produces correct values; do not loosen the fixture to accept the broken values. The one legitimate reason to edit a fixture during repair is when the site itself changed shape (e.g. URL format migration) — in that case update the fixture and note the change in~/.opencli/sites//notes.md. Otherwise editing the fixture is covering up a silent correctness regression.
Step 5: Verify the Fix
# Run the command normally
opencli [args...]
If it still fails, go back to Step 1 and collect a fresh trace. You have a budget of 3 repair rounds (trace → fix → retry). If the same error persists after a fix, try a different approach. After 3 rounds, stop and report what was tried.
Step 6: File an Upstream Issue
If the retry passes, the local adapter has drifted from upstream. File a GitHub issue so the fix flows back to jackwener/OpenCLI.
Do NOT file for:
AUTH_REQUIRED,BROWSER_CONNECT,ARGUMENT,CONFIG— environment/usage issues, not adapter bugs- CAPTCHA or rate limiting — not fixable upstream
- Failures you couldn't actually fix (3 rounds exhausted)
Only file after a verified local fix — the retry must pass first.
Procedure:
- Prepare the issue content from the trace summary you already have:
- Title:
[autofix] /:(e.g.[autofix] zhihu/hot: SELECTOR) - Body (use this template):
## Summary
OpenCLI autofix repaired this adapter locally, and the retry passed.
## Adapter
- Site: ``
- Command: ``
- OpenCLI version: ``
## Original failure
- Error code: ``
~~~
~~~
## Local fix summary
~~~
~~~
_Issue filed by OpenCLI autofix after a verified local repair._
- Ask the user before filing. Show them the draft title and body. Only proceed if they confirm.
- If the user approves and
gh auth statussucceeds:
gh issue create --repo jackwener/OpenCLI \
--title "[autofix] /: " \
--body ""
If gh is not installed or not authenticated, tell the user and skip — do not error out.
When to Stop
Hard stops (do not modify code):
- AUTHREQUIRED / BROWSERCONNECT — environment issue, not adapter bug
- Site requires CAPTCHA — can't automate this
- Rate limited / IP blocked — not an adapter issue
Soft stops (report after attempting):
- 3 repair rounds exhausted — stop, report what was tried and what failed
- Feature completely removed — the data no longer exists
- Major redesign — needs full adapter rewrite via
opencli-adapter-authorskill
In all stop 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 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 open https://www.zhihu.com/hot && opencli browser 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 "..."
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: mxyhi
- Source: mxyhi/ok-skills
- License: Apache-2.0
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.