mcpField
O
opencli-operate

opencli-operate

github.com/jackwenerAgent 工作流30.7k1.9k 次安装2 天前更新
代码仓库

关于 opencli-operate

opencli-operate 是面向 AI Agent 的浏览器自动化技能,通过命令行逐步控制 Chrome,并复用已有登录会话。它提供结构化页面检查、交互、数据提取和 API 探索,也可将操作沉淀为可复用的 CLI adapter。

主要功能

  1. 01通过命令行控制 Chrome
  2. 02检查结构化页面状态与元素
  3. 03点击、输入、选择及键盘操作
  4. 04读取页面数据并检查网络请求
  5. 05生成并验证可复用 CLI adapter

适用场景

  1. 01使用已有登录会话操作网站
  2. 02填写网页表单并核对输入
  3. 03从页面或 API 提取数据
  4. 04将重复浏览任务保存为 CLI 命令

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jackwener/opencli --skill opencli-operate

安装后在 Claude Code 中输入/opencli-operate确认已加载。

详细介绍

OpenCLI Operate — 面向 AI Agent 的浏览器自动化

通过命令行逐步控制 Chrome。复用已有的登录会话,无需密码。

前置条件

opencli doctor    # Verify extension + daemon connectivity

要求:Chrome 正在运行,并已安装 OpenCLI Browser Bridge 扩展。

关键规则

  1. 始终使用 state 检查页面,绝不使用 screenshot — state 返回带有 [N] 元素索引的结构化 DOM,即时完成且不消耗 token。screenshot 需要视觉处理,速度慢。只有当用户明确要求保存视觉图像时才使用 screenshot。
  2. 交互始终使用 click/type/select,绝不使用 eval 来点击或输入 — eval "el.click()" 会绕过 scrollIntoView 和 CDP 点击流程,导致对视口外元素的操作失败。使用 state 找到 [N] 索引,然后执行 click <N>。
  3. 用 get value 验证输入,而不是截图 — 执行 type 后,运行 get value <index> 进行确认。
  4. 每次页面变化后运行 state — 在 open、click(点击链接)、scroll 之后,始终运行 state 以查看新元素及其索引。切勿猜测索引。
  5. 积极使用 && 串联命令 — 将 open + state、多个 type 调用以及 type + get value 合并到单个 && 链中。每次工具调用都有开销,串联可以减少开销。
  6. eval 仅用于读取 — 只能用 eval 进行数据提取(JSON.stringify(...)),绝不用于点击、输入或导航。始终包裹在 IIFE 中以避免变量冲突:eval "(function(){ const x = ...; return JSON.stringify(x); })()"。
  7. 尽量减少工具调用总数 — 行动前先规划好步骤顺序。一次良好的任务完成应使用 3-5 次工具调用,而不是 15-20 次。将 open + state 合并为一次调用。将 type + type + click 合并为一次调用。只有在需要发现新索引时才单独运行 state。
  8. 优先使用 network 发现 API — 大多数网站都提供 JSON API。基于 API 的适配器比 DOM 抓取更可靠。

命令成本指南

成本命令使用时机
免费且即时state、get *、eval、network、scroll、keys默认使用这些
免费但会改变页面open、click、type、select、back交互操作 — 之后运行 state
高成本(视觉 token)screenshot仅当用户需要保存图像时

操作串联规则

命令可以用 && 串联。浏览器通过守护进程保持运行,因此串联是安全的。

尽可能始终串联 — 工具调用越少,完成越快:

# GOOD: open + inspect in one call (saves 1 round trip)
opencli operate open https://example.com && opencli operate state

# GOOD: fill form in one call (saves 2 round trips)
opencli operate type 3 "hello" && opencli operate type 4 "world" && opencli operate click 7

# GOOD: type + verify in one call
opencli operate type 5 "[email protected]" && opencli operate get value 5

# GOOD: click + wait + state in one call (for page-changing clicks)
opencli operate click 12 && opencli operate wait time 1 && opencli operate state

# BAD: separate calls for each action (wasteful)
opencli operate type 3 "hello"    # Don't do this
opencli operate type 4 "world"    # when you can chain
opencli operate click 7            # all three together

会改变页面的命令 — 始终放在链的最后(后续命令会看到过时的索引):

  • open <url>、back、click <会导航的链接/按钮>

规则:当你已经知道索引时进行串联。当需要先发现索引时,单独运行 state。

核心工作流

  1. 导航:opencli operate open <url>
  2. 检查:opencli operate state → 带有 [N] 索引的元素
  3. 交互:使用索引 — click、type、select、keys
  4. 等待(如需要):opencli operate wait selector ".loaded" 或 wait text "Success"
  5. 验证:opencli operate state 或 opencli operate get value <N>
  6. 重复:命令之间浏览器保持打开
  7. 保存:将 TS 适配器写入 ~/.opencli/clis/<site>/<command>.ts

命令

导航
opencli operate open <url>              # Open URL (page-changing)
opencli operate back                    # Go back (page-changing)
opencli operate scroll down             # Scroll (up/down, --amount N)
opencli operate scroll up --amount 1000
检查(免费且即时)
opencli operate state                   # Structured DOM with [N] indices — PRIMARY tool
opencli operate screenshot [path.png]   # Save visual to file — ONLY for user deliverables
获取(免费且即时)
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 (use to verify after type)
opencli operate get html                # Full page HTML
opencli operate get html --selector "h1" # Scoped HTML
opencli operate get attributes <index>  # Element attributes
交互
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)
等待

