opencli-browser

opencli-browser

熱門

当 Agent 需要通过 opencli 操作真实的 Chrome 窗口时使用 — 包含检视页面、填写表单、点击执行已登录流程或即时提取数据。涵盖选择器优先(selector-first)的目标契约、复合表单字段、过时引用(stale-ref)处理、网络包抓取,以及 CLI 返回的 Agent 原生数据封装(envelopes)。本 Skill 不用于撰写 Adapter — 撰写 Adapter 请参阅 opencli-adapter-author。

2.6萬星標
2565分支
更新於 2026/6/27
SKILL.md
唯讀
名稱
opencli-browser
描述

当 Agent 需要通过 opencli 操作真实的 Chrome 窗口时使用 — 包含检视页面、填写表单、点击执行已登录流程或即时提取数据。涵盖选择器优先(selector-first)的目标契约、复合表单字段、过时引用(stale-ref)处理、网络包抓取,以及 CLI 返回的 Agent 原生数据封装(envelopes)。本 Skill 不用于撰写 Adapter — 撰写 Adapter 请参阅 opencli-adapter-author。

opencli-browser

本 CLI 的首要读者是 Agent,而非人类。每一个子命令都会返回结构化的 Envelope,明确告知你匹配到的内容、匹配可信度(confidence),以及未匹配时的处理方式。请善用这些 Envelope,切勿靠盲猜。

本 Skill 用于操作实时/运行中的浏览器来完成 Agent 任务。如果你要在 ~/.opencli/clis/<site>/ 下构建可复用的 Adapter,请改用 opencli-adapter-author


Prerequisites(前置条件)

opencli doctor

doctor 检查全数通过(green)之前,其他功能都无法正常运作。常见的失败原因包括:Chrome 未运行、扩展程序未安装、调试端口(debug port)被 1Password 或其他扩展程序阻挡。doctor 的输出会明确提示问题出在哪。


Session lifecycle(会话生命周期)

  • opencli browser * 命令必须在 browser 之后紧接着传入 <session> 位置参数。多步骤流程请使用相同的会话名称;若要隔离平行的浏览器操作,请使用不同的会话名称。
  • 任何多命令或搭配人工节奏的浏览器工作流,都请使用固定的会话名称。例如:opencli browser fb-yaya-warmup open https://example.com,接着复用 opencli browser fb-yaya-warmup stateextractclick 等命令。
  • OpenCLI 专属的浏览器会话(Owned sessions)会在多次调用之间保持标签页租约(tab lease)。可以通过 opencli browser <session> close 释放租约,或等待闲置超时(idle timeout)自动过期。
  • opencli browser <session> bind 会将你当前已打开的 Chrome 标签页绑定到该会话。适用于已登录页面、SSO 单点登录流程,或在交由 Agent 控制前由你手动定位的页面。
  • --window foreground|background(或 OPENCLI_WINDOW=foreground|background)用于指定 OpenCLI 是要为专属会话创建/聚焦前台浏览器窗口,还是使用后台浏览器窗口。

Bind Tab(绑定标签页)

opencli browser gmail bind
opencli browser gmail state
opencli browser gmail click "Search"
opencli browser gmail network
opencli browser gmail unbind

绑定操作绝不会占用用户的窗口,也绝不会关闭用户的标签页。若标签页被关闭或无法再进行调试,它会采取安全失败机制(fail closed)。当切换到另一个真实的标签页时,请重新运行 opencli browser <session> bind

在已绑定的会话上允许导航操作,因为此时会话代表 Agent 已明确拥有该标签页的操作权。但针对已绑定的会话,标签页变更操作(tab newtab selecttab close)仍会被阻挡。如果你希望 OpenCLI 管理标签页的生命周期,请使用专属会话(owned session)。

已绑定会话没有 OpenCLI 的闲置自动关闭计时器;绑定关系会一直维持到执行 unbind、标签页关闭、窗口关闭或 Daemon 重启为止。


Mental model(心智模型)

  1. 选择器优先的目标契约(Selector-first target contract)。 每一个交互命令(clicktypeselectget text/value/attributes)都会接收一个 <target>,它可以是来自 state/find 的数字引用(numeric ref),或者是 CSS 选择器(CSS selector)。存在多个 CSS 匹配项时,可使用 --nth <n> 来消除歧义。
  2. 每个 Envelope 都会报告 matches_nmatch_level match_level 包含 exactstablereidentified — CLI 已经替你自动修正了轻度的 DOM 结构偏移,但该层级能告知你目前匹配的可信度有多高。
  3. 先提供精简输出,需要时再请求完整 Payload。 state 是兼顾上下文预算(context budget)的快照;get html --as json 支持 --depth/--children-max/--text-maxnetwork 会返回结构预览(shape previews),你可以通过 --detail <key> 重新获取单个响应体。如果你直接输出庞大的 Payload,就会无谓地消耗不需要消耗的上下文。
  4. 结构化错误是机器可读的。 发生失败时,CLI 会输出 {error: {code, message, hint?, candidates?}}。请根据 code 做出逻辑分支,而不是去匹配 message 字符串。

