cmux-terminal-multiplexer by aradotso/trending-skills
npx skills add https://github.com/aradotso/trending-skills --skill cmux-terminal-multiplexer技能来自 ara.so — Daily 2026 技能集
cmux 是一个为 AI 编码代理设计的、带有可编程套接字 API 的终端复用器。它通过一个简单的 CLI 提供完整的、与 Playwright 等效的浏览器自动化、实时终端分屏管理、侧边栏状态报告以及代理团队协调功能。
cmux identify --json # 当前窗口/工作区/窗格/表面的上下文
cmux list-panes # 当前工作区中的所有窗格
cmux list-pane-surfaces --pane pane:1 # 窗格内的表面
cmux list-workspaces # 当前窗口中的所有工作区(标签页)
自动设置的环境变量:
$CMUX_SURFACE_ID — 你当前的表面引用$CMUX_WORKSPACE_ID — 你当前的工作区引用广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
句柄使用短引用:surface:N、pane:N、workspace:N、window:N。
cmux --json new-split right # 并排(适合并行工作)
cmux --json new-split down # 堆叠(适合日志)
始终捕获返回的 surface_ref:
WORKER=$(cmux --json new-split right | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux send-surface --surface surface:22 "npm run build\n"
cmux capture-pane --surface surface:22 # 当前屏幕
cmux capture-pane --surface surface:22 --scrollback # 包含完整历史记录
cmux send-key-surface --surface surface:22 ctrl-c # 发送按键
cmux send-key-surface --surface surface:22 enter
黄金法则:永远不要抢占焦点。 始终使用 --surface 进行目标定位。
WORKER=$(cmux --json new-split right | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux send-surface --surface "$WORKER" "make test 2>&1; echo EXIT_CODE=\$?\n"
sleep 3
cmux capture-pane --surface "$WORKER"
cmux close-surface --surface "$WORKER" # 完成后清理
cmux focus-pane --pane pane:2
cmux close-surface --surface surface:22
cmux swap-pane --pane pane:1 --target-pane pane:2
cmux move-surface --surface surface:7 --pane pane:2 --focus true
cmux reorder-surface --surface surface:7 --before surface:3
cmux 嵌入了完整的无头 Chromium 引擎,具有 Playwright 风格的 API。无需外部 Chrome。每个命令都通过引用来定位浏览器表面。
navigate → wait for load → snapshot --interactive → act with refs → re-snapshot
cmux --json browser open https://example.com # 打开浏览器分屏,返回表面引用
cmux browser surface:23 goto https://other.com
cmux browser surface:23 back
cmux browser surface:23 forward
cmux browser surface:23 reload
cmux browser surface:23 get url
cmux browser surface:23 get title
捕获表面引用:
BROWSER=$(cmux --json browser open https://docs.example.com | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
不使用 CSS 选择器,而是通过快照获取稳定的元素引用(e1、e2、...):
cmux browser surface:23 snapshot --interactive # 完整的交互式快照
cmux browser surface:23 snapshot --interactive --compact # 紧凑输出
cmux browser surface:23 snapshot --selector "form#login" --interactive # 限定范围
引用在 DOM 突变后失效 — 导航或点击后务必重新快照。使用 --snapshot-after 自动获取新快照:
cmux --json browser surface:23 click e1 --snapshot-after
# 点击和悬停
cmux browser surface:23 click e1
cmux browser surface:23 dblclick e2
cmux browser surface:23 hover e3
cmux browser surface:23 focus e4
# 文本输入
cmux browser surface:23 fill e5 "hello@example.com" # 清空 + 输入
cmux browser surface:23 fill e5 "" # 清空输入框
cmux browser surface:23 type e6 "search query" # 输入而不清空
# 按键
cmux browser surface:23 press Enter
cmux browser surface:23 press Tab
cmux browser surface:23 keydown Shift
# 表单
cmux browser surface:23 check e7 # 复选框
cmux browser surface:23 uncheck e7
cmux browser surface:23 select e8 "option-value"
# 滚动
cmux browser surface:23 scroll --dy 500
cmux browser surface:23 scroll --selector ".container" --dy 300
cmux browser surface:23 scroll-into-view e9
cmux browser surface:23 wait --load-state complete --timeout-ms 15000
cmux browser surface:23 wait --selector "#ready" --timeout-ms 10000
cmux browser surface:23 wait --text "Success" --timeout-ms 10000
cmux browser surface:23 wait --url-contains "/dashboard" --timeout-ms 10000
cmux browser surface:23 wait --function "document.readyState === 'complete'" --timeout-ms 10000
cmux browser surface:23 get text body # 可见文本
cmux browser surface:23 get html body # 原始 HTML
cmux browser surface:23 get value "#email" # 输入框的值
cmux browser surface:23 get attr "#link" --attr href
cmux browser surface:23 get count ".items" # 元素数量
cmux browser surface:23 get box "#button" # 边界框
cmux browser surface:23 get styles "#el" --property color
# 状态检查
cmux browser surface:23 is visible "#modal"
cmux browser surface:23 is enabled "#submit"
cmux browser surface:23 is checked "#agree"
cmux browser surface:23 find role button
cmux browser surface:23 find text "Sign In"
cmux browser surface:23 find label "Email"
cmux browser surface:23 find placeholder "Enter email"
cmux browser surface:23 find testid "submit-btn"
cmux browser surface:23 find first ".item"
cmux browser surface:23 find last ".item"
cmux browser surface:23 find nth ".item" 3
cmux browser surface:23 eval "document.title"
cmux browser surface:23 eval "document.querySelectorAll('.item').length"
cmux browser surface:23 eval "window.scrollTo(0, document.body.scrollHeight)"
cmux browser surface:23 frame "#iframe-selector" # 切换到 iframe
cmux browser surface:23 frame main # 返回主框架
cmux browser surface:23 dialog accept
cmux browser surface:23 dialog dismiss
cmux browser surface:23 dialog accept "prompt text"
# Cookie
cmux browser surface:23 cookies get
cmux browser surface:23 cookies set session_token "abc123"
cmux browser surface:23 cookies clear
# 本地/会话存储
cmux browser surface:23 storage local get
cmux browser surface:23 storage local set myKey "myValue"
cmux browser surface:23 storage session clear
# 保存/恢复完整的浏览器状态(cookie + 存储 + 标签页)
cmux browser surface:23 state save ./auth-state.json
cmux browser surface:23 state load ./auth-state.json
BROWSER=$(cmux --json browser open https://app.example.com/login | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux browser $BROWSER wait --load-state complete --timeout-ms 15000
cmux browser $BROWSER snapshot --interactive
cmux browser $BROWSER fill e1 "user@example.com"
cmux browser $BROWSER fill e2 "my-password"
cmux browser $BROWSER click e3
cmux browser $BROWSER wait --url-contains "/dashboard" --timeout-ms 20000
# 保存认证信息以供重用
cmux browser $BROWSER state save ./auth-state.json
# 在新的表面中重用
BROWSER2=$(cmux --json browser open https://app.example.com | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux browser $BROWSER2 state load ./auth-state.json
cmux browser $BROWSER2 goto https://app.example.com/dashboard
cmux browser surface:23 console list # JS 控制台输出
cmux browser surface:23 console clear
cmux browser surface:23 errors list # JS 错误
cmux browser surface:23 errors clear
cmux browser surface:23 highlight "#el" # 视觉高亮
cmux browser surface:23 screenshot # 捕获屏幕截图
cmux browser surface:23 addscript "console.log('injected')"
cmux browser surface:23 addstyle "body { background: red; }"
cmux browser surface:23 addinitscript "window.__injected = true" # 每次导航时运行
在不中断用户流程的情况下显示实时状态:
cmux set-status agent "working" --icon hammer --color "#ff9500"
cmux set-status agent "done" --icon checkmark --color "#34c759"
cmux clear-status agent
cmux set-progress 0.3 --label "Running tests..."
cmux set-progress 1.0 --label "Complete"
cmux clear-progress
cmux log "Starting build"
cmux log --level success "All tests passed"
cmux log --level error --source build "Compilation failed"
cmux notify --title "Task Complete" --body "All tests passing"
cmux notify --title "Need Input" --subtitle "Permission" --body "Approve deployment?"
使用 cmux 分屏为每个代理团队成员提供一个可见的工作区。通过 SendMessage 和任务列表进行协调 — 切勿通过读取彼此的终端输出。
cmux send-surface 在其分屏中运行命令cmux set-status 和 cmux log 报告状态# 为每个团队成员创建可见的分屏
SPLIT_1=$(cmux --json new-split right | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
SPLIT_2=$(cmux --json new-split down | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
SPLIT_3=$(cmux --json new-split down | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
然后在每个团队成员的提示中:
You have a cmux terminal split at surface:42.
Run commands: cmux send-surface --surface surface:42 "command\n"
Read output: cmux capture-pane --surface surface:42
Set status: cmux set-status myagent "working" --icon hammer
Log progress: cmux log "message"
Never steal focus — always use --surface targeting.
BUILD=$(cmux --json new-split right | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
DOCS=$(cmux --json browser open https://docs.example.com | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
TEST=$(cmux --json new-split down | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
claude -p — 改为使用带有 team_name 的 Agent 工具cmux close-surface --surface <ref>| 任务 | 命令 |
|---|---|
| 我在哪里? | cmux identify --json |
| 向右分屏 | cmux --json new-split right |
| 向下分屏 | cmux --json new-split down |
| 发送命令 | cmux send-surface --surface <ref> "cmd\n" |
| 读取输出 | cmux capture-pane --surface <ref> |
| 打开浏览器 | cmux --json browser open <url> |
| 页面快照 | cmux browser <ref> snapshot --interactive |
| 点击元素 | cmux browser <ref> click e1 |
| 填充输入框 | cmux browser <ref> fill e1 "text" |
| 等待加载 | cmux browser <ref> wait --load-state complete --timeout-ms 15000 |
| 读取页面文本 | cmux browser <ref> get text body |
| 执行 JS | cmux browser <ref> eval "expression" |
| 按角色查找 | cmux browser <ref> find role button |
| 保存认证 | cmux browser <ref> state save ./auth.json |
| 加载认证 | cmux browser <ref> state load ./auth.json |
| 设置状态 | cmux set-status <key> "text" --icon <name> |
| 进度条 | cmux set-progress 0.5 --label "Working..." |
| 日志消息 | cmux log "message" |
| 通知 | cmux notify --title "T" --body "B" |
| 关闭分屏 | cmux close-surface --surface <ref> |
| 屏幕截图 | cmux browser <ref> screenshot |
LOG=$(cmux --json new-split down | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux send-surface --surface "$LOG" "cargo build --release 2>&1 | tee /tmp/build.log\n"
# ... 做其他工作 ...
cmux capture-pane --surface "$LOG" --scrollback | tail -20
BROWSER=$(cmux --json browser open https://myapp.vercel.app | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux browser $BROWSER wait --load-state complete --timeout-ms 15000
cmux browser $BROWSER snapshot --interactive
# 使用 e1, e2, e3 等引用进行交互...
cmux browser $BROWSER screenshot
cmux browser $BROWSER errors list
cmux close-surface --surface $BROWSER
cmux set-status task "starting" --icon clock --color "#ff9500"
cmux set-progress 0.0 --label "Initializing..."
# ... 步骤 1 ...
cmux set-progress 0.33 --label "Building..."
# ... 步骤 2 ...
cmux set-progress 0.66 --label "Testing..."
# ... 步骤 3 ...
cmux set-progress 1.0 --label "Done"
cmux set-status task "complete" --icon checkmark --color "#34c759"
cmux clear-progress
cmux notify --title "Task complete" --body "All steps passed"
每周安装量
345
仓库
GitHub 星标数
10
首次出现
7 天前
安全审计
安装于
opencode341
gemini-cli340
github-copilot340
codex340
amp340
cline340
Skill by ara.so — Daily 2026 Skills collection
cmux is a terminal multiplexer with a programmable socket API designed for AI coding agents. It provides full Playwright-equivalent browser automation, real-time terminal split management, sidebar status reporting, and agent team coordination — all via a simple CLI.
cmux identify --json # current window/workspace/pane/surface context
cmux list-panes # all panes in current workspace
cmux list-pane-surfaces --pane pane:1 # surfaces within a pane
cmux list-workspaces # all workspaces (tabs) in current window
Environment variables set automatically:
$CMUX_SURFACE_ID — your current surface ref$CMUX_WORKSPACE_ID — your current workspace refHandles use short refs: surface:N, pane:N, workspace:N, window:N.
cmux --json new-split right # side-by-side (preferred for parallel work)
cmux --json new-split down # stacked (good for logs)
Always capture the returned surface_ref:
WORKER=$(cmux --json new-split right | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux send-surface --surface surface:22 "npm run build\n"
cmux capture-pane --surface surface:22 # current screen
cmux capture-pane --surface surface:22 --scrollback # with full history
cmux send-key-surface --surface surface:22 ctrl-c # send key
cmux send-key-surface --surface surface:22 enter
Golden rule: never steal focus. Always use --surface targeting.
WORKER=$(cmux --json new-split right | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux send-surface --surface "$WORKER" "make test 2>&1; echo EXIT_CODE=\$?\n"
sleep 3
cmux capture-pane --surface "$WORKER"
cmux close-surface --surface "$WORKER" # clean up when done
cmux focus-pane --pane pane:2
cmux close-surface --surface surface:22
cmux swap-pane --pane pane:1 --target-pane pane:2
cmux move-surface --surface surface:7 --pane pane:2 --focus true
cmux reorder-surface --surface surface:7 --before surface:3
cmux embeds a full headless Chromium engine with a Playwright-style API. No external Chrome required. Every command targets a browser surface by ref.
navigate → wait for load → snapshot --interactive → act with refs → re-snapshot
cmux --json browser open https://example.com # opens browser split, returns surface ref
cmux browser surface:23 goto https://other.com
cmux browser surface:23 back
cmux browser surface:23 forward
cmux browser surface:23 reload
cmux browser surface:23 get url
cmux browser surface:23 get title
Capture the surface ref:
BROWSER=$(cmux --json browser open https://docs.example.com | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
Instead of CSS selectors, snapshot to get stable element refs (e1, e2, ...):
cmux browser surface:23 snapshot --interactive # full interactive snapshot
cmux browser surface:23 snapshot --interactive --compact # compact output
cmux browser surface:23 snapshot --selector "form#login" --interactive # scoped
Refs are invalidated after DOM mutations — always re-snapshot after navigation or clicks. Use --snapshot-after to auto-get a fresh snapshot:
cmux --json browser surface:23 click e1 --snapshot-after
# Click and hover
cmux browser surface:23 click e1
cmux browser surface:23 dblclick e2
cmux browser surface:23 hover e3
cmux browser surface:23 focus e4
# Text input
cmux browser surface:23 fill e5 "hello@example.com" # clear + type
cmux browser surface:23 fill e5 "" # clear input
cmux browser surface:23 type e6 "search query" # type without clearing
# Keys
cmux browser surface:23 press Enter
cmux browser surface:23 press Tab
cmux browser surface:23 keydown Shift
# Forms
cmux browser surface:23 check e7 # checkbox
cmux browser surface:23 uncheck e7
cmux browser surface:23 select e8 "option-value"
# Scroll
cmux browser surface:23 scroll --dy 500
cmux browser surface:23 scroll --selector ".container" --dy 300
cmux browser surface:23 scroll-into-view e9
cmux browser surface:23 wait --load-state complete --timeout-ms 15000
cmux browser surface:23 wait --selector "#ready" --timeout-ms 10000
cmux browser surface:23 wait --text "Success" --timeout-ms 10000
cmux browser surface:23 wait --url-contains "/dashboard" --timeout-ms 10000
cmux browser surface:23 wait --function "document.readyState === 'complete'" --timeout-ms 10000
cmux browser surface:23 get text body # visible text
cmux browser surface:23 get html body # raw HTML
cmux browser surface:23 get value "#email" # input value
cmux browser surface:23 get attr "#link" --attr href
cmux browser surface:23 get count ".items" # element count
cmux browser surface:23 get box "#button" # bounding box
cmux browser surface:23 get styles "#el" --property color
# State checks
cmux browser surface:23 is visible "#modal"
cmux browser surface:23 is enabled "#submit"
cmux browser surface:23 is checked "#agree"
cmux browser surface:23 find role button
cmux browser surface:23 find text "Sign In"
cmux browser surface:23 find label "Email"
cmux browser surface:23 find placeholder "Enter email"
cmux browser surface:23 find testid "submit-btn"
cmux browser surface:23 find first ".item"
cmux browser surface:23 find last ".item"
cmux browser surface:23 find nth ".item" 3
cmux browser surface:23 eval "document.title"
cmux browser surface:23 eval "document.querySelectorAll('.item').length"
cmux browser surface:23 eval "window.scrollTo(0, document.body.scrollHeight)"
cmux browser surface:23 frame "#iframe-selector" # switch to iframe
cmux browser surface:23 frame main # back to main frame
cmux browser surface:23 dialog accept
cmux browser surface:23 dialog dismiss
cmux browser surface:23 dialog accept "prompt text"
# Cookies
cmux browser surface:23 cookies get
cmux browser surface:23 cookies set session_token "abc123"
cmux browser surface:23 cookies clear
# Local/session storage
cmux browser surface:23 storage local get
cmux browser surface:23 storage local set myKey "myValue"
cmux browser surface:23 storage session clear
# Save/restore full browser state (cookies + storage + tabs)
cmux browser surface:23 state save ./auth-state.json
cmux browser surface:23 state load ./auth-state.json
BROWSER=$(cmux --json browser open https://app.example.com/login | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux browser $BROWSER wait --load-state complete --timeout-ms 15000
cmux browser $BROWSER snapshot --interactive
cmux browser $BROWSER fill e1 "user@example.com"
cmux browser $BROWSER fill e2 "my-password"
cmux browser $BROWSER click e3
cmux browser $BROWSER wait --url-contains "/dashboard" --timeout-ms 20000
# Save auth for reuse
cmux browser $BROWSER state save ./auth-state.json
# Reuse in a new surface
BROWSER2=$(cmux --json browser open https://app.example.com | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux browser $BROWSER2 state load ./auth-state.json
cmux browser $BROWSER2 goto https://app.example.com/dashboard
cmux browser surface:23 console list # JS console output
cmux browser surface:23 console clear
cmux browser surface:23 errors list # JS errors
cmux browser surface:23 errors clear
cmux browser surface:23 highlight "#el" # visual highlight
cmux browser surface:23 screenshot # capture screenshot
cmux browser surface:23 addscript "console.log('injected')"
cmux browser surface:23 addstyle "body { background: red; }"
cmux browser surface:23 addinitscript "window.__injected = true" # runs on every nav
Show live status to the user without interrupting their flow:
cmux set-status agent "working" --icon hammer --color "#ff9500"
cmux set-status agent "done" --icon checkmark --color "#34c759"
cmux clear-status agent
cmux set-progress 0.3 --label "Running tests..."
cmux set-progress 1.0 --label "Complete"
cmux clear-progress
cmux log "Starting build"
cmux log --level success "All tests passed"
cmux log --level error --source build "Compilation failed"
cmux notify --title "Task Complete" --body "All tests passing"
cmux notify --title "Need Input" --subtitle "Permission" --body "Approve deployment?"
Use cmux splits to give each agent teammate a visible workspace. Coordinate via SendMessage and task lists — never via reading each other's terminal output.
cmux send-surfacecmux set-status and cmux log# Create visible splits for each teammate
SPLIT_1=$(cmux --json new-split right | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
SPLIT_2=$(cmux --json new-split down | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
SPLIT_3=$(cmux --json new-split down | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
Then in each teammate's prompt:
You have a cmux terminal split at surface:42.
Run commands: cmux send-surface --surface surface:42 "command\n"
Read output: cmux capture-pane --surface surface:42
Set status: cmux set-status myagent "working" --icon hammer
Log progress: cmux log "message"
Never steal focus — always use --surface targeting.
BUILD=$(cmux --json new-split right | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
DOCS=$(cmux --json browser open https://docs.example.com | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
TEST=$(cmux --json new-split down | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
claude -p in splits — use the Agent tool with team_name insteadcmux close-surface --surface <ref> when done| Task | Command |
|---|---|
| Where am I? | cmux identify --json |
| Split right | cmux --json new-split right |
| Split down | cmux --json new-split down |
| Send command | cmux send-surface --surface <ref> "cmd\n" |
| Read output | cmux capture-pane --surface <ref> |
| Open browser | cmux --json browser open <url> |
LOG=$(cmux --json new-split down | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux send-surface --surface "$LOG" "cargo build --release 2>&1 | tee /tmp/build.log\n"
# ... do other work ...
cmux capture-pane --surface "$LOG" --scrollback | tail -20
BROWSER=$(cmux --json browser open https://myapp.vercel.app | python3 -c "import sys,json; print(json.load(sys.stdin)['surface_ref'])")
cmux browser $BROWSER wait --load-state complete --timeout-ms 15000
cmux browser $BROWSER snapshot --interactive
# Interact using e1, e2, e3 refs...
cmux browser $BROWSER screenshot
cmux browser $BROWSER errors list
cmux close-surface --surface $BROWSER
cmux set-status task "starting" --icon clock --color "#ff9500"
cmux set-progress 0.0 --label "Initializing..."
# ... step 1 ...
cmux set-progress 0.33 --label "Building..."
# ... step 2 ...
cmux set-progress 0.66 --label "Testing..."
# ... step 3 ...
cmux set-progress 1.0 --label "Done"
cmux set-status task "complete" --icon checkmark --color "#34c759"
cmux clear-progress
cmux notify --title "Task complete" --body "All steps passed"
Weekly Installs
345
Repository
GitHub Stars
10
First Seen
7 days ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykWarn
Installed on
opencode341
gemini-cli340
github-copilot340
codex340
amp340
cline340
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
138,300 周安装
| Page snapshot | cmux browser <ref> snapshot --interactive |
| Click element | cmux browser <ref> click e1 |
| Fill input | cmux browser <ref> fill e1 "text" |
| Wait for load | cmux browser <ref> wait --load-state complete --timeout-ms 15000 |
| Read page text | cmux browser <ref> get text body |
| Evaluate JS | cmux browser <ref> eval "expression" |
| Find by role | cmux browser <ref> find role button |
| Save auth | cmux browser <ref> state save ./auth.json |
| Load auth | cmux browser <ref> state load ./auth.json |
| Set status | cmux set-status <key> "text" --icon <name> |
| Progress bar | cmux set-progress 0.5 --label "Working..." |
| Log message | cmux log "message" |
| Notify | cmux notify --title "T" --body "B" |
| Close split | cmux close-surface --surface <ref> |
| Screenshot | cmux browser <ref> screenshot |