有三种变体 — 根据情况选择合适的一种:

opencli operate wait time 3                       # Wait N seconds (fixed delay)
opencli operate wait selector ".loaded"            # Wait until element appears in DOM
opencli operate wait selector ".spinner" --timeout 5000  # With timeout (default 30s)
opencli operate wait text "Success"                # Wait until text appears on page

何时等待:在 SPA 上执行 open 之后、触发异步加载的 click 之后,以及对动态渲染内容执行 eval 之前。

提取(免费且即时,只读)

仅使用 eval 读取数据。绝不用它来点击、输入或导航。

opencli operate eval "document.title"
opencli operate eval "JSON.stringify([...document.querySelectorAll('h2')].map(e => e.textContent))"

# IMPORTANT: wrap complex logic in IIFE to avoid "already declared" errors
opencli operate eval "(function(){ const items = [...document.querySelectorAll('.item')]; return JSON.stringify(items.map(e => e.textContent)); })()"

选择器安全:始终使用备用选择器 — querySelector 未匹配时返回 null:

# BAD: crashes if selector misses
opencli operate eval "document.querySelector('.title').textContent"

# GOOD: fallback with || or ?.
opencli operate eval "(document.querySelector('.title') || document.querySelector('h1') || {textContent:''}).textContent"
opencli operate eval "document.querySelector('.title')?.textContent ?? 'not found'"
网络(API 发现)
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 resources
沉淀为 CLI(Save as CLI)
opencli operate init hn/top              # Generate adapter scaffold at ~/.opencli/clis/hn/top.ts
opencli operate verify hn/top            # Test the adapter (adds --limit 3 only if `limit` arg is defined)
  • init 会从当前活动的浏览器会话中自动检测域名(无需手动指定)
  • init 会创建文件,并从当前页面填充 site、name、domain 和 columns
  • verify 会端到端运行适配器并打印输出;如果适配器中没有 limit 参数,则不会传入 --limit 3
会话(Session)
opencli operate close                   # Close automation window

示例:提取 HN 故事

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 close

示例:填写表单

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 close

保存为可复用的 CLI:完整流程

分步沉淀流程:
# 1. Explore the website
opencli operate open https://news.ycombinator.com
opencli operate state                          # Understand DOM structure

# 2. Discover APIs (crucial for high-quality adapters)
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

# 3. Generate scaffold
opencli operate init hn/top                    # Creates ~/.opencli/clis/hn/top.ts

# 4. Edit the adapter (fill in func logic)
# - If API found: use fetch() directly (Strategy.PUBLIC or COOKIE)
# - If no API: use page.evaluate() for DOM extraction (Strategy.UI)

# 5. Verify
opencli operate verify hn/top                  # Runs the adapter and shows output

# 6. If verify fails, edit and retry
# 7. Close when done
opencli operate close
示例适配器:
// ~/.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>.ts 后,即可立即通过 opencli <site> <command> 使用。

策略指南
策略适用场景browser:
Strategy.PUBLIC公开 API,无需认证false
Strategy.COOKIE需要登录 Cookietrue
Strategy.UI直接操作 DOMtrue

始终优先使用 API 而非 UI:如果你在浏览过程中发现了 API,直接使用 fetch() 调用。

实用技巧

  1. 始终先执行 state:不要猜测元素索引,务必先检查
  2. 会话会保持:浏览器在命令之间保持打开,无需重新打开
  3. 使用 eval 提取数据:eval "JSON.stringify(...)" 比多次调用 get 更快
  4. 使用 network 查找 API:JSON API 比 DOM 抓取更可靠
  5. 别名:opencli op 是 opencli operate 的简写

常见误区

  1. form.submit() 在自动化中会失败:不要使用 form.submit() 或 eval 提交表单。请直接导航到搜索 URL:

    # BAD: form.submit() often silently fails
    opencli operate eval "document.querySelector('form').submit()"
    # GOOD: construct the URL and navigate
    opencli operate open "https://github.com/search?q=opencli&type=repositories"
    
  2. GitHub 的 DOM 经常变化:如果可用,优先使用 data-testid 属性;它们比类名或标签结构更稳定。

  3. SPA 页面在提取前需要 wait:在单页应用上执行 open 或 click 后,DOM 不会立即就绪。在执行 eval 之前,务必先执行 wait selector 或 wait text。

  4. 点击前先使用 state:运行 opencli operate state 检查可交互元素及其索引。不要凭记忆猜测索引。

  5. evaluate 在浏览器上下文中运行:适配器中的 page.evaluate() 在浏览器内执行。Node.js API(fs、path、process)不可用。网络请求请使用 fetch(),页面数据请使用 DOM API。

  6. page.evaluate 中的反引号会破坏 JSON 存储:编写需要以 JSON 形式存储或传输的适配器时,避免在 page.evaluate 中使用模板字符串。请改用字符串拼接或函数式 evaluate:

    // BAD: template literal backticks break when adapter is in JSON
    page.evaluate(`document.querySelector("${selector}")`)
    // GOOD: function-style evaluate
    page.evaluate((sel) => document.querySelector(sel), selector)
    

故障排查

错误解决方法
"Browser not connected"运行 opencli doctor
"attach failed: chrome-extension://"暂时禁用 1Password
找不到元素opencli operate scroll down && opencli operate state
页面变化后索引失效重新运行 opencli operate state 获取最新索引

评论

支持 Markdown