Critical rules(关键规则)

  1. 行动前务必先检视。 先运行 statefind。绝不要凭记忆跨会话硬编码 ref 或选择器 — 索引仅在单次快照内有效。
  2. 优先使用网站 Adapter,而非直接进行底层浏览器驱动。 如果 opencli <site> <command> 已经涵盖该任务,请优先使用该 Adapter 命令(例如 opencli facebook notificationsopencli reddit readopencli chatgpt model <level> 等)。仅在 Adapter 未提供、存在功能缺失、需要调试或处理一次性 UI 流程时,才使用 opencli browser ...
  3. 获取数字 Ref 后,优先于 CSS 选择器使用。 数字 ref 在 DOM 发生微调时仍能维持有效,因为 CLI 会为每个已标记的元素建立指纹(fingerprint)。手动编写的 CSS 选择器在网站重新渲染后很容易失效。
  4. 每次写入操作后都应检查 match_level exact = 一切正常。stable = 元素相同,但部分非关键属性发生了偏移 — 你的操作仍然生效。reidentified = 原始 ref 已消失,CLI 找到了唯一的替代元素并重新标记了旧 ref;请 double-check 确认是否操作到了正确的元素。
  5. 对表单控件使用 compound 字段。 不要用正则匹配去猜测日期格式,也不要运行两次 state 来获取完整的 <select> 选项列表。Compound envelope 包含格式化字符串、最多 50 个完整选项列表、用于处理溢出的 options_total,以及针对 <input type=file>accept/multiple 属性。
  6. 对关键的写入操作进行验证。 在执行 type <target> <text> 后,运行 get value <target>。在执行 select 后,运行 get value。自动补全控件(Autocomplete)、React 受控输入框(controlled inputs)以及掩码字段(masked fields)都有可能静默丢字。CLI 无法自动替你检测这种情况。
  7. 页面变更后遵循 state → 操作 → state 流程。 页面导航、表单提交和 SPA 路由变更都会导致之前的 ref 失效。请重新获取最新的快照。切勿复用页面切换前的 ref。
  8. 复用新解析的 ref 时,使用 && 链式调用。 链式调用的命令序列会在同一个 Shell 中运行,因此刚从输出中提取的 ref 可以直接传递给下一个命令。独立的 Shell 调用虽然能保留具名浏览器会话,但在页面变更后,前一个命令中的 Shell 局部变量或复制的 ref 可能会过时失效。
  9. eval 是纯读操作。 请将 JS 包装在 IIFE 中并返回 JSON。如果你需要修改页面,请改用结构化的 click / type / select / keys 命令 — 它们会生成结构化输出和指纹,而 eval 不会。
  10. 优先使用 network 抓取包,而非屏幕抓取(Screen-scraping)。 如果你关心的页面是通过 JSON API 获取数据的,使用 API 几乎总是比解析渲染后的 DOM 更可靠。抓取一次包,检视结构,然后用 --detail <key> 获取你需要的响应体。

Sitemaps(网站地图)

如果 browser openbrowser analyze 返回 sitemap.available: true,在继续进行多步骤网站流程前,请先切换到 opencli-browser-sitemap。Sitemap 是页面、操作、工作流、API 和踩坑点的前置上下文;但它并非绝对事实。如果浏览器当前状态与 Sitemap 不符,请以浏览器为准,并通过 opencli-sitemap-author 将 Sitemap 标记为过时(stale)。


Target contract(<target> 适用于 click / type / select / get text|value|attributes)

<target> ::= <numeric-ref> | <css-selector>
  • 数字 Ref(Numeric ref) — 来自 statefind[N] 索引。轻量且对 DOM 微调具备容错能力。
  • CSS 选择器(CSS selector) — 任何 querySelectorAll 支持的表达式。在写入操作中必须具备唯一性,或者搭配 --nth <n> 使用。

Envelope 成功响应格式

{ "clicked": true, "target": "3", "matches_n": 1, "match_level": "exact" }
{ "value": "kalevin@example.com", "matches_n": 1, "match_level": "stable" }

