mcpField
C
cmux-workspace

cmux-workspace

github.com/manaflow-aiAgent 工作流39761 次安装9 周前更新
代码仓库

关于 cmux-workspace

cmux-workspace 是一项 Agent 技能,用于将 cmux 操作限定在调用 Agent 的工作区。它强调先确认调用者上下文,并避免意外更改焦点或布局。

主要功能

  1. 01以调用者工作区为操作锚点
  2. 02检查工作区、窗格和界面上下文
  3. 03创建可复用的右侧辅助窗格
  4. 04避免未经请求更改焦点
  5. 05报告前验证辅助终端

适用场景

  1. 01在调用者终端旁打开任务日志
  2. 02重复预览时复用辅助窗格
  3. 03执行限定工作区的 cmux 操作
  4. 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 用作临时目录,然后在打开或报告已接受的产物前,将它们复制到持久目录树中。

使用绝对持久路径,或相对于当前仓库检出目录的路径。如果产物位于工作树中,请在最终交接前将其复制到按分支划分的持久资源目录树中;不要报告仅在工作树内有效的路径。

按以下顺序解析工作区和窗格:

  1. 优先使用 CMUX_WORKSPACE_ID 和 CMUX_SURFACE_ID。
  2. 如果它们缺失或被 cmux 拒绝,请检查 cmux identify --json,并说明正在回退到当前聚焦的 cmux 上下文。
  3. 如果有明显可复用的非调用方辅助窗格,请复用。
  4. 如果没有辅助窗格,请使用 --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

参考资料

规则

  • 默认在当前调用方工作区中操作。
  • 优先使用 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> 检查通过后,才能完成交接。

评论

支持 Markdown