#คำสั่งที่กำหนดเอง
กำหนดคำสั่งที่กำหนดเองและเลย์เอาต์ workspace โดยเพิ่มไฟล์ cmux.json ลงในรากโปรเจกต์หรือ ~/.config/cmux/ คำสั่งจะปรากฏในแผงคำสั่ง
#ตำแหน่งไฟล์
cmux ค้นหาการตั้งค่าจากสองที่:
- ต่อโปรเจกต์:
./.cmux/cmux.json- อยู่ในไดเรกทอรีโปรเจกต์ของคุณ มีความสำคัญสูงกว่า - local fallback:
./cmux.json- ยังรองรับสำหรับ repo ที่มีอยู่ - การตั้งค่าส่วนกลาง:
~/.config/cmux/cmux.json- ใช้กับทุกโปรเจกต์ เติมคำสั่งที่ยังไม่ได้กำหนดในท้องถิ่น
actions, shortcut หรือ ui.surfaceTabBar.buttonsแก้ไข cmux.json แล้วกด Cmd+Shift+, หรือรัน cmux reload-config เพื่อใช้การเปลี่ยนแปลง
#สคีมา
commands ยังคงใช้กำหนด shell commands และ workspace layouts ที่นำกลับมาใช้ซ้ำได้ Nightly builds เพิ่มรีจิสทรี actions แอ็กชันคือ public IDs ที่ใช้ร่วมกันระหว่างแถบแท็บ surface, Command Palette และ shortcuts ระดับแอ็กชัน
{
"actions": {
"cmux.newTerminal": {
"type": "command",
"title": "Codex",
"subtitle": "Open Codex in a new terminal tab",
"command": "codex --yolo",
"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 แมป stable IDs เข้ากับ behavior ที่รันได้ ใช้ built-in IDs cmux.newTerminal, cmux.newBrowser, cmux.splitRight และ cmux.splitDown เพื่อ override ค่าเริ่มต้น ใช้ IDs ของคุณเองสำหรับเครื่องมือเฉพาะโปรเจกต์
palette มีค่าเริ่มต้นเป็น true ตั้งเป็น false เพื่อซ่อนแอ็กชันจาก Command Palette แต่ยังให้เรียกจากแถบแท็บ surface หรือ shortcut ได้ shortcut ใช้ syntax เดียวกับ shortcuts ใน settings เช่น cmd+shift+c หรือ ["cmd+k", "cmd+c"]
ui.surfaceTabBar.buttons จะแทนที่รายการปุ่มเริ่มต้นเมื่อมีค่าอยู่ ไม่ใส่ built-in ID เพื่อซ่อนรายการนั้น ไอคอนใช้รูปแบบ object เสมอ: { "type": "symbol", "name": "play.circle" }, { "type": "emoji", "value": "🧪", "scale": 0.9 } หรือ { "type": "image", "path": "./icons/codex.svg" } path ของรูปภาพอ้างอิงจากไฟล์ config ค่า emoji scale เป็น optional และมีค่าเริ่มต้น 1 รองรับ SVG, PDF, PNG, JPEG, GIF, TIFF, BMP, HEIC, HEIF, WebP, AVIF, ICO และ ICNS
รายการปุ่มแต่ละรายการอาจเป็น string ของ action ID หรือ button object ใช้ button object เมื่อคุณต้องการแอ็กชันเดียวกันแต่มี surface label, icon หรือ tooltip ต่างกัน ชื่อปุ่มที่ resolve แล้วจะถูกใช้เป็นชื่อของ trust prompt ด้วย
ใส่ approval หรือ permission flags ไว้ใน command string ที่คุณต้องการรันจริงโดยตรง target เริ่มต้นของแอ็กชันคือ newTabInCurrentPane ดังนั้น pattern ทั่วไปคือเปิด terminal tab ใหม่ใน pane ปัจจุบันแล้วเริ่ม Codex, Claude Code หรือ OpenCode ที่นั่น
#Custom actions และ Command Palette
actions คือรายการที่ cmux ใช้รันซ้ำได้ ใช้ actions เมื่อ behavior เดียวกันควรเรียกได้จาก Command Palette, surface tab bar, shortcuts หรือเมนูของปุ่มบวก เก็บ commands ไว้สำหรับ shell commands และ workspace layouts ที่ใช้ซ้ำได้ ตั้ง palette เป็น false เมื่อไม่ต้องการให้ action แสดงใน Command Palette
#ประเภท action
"builtin": สร้าง alias ให้ built-in cmux action เช่น cmux.newTerminal, cmux.newBrowser, cmux.splitRight หรือ cmux.splitDown"command": รันข้อความ shell ใน terminal ใช้ target เพื่อเลือก terminal ปัจจุบันหรือ tab ใหม่ใน pane ปัจจุบัน"agent": เริ่ม coding agent ที่รองรับ ปัจจุบันรองรับ codex และ claude พร้อม args แบบเลือกได้"workspaceCommand": รัน workspace definition ที่มีชื่อจาก commands ใช้สำหรับเลย์เอาต์หลาย pane, working directory แบบกำหนดเอง และ startup commands"workspace": Create a workspace from an inline workspace definition, with optional restart behavior. Offered in the new-workspace plus-button menu automatically.
#ฟิลด์ของ action
title: ชื่อแถวใน Command Palette, label ของปุ่ม, ชื่อ item ในเมนู และชื่อ trust prompt เว้นแต่ entry จะ override ค่าไว้subtitle/description: ข้อความรองใน Command Palette โดย description ใช้เป็น alias ของ subtitle ได้keywords: คำค้นหาเพิ่มเติมสำหรับ Command Palettepalette: ค่าเริ่มต้นคือ true สำหรับ custom actions ตั้งเป็น false เพื่อซ่อน action จาก Command Palette แต่ยังเรียกจากที่อื่นได้shortcut: shortcut ของ action แบบเลือกได้ ใช้ syntax แบบ single-stroke หรือ two-stroke chord เหมือน shortcuts ใน settingstarget: สำหรับ command และ agent actions เท่านั้น ใช้ currentTerminal หรือ newTabInCurrentPaneconfirm: ถามยืนยันก่อนรัน actionnewWorkspaceMenu: Set true to offer any action in the new-workspace plus-button menu, or false to hide a workspace action from it.
#พฤติกรรมของ Command Palette
Command Palette อ่าน action registry ที่ resolve แล้ว Custom action IDs จะถูกเพิ่มเป็นแถวเมื่อ palette ไม่ใช่ false ส่วน commands แบบเดิมจะถูกเพิ่มเป็นแถว custom โดยอัตโนมัติ เว้นแต่มี action ที่ใช้ generated ID เดียวกันอยู่แล้ว Built-in commands ยังใช้ labels ปกติ แต่การ override built-in ID เช่น cmux.newTerminal จะเปลี่ยน behavior หลัง entrypoint ร่วมนั้น
#แอ็กชันกำหนดเองของปุ่มบวก
ใช้ ui.newWorkspace.action เพื่อ override สิ่งที่ปุ่มบวกทำ ใช้ ui.newWorkspace.contextMenu (หรือ alias rightClick) เพื่อกำหนดเมนูคลิกขวาที่เรียงลำดับแล้ว รายการเมนูอาจเป็น action IDs, action objects หรือ { "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 --yolo"
}
]
}
},
{
"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"
}
]
}
}
]
}
]
}
}
}
]
}ตัวอย่างนี้ทำให้การคลิกปุ่มบวกตามปกติรัน action worktree-agents คำสั่ง workspace จาก commands ใช้ terminal setup ที่มองเห็นได้เพื่อสร้าง Git worktree ก่อน Codex และ Claude เริ่มพร้อมกัน รอไฟล์ state เฉพาะ workspace แล้ว cd เข้า directory ที่สร้างขึ้นก่อน exec
#Workspace layouts
A workspace layout is stored as a workspace action, embedding a full workspace definition directly in the action so it needs no separate commands entry. It supports the same workspace fields plus setup, a bootstrap command sent to the first terminal before that terminal's own command:
{
"actions": {
"review-setup": {
"type": "workspace",
"title": "Review Setup",
"icon": { "type": "symbol", "name": "rectangle.stack.badge.plus" },
"restart": "confirm",
"workspace": {
"name": "Review",
"cwd": "~/code/app",
"setup": "git fetch --all --prune",
"layout": {
"direction": "horizontal",
"split": 0.5,
"children": [
{
"pane": {
"surfaces": [
{ "type": "terminal", "name": "Claude", "command": "claude", "focus": true }
]
}
},
{
"pane": {
"surfaces": [
{ "type": "terminal", "name": "OpenCode", "command": "opencode" }
]
}
}
]
}
}
}
}
}Workspace layouts appear in the plus-button right-click menu automatically. Set newWorkspaceMenu to false to hide one, or to true on any other action to add it to the menu.
You can also create these without writing JSON: right-click the plus button and choose Save Workspace as Layout to capture the current workspace's splits, directories, running agents, and browser tabs into ~/.config/cmux/cmux.json. They are stored as entries in the actions block. Customize Workspace Layouts opens that file in your editor.
#Default for new workspaces
Use the Default for New Workspace submenu to pick which saved workspace layout plain New Workspace should run, or choose None to return to a blank terminal. The save dialog also has a Use as default for new workspaces checkbox. The setting is ui.newWorkspace.action; a project-local .cmux/cmux.json value wins over ~/.config/cmux/cmux.json.
#คำสั่งแบบง่าย
คำสั่งแบบง่ายรันคำสั่ง 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)" && เพื่อรันจากรูทของ repo หรือ cd /your/path && สำหรับไดเรกทอรีที่ต้องการ
#คำสั่ง workspace
คำสั่ง workspace สร้าง workspace ใหม่ที่มีเลย์เอาต์กำหนดเองของการแบ่ง เทอร์มินัล และแผงเบราว์เซอร์:
{
"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" }
}
]
}
}
]
}
}
}
]
}#ฟิลด์ workspace
name: ชื่อแท็บ workspace (ค่าเริ่มต้นคือชื่อคำสั่ง)cwd: ไดเรกทอรีทำงานสำหรับ workspacecolor: สีแท็บ workspaceenv: Environment variables inherited by every shell in the workspacesetup: Bootstrap command sent to the workspace's first terminal before that terminal's own commandlayout: ต้นไม้เลย์เอาต์ที่กำหนดการแบ่งและแผง
#พฤติกรรมการรีสตาร์ท
ควบคุมสิ่งที่เกิดขึ้นเมื่อ workspace ที่มีชื่อเดียวกันมีอยู่แล้ว:
"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 นี้หลังสร้าง
#การแก้ไขไดเรกทอรีทำงาน
.หรือ ละไว้: ไดเรกทอรีทำงานของ workspace./subdir: สัมพัทธ์กับไดเรกทอรีทำงานของ workspace~/path: ขยายไปยังไดเรกทอรีหลัก- พาธสัมบูรณ์: ใช้ตามที่เป็น
#ตัวอย่างเต็ม
{
"actions": {
"web-dev": { "type": "workspaceCommand", "commandName": "Web Dev" },
"cmux.newTerminal": {
"type": "command",
"title": "Codex",
"command": "codex --yolo",
"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
}
]
}