match_level 说明

层级(level) 含义 你应该怎么做
exact 标签(Tag)与强标识符(Strong IDs)完全一致,最多仅有一处非关键偏移 继续操作。
stable 标签与强标识符依然一致,但弱信号(aria-label, role, text)发生偏移 继续操作,但如果输入/点击的内容很关键,请用 get valuestate 再次核对。
reidentified 原始 ref 已不存在;一个新的实时元素匹配了该指纹,并重新标记为旧的 ref 在链式执行更多写入操作之前,务必 double-check 是否选中了正确的元素。

结构化错误代码

请针对以下代码(code)编写分支逻辑,而不是针对人类可读的 message:

代码(code) 含义
not_found 数字 ref 不再存在于 DOM 中。请重新运行 state
stale_ref ref 仍然存在,但该 ref 对应的元素身份已改变。请重新运行 state
invalid_selector CSS 选择器被 querySelectorAll 拒绝。请修正该选择器。
selector_not_found CSS 选择器匹配到 0 个元素。尝试使用条件较宽松的选择器运行 find
selector_ambiguous CSS 选择器匹配到 >1 个元素且未指定 --nth。请添加 --nth 或缩小选择器范围。
selector_nth_out_of_range --nth 超过了实际匹配到的数量。
option_not_found select 找不到匹配该标签/值的选项。错误 Envelope 会包含实际选项标签列表 available: string[]
not_a_select 在非 <select> 元素上调用了 select

错误 Envelope 始终包含 error.codeerror.message。目标错误(selector_not_foundselector_ambiguous 等)通常会附加 error.candidates: string[] 提供建议的选择器。option_not_found 则会附加 error.available: string[]


Command reference(命令参考)

Inspect(检视)

命令 用途
browser state 快照:带有 [N] ref 的文本树、滚动提示、隐藏交互提示,以及用于日期/下拉菜单/文件 ref 的 compounds (N): 侧边栏/附加数据。
browser state --source ax 可选的可访问性树(Accessibility-tree)快照。当自定义控件、Portals 或 iframe 内容在常规 state 中难以识别时使用。AX ref 可以通过 role/name/nth 在 React 重新渲染后恢复失效的 ref,并且可以路由同源 iframe ref。跨源 iframe ref 属于尽力而为(best-effort),因为 Chrome 可能不会向扩展程序暴露可附加的 OOPIF 目标。
browser state --compare-sources 仅包含度量指标的 DOM vs AX 对比,用于决定是否应将 AX 作为默认设置。它只会打印数量和大小,不包含页面文本,因此在进行验证共享时更安全。
browser find --css <sel> [--limit N] [--text-max N] 执行 CSS 查询,并为每个匹配项返回包含 {nth, ref, tag, role, text, attrs, visible, compound?} 的条目。会为上一次快照未标记的匹配项分配 ref。当你已知选择器时,这是比 state 更轻量的替代方案。
browser find --role button --name Save 语义化定位器查询。亦支持 --label--text--testid。当控件具有可访问标签时,优先于原生 CSS 使用。
browser frames 列出跨源 iframe 目标。将索引传递给 eval--frame 参数。
browser screenshot [path] 视口(Viewport)PNG 图。若未提供路径 → 输出 base64 至 stdout。若只需结构信息,优先使用 state
browser screenshot --annotate [path] 视觉 ref 映射图。刷新 DOM ref 并叠加显示可视的 [N] 标记,使截图可以对应回 browser click <ref> 的目标。适用于仅有图标的控件、视觉布局、图表,或文本状态有歧义时。

Get(只读)

命令 返回内容
browser get title 纯文本
browser get url 纯文本
browser get text <target> [--nth N] {value, matches_n, match_level}
browser get value <target> [--nth N] {value, matches_n, match_level}
browser get attributes <target> [--nth N] {value: {attr: val, ...}, matches_n, match_level}
browser get text --role option --name Travel 无需预先调用 state 的语义化定位器读取。参数与 browser find 相同。
browser get html [--selector <css>] [--as html|json] [--depth N] [--children-max N] [--text-max N] [--max N] 原始 HTML 或结构化树状图。JSON 树节点包含 {tag, attrs, text, children[], compound?}。截断信息通过 truncated: {depth?, children_dropped?, text_truncated?} 报告。

Interact(交互)

命令 备注
browser click <target> [--nth N] 返回 {clicked, target, matches_n, match_level}
browser click --role button --name Submit 语义化点击。写入操作需要唯一的匹配项;存在歧义的定位器会返回候选项而非直接执行。