opencli-operate
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseOpenCLI — Make Websites Accessible for AI Agents
OpenCLI — 让网站可被AI Agent访问
Control Chrome step-by-step via CLI. Reuses existing login sessions — no passwords needed.
通过CLI逐步控制Chrome。复用现有登录会话,无需输入密码。
Prerequisites
前置条件
bash
opencli doctor # Verify extension + daemon connectivityRequires: Chrome running + OpenCLI Browser Bridge extension installed.
bash
opencli doctor # Verify extension + daemon connectivity要求:Chrome正在运行,且已安装OpenCLI Browser Bridge扩展。
Quickstart for AI Agents (1 step)
AI Agent快速上手(1步)
Point your AI agent to this file. It contains everything needed to operate browsers.
将你的AI Agent指向此文件,它包含操作浏览器所需的所有内容。
Quickstart for Humans (3 steps)
普通用户快速上手(3步)
bash
npm install -g @jackwener/opencli # 1. Installbash
npm install -g @jackwener/opencli # 1. InstallInstall extension from chrome://extensions # 2. Load extension
Install extension from chrome://extensions # 2. Load extension
opencli operate open https://example.com # 3. Go!
undefinedopencli operate open https://example.com # 3. Go!
undefinedCore Workflow
核心工作流
- Navigate:
opencli operate open <url> - Inspect: → see elements with
opencli operate stateindices[N] - Interact: use indices — ,
click,type,selectkeys - Wait: or
opencli operate wait selector ".loaded"wait text "Success" - Verify: or
opencli operate get titleopencli operate screenshot - Repeat: browser stays open between commands
- Save: write a TS adapter to
~/.opencli/clis/<site>/<command>.ts
- 导航:
opencli operate open <url> - 检查:→ 查看带有
opencli operate state索引的元素[N] - 交互:使用索引执行、
click、type、select操作keys - 等待:或
opencli operate wait selector ".loaded"wait text "Success" - 验证:或
opencli operate get titleopencli operate screenshot - 重复:浏览器在命令执行间隙保持打开状态
- 保存:编写TS适配器保存到
~/.opencli/clis/<site>/<command>.ts
Commands
命令
Navigation
导航
bash
opencli operate open <url> # Open URL
opencli operate back # Go back
opencli operate scroll down # Scroll (up/down, --amount N)
opencli operate scroll up --amount 1000bash
opencli operate open <url> # Open URL
opencli operate back # Go back
opencli operate scroll down # Scroll (up/down, --amount N)
opencli operate scroll up --amount 1000Inspect
检查
bash
opencli operate state # Elements with [N] indices
opencli operate screenshot [path.png] # Screenshotbash
opencli operate state # Elements with [N] indices
opencli operate screenshot [path.png] # ScreenshotGet (structured data)
获取(结构化数据)
bash
opencli operate get title # Page title
opencli operate get url # Current URL
opencli operate get text <index> # Element text content
opencli operate get value <index> # Input/textarea value
opencli operate get html # Full page HTML
opencli operate get html --selector "h1" # Scoped HTML
opencli operate get attributes <index> # Element attributesbash
opencli operate get title # Page title
opencli operate get url # Current URL
opencli operate get text <index> # Element text content
opencli operate get value <index> # Input/textarea value
opencli operate get html # Full page HTML
opencli operate get html --selector "h1" # Scoped HTML
opencli operate get attributes <index> # Element attributesInteract
交互
bash
opencli operate click <index> # Click element [N]
opencli operate type <index> "text" # Type into element [N]
opencli operate select <index> "option" # Select dropdown
opencli operate keys "Enter" # Press key (Enter, Escape, Tab, Control+a)bash
opencli operate click <index> # Click element [N]
opencli operate type <index> "text" # Type into element [N]
opencli operate select <index> "option" # Select dropdown
opencli operate keys "Enter" # Press key (Enter, Escape, Tab, Control+a)Wait
等待
bash
opencli operate wait selector ".loaded" # Wait for element
opencli operate wait selector ".spinner" --timeout 5000 # With timeout
opencli operate wait text "Success" # Wait for text
opencli operate wait time 3 # Wait N secondsbash
opencli operate wait selector ".loaded" # Wait for element
opencli operate wait selector ".spinner" --timeout 5000 # With timeout
opencli operate wait text "Success" # Wait for text
opencli operate wait time 3 # Wait N secondsExtract
提取
bash
opencli operate eval "document.title"
opencli operate eval "JSON.stringify([...document.querySelectorAll('h2')].map(e => e.textContent))"bash
opencli operate eval "document.title"
opencli operate eval "JSON.stringify([...document.querySelectorAll('h2')].map(e => e.textContent))"Network (API Discovery)
网络(API发现)
bash
opencli operate network # Show captured API requests (auto-captured since open)
opencli operate network --detail 3 # Show full response body of request #3
opencli operate network --all # Include static resourcesbash
opencli operate network # Show captured API requests (auto-captured since open)
opencli operate network --detail 3 # Show full response body of request #3
opencli operate network --all # Include static resourcesSedimentation (Save as CLI)
沉淀(保存为CLI命令)
bash
opencli operate init hn/top # Generate adapter scaffold
opencli operate verify hn/top # Test the adapterbash
opencli operate init hn/top # Generate adapter scaffold
opencli operate verify hn/top # Test the adapterSession
会话
bash
opencli operate close # Close automation windowbash
opencli operate close # Close automation windowExample: Extract HN Stories
示例:提取Hacker News文章
bash
opencli operate open https://news.ycombinator.com
opencli operate state # See [1] a "Story 1", [2] a "Story 2"...
opencli operate eval "JSON.stringify([...document.querySelectorAll('.titleline a')].slice(0,5).map(a => ({title: a.textContent, url: a.href})))"
opencli operate closebash
opencli operate open https://news.ycombinator.com
opencli operate state # See [1] a "Story 1", [2] a "Story 2"...
opencli operate eval "JSON.stringify([...document.querySelectorAll('.titleline a')].slice(0,5).map(a => ({title: a.textContent, url: a.href})))"
opencli operate closeExample: Fill a Form
示例:填写表单
bash
opencli operate open https://httpbin.org/forms/post
opencli operate state # See [3] input "Customer Name", [4] input "Telephone"
opencli operate type 3 "OpenCLI"
opencli operate type 4 "555-0100"
opencli operate get value 3 # Verify: "OpenCLI"
opencli operate closebash
opencli operate open https://httpbin.org/forms/post
opencli operate state # See [3] input "Customer Name", [4] input "Telephone"
opencli operate type 3 "OpenCLI"
opencli operate type 4 "555-0100"
opencli operate get value 3 # Verify: "OpenCLI"
opencli operate closeSaving as Reusable CLI — Complete Workflow
保存为可复用CLI——完整工作流
Step-by-step sedimentation flow:
分步沉淀流程:
bash
undefinedbash
undefined1. Explore the website
1. 探索网站
opencli operate open https://news.ycombinator.com
opencli operate state # Understand DOM structure
opencli operate open https://news.ycombinator.com
opencli operate state # 了解DOM结构
2. Discover APIs (crucial for high-quality adapters)
2. 发现API(高质量适配器的关键)
opencli operate eval "fetch('/api/...').then(r=>r.json())" # Trigger API calls
opencli operate network # See captured API requests
opencli operate network --detail 0 # Inspect response body
opencli operate eval "fetch('/api/...').then(r=>r.json())" # 触发API调用
opencli operate network # 查看捕获的API请求
opencli operate network --detail 0 # 查看响应体内容
3. Generate scaffold
3. 生成脚手架
opencli operate init hn/top # Creates ~/.opencli/clis/hn/top.ts
opencli operate init hn/top # 创建 ~/.opencli/clis/hn/top.ts
4. Edit the adapter (fill in func logic)
4. 编辑适配器(补充函数逻辑)
- If API found: use fetch() directly (Strategy.PUBLIC or COOKIE)
- 如果找到API:直接使用fetch()(Strategy.PUBLIC或COOKIE)
- If no API: use page.evaluate() for DOM extraction (Strategy.UI)
- 如果没有API:使用page.evaluate()做DOM提取(Strategy.UI)
5. Verify
5. 验证
opencli operate verify hn/top # Runs the adapter and shows output
opencli operate verify hn/top # 运行适配器并展示输出
6. If verify fails, edit and retry
6. 如果验证失败,编辑后重试
7. Close when done
7. 完成后关闭
opencli operate close
undefinedopencli operate close
undefinedExample adapter:
适配器示例:
typescript
// ~/.opencli/clis/hn/top.ts
import { cli, Strategy } from '@jackwener/opencli/registry';
cli({
site: 'hn',
name: 'top',
description: 'Top Hacker News stories',
domain: 'news.ycombinator.com',
strategy: Strategy.PUBLIC,
browser: false,
args: [{ name: 'limit', type: 'int', default: 5 }],
columns: ['rank', 'title', 'score', 'url'],
func: async (_page, kwargs) => {
const limit = Math.min(Math.max(1, kwargs.limit ?? 5), 50);
const resp = await fetch('https://hacker-news.firebaseio.com/v0/topstories.json');
const ids = await resp.json();
return Promise.all(
ids.slice(0, limit).map(async (id: number, i: number) => {
const item = await (await fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json`)).json();
return { rank: i + 1, title: item.title, score: item.score, url: item.url ?? '' };
})
);
},
});Save to → immediately available as .
~/.opencli/clis/<site>/<command>.tsopencli <site> <command>typescript
// ~/.opencli/clis/hn/top.ts
import { cli, Strategy } from '@jackwener/opencli/registry';
cli({
site: 'hn',
name: 'top',
description: 'Top Hacker News stories',
domain: 'news.ycombinator.com',
strategy: Strategy.PUBLIC,
browser: false,
args: [{ name: 'limit', type: 'int', default: 5 }],
columns: ['rank', 'title', 'score', 'url'],
func: async (_page, kwargs) => {
const limit = Math.min(Math.max(1, kwargs.limit ?? 5), 50);
const resp = await fetch('https://hacker-news.firebaseio.com/v0/topstories.json');
const ids = await resp.json();
return Promise.all(
ids.slice(0, limit).map(async (id: number, i: number) => {
const item = await (await fetch(`https://hacker-news.firebaseio.com/v0/item/${id}.json`)).json();
return { rank: i + 1, title: item.title, score: item.score, url: item.url ?? '' };
})
);
},
});保存到 → 即可立即作为命令使用。
~/.opencli/clis/<site>/<command>.tsopencli <site> <command>Strategy Guide
策略指南
| Strategy | When | browser: |
|---|---|---|
| Public API, no auth | |
| Needs login cookies | |
| Direct DOM interaction | |
Always prefer API over UI — if you discovered an API during browsing, use directly.
fetch()| 策略 | 适用场景 | browser取值 |
|---|---|---|
| 公开API,无需鉴权 | |
| 需要登录cookie | |
| 直接DOM交互 | |
始终优先使用API而非UI——如果你在浏览过程中发现了API,直接使用调用即可。
fetch()Troubleshooting
故障排查
| Error | Fix |
|---|---|
| "Browser not connected" | Run |
| "attach failed: chrome-extension://" | Disable 1Password temporarily |
| Element not found | |
| 错误 | 修复方案 |
|---|---|
| "Browser not connected" | 运行 |
| "attach failed: chrome-extension://" | 临时禁用1Password |
| 元素未找到 | 执行 |