自定义命令
通过在项目根目录或 ~/.config/cmux/ 中添加 cmux.json 文件来定义自定义命令和工作区布局。命令将显示在命令面板中。
文件位置
cmux 在两个地方查找配置:
- 按项目:
./.cmux/cmux.json- 位于项目目录中,优先级更高 - 本地回退:
./cmux.json- 仍支持现有仓库 - 全局:
~/.config/cmux/cmux.json- 适用于所有项目,补充本地未定义的命令
actions、shortcut 或 ui.surfaceTabBar.buttons 前,请安装最新 nightly 构建。编辑 cmux.json 后,按 Cmd+Shift+, 或运行 cmux reload-config 来应用更改。
配置架构
commands 仍用于定义可复用的 shell 命令和 workspace 布局。Nightly 构建会加入 actions 注册表。动作是 surface 标签栏、Command Palette 和动作级快捷键共享的公开 ID。
{
"actions": {
"cmux.newTerminal": {
"type": "command",
"title": "Codex",
"subtitle": "Open Codex in a new terminal tab",
"command": "codex --dangerously-bypass-approvals-and-sandbox",
"target": "newTabInCurrentPane",
"shortcut": "cmd+t",
"icon": { "type": "image", "path": "./icons/codex.svg" }
},
"claude": {
"type": "command",
"title": "Claude Code",
"command": "claude --dangerously-skip-permissions",
"target": "newTabInCurrentPane",
"shortcut": "cmd+shift+c",
"icon": { "type": "image", "path": "./icons/claude.svg" }
},
"opencode": {
"type": "command",
"title": "OpenCode",
"command": "opencode",
"target": "newTabInCurrentPane",
"palette": false,
"icon": { "type": "emoji", "value": "🧪", "scale": 0.9 }
},
"web-dev": {
"type": "workspaceCommand",
"title": "Web Dev",
"commandName": "Web Dev"
}
},
"ui": {
"surfaceTabBar": {
"buttons": [
"cmux.newTerminal",
"cmux.newBrowser",
"cmux.splitRight",
"cmux.splitDown",
"claude"
]
}
},
"commands": [
{
"name": "Web Dev",
"keywords": ["dev", "start"],
"workspace": { ... }
}
]
}Nightly 动作注册表
actions 将稳定 ID 映射到可运行的行为。使用内置 ID cmux.newTerminal、cmux.newBrowser、cmux.splitRight 和 cmux.splitDown 覆盖默认值。项目专用工具可以使用你自己的 ID。
palette 默认是 true。将其设为 false 可以让动作不显示在 Command Palette 中,但仍可从 surface 标签栏或快捷键调用。shortcut 使用与设置快捷键相同的语法,例如 cmd+shift+c 或 ["cmd+k", "cmd+c"]。
存在 ui.surfaceTabBar.buttons 时,它会替换默认按钮列表。省略某个内置 ID 即可隐藏它。图标始终使用对象形式:{ "type": "symbol", "name": "play.circle" }、{ "type": "emoji", "value": "🧪", "scale": 0.9 } 或 { "type": "image", "path": "./icons/codex.svg" }。图片路径相对于配置文件。Emoji scale 可选,默认值为 1。支持 SVG、PDF、PNG、JPEG、GIF、TIFF、BMP、HEIC、HEIF、WebP、AVIF、ICO 和 ICNS。
每个按钮条目可以是动作 ID 字符串,也可以是按钮对象。当你想让同一个动作使用不同的 surface 标签、图标或 tooltip 时,请使用按钮对象。解析后的按钮标题也会用作信任提示标题。
请把任何 approval 或 permission flags 直接放进你真正想运行的命令字符串里。默认动作目标是 newTabInCurrentPane,所以常见模式是在当前 pane 中打开新的终端标签,并在那里启动 Codex、Claude Code 或 OpenCode。
自定义操作和 Command Palette
actions 条目是 cmux 执行的可复用行为。当同一行为需要从 Command Palette、表面标签栏、快捷键或加号按钮菜单触发时,请使用操作。将 commands 保留给可复用的 shell 命令和工作区布局。如果某个操作不应出现在 Command Palette 中,请将 palette 设为 false。
操作类型
"builtin": 为内置 cmux 操作创建别名,例如 cmux.newTerminal、cmux.newBrowser、cmux.splitRight 或 cmux.splitDown。"command": 在终端中运行 shell 文本。使用 target 选择当前终端或当前面板中的新标签。"agent": 启动受支持的编码代理。目前支持 codex 和 claude,并可传入可选参数。"workspaceCommand": 运行 commands 中的命名工作区定义。用于多面板布局、自定义工作目录和启动命令。
操作字段
title: Command Palette 行标题、表面按钮标签、菜单项标题以及信任提示标题,除非条目自行覆盖。subtitle/description: Command Palette 中的副标题文本。description 可作为 subtitle 的别名。keywords: Command Palette 的额外搜索词。palette: 自定义操作默认为 true。设为 false 可将操作从 Command Palette 隐藏,同时仍可从其他位置调用。shortcut: 可选的操作快捷键,使用与设置快捷键相同的单键或两段式按键序列语法。target: 仅用于 command 和 agent 操作。使用 currentTerminal 或 newTabInCurrentPane。confirm: 运行操作前请求确认。
Command Palette 行为
Command Palette 读取解析后的操作注册表。当 palette 不是 false 时,自定义操作 ID 会作为行加入。旧的 commands 会自动作为自定义行加入,除非已有相同生成 ID 的操作。内置命令保留正常的面板标签,但覆盖 cmux.newTerminal 等内置 ID 会改变该共享入口背后的行为。
加号按钮的自定义动作
使用 ui.newWorkspace.action 覆盖加号按钮的行为。使用 ui.newWorkspace.contextMenu(或别名 rightClick)定义有序的右键菜单。菜单项可以是动作 ID、动作对象,或 { "type": "separator" }。
{
"actions": {
"worktree-agents": {
"type": "workspaceCommand",
"title": "Worktree Agents",
"commandName": "Worktree Agents",
"icon": { "type": "symbol", "name": "folder.badge.plus" }
}
},
"ui": {
"newWorkspace": {
"action": "worktree-agents",
"contextMenu": [
{ "action": "worktree-agents", "title": "Worktree Agents" },
{ "type": "separator" },
{ "action": "cmux.newTerminal", "title": "New Terminal" },
{ "action": "cmux.newBrowser", "title": "New Browser" }
]
}
},
"commands": [
{
"name": "Worktree Agents",
"description": "Create a fresh Git worktree and start Codex and Claude inside it",
"workspace": {
"name": "Worktree Agents",
"cwd": ".",
"layout": {
"direction": "horizontal",
"split": 0.38,
"children": [
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Worktree",
"command": "set -euo pipefail; state=\"${TMPDIR:-/tmp}/cmux-worktree-${CMUX_WORKSPACE_ID:-manual}.dir\"; rm -f \"$state\"; repo=$(git rev-parse --show-toplevel); mkdir -p \"$repo/../worktrees\"; slug=agents-$(date +%Y%m%d-%H%M%S); dir=\"$repo/../worktrees/$slug\"; git -C \"$repo\" worktree add -b \"$slug\" \"$dir\"; printf \"%s\\n\" \"$dir\" > \"$state\"; cd \"$dir\"; exec \"${SHELL:-/bin/zsh}\" -l",
"focus": true
}
]
}
},
{
"direction": "vertical",
"split": 0.5,
"children": [
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Codex",
"command": "state=\"${TMPDIR:-/tmp}/cmux-worktree-${CMUX_WORKSPACE_ID:-manual}.dir\"; echo \"Waiting for worktree...\"; while [ ! -s \"$state\" ]; do sleep 0.2; done; dir=$(cat \"$state\"); cd \"$dir\"; exec codex --dangerously-bypass-approvals-and-sandbox"
}
]
}
},
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Claude",
"command": "state=\"${TMPDIR:-/tmp}/cmux-worktree-${CMUX_WORKSPACE_ID:-manual}.dir\"; echo \"Waiting for worktree...\"; while [ ! -s \"$state\" ]; do sleep 0.2; done; dir=$(cat \"$state\"); cd \"$dir\"; exec claude --dangerously-skip-permissions"
}
]
}
}
]
}
]
}
}
}
]
}此示例让普通加号点击运行 worktree-agents 操作。来自 commands 的工作区命令会先使用可见的设置终端创建 Git worktree。Codex 和 Claude 同时启动,等待该工作区专用的状态文件,然后在 exec 前进入创建的目录。
简单命令
简单命令在当前聚焦的终端中运行 shell 命令:
{
"commands": [
{
"name": "Run Tests",
"keywords": ["test", "check"],
"command": "npm test",
"confirm": true
}
]
}字段
name: 在命令面板中显示(必填)description: 可选描述keywords: 命令面板的额外搜索词command: 在聚焦终端中运行的 shell 命令confirm: 运行前显示确认对话框
简单命令在当前聚焦终端的工作目录中运行。如果命令依赖于项目相对路径,请在前面加上 cd "$(git rev-parse --show-toplevel)" && 以从仓库根目录运行,或使用 cd /your/path && 指定任意目录。
工作区命令
工作区命令会创建一个新工作区,具有自定义的分屏、终端和浏览器面板布局:
{
"commands": [
{
"name": "Dev Environment",
"keywords": ["dev", "fullstack"],
"workspace": {
"name": "Dev",
"cwd": ".",
"layout": {
"direction": "horizontal",
"split": 0.5,
"children": [
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Frontend",
"command": "npm run dev",
"focus": true
}
]
}
},
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Backend",
"command": "cargo watch -x run",
"cwd": "./server",
"env": { "RUST_LOG": "debug" }
}
]
}
}
]
}
}
}
]
}工作区字段
name: 工作区标签页名称(默认为命令名称)cwd: 工作区的工作目录color: 工作区标签页颜色layout: 定义分屏和面板的布局树
重启行为
控制当同名工作区已存在时的行为:
"new": 创建新的 workspace(默认)"ignore": 切换到现有 workspace"recreate": 不询问,直接关闭并重新创建"confirm": 重新创建前询问用户
布局树
布局树使用递归分割节点定义面板的排列方式:
分割节点
将空间分割为两个子节点:
direction:"horizontal"或"vertical"split: 分割线位置,从 0.1 到 0.9(默认 0.5)children: 恰好两个子节点(分割或面板)
面板节点
包含一个或多个 surface(面板内标签页)的叶节点。
Surface 定义
面板中的每个 surface 可以是终端或浏览器:
type:"terminal"或"browser"name: 自定义标签页标题command: 创建时自动运行的 shell 命令(仅限终端)cwd: 此 surface 的工作目录env: 以键值对形式表示的环境变量url: 要打开的 URL(仅限浏览器)focus: 创建后聚焦此 surface
工作目录解析
.或 省略: 工作区工作目录./subdir: 相对于工作区工作目录~/path: 展开到主目录- 绝对路径: 按原样使用
完整示例
{
"actions": {
"web-dev": { "type": "workspaceCommand", "commandName": "Web Dev" },
"cmux.newTerminal": {
"type": "command",
"title": "Codex",
"command": "codex --dangerously-bypass-approvals-and-sandbox",
"target": "newTabInCurrentPane",
"shortcut": "cmd+t",
"icon": { "type": "image", "path": "./icons/codex.svg" }
},
"claude": {
"type": "command",
"title": "Claude Code",
"command": "claude --dangerously-skip-permissions",
"target": "newTabInCurrentPane",
"shortcut": "cmd+shift+c",
"icon": { "type": "image", "path": "./icons/claude.svg" }
},
"start-dev": {
"type": "command",
"command": "npm run dev",
"target": "newTabInCurrentPane",
"icon": { "type": "symbol", "name": "play.circle" }
}
},
"ui": {
"surfaceTabBar": {
"buttons": [
"cmux.newTerminal",
"cmux.newBrowser",
"cmux.splitRight",
"cmux.splitDown",
{
"action": "claude",
"title": "Claude Here"
},
"start-dev"
]
}
},
"commands": [
{
"name": "Web Dev",
"description": "Docs site with live preview",
"keywords": ["web", "docs", "next", "frontend"],
"workspace": {
"name": "Web Dev",
"cwd": "./web",
"color": "#3b82f6",
"layout": {
"direction": "horizontal",
"split": 0.5,
"children": [
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Next.js",
"command": "npm run dev",
"focus": true
}
]
}
},
{
"direction": "vertical",
"split": 0.6,
"children": [
{
"pane": {
"surfaces": [
{
"type": "browser",
"name": "Preview",
"url": "http://localhost:3777"
}
]
}
},
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Shell",
"env": { "NODE_ENV": "development" }
}
]
}
}
]
}
]
}
}
},
{
"name": "Debug Log",
"description": "Tail the debug event log from the running dev app",
"keywords": ["log", "debug", "tail", "events"],
"workspace": {
"name": "Debug Log",
"layout": {
"direction": "horizontal",
"split": 0.5,
"children": [
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Events",
"command": "tail -f /tmp/cmux-debug.log",
"focus": true
}
]
}
},
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Shell"
}
]
}
}
]
}
}
},
{
"name": "Setup",
"description": "Initialize submodules and build dependencies",
"keywords": ["setup", "init", "install"],
"command": "./scripts/setup.sh",
"confirm": true
},
{
"name": "Reload",
"description": "Build and launch the debug app tagged to the current branch",
"keywords": ["reload", "build", "run", "launch"],
"command": "./scripts/reload.sh --tag $(git branch --show-current)"
},
{
"name": "Run Unit Tests",
"keywords": ["test", "unit"],
"command": "./scripts/test-unit.sh",
"confirm": true
}
]
}