OpenCLI — Complete Guide
Make any website or Electron App your CLI. Reuse Chrome login, zero risk, AI-powered discovery.
Install & Run
npm install -g @jackwener/opencli
opencli <command>
npm update -g @jackwener/opencli # Update
opencli --version # Check version
Prerequisites
Browser commands require:
- Chrome running (logged into target sites)
- opencli Browser Bridge Chrome extension installed
- Daemon auto-starts on first browser command
opencli doctor # Diagnose extension + daemon connectivity
Public API commands (
hackernews,arxiv,npm,pubmed…) need no browser.
Command Quick Reference
Usage: opencli <site> <command> [args] [--limit N] [-f json|yaml|md|csv|table]
Type legend: 🌐 = Browser (needs Chrome login) · ✅ = Public API · 🖥️ = Desktop (Electron/CDP) · 🔧 = External CLI
Website Adapters (136 sites)
| Site | Type | Commands |
|---|---|---|
| 1688 | 🌐 | search item download store assets |
| 1point3acres | 🌐 | hot latest digest search thread forum forums user notifications |
| 36kr | 🌐 | hot news search article |
| 51job | 🌐 | search hot detail company |
| aibase | 🌐 | news |
| amazon | 🌐 | bestsellers search product offer discussion movers-shakers new-releases |
| apple-podcasts | ✅ | top search episodes |
| arxiv | ✅ | search paper recent author |
| baidu-scholar | 🌐 | search |
| band | 🌐 | bands posts post mentions |
| barchart | 🌐 | quote options greeks flow |
| bbc | ✅ | news topic |
| bilibili | 🌐 | hot search me favorite history feed feed-detail user-videos subtitle dynamic ranking following comments download video |
| binance | ✅ | top ticker price klines gainers losers pairs trades depth asks prices |
| bloomberg | ✅🌐 | RSS: main markets tech politics economics opinions · Browser: news |
| bluesky | 🌐 | search profile user feeds followers following thread trending starter-packs |
| boss | 🌐 | search detail recommend joblist greet batchgreet send chatlist chatmsg invite mark exchange resume stats |
| brave | 🌐 | search |
| chaoxing | 🌐 | assignments exams |
| claude | 🌐 | status new send read ask detail history |
| cnki | 🌐 | search |
| coingecko | ✅ | top coin trending categories exchanges derivatives global |
| coupang | 🌐 | search add-to-cart |
| crates | ✅ | search crate |
| ctrip | 🌐 | search hotel-search hotel-suggest flight |
| dblp | ✅ | search author paper venue |
| deepseek | 🌐 | status new send read ask detail history |
| defillama | ✅ | protocols protocol |
| devto | ✅ | top tag user |
| dianping | 🌐 | search shop |
| dictionary | ✅ | search synonyms examples |
| dockerhub | ✅ | search image |
| doubao | 🌐 | status new send read ask detail history meeting-summary meeting-transcript |
| douban | 🌐 | search top250 subject photos download marks reviews movie-hot book-hot |
| douyin | 🌐 | profile videos user-videos activities collections hashtag location stats publish draft drafts delete update |
| duckduckgo | 🌐 | search suggest |
| eastmoney | 🌐 | quote kline hot-rank rank index-board sectors northbound money-flow kuaixun announcement etf convertible holders longhu |
| endoflife | ✅ | product |
| 🌐 | feed profile search friends groups events notifications memories add-friend join-group marketplace-inbox marketplace-listings |
|
| flathub | ✅ | search app |
| gemini | 🌐 | ask new image deep-research deep-research-result |
| gitee | 🌐 | search trending user |
| ✅ | news search suggest trends |
|
| google-scholar | 🌐 | search profile cite |
| goproxy | ✅ | module versions |
| gov-law | 🌐 | search recent |
| gov-policy | 🌐 | search recent |
| grok | 🌐 | ask |
| hackernews | ✅ | top new best ask show jobs search user |
| hf | ✅ | top |
| homebrew | ✅ | popular formula cask |
| hupu | 🌐 | hot search detail like unlike reply mentions |
| imdb | ✅ | top trending search title person reviews |
| indeed | 🌐 | search job |
| 🌐 | explore profile search user followers following follow unfollow like unlike comment save unsave saved reel story post note download collection-create collection-delete |
|
| jd | 🌐 | item |
| jike | 🌐 | feed search create like comment repost notifications post topic user |
| jimeng | 🌐 | generate history |
| ke | 🌐 | ershoufang chengjiao xiaoqu zufang |
| lesswrong | ✅ | frontpage curated new top top-week top-month top-year shortform read comments user user-posts sequences tags tag |
| lichess | ✅ | top user |
| 🌐 | search timeline |
|
| linux-do | 🌐 | hot latest feed search categories category tags topic topic-content user-posts user-topics |
| lobsters | ✅ | hot newest active tag |
| maimai | 🌐 | search-talents |
| maven | ✅ | search artifact |
| mdn | ✅ | search |
| medium | 🌐 | feed search user |
| mubu | 🌐 | search recent doc docs notes |
| notebooklm | 🌐 | status list open current get history summary note-list notes-get source-list source-get source-fulltext source-guide |
| nowcoder | 🌐 | hot trending search suggest jobs companies experience salary practice papers topics creators detail notifications recommend referral |
| npm | ✅ | search package downloads |
| nuget | ✅ | search package |
| nvd | ✅ | cve |
| oeis | ✅ | search sequence |
| ones | 🌐 | login logout me tasks task my-tasks worklog token-info |
| openalex | ✅ | search work |
| openfda | ✅ | drug-label food-recall |
| openreview | ✅ | search paper author venue reviews |
| osv | ✅ | vulnerability query |
| packagist | ✅ | search package |
| pixiv | 🌐 | ranking search user illusts detail download |
| powerchina | 🌐 | search |
| producthunt | ✅ | today hot browse posts |
| pubmed | ✅ | search article author citations related |
| pypi | ✅ | package downloads |
| quark | 🌐 | ls mkdir mv rename rm save share-tree |
| qwen | 🌐 | status new send read ask image detail history |
| 🌐 | hot frontpage home popular search subreddit subreddit-info read user user-posts user-comments upvote save comment reply subscribe saved upvoted whoami |
|
| rednote | 🌐 | search feed user note comments download notifications |
| rest-countries | ✅ | country region |
| reuters | 🌐 | search |
| rfc | ✅ | rfc |
| rubygems | ✅ | search gem |
| sinablog | 🌐 | hot search article user |
| sinafinance | ✅ | news |
| smzdm | 🌐 | search |
| spotify | ✅ | auth status play pause next prev volume search queue shuffle repeat |
| stackoverflow | ✅ | hot search bounties unanswered |
| steam | ✅ | top-sellers |
| substack | 🌐 | feed search publication |
| taobao | 🌐 | search detail reviews add-cart cart |
| tdx | 🌐 | hot-rank |
| ths | 🌐 | hot-rank |
| tieba | 🌐 | hot search posts read |
| tiktok | 🌐 | explore search profile user following follow unfollow like unlike comment save unsave live notifications friends |
| toutiao | 🌐 | hot articles |
| tvmaze | ✅ | search show |
| 🌐 | trending bookmarks search profile timeline thread article follow unfollow bookmark unbookmark bookmark-folders post like likes reply quote retweet unretweet delete block unblock followers following notifications download lists list-tweets list-add list-remove tweets unlike spaces |
|
| uisdc | 🌐 | news |
| uiverse | 🌐 | code preview |
| v2ex | ✅🌐 | Public: hot latest topic node nodes member user replies · Browser: daily me notifications |
| wanfang | 🌐 | search |
| web | 🌐 | read — any URL to Markdown |
| 🌐 | hot search feed user me post comments |
|
| wikidata | ✅ | search entity |
| wikipedia | ✅ | search summary random trending |
| weixin | 🌐 | download — 公众号 article to Markdown |
| weread | 🌐 | shelf search book highlights notes notebooks ranking |
| wttr | ✅ | current forecast |
| xianyu | 🌐 | search item chat |
| xiaoe | 🌐 | courses catalog content detail play-url |
| xiaohongshu | 🌐 | search notifications feed user note comments download publish creator-notes creator-note-detail creator-notes-summary creator-profile creator-stats |
| xiaoyuzhou | ✅ | podcast podcast-episodes episode |
| xueqiu | 🌐 | hot-stock stock watchlist feed hot search comments earnings-date fund-holdings fund-snapshot |
| yahoo | 🌐 | search |
| yahoo-finance | 🌐 | quote |
| yollomi | 🌐 | models generate video upload remove-bg edit background face-swap object-remover restore try-on upscale |
| youtube | 🌐 | search video transcript feed history channel playlist comments like unlike subscribe unsubscribe subscriptions watch-later |
| yuanbao | 🌐 | new ask |
| zhihu | 🌐 | hot search question |
| zlibrary | 🌐 | search info |
| zsxq | 🌐 | groups dynamics topics topic search |
Desktop Apps (CDP/Electron)
| App | Commands |
|---|---|
| antigravity | status send read new dump extract-code model watch |
| chatgpt-app | status new send read ask model |
| chatwise | status new send read ask model history export screenshot |
| codex | status send read new dump extract-diff model ask screenshot history export |
| cursor | status send read new dump composer model extract-code ask screenshot history export |
| discord-app | status send read channels servers search members |
| doubao-app | status new send read ask screenshot dump |
| notion | status search read new write sidebar favorites export |
External CLI (passthrough)
| CLI | Installed | Description |
|---|---|---|
| gh | ✅ | GitHub CLI — repos, PRs, issues, releases |
| obsidian | ✅ | Obsidian vault — notes, search, tags |
| docker | ✅ | Docker CLI |
| lark-cli | ✅ | Lark/Feishu — messages, docs, calendar, tasks (200+ commands) |
| vercel | ✅ | Vercel — deploy, domains, env vars, logs |
| wx | ✅ | WeChat local data CLI — sessions, messages, search, export |
| discord | ❌ | Discord CLI |
| dws | ❌ | DingTalk Workspace |
| longbridge | ❌ | Longbridge CLI — market data, account, trading |
| ntn | ❌ | Notion CLI |
| tg | ❌ | Telegram CLI |
| wecom-cli | ❌ | WeCom/企业微信 |
opencli external install discord # Install external CLI
opencli external list # Show all external CLIs
opencli gh pr list --limit 5 # Passthrough to gh
opencli wx messages # Passthrough to wx-cli
Management Commands
opencli list [-f json|yaml] # All available commands
opencli doctor # Diagnose extension + daemon
opencli daemon status|restart|stop # Daemon control
opencli adapter eject [site] # Eject adapter to ~/.opencli/clis/ for local editing
opencli adapter reset [site] # Reset ejected adapter to upstream
opencli profile list|use|rename # Chrome profile management
opencli plugin list|install|update # Plugin management
Browser Automation
Control Chrome step-by-step. Reuses existing login sessions.
Critical Rules
- Always
statefirst — never guess element indices.statereturns structured DOM with[N]indices, is instant and costs zero tokens. - Never use
evalto click or type — useclick <N>andtype <N> "text"instead. - Verify inputs with
get value— aftertype, runget value <index>to confirm. - Run
stateafter every page change — afteropen,click(on links),scroll. - Chain commands aggressively —
open + state,type + type + clickin one&&chain. Target 3-5 tool calls total. evalis read-only — use ONLY for data extraction (JSON.stringify(...)), never for clicking/typing/navigating.- Prefer
networkto discover APIs — JSON APIs are more reliable than DOM scraping.
Command Cost Guide
| Cost | Commands |
|---|---|
| Free & instant | state, get *, eval, network, scroll, keys |
| Free but changes page | open, click, type, select, back |
| Expensive (vision) | screenshot — ONLY when user needs a saved image |
Commands
# Navigation
opencli browser open <url>
opencli browser back
opencli browser scroll down|up [--amount N]
# Inspect (free)
opencli browser state # Primary — structured DOM with [N] indices
opencli browser screenshot [path.png] # Only for user deliverables
# Get (free)
opencli browser get title|url|html
opencli browser get text|value|attributes <index>
# Interact
opencli browser click <index>
opencli browser type <index> "text"
opencli browser select <index> "option"
opencli browser keys "Enter" # Enter, Escape, Tab, Control+a
# Wait
opencli browser wait time 3
opencli browser wait selector ".loaded" [--timeout 5000]
opencli browser wait text "Success"
# Extract (read-only)
opencli browser eval "JSON.stringify([...document.querySelectorAll('h2')].map(e => e.textContent))"
# Network (API discovery)
opencli browser network
opencli browser network --detail 3 # Full response body of request #3
# Save as CLI
opencli browser init hn/top # Scaffold adapter at ~/.opencli/clis/hn/top.ts
opencli browser verify hn/top # Test the adapter
opencli browser close
Chaining Examples
# GOOD: open + inspect in one call
opencli browser open https://example.com && opencli browser state
# GOOD: fill form in one call
opencli browser type 3 "hello" && opencli browser type 4 "world" && opencli browser click 7
# GOOD: click + wait + state (for page-changing clicks)
opencli browser click 12 && opencli browser wait time 1 && opencli browser state
Troubleshooting
| Error | Fix |
|---|---|
| "Browser not connected" | Run opencli doctor |
| "attach failed: chrome-extension://" | Disable 1Password temporarily |
| Element not found | opencli browser scroll down && opencli browser state |
| Stale indices after page change | Run opencli browser state again |
Auto-Fix Broken Adapters
When an opencli command fails because a website changed its DOM/API, automatically diagnose, fix, and retry — don't just report the error.
Safety Boundaries
AUTH_REQUIRED(exit 77) — STOP. Tell user to log in. Do not modify code.BROWSER_CONNECT(exit 69) — STOP. Tell user to runopencli doctor.- CAPTCHA / rate limiting — STOP. Not an adapter issue.
- Only modify the file at
RepairContext.adapter.sourcePath. Never touchsrc/,extension/,tests/,package.json. - Max 3 repair rounds per failure.
Before Repairing: "Empty" ≠ "Broken"
EMPTY_RESULT is often NOT a bug — platforms degrade results under anti-scrape heuristics. Before patching:
- Retry with an alternative query (e.g.,
"AI 攻略"vs"AI") - Spot-check in a normal Chrome tab — if visible there but empty via adapter, it's auth/rate-limit
0 resultsfrom a search is a valid answer, not a bug
Repair Workflow
Step 1: Collect diagnostics
OPENCLI_DIAGNOSTIC=1 opencli <site> <command> [args...] 2>diagnostic.json
cat diagnostic.json | sed -n '/___OPENCLI_DIAGNOSTIC___/{n;p;}'
Output is a RepairContext JSON with: error.code, adapter.sourcePath, adapter.source, page.snapshot, page.networkRequests.
Step 2: Classify the failure
| Error Code | Likely Cause | Strategy |
|---|---|---|
| SELECTOR | DOM restructured | Explore current DOM → find new selector |
| EMPTY_RESULT | API response schema changed | Check network → find new response path |
| API_ERROR | Endpoint URL changed | Discover new API via network intercept |
| AUTH_REQUIRED | Cookies expired | STOP — tell user to log in |
| TIMEOUT | Page loads differently | Add/update wait conditions |
Step 3: Explore live site
# DOM changed
opencli browser open https://example.com/target-page && opencli browser state
# API changed
opencli browser open https://example.com && opencli browser network
opencli browser network --detail <index>
Step 4: Patch the adapter
Read RepairContext.adapter.sourcePath and make minimal targeted fixes:
- Selector update: replace
.old-classwith.new-class - API endpoint: update URL in
fetch() - Response schema: fix data path (
data.results→data.data.items)
Step 5: Verify
opencli <site> <command> [args...] # Run without diagnostic mode
If still failing, go back to Step 1. After 3 rounds, stop and report what was tried.
Create New Adapters
Quick Method (4 steps — for a single URL + goal)
Open page + capture API
# Navigate and wait 3-5s for page to load # Check network for JSON APIs opencli browser open <url> && opencli browser wait time 3 && opencli browser networkLock down the target API — find the one returning
application/jsonwith the data you needVerify the API is reusable
# Test in browser context fetch('/api/endpoint', { credentials: 'include' }).then(r => r.json())Write adapter from template (see templates below)
Auth decision tree:
fetch(url) works? → Tier 1: PUBLIC (browser: false)
fetch(url, {credentials:'include'}) works? → Tier 2: COOKIE (most common)
Needs Bearer/CSRF header? → Tier 3: HEADER
Page requests it but fetch can't? → Tier 4: INTERCEPT (installInterceptor)
Adapter Templates
Tier 1 — Public API (fastest)
// ~/.opencli/clis/<site>/<name>.ts
import { cli, Strategy } from '@jackwener/opencli/registry';
cli({
site: 'mysite', name: 'hot', description: '一句话描述',
domain: 'www.example.com',
strategy: Strategy.PUBLIC, browser: false,
args: [{ name: 'limit', type: 'int', default: 20 }],
columns: ['rank', 'title', 'score'],
func: async (_page, kwargs) => {
const res = await fetch('https://api.example.com/hot');
const data = await res.json();
return data.items.slice(0, kwargs.limit).map((item: any, i: number) => ({
rank: i + 1, title: item.title, score: item.score,
}));
},
});
Tier 2 — Cookie auth (most common)
import { cli, Strategy } from '@jackwener/opencli/registry';
cli({
site: 'mysite', name: 'feed', description: '一句话描述',
domain: 'www.example.com',
strategy: Strategy.COOKIE, browser: true,
args: [{ name: 'limit', type: 'int', default: 20 }],
columns: ['rank', 'title', 'value'],
func: async (page, kwargs) => {
await page.goto('https://www.example.com');
const data = await page.evaluate(`(async () => {
const res = await fetch('/api/feed', { credentials: 'include' });
const d = await res.json();
return (d.data?.items || []).map(item => ({ title: item.title, value: item.value }));
})()`);
return (data as any[]).slice(0, kwargs.limit).map((item, i) => ({
rank: i + 1, title: item.title || '', value: item.value || '',
}));
},
});
Tier 4 — Intercept (for sites with signing/anti-scrape)
import { cli, Strategy } from '@jackwener/opencli/registry';
cli({
site: 'mysite', name: 'feed', description: '一句话描述',
domain: 'www.example.com',
strategy: Strategy.INTERCEPT, browser: true,
args: [{ name: 'limit', type: 'int', default: 20 }],
columns: ['rank', 'title', 'value'],
func: async (page, kwargs) => {
await page.goto('https://www.example.com/target');
await page.wait(3);
await page.installInterceptor('api-keyword'); // URL substring match
await page.autoScroll({ times: 2, delayMs: 2000 }); // Trigger lazy load
const requests = await page.getInterceptedRequests();
if (!requests?.length) return [];
const results: any[] = [];
for (const req of requests) {
results.push(...(req.data?.data?.items || []));
}
return results.slice(0, kwargs.limit).map((item, i) => ({
rank: i + 1, title: item.title || '', value: item.value || '',
}));
},
});
Test After Writing
npm run build # Syntax check
opencli list | grep mysite # Confirm registered
opencli mysite mycommand --limit 3 -v # Verify actual output
Full Exploration Guide (for new sites)
When you need to explore a site from scratch rather than a single URL:
Step 1: API Discovery
opencli explore https://www.example.com --site mysite
Outputs to .opencli/explore/mysite/: endpoints.json, capabilities.json, auth.json
Or auto-generate everything:
opencli generate https://www.example.com --goal "hot"
Key discovery tactics:
.jsonsuffix trick — Reddit-style sites: just append.jsonto URL for clean REST data__INITIAL_STATE__— SSR sites (Bilibili, Xiaohongshu) embed data inwindow.__INITIAL_STATE__- Active interaction — Lazy-load APIs (comments, subtitles) only appear after clicking a button
- Pinia/Vuex intercept — Vue sites: call store actions to trigger signed requests without reverse-engineering signatures
Step 2: Pick auth tier — run opencli cascade <api-url> to auto-detect
Step 3: Find existing adapter to copy — ls clis/<site>/, copy the closest one, change 3 fields: name, API URL, field mapping
Step 4: Test
opencli mysite hot --limit 3 -v # verbose: see pipeline data flow
opencli mysite hot -f json | jq '.[0]' # confirm JSON structure
Common pitfalls:
| Pitfall | Fix |
|---|---|
Missing navigate before evaluate |
Add page.goto() before evaluate |
| Public API starts browser anyway | Add strategy: Strategy.PUBLIC, browser: false |
evaluate returns empty on SPA |
Add wait selector or wait time before evaluate |
| Cookie expired | Re-login in Chrome |
EMPTY_RESULT after intercept |
Check if installInterceptor keyword matches actual URL |