参考 / Reference
命令参考
自定义下拉框会先即时滚入视口,再用真实指针事件打开。pick 未确认选中时返回 verified: false 和警告。页面及容器滚动使用即时移动,避免 CSS 平滑滚动在后台标签页停滞;位置未变化时返回 scrolled: false 和警告。
这是 chrome-use 全部命令、别名与旗标的完整速查表。按命令组组织,方便扫读与查证。 想先建立整体节奏,请看 核心循环;命令跑不通时,翻 故障排查。
@e1、@e2 是 snapshot 输出的元素引用(ref)。
先跑 snapshot -i 拿到 ref,再用 ref 操作。带 @ref 的命令始终作用在快照运行时的当前活动标签页。
有效增量快照的 JSON refs 只包含增量片段中的节点;无变化时为空。会话仍保留完整实时映射和先前引用;回退完整树时保持普通完整快照的行为。
read --filter 按字面文本匹配,忽略 ASCII 大小写,不支持正则;优先返回匹配标题及其子章节,否则按正文内容筛选章节。可先用 read --outline 找标题。snapshot --filter 则支持正则。读取选项见 read --help。
导航
打开、跳转、前进后退与关闭浏览器。open 不带 URL 时只启动浏览器、停在
about:blank,便于在首次真正导航之前先注册网络拦截、Cookie 或 init 脚本。
# 只启动浏览器,不导航;停在 about:blank
$ chrome-use open
# 启动并导航(别名:goto, navigate);无协议时自动补 https://
$ chrome-use open <url>
$ chrome-use back # 后退
$ chrome-use forward # 前进
$ chrome-use reload # 重新加载
# SPA 客户端导航:自动探测 Next.js router.push,回退 history.pushState
$ chrome-use pushstate <url>
# 已在目标同源、且页面里有指向目标的链接时,点那个链接而不是整页导航
# (实测 react.dev:站内 19 个请求 vs 整页导航 47 个);不满足条件就照常导航
$ chrome-use open <url> --prefer-spa
$ chrome-use close # 关闭浏览器(别名:quit, exit)
$ chrome-use connect 9222 # 通过 CDP 端口连接
Page.navigate 超时后,通过 Chrome 的浏览器级
标签 API 重试这次明确导航。命令会返回警告并保留原 session,不再要求重启整个 session。
导航前的准备可以用 batch 在一轮里排好队 —— 先干净启动,再依次注册拦截 / Cookie,最后导航。
适合 SSR-only 调试(只放行 --resource-type script 之外)、受保护来源鉴权,或抓取干净的
react suspense / vitals 状态。
$ chrome-use batch \
'["open"]' \
'["network","route","*","--abort","--resource-type","script"]' \
'["cookies","set","--curl","cookies.curl","--domain","localhost"]' \
'["navigate","http://localhost:3000/target"]'
快照(页面分析)
交互快照会为邻近商品卡片、列表项、表格行或带标题的分组中的控件附加有限长度的 context,保留价格等局部文字,不改变控件名称与引用。只有一个商品链接名称和一个操作控件的局部分组也可提供上下文;上下文已附在操作控件上时,同名商品链接省略这段重复文字。交互快照和动作观察也保留 status 状态回执,限制文字长度并明确标记截断。上下文可能缺失或标记为截断;需要的信息不完整时,读取局部或完整快照。
snapshot 拿到页面的结构化可访问性视图,是所有交互的起点。
推荐 snapshot -i:只列可交互元素,输出精简、ref 齐全。
$ chrome-use snapshot # 完整可访问性树
$ chrome-use snapshot -i # 仅可交互元素(推荐)
$ chrome-use snapshot -c # 精简输出
$ chrome-use snapshot -d 3 # 限制深度为 3
$ chrome-use snapshot -s "#main" # 限定到 CSS 选择器范围
$ chrome-use snapshot -i --dom # 从 DOM 遍历列出可操作元素(穿透 shadow root;AX 树无 ref 时自动启用)
$ chrome-use snapshot -i -f "SSH|确定" # 只保留匹配行 + 其祖先(refs 保持完整)
$ chrome-use snapshot -i --diff # 只回传相对上一张快照变化的部分
$ chrome-use snapshot -i --max-bytes 4000 # 按整节点裁剪,并说明漏了什么 + 续读游标
$ chrome-use snapshot -i --max-bytes 4000 --from 70 # 从上次停下的地方续读
点击之外的动作
$ chrome-use actions @e15 # 这个元素此刻支持什么(实时读)
$ chrome-use do @e15 expand # 只做其中之一;集合外的一律拒绝
expand / collapse、showMenu、
increment / decrement、toggle,
由元素的无障碍属性推导。做完会再报一次动作集,
没动的控件不会读起来像成功。详见
交互。
不过只有 expand / collapse 事后判得出成败——
做完元素必须提供相反的那个动作。showMenu、toggle、
increment / decrement 无论控件响应与否,树里看起来都一样,
所以它们标 · 而不是 ✓,JSON 里 confirmed 为
null:已派发,结果未知。别把 null 当成功,自己读一眼页面。
交互操作
用 snapshot 拿到的 @ref 驱动真实浏览器:点击、输入、勾选、拖拽、上传。
拖拽方式取决于当前会话的连接及目标框架;其他 Chrome profile 中运行的扩展不会改变独立启动浏览器的拖拽方式。
$ chrome-use click @e1 # 点击
$ chrome-use click @e1 --new-tab # 点击并在新标签打开
$ chrome-use dblclick @e1 # 双击
$ chrome-use focus @e1 # 聚焦元素
$ chrome-use fill @e2 "text" # 清空后输入
$ chrome-use type @e2 "text" # 直接输入(不清空)
$ chrome-use press Enter # 在当前焦点按键(别名:key),输出报告落点;页面没有监听器时 ⚠ 警告
$ chrome-use press Enter --selector @e2 # 先聚焦目标再按(别名:--on)
$ chrome-use press Control+a # 组合键
$ chrome-use keydown Shift # 按住键
$ chrome-use keyup Shift # 释放键
$ chrome-use hover @e1 # 悬停
$ chrome-use check @e1 # 勾选复选框
$ chrome-use uncheck @e1 # 取消勾选
$ chrome-use select @e1 "value" # 选择下拉项
$ chrome-use select @e1 "a" "b" # 多选
$ chrome-use scroll down 500 # 滚动页面(默认 down 300px)
$ chrome-use scroll down --until "#footer" # 逐步滚到目标进入视口(selector/@ref/text=)
$ chrome-use scrollintoview @e1 # 滚动元素进入视口(别名:scrollinto)
$ chrome-use drag @e1 @e2 # 拖放
$ chrome-use upload @e1 file.pdf # 上传文件
$ chrome-use download @e2 ./file.pdf # 从链接或控件下载
$ chrome-use download-url https://example.com/file.pdf ./file.pdf
$ chrome-use downloads --limit 10 --json # 机器可读的 Chrome 下载记录
fill 会在返回成功前回读控件或富编辑器 model,并精确比较结果。若 Monaco 隐藏了 model API,则通过一次可信的编辑器 paste 写入,再通过编辑器 copy 处理器精确回读,并在结束后恢复浏览器剪贴板。paste 无法校验或回读不一致时会报错,不会静默成功。报错会同时引用两边的值(如 read back "" after writing "千代田区");若非 ASCII 字符全部消失而 ASCII 仍在,会明确指出页面过滤了非拉丁输入(仅限拉丁 / 带掩码的字段),重打一遍没有用。type 也会回读:字段里没有刚输入的文本时打印 ⚠ 警告(退出码仍为 0,JSON 多出 readBack)。文本输入框用可信输入事件写入;保存 / 提交按钮在填写前后都禁用时 fill 会警告,click 会拒绝点击禁用的控件(#358)。
press 对只靠页面 JavaScript 才有效果的键(文本框上的 Arrow/Home/End/PageUp/PageDown、Escape、表单外裸输入框上的 Enter)会探测从焦点元素到 window 有没有 keydown/keyup/keypress 监听器;一个都没有时仍退出 0,但打印 ⚠ 警告说明页面无法响应该键,建议直接 click 目标选项(JSON 多出 keyListeners)。组合键、Tab、Backspace、可打印字符不探测。
<li> 项常在输入框失焦时关闭。若 click 报成功但页面没反应,
用 AGENT_BROWSER_CLICK_MODE=dom 重试该次点击 —— 普通 <li> 没有可聚焦目标,输入框保持焦点,选项仍会被选中。
注意 DOM 派发的点击(扩展中继下左键点击的默认方式)现在会像真实点击一样移动焦点:被点元素、最近的可聚焦祖先或 label 对应的控件会获得焦点(除非点击处理器已经自己移动了焦点),所以 click <input> 再 press Meta+a 落在这个输入框上,而不是上一个焦点。
读取信息
从元素或页面读取文本、HTML、属性、值、包围盒与计算样式。
$ chrome-use get text @e1 # 元素文本
$ chrome-use get html @e1 # innerHTML
$ chrome-use get value @e1 # 输入框的值
$ chrome-use get attr @e1 href # 属性
$ chrome-use get title # 页面标题
$ chrome-use get url # 当前 URL
$ chrome-use get cdp-url # CDP WebSocket URL
$ chrome-use get count ".item" # 匹配元素数量
$ chrome-use get box @e1 # 包围盒
$ chrome-use get styles @e1 # 计算样式(字体、颜色、背景等)
检查状态
$ chrome-use is visible @e1 # 是否可见
$ chrome-use is enabled @e1 # 是否可用
$ chrome-use is checked @e1 # 是否勾选
截图与 PDF
$ chrome-use screenshot # 保存到临时目录
$ chrome-use screenshot path.png # 保存到指定路径
$ chrome-use screenshot main el.png # 单个元素:先选择器后路径
$ chrome-use screenshot el.png --selector main # 或用 --selector/-s,顺序不限
$ chrome-use screenshot --full # 整页截图
$ chrome-use pdf output.pdf # 保存为 PDF
无头 Chromium 截图会隐藏原生滚动条以获得一致的图像输出。启动时传
--hide-scrollbars false 可保留原生滚动条。
录屏
$ chrome-use record start ./demo.webm # 开始录制
$ chrome-use click @e1 # 执行操作
$ chrome-use record stop # 停止并保存
$ chrome-use record restart ./take2.webm # 停止当前 + 开始新录制
等待
在断言状态前等待元素、文本、URL、网络空闲或任意 JS 条件。
$ chrome-use wait @e1 # 等待元素
$ chrome-use wait 2000 # 等待毫秒数
$ chrome-use wait --text "Success" # 等待文本(或 -t)
$ chrome-use wait --url "**/dashboard" # 等待 URL 模式(或 -u)
$ chrome-use wait --load networkidle # 等待网络空闲(或 -l)
$ chrome-use wait --fn "window.ready" # 等待 JS 条件(或 -f)
鼠标控制
$ chrome-use mouse move 100 200 # 移动鼠标
$ chrome-use mouse down left # 按下按键
$ chrome-use mouse up left # 释放按键
$ chrome-use mouse wheel 100 # 滚轮
语义定位器
ref 之外的另一种定位方式:按角色、文本、标签、占位符、alt、title、testid 或位置定位, 并直接跟上要执行的动作。也可以直接传自然语言描述,返回排序候选而不执行动作。
$ chrome-use find role button click --name "Submit"
$ chrome-use find "编辑 Web服务规则 设置按钮" # 仅返回候选
$ chrome-use find text "Sign In" click
$ chrome-use find text "Sign In" click --exact # 仅精确匹配
$ chrome-use find label "Email" fill "user@test.com"
$ chrome-use find placeholder "Search" type "query"
$ chrome-use find alt "Logo" click
$ chrome-use find title "Close" click
$ chrome-use find testid "submit-btn" click
$ chrome-use find first ".item" click
$ chrome-use find last ".item" click
$ chrome-use find nth 2 "a" hover
浏览器设置
$ chrome-use set viewport 1920 1080 # 视口尺寸
$ chrome-use set viewport 1920 1080 2 # 2x 视网膜(CSS 尺寸不变,截图分辨率更高)
$ chrome-use set device "iPhone 14" # 模拟设备
$ chrome-use set geo 37.7749 -122.4194 # 地理位置(别名:geolocation)
$ chrome-use set offline on # 离线模式开关
$ chrome-use set headers '{"X-Key":"v"}' # 额外 HTTP 头
$ chrome-use set credentials user pass # HTTP 基本认证(别名:auth)
$ chrome-use set media dark # 模拟配色方案
$ chrome-use set media light reduced-motion # 浅色 + 减少动效
Cookie 与存储
$ chrome-use cookies # 获取所有 Cookie
$ chrome-use cookies set name value # 设置 Cookie
$ chrome-use cookies clear --domain example.com # 只清这个站点的 Cookie;--all --yes 清空整个浏览器
$ chrome-use storage local # 全部 localStorage
$ chrome-use storage local key # 指定键
$ chrome-use storage local set k v # 设置值
$ chrome-use storage local clear # 全部清空
从 cURL 导入 Cookie
自动识别格式:{name, value} 的 JSON 数组、DevTools → Network → Copy as cURL 的转储,
或裸 Cookie 头。出错时绝不回显 Cookie 值。
$ chrome-use cookies set --curl <file> # 自动识别 JSON / cURL / Cookie 头
$ chrome-use cookies set --curl <file> --domain example.com # 限定域名
网络拦截
拦截、阻断、Mock 响应、改写请求,或编辑真实响应。深入用法见 核心循环 中的网络章节。
$ chrome-use network route <url> # 拦截请求
$ chrome-use network route <url> --abort # 阻断请求
# Mock 响应(fulfill)
$ chrome-use network route <url> --body '{}' --status 200 --header K=V --content-type application/json
# 改写请求(continue)
$ chrome-use network route <url> --method POST --set-body '{}' --set-header K=V --rewrite-url <u>
# 编辑真实响应
$ chrome-use network route <url> --edit-status 503 --edit-header K=V --replace 'from=>to'
$ chrome-use network unroute [url] # 移除路由
$ chrome-use network requests # 查看已跟踪的请求
$ chrome-use network requests --filter api # 过滤请求
按资源类型拦截
# 只阻断脚本(SSR-lock 模式)
$ chrome-use network route '*' --abort --resource-type script
# 用空响应替换图片和字体
$ chrome-use network route '*' --resource-type image,font --body ''
标签页与窗口
标签 id 是形如 t1、t2 的稳定字符串,会话内不重用。
重新连接后(例如 relay 重启)每个 id 仍绑定到同一个 Chrome 标签页;找不到原标签页的 id 会被拒绝,不会转给其他标签页,它的标签名也继续保留给那个标签页。如果正在操作的标签页不见了,作用于当前标签页的命令会被拒绝,直到用 tab <id>、tab new <url> 或 --tab <id> 选定一个标签页。
位置整数不被接受 —— tab 2 会报错,请用 t2。
你也可以给标签起可读的 label(docs、app),与 id 通用。
$ chrome-use tab # 列出标签(含 tabId 与 label)
$ chrome-use tab new [url] # 新标签
$ chrome-use tab new --label docs [url] # 带可读 label 的新标签
$ chrome-use tab new [url] --activate # 初始化前激活标签
$ chrome-use tab duplicate [ref] # 原生复制标签,默认复制当前标签
$ chrome-use tab duplicate docs --label copy # 按 ref 复制并设置 label
$ chrome-use tab t2 # 按 id 切换
$ chrome-use tab select t2 # 显式切换语法
$ chrome-use tab select t2 --activate # 存活探针之前激活标签
$ chrome-use tab adopt "example.com/stuck" # 接管现有标签,不导航
$ chrome-use tab adopt "example.com" --activate # 接管并保留在前台
$ chrome-use tab inspect t2 # 不运行页面 JS,读取浏览器级状态
$ chrome-use tab docs # 按 label 切换
$ chrome-use tab close # 关闭当前标签
$ chrome-use tab close t2 # 按 id 关闭
$ chrome-use tab close docs # 按 label 关闭
$ chrome-use tab list --all # profile 里的全部标签,含用户自己的(只读)
$ chrome-use --tab chrome-tab:812 --force snapshot -i # 原地操作用户的标签(用户要求时)
$ chrome-use tab close chrome-tab:812 --force # 关闭用户的标签(用户要求时)
$ chrome-use window new # 新窗口
tab list --all 用来回答“我开着哪些标签”:列出当前 Chrome profile 所有窗口里的全部标签,
包括用户自己的和其他 chrome-use 会话的。它只做观察(走 relay 时读 chrome.tabs.query 和
ABExt.state,需要 ab-connect 0.5.25+;直接 CDP 时读 Target.getTargets 和
Browser.getWindowForTarget):首次查询也不启动 daemon、不开窗口或标签。不 attach、不激活、不聚焦、不移动、不刷新任何标签,也不读页面内容。已有会话继续读取它连接的浏览器;非 relay 会话没有运行中的 daemon 时,需要用 --cdp 指定已有浏览器。查询不会启动浏览器、创建云端实例或升级 daemon,仍遵守 action-policy。
每行有 handle(relay 下是 chrome-tab:<id>,直接 CDP 下是 targetId)、窗口、
是否是该窗口的当前标签、pinned/incognito/discarded(relay)、标题、URL 和归属:
{kind: "self"}、{kind: "session", session, live} 或 {kind: "user"},
文字版是 this session、session alpha (live)、the user。
排序:先本会话的,再按名字分组的其他会话,最后是用户的;组内按窗口、标签位置。最多 200 行
(--limit,上限 1000);标题超过 300、URL 超过 2048 字符会截断,回复会说明省略了什么。
URL 按 Chrome 原样给出,可能带会话 token。
操作不属于本会话的标签需要 --force,而且只在用户要求操作那个标签时使用。
--tab <handle> --force <命令> 在该标签上原地执行任意页面命令:会 attach,但不激活、
不聚焦、不移出窗口(要同时切到前台,只在用户要求时用 tab adopt <handle> --activate)。
tab close <handle> --force 关闭它并读回确认。每个 forced 结果都带 forced: true
和 forcedTab(标题、URL、归属);另一个正在运行的会话的标签还会带警告。不加 --force
时的拒绝信息会写明归属和这个参数。close 不会关掉 forced 标签:它保持打开并被释放
(forcedTabsLeftOpen;走 relay 时需要 ab-connect 0.5.34,旧扩展会保持 attach 直到扩展重启)。
chrome-tab: handle 需要 ab-connect 0.5.30+。
页面诊断:diag pages
$ chrome-use diag pages --json # 全部页面、归属、过期 relay 记录、扩展版本(不 attach 任何东西)
$ chrome-use diag pages --measure --json # 加上已 attach 页面的堆、节点、监听器数
$ chrome-use diag pages --watch 60 --force --json # 间隔 60 秒采两次,每页给出泄漏类别
diag pages 是给外部工具(例如 Thermo)查泄漏页面用的稳定、只读、带版本号的报告(JSON
"schema": 1),用来代替直接拿 raw CDP 驱动 relay。它用自己的诊断连接:不启动 daemon、不开会话标签、
不重启 relay。每个页面给出 handle、targetId、URL、标题、windowId、
active / visible / discarded(relay 下)、attached 和归属
(self / session / user);顶层另有过期 relay 记录数、扩展版本及是否落后于商店发布版
(附带和 doctor 相同的更新 / 重新加载提示)、profile 和 relay 连接状态。
不加 --measure 时绝不 attach 任何页面。--measure 通过 Performance.getMetrics
给出 JSHeapUsedSize、Nodes、JSEventListeners、Documents,只测本会话的页面,
以及 chrome-use 已经 attach 且不属于其他运行中会话的页面;worker 按站点汇总 Runtime.getHeapUsage。其余页面跳过并写明原因。
--force(配合 --measure / --watch)也测其余页面:没 attach 的标签会被 attach、测量后立即释放
(ab-connect 0.5.34+),不激活、不聚焦;期间该页会显示 Chrome 的调试提示条,所以只在用户要求时用。
--watch <秒> 隔这么久采两次,给出每页增量和泄漏类别:listeners_growing_nodes_flat、
heap_growing(≥ 1.5 MiB/分钟)、nodes_climbing 或 none。
输出有上限(--limit 默认 200 页,最多 1000;标题截到 300、URL 截到 2048 字符),并说明省略了什么。
退出码:0 正常,1 用法错误,2 扩展 relay(或 --cdp 端点)未连接,3 未加 --force 做 --measure
而所有页面都被其他运行中的 chrome-use 会话占用。JSON 结构见 core skill 的 references/diag-pages.md。
会话只剩一个标签、且它是本会话创建的时候,tab close 直接按 close 结束会话
(返回 sessionClosed: true),不用再跑一次 close。不是本会话创建的标签
(adopt 来的、用户自己的)永远不会被关,拒绝信息会告诉你保持它打开并运行 close。
close 关完之后会逐个读回:走 relay 时用扩展的 ABExt.tabPresence(ab-connect 0.5.33+:先查 Chrome 自己的 target 注册表里这个确切的 target,
再查确切的 tab id;任何 API 错误都算无法确认),直连 CDP 时查 Chrome 自己的 target 列表。旧版扩展无法确认标签已关,结果一律是
unverified。整个关闭过程共用 15 秒预算,到时还没确认的标签保持 unverified 并保留归属。
关闭多个标签中的一个(tab close t2)也会读回;没确认关掉就报错,标签和关闭权都保留。返回 tabsClosed(确认已关的标签)和 verifiedAbsent: true。
只要有本会话创建的标签还开着,或无法确认已关(unverified),就返回 close incomplete
并列出这些标签;会话、daemon 和标签归属记录都保留,重试 close 即可。
原生复制只支持通过 chrome-use 扩展连接的真实 Chrome。命令完成后会恢复此前可见的前台标签, 同时让副本成为 chrome-use 内部活动标签。启动型 Chrome、raw CDP、Lightpanda 和云 provider 不会退化为同 URL 新建标签;副本是否在后台开始加载仍由 Chrome 决定。
tab select <ref> 与 tab <ref> 等价。
tab adopt <URL 子串|targetId> 支持扩展和直接 CDP 连接,会在当前会话中附加现有标签,不刷新页面。直接 CDP 请使用 chrome-use --session example --cdp 9222 tab adopt <targetId>,后续命令保持相同 session 和端点;顶层 adopt 仍选择扩展连接。
在外部或扩展连接的 Chrome 中,tab list 会把标签标记为
created、adopted 或 foreign。只有 created/adopted
标签可以切换,只有当前 session 创建的标签可以关闭;adopted 标签仍属于用户。同名 session
连接同一浏览器端点重启后仍会恢复 created 所有权,因此中断的清理可以安全继续。
tab inspect <ref> 只读取 Chrome 的标签元数据,因此 renderer 主线程被页面
JavaScript 卡住时仍可返回 URL、加载状态、discard/freeze 状态与 debugger 附加状态。
页面主线程恢复响应前,eval 仍无法完成。
通过扩展连接时,tab inspect 需要 ab-connect 0.5.16 或更新版本。
tab select 的存活探针失败不能单独证明 renderer 已卡死;如果警告显示当前扩展
落后于 CLI 内置版本,请在 chrome://extensions 更新或重新加载扩展后重试。
普通 click 打开的新标签(target=_blank、window.open)会以
openedTab 报告,并归入当前会话:tab list 能列出,tab close 和
close 会关闭它。--follow 会切到它;配合 --observe 时,等待稳定和快照都针对新标签;
切换失败时 followed 为 false,会话留在被点击的标签上。
在你自己的 Chrome 里,只接管由本会话标签打开的标签(在本会话的标签组里,或不在任何组且 opener 是本会话标签);
其他组里的标签和你自己打开的标签不会被接管。接管按 Chrome 标签 id 附加,需要 ab-connect 0.5.30 或更新版本。
看到但没有接管时,会设置 openedTabWarning 和 openedTabStatus:unadopted
(有意不接管)或 unknown(Chrome 或扩展没有在预算内回应:查找约 2 秒,附加约 3 秒)。
之后可用 tab adopt <url> 接管。
网页自己打开的标签(target=_blank、window.open)会让 Chrome 跑到你正在用的应用前面(#468)。默认情况下
chrome-use 让 Chrome 自己打开,和用户点击完全一样;在你自己的 Chrome 里,click 会在 openedTabWarning 里说明。在 macOS 上 chrome-use 默认会把点击前在前台的应用切回前台:只在点击后 1.5 秒内 Chrome 带着一个点击前不存在的新标签跑到前面时才做;点击前 Chrome 本来就在前台、或你切到了别的应用时都不动(结果里的 focusRestored / focusNote 说明)。Windows 和 Linux 不做。AGENT_BROWSER_RESTORE_FOCUS=0 关闭。
需主动开启:AGENT_BROWSER_BACKGROUND_LINKS=cross-site(也可写 1/on)后,在本会话创建的标签上,
跨站的 target=_blank 链接(左键、无修饰键、http(s) 地址,页面和链接两端按公共后缀列表都属于不同的可注册域名,
没有 rel=opener、download 或 ping)由 chrome-use 自己打开:网页的点击处理函数照常全部执行,
没有被取消时,链接在本会话的后台标签里打开(openedTabMode: "background"),并带上当前页作为 referrer(需要 ab-connect 0.5.31+)。
与 Chrome 自己的点击相比的代价:新标签多一条 about:blank 历史记录;重定向回当前站点的链接,最后一跳收不到
SameSite=Strict cookie(用户可能显示为未登录)。all 连同站链接也接管,它们一律收不到这些 cookie;
不设、0 或 off 不接管(默认)。即使开启,以下情况仍由 Chrome 打开并在 click 结果里说明:同站链接(除非 all)、
IP 地址、localhost 和不在公共后缀列表里的主机、点击过程中被处理函数改到另一个主机的链接、受 ChooseBrowser 规则约束的链接、
无法判断站点的页面、window.open、rel=opener、具名窗口、表单、阻止了点击传播的处理函数,以及稍后才弹出的页面。
daemon 启动时读取这个变量:请在会话的第一条命令之前设置,或先 close 再重新开始。
tab new、tab select 和 tab adopt 默认在后台进行。
加上 --activate(别名 --front)会在 renderer 初始化或存活探针
之前激活目标,并将标签保持在前台。这会切换可见标签,并把那个 Chrome 窗口提到用户正在用的程序之上,
所以只在用户要求时使用;激活本身不代表页面已可读。
新标签初始化失败后,错误会报告保留的目标 ID。保持相同 session 和连接端点,执行
tab select <targetId> --activate,然后用 snapshot -i 验证恢复。
不要反复新建标签,也不要自动重放结果未知的点击。
@eN 归属于快照运行时的那个标签。要操作另一个标签,
先切过去再快照。label 永不自动生成、导航后不改写、会话内唯一。
框架(iframe)
快照时自动检测 iframe,其内容会内联在 iframe 元素下方(一层嵌套)。 iframe 内的 ref 可直接操作;也可切换框架上下文做限定快照。
$ chrome-use frames # [0] top … [1] accessory_layer …
$ chrome-use frame 1 # 按 frames 打印的序号切换(0 = 顶层文档)
$ chrome-use frame "#iframe" # 按 CSS 选择器切换到 iframe
$ chrome-use frame @e3 # 按元素 ref 切换到 iframe
$ chrome-use frame main # 返回主框架
跨域浮层是独立的框架——银行/分行选择器、支付字段这类,
页面上的 snapshot -i 看不到里面的东西,focus / press
也只会落在 iframe 元素本身。路径是 frames → frame <序号>
→ 在里面 snapshot -i / click / fill;
只做一次的话用 eval --frame <f>。
frame 接受三种输入:元素 ref(frame @e3)、
CSS 选择器(frame "#payment-iframe")、以及
框架 name / URL(匹配浏览器的框架树)。
对话框
默认自动接受 alert 与 beforeunload,避免阻塞代理;
confirm 和 prompt 仍需显式处理。触发它们的 click 会立即返回待处理状态,
因此同一会话可以继续执行下面的 dialog 命令。用 --no-auto-dialog 关闭自动处理行为。
$ chrome-use dialog accept [text] # 接受对话框
$ chrome-use dialog dismiss # 取消对话框
$ chrome-use dialog status # 检查是否有对话框打开
执行 JavaScript
eval 在页面 MAIN world 中运行,状态会持久、处理器会触发。
含嵌套引号或特殊字符时,用 -b / --stdin 更可靠 —— Shell 转义很容易出错。
$ chrome-use eval "document.title" # 仅限简单表达式
$ chrome-use eval -b "<base64>" # 任意 JS(base64 编码)
$ chrome-use eval --stdin # 从 stdin 读取脚本
# 多行脚本用 stdin + heredoc:
$ cat <<'EOF' | chrome-use eval --stdin
const links = document.querySelectorAll('a');
Array.from(links).map(a => a.href);
EOF
用 eval 调试表单 / 隐藏状态
# 导出每个字段 name → value,含隐藏输入与未选中的 radio
$ chrome-use eval "JSON.stringify([...document.forms[0].elements].map(e=>({name:e.name,type:e.type,value:e.value,checked:e.checked})).filter(e=>e.name))"
# 为什么提交不了?问浏览器自己的 validity API
$ chrome-use eval "[...document.forms[0].elements].filter(e=>!e.validity?.valid).map(e=>e.name+': '+e.validationMessage)"
单次成型脚本(batch / script)
多步流程不必一条命令一次往返。batch 把固定序列一次跑完;script 再加上
步骤间传值、循环、条件、断言。详见 单次成型脚本。
普通 CLI --json 返回 success/data/timing envelope;加 --no-timing(或 AGENT_BROWSER_TIMING=0)时回复不带 timing,timing.jsonl 照常记录。batch --json 打印 {command,success,result,error} 条目的数组;script --json 打印程序结果本身(ok、return、logs、error、advisories 等)。batch 和 script 的 CLI 输出没有顶层 timing。
batch 的每一步可以带自己的单命令参数(--observe、--no-settle、--settle-ms、--with-screenshot、--if-present、--new-tab、--tab):batch "fill @e1 Ada" "click @e2 --observe" 会把 observed 放进这一步的 result。作用于整个会话的参数(--headed、--profile 等)写在 batch 前面;写在某一步里会被拒绝。某一步里显式写的 --observe false / --if-present false 会覆盖 batch 的同名参数;某一步的 --tab 不会替换命令自己指定的标签页(tab close t1 --tab t2 会被拒绝)。
程序结果与传输成功分开判断:daemon envelope 中嵌套 script 的 data.ok:false 会使父脚本失败,即使 success:true。JS 失败仍保留 ok:false、return:null、error 和 logs。两种脚本都在 advisories(CLI script --json 顶层;daemon envelope 中为 data.advisories) 中保留观察提示,最多 20 条,嵌套和失败运行也保留;JSON op-list 的 steps 另带对应动作的 noProgress。文字输出只打印汇总提示一次。这些提示不改变动作 success,也不重试动作。
# JSON op-list:值总线 {{name.path}} + waitUntil/forEach/assert/return,--dry-run 可预验
$ chrome-use script prog.json
$ chrome-use script - --dry-run < prog.json
# JS 形式:一段同步 JS,用 cu.* 助手驱动(ego 的 code base 写法)
$ chrome-use script --timeout 120000 <<'JS'
cu.open('https://news.ycombinator.com');
const rows = cu.eval("[...document.querySelectorAll('.athing')].length");
return { count: rows };
JS
选项:--timeout <ms>、--dry-run(仅校验 JSON 程序)、--yes(脚本内自动确认)、
--arg k=v(预置变量)。退出码:0 成功、1 运行失败或断言不过、2 程序非法。
Agent 循环(实验性)
jev run 端到端推进一个目标:由 TypeSafe 的 Jev 在带编号的元素表里选每一步的操作和目标,
只有需要填字时才调用一个小模型。需要 TYPESAFE_API_KEY(或 ~/.config/typesafe/key)。
$ chrome-use jev run --goal "查苏黎世到伦敦的航班" --url https://www.google.com/travel/flights
# 额外问一句「这个动作是不是就完成了目标」,并把它和收尾决策的实际判断对照记录
$ chrome-use jev run --goal "..." --terminal-shadow
结果包含 elapsed_ms、jev_ms、text_ms、observe_ms、act_ms、fresh_ms 及决策、动作计数。应测量实际任务,不能把某个页面或 provider 的耗时比例推广到其他场景。
--terminal-shadow 在模型请求中增加完成预测问题,记录 terminal_predicted、terminal_condition_observed、terminal_confirmed_done 和 terminal_refuted,不会跳过正常的完成决策。与后续模型判断一致不等于任务已通过独立验收;增加问题也可能影响模型选择和延迟。
stale_by_phase 和 stale_fields 按类别记录 marker 新鲜度检查的拒绝原因,不写入原始正文。click/select 的 guard 拒绝不包含在这些分类统计中。URL 改变或控件离开可操作集合都不能证明目标完成,这些计数也不能证明哪些模型调用可以安全省掉。
JEV_TRACE=<文件> 每次决策追加一行 JSON:发出去的请求、模型看到的候选(id、类型、标签、当前值、勾选状态)、它的选择,以及 Jev 带概率的原始回答。不设置就不启用。它会记录目标文本、页面文字和字段值,也就包括表单里已经填进去的内容,请把这个文件当作敏感数据。运行报告还会把 act_ms 拆成 act_read_ms、cmd_click_ms、cmd_press_ms、cmd_insert_ms。
状态管理
$ chrome-use state save auth.json # 保存 Cookie、存储与鉴权状态
$ chrome-use state load auth.json # 恢复已保存的状态
Init 脚本
$ chrome-use open --init-script <path> # 首次导航前注册(可重复)
$ chrome-use addinitscript <js> # 运行时注册(返回标识符)
$ chrome-use removeinitscript <id> # 移除已注册的 init 脚本
React / Web Vitals
react ... 命令需要启动时带 --enable react-devtools;
vitals 与 pushstate 与框架无关。
$ chrome-use open --enable react-devtools <url> # 带 React hook 启动
$ chrome-use react tree # 完整组件树
$ chrome-use react inspect <fiberId> # props / hooks / state / source
$ chrome-use react renders start # 开始记录重渲染
$ chrome-use react renders stop [--json] # 停止并打印渲染分析
$ chrome-use react suspense [--only-dynamic] [--json] # Suspense 边界 + 分类器
$ chrome-use vitals [url] [--json] # LCP/CLS/TTFB/FCP/INP + hydration
$ chrome-use pushstate <url> # SPA 客户端导航(自动探测 Next router)
无障碍审计
a11y 运行内嵌在 chrome-use 二进制里的 axe-core,不会临时下载 CDN 脚本。
即使页面启用了严格 CSP,审计也能运行;页面自己的 window.axe 不会被覆盖。
同源与跨域 iframe 的问题都会保留各自的 frame 选择器路径。该命令依赖 CDP,
Safari 和 iOS WebDriver 会直接返回不支持错误。
$ chrome-use a11y # 审计当前页面
$ chrome-use a11y https://example.com # 先导航,再审计
$ chrome-use a11y --tags wcag2a,wcag2aa # 按 axe 规则标签过滤
$ chrome-use a11y --selector "#main" # 只审计一个子树
$ chrome-use a11y https://example.com --json # 输出结构化结果
文本结果列出影响级别、规则 id、修复说明和失败选择器。JSON 结果包含计数、
violations 与 incomplete 数组。MCP 客户端可在
all 工具 profile 中调用 chrome_use_a11y。
调试
console / errors 的捕获默认关闭 —— 活跃的 CDP
Runtime 域是可被探测的 bot 信号。需要时用
AGENT_BROWSER_CAPTURE_CONSOLE=1 启动会话。
$ chrome-use --headed open example.com # 显示浏览器窗口
$ chrome-use --cdp 9222 snapshot # 通过 CDP 端口连接
$ chrome-use connect 9222 # 另一种:connect 命令
$ chrome-use console # 查看控制台消息(需 AGENT_BROWSER_CAPTURE_CONSOLE=1)
$ chrome-use console --limit 20 # 只看最近 20 条控制台消息
$ chrome-use console --level error,warn # 只看错误和警告
$ chrome-use console --filter cart --limit 5 # 含 cart 的最后 5 条(先筛再截)
$ chrome-use console --clear # 清空控制台
$ chrome-use errors # 查看页面错误(需 AGENT_BROWSER_CAPTURE_CONSOLE=1)
$ chrome-use errors --clear # 清空错误
$ chrome-use diagnose # 页面为何空白:查资源 404/MIME、挂载状态
$ chrome-use highlight @e1 # 高亮元素
$ chrome-use inspect # 打开本会话的 DevTools
$ chrome-use trace start # 开始记录 trace
$ chrome-use trace stop trace.zip # 停止并保存
$ chrome-use profiler start # 开始性能分析
$ chrome-use profiler stop trace.json # 停止并保存 profile
查找用户保存的页面(find-url)
按关键词搜索本地 Chrome/Edge 书签 —— 用于公共搜索够不到的内部系统或先前保存的页面。
本地读取,无需浏览器 / 守护进程。结果按最近添加排序,跳过 javascript: / data: 书签。
$ chrome-use find-url jira board # 所有关键词都要命中(name 或 url)
$ chrome-use find-url --limit 10 invoices
$ chrome-use find-url --browser edge --profile "Profile 1" wiki
$ chrome-use find-url grafana --json # {results:[{name,url,folder}], count}
驱动你真实的登录态 Chrome(扩展)
Chrome 136 封锁了默认配置文件上的 --remote-debugging-port,所以要驱动用户现有的登录窗口,
chrome-use 走一个 Chrome 扩展 + 原生消息 —— 无端口、无令牌、无每次确认。
一次性安装写入原生消息宿主清单:
$ chrome-use extension install # 写入原生消息宿主清单(一次性)
$ chrome-use status # CLI、扩展、中继、profile 与会话健康总览
$ chrome-use extension connect # 自动挂接到真实的登录标签
$ chrome-use tab # 列出它现在控制的真实标签
$ chrome-use tab t3 # 把会话切到其中一个
$ chrome-use snapshot -i # 像普通会话一样驱动它
$ chrome-use extension status # 宿主是否已安装?
$ chrome-use extension uninstall # 移除宿主清单
# macOS:跳过那个会让 Chrome 进入受管理状态的策略描述文件
$ chrome-use extension install --no-profile
$ chrome-use extension install --all-profiles # 在每个缺失的 profile 里打开商店页
$ chrome-use extension install --user-data-dir <path> # 为用 --user-data-dir 启动的 Chrome 注册 host(macOS/Linux;运行中的会自动扫描)
扩展 0.5.48 增加 Thermo 使用的原生标签组操作:只接受已经预览确认的清单,逐页重查, 保留已有标签组及当前、固定、音频、隐私、agent 标签,不跨窗口或 profile。 执行前保存记录,执行后核对,并支持不重放不明结果的一次性撤销。普通 chrome-use 会话的标签所有权规则不变。
--no-profile 跳过,或用 profiles remove -identifier com.leeguoo.chrome-use.connect 退出
(Chrome 会一并卸载它装的扩展,从商店重装即可)。当前状态随时可查:chrome-use extension status。
chrome-use status 会区分「已安装清单」和「launcher 确实指向可执行文件」;
JSON 输出通过 extension.hostHealthy 报告 launcher 健康状态。
knfcmbamhjmaonkfnjhldjedeobeafmk)。加载已解压的开发版可能在
Chrome 重启时被停用 / 丢弃,从而悄悄断掉中继 —— 无人值守场景请用商店版。
--extension <path> 无关 —— 那是把扩展加载进一个新启动的浏览器。
全局选项
这些旗标放在命令前,作用于整个会话。注意:无头模式被禁止(bot 信号),
默认且始终有头(隐身);无显示服务器上用 AGENT_BROWSER_ALLOW_HEADLESS=1。
$ chrome-use --session <name> ... # 隔离的浏览器会话
$ chrome-use --json ... # JSON 输出,便于解析
$ chrome-use --headed ... # 默认且始终开启(隐身)
$ chrome-use --full ... # 整页截图(-f)
$ chrome-use --cdp <port> ... # 通过 CDP 连接
$ chrome-use -p <provider> ... # 云浏览器提供商(--provider)
$ chrome-use --proxy <url> ... # 使用代理服务器
$ chrome-use --proxy-bypass <hosts> # 绕过代理的主机
$ chrome-use --headers <json> ... # 限定到 URL 来源的 HTTP 头
$ chrome-use --executable-path <p> # 自定义浏览器可执行文件
$ chrome-use --extension <path> ... # 加载扩展(可重复)
$ chrome-use --ignore-https-errors # 忽略 SSL 证书错误
$ chrome-use --hide-scrollbars false # 无头 Chromium 截图保留原生滚动条
$ chrome-use --help # 帮助(-h)
$ chrome-use --version # 版本(-V)
$ chrome-use <command> --help # 某个命令的详细帮助
环境变量
AGENT_BROWSER_SESSION="mysession" # 显式会话名
AGENT_BROWSER_SESSION_ID="agent-id" # 用于自动隔离的稳定运行器 ID
CODEX_THREAD_ID="thread-id" # Codex 任务自动识别
AGENT_BROWSER_EXECUTABLE_PATH="/path/chrome" # 自定义浏览器路径
AGENT_BROWSER_EXTENSIONS="/ext1,/ext2" # 逗号分隔的扩展路径
AGENT_BROWSER_INIT_SCRIPTS="/a.js,/b.js" # 逗号分隔的 init 脚本路径
AGENT_BROWSER_ENABLE="react-devtools" # 逗号分隔的内置 init 特性
AGENT_BROWSER_HIDE_SCROLLBARS="false" # 保留原生滚动条
AGENT_BROWSER_PROVIDER="browserbase" # 云浏览器提供商
AGENT_BROWSER_STREAM_PORT="9223" # 覆盖 WebSocket 流端口
AGENT_BROWSER_DASHBOARD_ALLOWED_HOSTS="ws.example.com" # dashboard 额外允许的主机名(反向代理用);默认只接受本机回环地址
AGENT_BROWSER_CLICK_MODE="dom" # 点击策略:""(默认) / "coord" / "dom"
AGENT_BROWSER_BACKGROUND_LINKS="cross-site" # 需主动开启(#468):跨站 target=_blank 链接在后台标签打开。不设/"off"/"0"(默认) 不接管;"cross-site"/"1"/"on";"all" 连同站也接管。代价:重定向回本站时收不到 SameSite=Strict cookie;daemon 启动时读取
隐身 / 反检测开关(fork)
AGENT_BROWSER_CAPTURE_CONSOLE="1" # 启用 console/errors 捕获(默认关,Runtime 域是 bot 信号)
AGENT_BROWSER_TIMEZONE="Asia/Tokyo" # 仅 --launch。原生时区覆盖(IANA id 或 "auto")
AGENT_BROWSER_BLOCK_WEBRTC="1" # 仅 --launch。经 WebRTC 隐藏本地 IP
AGENT_BROWSER_HIDE_CANVAS="1" # 仅 --launch。会话稳定的 canvas/audio 指纹噪声
AGENT_BROWSER_ADAPTIVE_REF="0" # 关闭自适应 @ref 重定位(默认开)
{"messages":[]} / {"errors":[]} 加一条
hint,直到你用 AGENT_BROWSER_CAPTURE_CONSOLE=1 启动会话 —— 这样常见自动化路径下
CDP Runtime 域始终禁用。跑不通时可对照 故障排查。
语义 find role/text/label/placeholder/alt/title/testid 要求恰好一个可见匹配,只定位不操作时也一样。多个匹配会返回最多八个候选及可见状态、选择器和上下文提示,不派发动作,也不输出输入框的值。用 --name/--exact 消歧,或用 --within <CSS|@ref> 限定到唯一容器。范围必须属于当前标签页的主文档,跨 iframe 的 ref 和已选中的 iframe 上下文会被拒绝;可用 iframe 内的直接 ref 动作,或先 `frame main`。find first/last/nth 保留显式按序选择;传给动作(click、fill、type、hover、check、select、drag 等)的普通 CSS 选择器或 XPath 也必须恰好匹配一个元素:匹配多个时以 selector_ambiguous 拒绝,列出前五个匹配的文字和位置,什么都不做。收窄选择器、改用 @ref,或用 find nth <序号> <选择器> <动作> 按序号指定;旧脚本需要首个匹配时设 AGENT_BROWSER_STRICT_SELECTORS=0(会话的 daemon 启动时读取)。role 和 label 名称来自 Chrome 无障碍数据,包含 aria-labelledby;每次语义调用重新定位。派发前目标已脱离时安全失败,结果不确定的动作不会重放。
先从页面发现范围:find query "Beta account" 返回候选的选择器锚点;选出对应标题的 article/容器,再执行 find role button click --name Save --exact --within "<返回的选择器>"。范围有歧义时用 snapshot -s "<选择器>" 查看并缩小范围,不取第一个。未知语义 find 参数和重复 --within 会被拒绝;输入像参数的文字可写 find label Email fill -- --name。--exact false 使用子串匹配。
现有 mcp --tools all 的 chrome_use_find 工具接受 within,使用相同的唯一范围规则,工具数量不变。fill/type 的 text 按文字原样传入,--name --observe 不会被当作 CLI 参数。
语义 find 的 --observe 仍按已有行为提示不支持;已知范围和回执时可在同一个 batch 中执行范围内 find 动作及任务专属的 get text 核验。MCP find 工具不声明 observe 字段。