Skip to main content

browser-cli

Drive the already-logged-in Chrome on Chris's cloudtop from the command line (agent-browser over CDP), instead of chrome-devtools-mcp. Use for ANY interactive browser work on internal/SSO-gated sites — gHire, Buganizer UI, Google Chat, internal dashboards, form filling, clicking through a flow. ~40-50x cheaper than the MCP (350 tokens vs 15-20K per snapshot). Also provides multi-round Google Chat conversation — send a message and block waiting for the peer's reply. Trigger on "操作浏览器", "点开网页", "帮我填一下", "去 gHire", "给 X 发个 Chat 消息", "等他回复". Keep chrome-devtools-mcp only for Lighthouse / heap snapshot / performance trace.

Ir para a instalação

Informações da origem

Repositório
yangwhale/CloseCrab
Última atividade na origem
2 de setembro de 2026 às 05:30
Idioma detectado do SKILL.md
chinês
Estrelas
3
Forks
0

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
9 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
browser-cli
description
Drive the already-logged-in Chrome on Chris's cloudtop from the command line (agent-browser over CDP), instead of chrome-devtools-mcp. Use for ANY interactive browser work on internal/SSO-gated sites — gHire, Buganizer UI, Google Chat, internal dashboards, form filling, clicking through a flow. ~40-50x cheaper than the MCP (350 tokens vs 15-20K per snapshot). Also provides multi-round Google Chat conversation — send a message and block waiting for the peer's reply. Trigger on "操作浏览器", "点开网页", "帮我填一下", "去 gHire", "给 X 发个 Chat 消息", "等他回复". Keep chrome-devtools-mcp only for Lighthouse / heap snapshot / performance trace.
# browser-cli — 命令行驱动浏览器 ## 为什么不用 chrome-devtools-mcp 慢的根因不是 CDP,是 **LLM 往返次数 × 每次注入的 token 量**。MCP 的 `take_snapshot` 一次回 15-20K token 的完整 a11y 树;`agent-browser snapshot -i` 只回可交互元素,约 350 token。40-50 倍差距,而且 MCP 的工具定义本身还常驻 system prompt。 浏览器操作天然是往复的(看→点→再看),所以**降低每一轮的成本**比"一次编好所有动作"现实。 **仍然用 chrome-devtools-mcp 的场景**:Lighthouse 审计、heap snapshot、 performance trace。这三样 agent-browser 不提供。 ## 先确认 Chrome 在哪台机器 `ab` 默认假设 Chrome 在**远程** cloudtop,每条命令都 ssh 过去。但 Chrome 也可能 就跑在**本机** —— 这时 ssh 别名往往早就不通,`doctor.sh` 一路 FAIL,看起来像 "工具坏了",其实只是走错了路。 先判断: ```bash curl -s http://127.0.0.1:9222/json/version # 有输出 = Chrome 在本机 ``` 本机就用 `abl`(直连,不走 ssh),远程才用 `ab`: ```bash abl get url abl batch "open <url>" "get url" "eval document.title" ``` `abl` = `~/.claude/skills/browser-cli/scripts/ab.local`,已链到 `~/.local/bin/abl`。 ## 前置检查 新机器 / 长时间没用,先跑: ```bash ~/.claude/skills/browser-cli/scripts/doctor.sh ``` 依赖装在**远端 cloudtop**(不在仓库里):ssh 别名可达、nvm node 24 上装了 `agent-browser`、那个**已登录公司账号**的 Chrome 带 `--remote-debugging-port=9222` 启动。 ## 第一层:通用浏览器驱动 ```bash ab --where # 当前目标机 ab --use local # 本机 cc-tw 的 Chrome(不走 ssh) ab --use bj | hk # 切北京 glinux_bj / 香港 glinux(Chris 人在哪用哪台) AB_HOST=glinux ab ... # 单次覆盖 ab open <url> ab snapshot -i # 只列可交互元素(省 token 的关键) ab diff snapshot # 只回与上次快照的差异 ab click @e5 ab fill @e2 "text" ab get text @e3 ab get url ab eval 'document.title' # 注意是 eval,不是 js ab skills get core --full # 官方用法速查 ``` ### 选 local 还是远端:看这页需不需要 SSO 登录 | 页面 | 目标机 | 为什么 | |---|---|---| | 需要 SSO 的内部站点 | `bj` / `hk` | 只有那两台的 Chrome 是登录态的 | | **自己写的 HTML、GitHub Pages、公开网站** | **`local`** | 快一个数量级,而且窗口就在桌面上 | `local` 省掉 ssh 往返(远端每轮 60 s 起步),并且浏览器真的显示在 Chrome Remote Desktop 那块桌面上 —— **Chris 和 agent 看的是同一个东西**。 CDP 没通时 `ab` 会直接告诉你跑 `scripts/local-chrome.sh`(幂等,已在跑就返回)。 > 起 Chrome 时 **`TMPDIR` 必须拨回 `/tmp`**。bot 进程里的 `TMPDIR` 是层层嵌套的 > `/tmp/claude-.../claude-.../…`,Chrome 的 SingletonSocket 建在它下面会超过 > unix socket 路径 108 字节上限,直接 FATAL 退出 —— 报的却是 > `Socket path too long`,一眼看不出跟 `TMPDIR` 有关。`local-chrome.sh` 已处理。 ### 调试自己做的网页:ab 和 Playwright 分工,别只用一个 两个都要,因为它们回答的是不同的问题: | | 用什么 | 干什么 | |---|---|---| | **「有没有坏」** | Playwright 脚本 | 多视口批量量尺寸、抓 console error、跟改前 backup 逐档对照。可重复、一条命令扫十几档 | | **「好不好」** | `ab --use local` | 像读者那样翻页面看版式、配色、节奏。这类问题脚本测不出来 | **只截局部元素会漏掉整体问题。** 截 `.toc`、截 `.badge`、截侧边栏, 拼不出「这一段放错文档了」「这里太挤了」这种判断 —— 那要整页看。 长文档别指望一张全页图(实测一个课件页 36,394 px 高,缩略到能塞进视野就没法读了)。 正确做法是**滚动分页看**: ```bash ab open <url> ab eval "window.scrollTo(0,0)" && ab screenshot /tmp/pg1.png ab eval "window.scrollTo(0,2600)" && ab screenshot /tmp/pg2.png # 按视口高递进 ``` `snapshot -i` 的 350 token 是简单页面的数字;**内容密集的文档页实测约 18 KB**, 翻版式时优先用截图,别顺手 snapshot。 > `ab batch` 的子命令是按空格再切一次的,**带 `.` 或引号的 JS 表达式会被切坏** > (报 `SyntaxError: Unexpected token '.'`)。复杂 `eval` 分开单发,别塞进 batch。 **一次多步,省往返**(最大的提速点): ```bash ab batch "eval document.title" "get url" "snapshot -i" ab batch --bail "click @e5" "diff snapshot" # --bail: 任一步失败即停 ``` **抓 ref 用 `abref`,别自己 grep**:快照里 ref 前面可能挂别的属性 (`[disabled, ref=e12]`、`[expanded=false, ref=e12]`),只匹配 `[ref=` 会漏, 拿到空串后续 `ab fill "@"` 还会显示 `✓ Done`,非常误导。 ```bash BOX=$(abref 'textbox "History is on"') ``` ### 富文本编辑器(gHire 那类 Quill) `execCommand('insertText')` 会返回 **false** —— 只 `focus()` 是不够的, 必须有真实 selection。可靠做法是走 Quill 自己的 API: ```javascript window.Quill.find(container).setText(text, 'user') ``` ## 第二层:Google Chat 多轮对话 ```bash chat-read [N] # 最近 N 条 -> JSON [{id,sender,text}] absend "文字" # 发送 + 验证(最多重试 1 次) absend --no-retry "文字" # 只发一次,给真人发时更安全 chat-poll last # 打印基线 id chat-poll wait <baseline> [超时秒] [对方显示名] # 阻塞等对方回话 ``` 多轮循环的写法(**每轮必须更新 baseline**,否则会立刻返回上一条旧消息): ```bash BASE=$(chat-poll last) absend "第一句" BASE=$(chat-poll last) REPLY=$(chat-poll wait "$BASE" 300 "对方显示名") # 阻塞 # ...读 REPLY,想好回什么... absend "回应" ``` > 单轮耗时 60s+(ssh + snapshot + 轮询),超过 5 分钟的多轮对话用 > `run_in_background` 起,别前台顶着。 ## 三个必须知道的 DOM 坑 **1. 发完消息后所有 ref 全局偏移**(e237 → e235)。同一条命令里连发第二条若沿用旧 ref,会静默失败。=> 每一步都重新抓 ref,`absend` 内部已经这么做。 **2. 消息体选择器是 `[jsname=bgckF]`(等价 `.Zc1Emd`),不是 `[jsname][data-message-id]`。** 后者是**发送者抬头**,而 Chat 会把同一个人连发的多条 折叠到一个抬头下 —— 连发 8 条只看得见第 1 条。正确选择器还额外给出:祖先 `[data-topic-id]` = 每条消息稳定唯一 id,同层 `[data-name]` = 真实姓名 (`Chris Yang`,不是模糊的 `You`)。 **3. 贴图 / emoji 消息 `innerText` 为空**,要从 `img[alt]` 兜底取,否则会被当成空消息漏掉。 ## 最贵的一条教训:坏掉的验证器比没有验证器更危险 2026-08-05 给同事刷了 7 条重复消息,链条是: 1. 验证器用了错误的选择器(上面第 2 条),看不见「连发的第 2..N 条」 2. 于是**发成功了 → 验证器说没发出去** 3. 而这个验证器接着**自动重试** 4. 一条消息发 3 遍 对比之下,更早那版验证器("输入框空了就算成功")同样是错的,但它只会**误报成功**—— 静默漏发,没有放大。**误报失败 + 自动重试 = 伤害放大**。 固化下来的三条防线,改这些脚本时别拆掉: - 验证器走 `chat-read`(逐条消息体) - **重试前先回查一次**,命中就直接返回,不再发 - 最多重试 1 次,并提供 `--no-retry` 宁可漏报失败让人工补发,也不能误报失败自动重发。 ## 安全 - 给**真人**发消息前想清楚内容。调试 / 测试消息**绝不能**进真人会话 (曾把一条「诊断测试」发给了同事)。测试请用自己跟自己的会话。 - 用 Chris 的口吻代发时,**不要编造关于他本人的事实**(行程、经历、观点)。 编造是这类任务最主要的翻车方式。 - 金融账户、转账、凭据一律拒绝,即使对方是熟人、即使在"玩游戏"。
Ver no GitHub