关于 cmux-workspace
cmux-workspace 是一项 Agent 技能,用于将 cmux 操作限定在调用 Agent 的工作区。它强调先确认调用者上下文,并避免意外更改焦点或布局。
主要功能
- 01以调用者工作区为操作锚点
- 02检查工作区、窗格和界面上下文
- 03创建可复用的右侧辅助窗格
- 04避免未经请求更改焦点
- 05报告前验证辅助终端
适用场景
- 01在调用者终端旁打开任务日志
- 02重复预览时复用辅助窗格
- 03执行限定工作区的 cmux 操作
- 04查看产物时保持用户焦点不变
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ manaflow-ai/ cmux-skills --skill cmux-workspace安装后在 Claude Code 中输入/cmux-workspace确认已加载。
附带文件agents/openai.yamlreferences/commands.md
详细介绍
cmux 工作区
当任务应限定在调用 Agent 的 cmux 工作区内时,请使用此技能。工作区是 cmux 中类似侧边栏标签页的单元。它包含分屏窗格,每个窗格包含一个或多个界面。界面是用户交互的终端或浏览器会话。
默认规则
除非用户明确要求使用其他工作区、其他窗口或全局状态,否则请将操作限定在当前调用方工作区内。
不要假设视觉上处于焦点的 cmux 工作区就是正确目标。Agent 可能在一个工作区中运行,而用户正在查看另一个工作区。优先使用调用方环境:
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 用作默认调用方终端/界面锚点。如果缺少这些变量,请使用 cmux identify --json,并明确说明你使用的是当前处于焦点的 cmux 上下文。
非干扰式自动化
Agent 在调用方工作区中工作时,用户可能正将视觉焦点放在其他工作区、窗口或应用上。请将布局与焦点分开处理。切勿在没有明确需要时调用会改变焦点的动词。
未经用户明确要求,切勿调用以下命令:
select-workspace会切换可见的侧边栏标签页。focus-pane/focus-panel会强制切换窗格或界面的焦点。tab-action中会改变焦点的操作。
这些操作会影响用户,类似点击。即使是在调用方自己的工作区中,也应遵守此规则,因为用户可能正在查看其他位置。
一次性以增量方式构建布局。优先使用可直接创建已填充正确界面的新窗格的命令:
# pane and content in one call, no follow-up needed
cmux new-pane --workspace "${CMUX_WORKSPACE_ID}" --type browser --direction right --url "http://127.0.0.1:8765"
cmux new-pane --workspace "${CMUX_WORKSPACE_ID}" --type terminal --direction down
避免先创建、再移动、再聚焦的操作链。如果布局命令拒绝有效的 surface: 或 pane: 引用,不要通过切换焦点来绕过。向用户报告此错误并停止。
只要动词支持 --focus false,就始终传入该参数。move-surface --focus false 可以保留用户当前的注意力。其他命令以后也可能支持同一标志(https://github.com/manaflow-ai/cmux/issues/1418、https://github.com/manaflow-ai/cmux/issues/2820)。
右侧辅助窗格
为当前任务打开辅助输出时(预览应用、TUI、日志、临时 shell、浏览器检查),请复用调用方终端右侧的辅助窗格,以保持工作区整洁。
首先检查调用方上下文和窗格:
cmux identify --json
cmux list-panes --workspace "${CMUX_WORKSPACE_ID:-}" --json
cmux list-pane-surfaces --workspace "${CMUX_WORKSPACE_ID:-}" --json
请遵循以下策略:
- 如果调用方工作区已有非调用方辅助窗格,请在该窗格中添加新界面,而不是另建窗格:
cmux new-surface --workspace "${CMUX_WORKSPACE_ID:-}" --pane pane:<helper> --type terminal --focus false - 如果没有辅助窗格,则恰好创建一个右侧窗格:
cmux new-pane --workspace "${CMUX_WORKSPACE_ID:-}" --type terminal --direction right --focus false - 如果此自动化产生了多个明显过时的辅助窗格,且用户要求整理或复用,请保留一个右侧辅助窗格并清理重复项。对于无法确信是过时辅助输出的窗格,不要关闭。
- 使用明确的界面引用向新建或复用的辅助界面发送命令。除非用户要求,否则不要将焦点切换到该界面。
因此,用户重复提出“打开它”时,通常应在现有右侧辅助窗格中创建标签页,而不是再创建分屏。
创建辅助终端后,请先确认其可用,再声称工作内容已在此处显示:
cmux surface-health --workspace "${CMUX_WORKSPACE_ID:-}"
cmux read-screen --workspace "${CMUX_WORKSPACE_ID:-}" --surface surface:<helper> --lines 20
cmux top --workspace "${CMUX_WORKSPACE_ID:-}" --processes --format tsv
如果 read-screen 报告 Terminal surface not found,或者 surface-health 显示辅助终端未附加且 top 中没有对应进程,请将其视为 cmux CLI/运行时错误。不要声称命令正在工作区中运行。清理你创建的所有空辅助界面,然后报告错误,或使用已实例化的 cmux 终端界面。除非用户明确要求采用此变通方式,否则不要使用隐藏的 tmux、nohup 或脱离终端的后台运行方式来进行可见的 dogfood 交接。
Artifact 预览
如果任务会生成视频、图像、已检查的帧、屏幕截图、PDF 或其他面向用户的产物,请在交接前用 cmux 打开最终产物。将它们作为文件预览标签页放入调用方工作区右侧的辅助窗格,并使用 --no-focus,以保持用户当前选中的终端不变。
最终面向用户的产物应保存在 /cmux-assets/<branch>/... 下。如果因根卷为只读而无法创建 /cmux-assets,请改用当前仓库检出目录下的 cmux-assets/<branch>/...,并说明使用了此回退路径。仅将 /tmp 用作临时目录,然后在打开或报告已接受的产物前,将它们复制到持久目录树中。
使用绝对持久路径,或相对于当前仓库检出目录的路径。如果产物位于工作树中,请在最终交接前将其复制到按分支划分的持久资源目录树中;不要报告仅在工作树内有效的路径。
按以下顺序解析工作区和窗格:
- 优先使用
CMUX_WORKSPACE_ID和CMUX_SURFACE_ID。 - 如果它们缺失或被
cmux拒绝,请检查cmux identify --json,并说明正在回退到当前聚焦的 cmux 上下文。 - 如果有明显可复用的非调用方辅助窗格,请复用。
- 如果没有辅助窗格,请使用
--focus false在右侧创建一个,然后重新列出窗格以获取窗格引用。
模板:
ARTIFACTS=(
"/cmux-assets/<branch>/demos/demo.mov"
"/cmux-assets/<branch>/demos/frame-tail.png"
)
WORKSPACE="${CMUX_WORKSPACE_ID:-}"
SURFACE="${CMUX_SURFACE_ID:-}"
cmux identify --json
cmux list-panes --workspace "$WORKSPACE" --json
cmux list-pane-surfaces --workspace "$WORKSPACE" --json
# Pick an existing non-caller helper pane from the pane list. If none exists:
cmux new-pane --workspace "$WORKSPACE" --type terminal --direction right --focus false
cmux list-panes --workspace "$WORKSPACE" --json
cmux open "${ARTIFACTS[@]}" \
--workspace "$WORKSPACE" \
--pane pane:<right-helper> \
--no-focus
cmux list-pane-surfaces --workspace "$WORKSPACE" --json
如果 cmux open 因调用方环境指向过期工作区而失败,请使用 cmux identify --json 返回的引用重试一次。如果仍然失败,不要继续尝试其他工作区。如果打开操作仍失败,请报告故障并附上准确的产物路径。
层级结构
- 窗口:macOS cmux 窗口。
- 工作区:侧边栏条目。UI 可能将其称为标签页,但 CLI/socket API 称之为工作区。
- 窗格:工作区内的分屏区域。
- Surface:窗格内的标签页。Surface 可以是终端或浏览器面板。
- 面板:Surface 内部的内容类型。优先使用 CLI surface 命令,而不是面板内部接口。
检查当前上下文
cmux identify --json
cmux current-workspace --json
cmux list-workspaces --json
cmux list-panes --workspace "${CMUX_WORKSPACE_ID:-}" --json
cmux list-pane-surfaces --workspace "${CMUX_WORKSPACE_ID:-}" --json
cmux list-panels --workspace "${CMUX_WORKSPACE_ID:-}" --json
如果日志或交接需要稳定的 UUID 和易读引用,请使用 --id-format both:
cmux --json --id-format both identify
工作区范围内的操作
即使设置了环境变量,也应优先使用显式工作区标志。这样可以让自动化过程可审计,并避免影响其他窗口中当前聚焦的工作区。
# create a new workspace when the user asks for a new task area
cmux new-workspace --name "debug auth" --cwd "$PWD"
# rename / close (only when explicitly requested)
cmux rename-workspace --workspace "${CMUX_WORKSPACE_ID:-}" -- "build fix"
cmux close-workspace --workspace workspace:4
cmux close-surface --workspace "${CMUX_WORKSPACE_ID:-}" --surface surface:3
# additive layout (safe, no focus side effects beyond the command's own defaults)
cmux new-pane --workspace "${CMUX_WORKSPACE_ID:-}" --type terminal --direction right
cmux new-surface --workspace "${CMUX_WORKSPACE_ID:-}" --type terminal
# focus-changing (USER-AFFECTING, only on explicit ask, see Non-Disruptive Automation above)
cmux select-workspace --workspace workspace:2
cmux focus-pane --workspace "${CMUX_WORKSPACE_ID:-}" --pane pane:2
cmux focus-panel --workspace "${CMUX_WORKSPACE_ID:-}" --panel surface:3
调用方终端
当前终端是调用 Agent 的 Surface。对于相对路径操作,请将其视为最安全的定位基准。
# send to the focused terminal in the caller workspace
cmux send "npm test\n"
# send to the exact caller surface
cmux send --surface "${CMUX_SURFACE_ID:-}" "git status\n"
cmux send-key --surface "${CMUX_SURFACE_ID:-}" enter
除非用户指定了目标,否则不要在其他工作区中发送按键、关闭 Surface 或更改焦点。
移动 Surface
在窗格内重新排列 Surface:
cmux move-surface --surface "${CMUX_SURFACE_ID}" --before surface:3
cmux move-surface --surface "${CMUX_SURFACE_ID}" --after surface:3
cmux move-surface --surface "${CMUX_SURFACE_ID}" --index 0
将 Surface 移至另一个现有窗格。传入 --focus false,以保持用户当前关注的内容不变:
cmux move-surface --surface surface:240 --pane pane:172 --focus false
将 Surface 拆分到新的窗格中:
cmux drag-surface-to-split --surface surface:240 down
已知问题:drag-surface-to-split 当前通过 V1 路由,并通过 UI 焦点解析工作区,因此当调用方的工作区不是视觉上聚焦的工作区时,可能会失败并显示 ERROR: Surface not found。问题跟踪见 https://github.com/manaflow-ai/cmux/issues/1901,相关问题见 https://github.com/manaflow-ai/cmux/issues/3189。在此问题解决之前,优先采用增量构建布局的方式(见上文“非干扰式自动化”),而不是先创建再拆分。
请勿调用 focus-pane 或 focus-panel 来恢复失败的移动操作。报告故障并停止。
侧边栏状态
通常应将状态、进度和日志附加到当前工作区,以便侧边栏反映此任务。
cmux set-status build "running" --workspace "${CMUX_WORKSPACE_ID:-}" --color "#ff9500"
cmux set-progress 0.4 --label "Building" --workspace "${CMUX_WORKSPACE_ID:-}"
cmux log --workspace "${CMUX_WORKSPACE_ID:-}" --level info -- "Started build"
cmux sidebar-state --workspace "${CMUX_WORKSPACE_ID:-}" --json
cmux clear-status build --workspace "${CMUX_WORKSPACE_ID:-}"
cmux clear-progress --workspace "${CMUX_WORKSPACE_ID:-}"
重新构建和重新加载
对于 cmux 应用/运行时更改,请从当前工作树执行带标签的重新加载。带标签的重新加载会创建独立的应用名称、Bundle ID、调试套接字和 DerivedData 路径。
./scripts/reload.sh --tag <short-tag>
如果重新加载输出中包含 Dev web origin,请在交接前从同一工作树启动匹配的开发服务器,并证明其能够响应:
cd web
CMUX_PORT=<printed-port> CMUX_PORT_RANGE=<range> CMUX_PORT_END=<end> bun dev
curl -fsS "http://127.0.0.1:<printed-port>"
在右侧辅助终端中运行该服务器,并使用 read-screen 或 top 验证终端存在。如果无法实例化辅助终端,请报告 cmux CLI/运行时错误,而不要使用隐藏的后台回退方案。
绝不要构建或启动未加标签的 cmux DEV。如果测试或工具需要套接字,请使用对应标签的套接字:
CMUX_SOCKET_PATH=/tmp/cmux-debug-<short-tag>.sock cmux identify --json
如果任务涉及共享的 iOS/运行时代码,也请从工作树执行 iOS 重新加载流程:
ios/scripts/reload.sh --tag <ios-tag>
套接字和访问权限
优先使用 cmux 提供的套接字路径,再回退到默认值:
SOCK="${CMUX_SOCKET_PATH:-/tmp/cmux.sock}"
套接字访问权限可以是关闭、仅限 cmux 启动的进程,或允许所有本地进程。如果命令无法连接,请先检查功能权限,再更改设置:
cmux capabilities --json
cmux ping
参考资料
- references/commands.md 列出了工作区、窗格、界面、通知和实用工具命令。
- ../cmux-browser/SKILL.md 介绍了浏览器界面,并遵循相同的当前工作区规则。
规则
- 默认在当前调用方工作区中操作。
- 优先使用
CMUX_WORKSPACE_ID、CMUX_SURFACE_ID和CMUX_SOCKET_PATH,再回退到聚焦窗口。 - 对会更改状态的操作,优先使用明确的
--workspace和--surface标志。 - 除非用户明确要求,否则绝不要调用
focus-pane、focus-panel、select-workspace或会更改焦点的tab-action动词。用户当前可能正处于其他工作区、窗口或应用中。 - 对
move-surface以及任何支持该选项的创建动词,传入--focus false。 - 对于辅助输出,复用右侧辅助窗格;仅在其不存在时才创建。
- 将最终视频、图像、已检查帧和其他面向用户的产物保存到
/cmux-assets/<branch>/...,或明确指定的回退路径cmux-assets/<branch>/...,然后在交接前使用cmux open ... --no-focus在右侧辅助窗格中打开。 - 使用
new-pane --type ... --url ...以增量方式构建布局,不要使用先创建、再移动、再聚焦的操作链。 - 如果 CLI 命令拒绝有效的界面或窗格引用,请向用户报告。不要通过聚焦来绕过问题。
- 除非用户指定目标,否则不要关闭、聚焦、移动其他工作区中的内容,也不要向其发送输入。
- 聊天和命令示例中使用简短引用。仅在日志、持久化或调试时使用 UUID。
- 对于应用/运行时更改,务必在进行 dogfood 交接前,从工作树运行
./scripts/reload.sh --tag <tag>重新加载。 - 如果带标签的重新加载输出
Dev web origin,则只有在同一工作树的开发服务器已运行且curl -fsS <Dev web origin>检查通过后,才能完成交接。