用途
cmux-browser 用于在 cmux 的 webview 浏览器表面(browser surface)内进行浏览器自动化。它与独立的浏览器自动化工具不同,因为每个浏览器表面都存在于 cmux 的工作区(workspace)、窗格(pane)和表面拓扑之中。
默认规则
默认在当前调用者工作区内打开和控制浏览器表面,除非用户明确指定了另一个工作区或窗口。
在改变浏览器状态之前,先识别调用者:
printf 'workspace=%s\nsurface=%s\nsocket=%s\n' \
"${CMUX_WORKSPACE_ID:-}" \
"${CMUX_SURFACE_ID:-}" \
"${CMUX_SOCKET_PATH:-}"
cmux identify --json
使用 CMUX_WORKSPACE_ID 创建新的浏览器分屏,使用 CMUX_SURFACE_ID 了解调用自动化的终端。如果视觉焦点所在的工作区与调用者工作区不同,不要在该视觉焦点工作区中打开浏览器。
核心工作流
# 在调用者工作区中打开并捕获返回的 surface 引用。
cmux --json browser open https://example.com --workspace "${CMUX_WORKSPACE_ID:-}"
# 使用返回的 surface,例如 surface:7。
cmux browser surface:7 get url
cmux browser surface:7 wait --load-state complete --timeout-ms 15000
cmux browser surface:7 snapshot --interactive --compact
cmux browser surface:7 click e2 --snapshot-after
cmux browser surface:7 snapshot --interactive --compact
循环:导航、验证 URL、等待、快照、操作,然后重新快照。快照引用是临时的。在导航、模态框变化、标签页切换或 DOM 更新后,需要重新快照。
定位
大多数子命令需要一个浏览器表面:
cmux browser identify
cmux browser identify --surface surface:2
cmux browser surface:2 get url
cmux browser --surface surface:2 get title
打开命令可以创建或复用浏览器分屏:
cmux browser open http://localhost:3000 --workspace "${CMUX_WORKSPACE_ID:-}" --json
cmux browser open-split https://example.com --workspace workspace:2 --json
cmux browser new https://example.com --window window:1 --json
除非用户要求多个标签页或页面,否则每个任务保持一个浏览器表面。
命令组
完整命令列表见 references/commands.md。主要命令组包括:
- 导航与定位:identify、open、open-split、new、navigate、goto、back、forward、reload、url、focus-webview、is-webview-focused。
- 等待:wait --selector、--text、--url-contains、--load-state、--function。
- DOM 交互:click、dblclick、hover、focus、check、uncheck、scroll-into-view、type、fill、press、keydown、keyup、select、scroll。
- 检查:snapshot、screenshot、get、is、find、highlight。
- JavaScript 与注入:eval、addinitscript、addscript、addstyle。
- 框架、对话框、下载:frame、dialog、download。
- 状态与会话:cookies、storage、state。
- 标签页与诊断:tab、console、errors。
- 环境与底层 API:viewport、geolocation、offline、trace、network、screencast、input。
常见模式
持久化捕获
在向用户报告之前,将浏览器截图、跟踪、下载的诊断信息和可复用会话状态保存在 /cmux-assets/<branch>/browser/... 下,而不是 /tmp。
BRANCH="$(git branch --show-current 2>/dev/null || true)"
BRANCH="${BRANCH:-$(basename "$PWD")}"
BRANCH="$(printf '%s' "$BRANCH" | tr -cs 'A-Za-z0-9._-' '-' | sed 's/^-//;s/-$//')"
ASSET_BASE="/cmux-assets"
if ! mkdir -p "$ASSET_BASE/$BRANCH" 2>/dev/null; then
ASSET_BASE="$(pwd)/cmux-assets"
mkdir -p "$ASSET_BASE/$BRANCH"
fi
BROWSER_ASSET_ROOT="$ASSET_BASE/$BRANCH/browser/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BROWSER_ASSET_ROOT"
如果 /cmux-assets 因根卷只读而不可用,使用回退路径并说明。不要将最终截图或会话文件只留在 /tmp 中。
导航、等待、检查
cmux --json browser open http://localhost:3000 --workspace "${CMUX_WORKSPACE_ID:-}"
cmux browser surface:7 get url
cmux browser surface:7 wait --load-state complete --timeout-ms 15000
cmux browser surface:7 snapshot --interactive --compact
cmux browser surface:7 get title
表单填写
cmux browser surface:7 fill "#email" --text "ops@example.com"
cmux browser surface:7 fill "#password" --text "$PASSWORD"
cmux browser surface:7 click "button[type='submit']" --snapshot-after
cmux browser surface:7 wait --text "Welcome" --timeout-ms 15000
cmux browser surface:7 is visible "#dashboard"
调试捕获
cmux browser surface:7 console list
cmux browser surface:7 errors list
cmux browser surface:7 screenshot --out "$BROWSER_ASSET_ROOT/cmux-failure.png"
cmux browser surface:7 snapshot --interactive --compact
会话保存与恢复
cmux browser surface:7 state save "$BROWSER_ASSET_ROOT/cmux-browser-session.json"
cmux browser surface:7 state load "$BROWSER_ASSET_ROOT/cmux-browser-session.json"
cmux browser surface:7 reload --snapshot-after
远程工作区
在远程 SSH 工作区中,浏览器窗格通过远程机器路由 HTTP 和 WebSocket 流量。localhost:3000 指的是远程主机的 localhost,浏览器存储按远程工作区上下文隔离。
重建与重载
如果浏览器自动化正在验证 cmux 应用/运行时变更,首先从活动工作树构建一个带标签的应用:
./scripts/reload.sh --tag <short-tag>
CMUX_SOCKET_PATH=/tmp/cmux-debug-<short-tag>.sock cmux browser open http://localhost:3000 --workspace "${CMUX_WORKSPACE_ID:-}"
切勿针对未标记的调试套接字进行测试或 dogfood 构建的自动化。
规则
- 默认将浏览器打开和操作限定在当前调用者工作区。
- 从 cmux 终端创建浏览器表面时,传递 --workspace "${CMUX_WORKSPACE_ID:-}"。
- 使用返回的 surface:N 引用,并在任何改变状态的操作后重新快照。
- 在等待或诊断页面状态之前,先验证 get url。
- 在需要立即验证时,对改变状态的操作使用 --snapshot-after。
- 脚本中优先使用 get、is 和 find。使用截图和快照供人工审查。
- 除非用户指定目标,否则不要关闭、移动或聚焦调用者工作区之外的浏览器表面。
- 不要使用不受支持的独立浏览器假设。cmux 使用 WKWebView 支持的浏览器表面。