Власні команди та дії
cmux.json — це місце, де ви навчаєте cmux своїх власних звичок: команд оболонки, які часто запускаєте, робочих просторів, що відкриваються із заздалегідь розташованими терміналами й браузерами, і дій, які можна прив’язати до скорочень, кнопок панелі вкладок і Command Palette. Тримайте його в .cmux/cmux.json усередині проєкту, у ~/.config/cmux/cmux.json для всіх проєктів або в обох місцях.
Звідки cmux читає cmux.json
Записи можуть надходити з файлу проєкту, з файлу для всього користувача або з обох. Для файлів проєкту cmux починає з поточного каталогу й також перевіряє кожен батьківський каталог вище.
- Проєкт:
./.cmux/cmux.json(знаходиться пошуком угору від робочого каталогу; має перевагу над файлом для всього користувача) - Локальний fallback:
./cmux.json(і далі підтримується для наявних репозиторіїв) - Для всього користувача:
~/.config/cmux/cmux.json(спільний для всіх проєктів; доповнює все, що не визначено у файлі проєкту)
Відредагуйте cmux.json, потім натисніть Cmd+Shift+, або виконайте cmux reload-config, щоб застосувати зміни.
Команди оболонки
Найпростіший запис — це назва й рядок команди. Якщо вибрати його в Command Palette, цей рядок буде введено в термінал, що має фокус, і виконано.
{
"commands": [
{
"name": "Format Changed Files",
"description": "Run the formatter on files that differ from main",
"keywords": [
"fmt",
"prettier",
"style"
],
"command": "git diff --name-only main -- '*.ts' '*.tsx' | xargs npx prettier --write"
},
{
"name": "Reset Local Database",
"keywords": [
"db",
"wipe"
],
"command": "cd \"$(git rev-parse --show-toplevel)\" && ./scripts/db-reset.sh",
"confirm": true
}
]
}Поля команди оболонки
name: Обов’язкова непорожня мітка, яку ви вибираєте в Command Palettecommand: Текст оболонки, який cmux вводить у термінал у фокусі та виконуєdescription: Необов’язковий додатковий текст, що показується поруч із записомkeywords: Додаткові слова, за якими цей запис має знаходитися під час пошуку в Command Paletteconfirm: Установіть true, щоб щоразу перед запуском отримувати запит на підтвердження
Команда оболонки виконується там, де саме перебуває термінал у фокусі. Якщо команді потрібна передбачувана початкова точка, почніть її з cd "$(git rev-parse --show-toplevel)" && щоб перейти до кореня Git-репозиторію, або з cd /some/folder && щоб закріпити її за певною папкою.
Команди, що відкривають робочий простір
Якщо замість рядка команди передати команді об’єкт workspace, вона натомість відкриє новий робочий простір, упорядкований як дерево розділених панелей із терміналами й браузерами. Запис має містити рівно одне з двох.
{
"commands": [
{
"name": "API Stack",
"keywords": [
"api",
"server",
"logs"
],
"restart": "confirm",
"workspace": {
"name": "API",
"cwd": "./services/api",
"color": "#10b981",
"env": {
"PORT": "8080"
},
"layout": {
"direction": "vertical",
"split": 0.65,
"children": [
{
"direction": "horizontal",
"children": [
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Server",
"command": "go run ./cmd/api",
"focus": true
}
]
}
},
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Worker",
"command": "go run ./cmd/worker",
"env": {
"QUEUE": "default"
}
}
]
}
}
]
},
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Logs",
"cwd": "/var/log",
"command": "tail -F system.log"
},
{
"type": "browser",
"name": "Health",
"url": "http://localhost:8080/healthz"
}
]
}
}
]
}
}
}
]
}Поля об’єкта workspace
name: Заголовок робочого простору; якщо його не задано, використовується назва командиcwd: Базовий каталог робочого простору; cwd кожної вкладки розв’язується відносно ньогоlayout: Кореневий вузол дерева розкладки, описаного нижчеcolor: Колір у бічній панелі: шістнадцяткове значення #RRGGBB або назва кольору робочого просторуenv: Environment variables inherited by every shell in the workspacesetup: Bootstrap command sent to the workspace's first terminal before that terminal's own command
Коли робочий простір уже відкрито
Задайте restart у команді, щоб визначити, що станеться, якщо робочий простір із такою самою назвою вже існує:
"new": Створити новий workspace (за замовчуванням)"confirm": Спершу запитати, а потім замінити, якщо ви погодитеся"recreate": Одразу замінити без запиту"ignore": Перемкнутися на наявний workspace
Опис розкладки
Розкладка — це дерево. Кожен внутрішній вузол ділить свою область на дві, а кожен лист є панеллю з вкладками.
Вузли розділення
Розділення ділить свою область на дві частини:
direction:"horizontal"або"vertical"children: Масив рівно з двох вузлів, кожен з яких є іншим розділенням або панеллюsplit: Положення розділювача як частка області. Типово 0.5; значення поза межами від 0.1 до 0.9 обмежуються цим діапазоном
Вузли панелей
Панель — це лист дерева. Її масив surfaces перелічує вкладки, з якими вона відкривається, і має містити принаймні один запис.
Поверхні
Кожен запис у масиві surfaces панелі відкриває одну вкладку — термінал або браузер:
type:"terminal"або"browser"name: Заголовок вкладки, що показується замість типовогоfocus: Установіть true, щоб після побудови розкладки клавіатурний фокус опинився на цій вкладціcommand: Лише для терміналів: текст оболонки, який треба виконати одразу після відкриття терміналаurl: Лише для браузерів: сторінка, яку треба завантажитиcwd: Початковий каталог для цієї вкладки, розв’язується за правилами нижчеenv: Об’єкт із назвами й значеннями додаткових змінних середовища
Як розв’язуються значення cwd
~/path: розв’язується всередині вашої домашньої папки- Шлях, що починається з /: використовується як є
./subdir: додається до каталогу робочого простору.або не задано: успадковує каталог робочого простору
Структура файлу
actions, shortcut або ui.surfaceTabBar.buttons.commands і далі визначає повторно використовувані shell-команди та розкладки workspace. Nightly-збірки додають реєстр actions. Дії — це публічні ID, спільні для surface tab bar, Command Palette та скорочень рівня дії.
{
"actions": {
"cmux.newTerminal": {
"type": "agent",
"agent": "claude",
"title": "Claude Code",
"subtitle": "Start Claude Code in a new tab"
},
"lint": {
"type": "command",
"title": "Lint",
"subtitle": "Run the linter in a fresh tab",
"keywords": [
"eslint",
"check"
],
"command": "npm run lint",
"shortcut": [
"cmd+k",
"cmd+l"
],
"icon": {
"type": "symbol",
"name": "checkmark.seal"
}
},
"scratch-dir": {
"type": "command",
"title": "Scratch Directory",
"command": "cd \"$(mktemp -d)\"",
"target": "currentTerminal",
"palette": false,
"icon": {
"type": "emoji",
"value": "📝",
"scale": 0.85
}
},
"api-stack": {
"type": "workspaceCommand",
"title": "API Stack",
"commandName": "API Stack"
}
},
"ui": {
"surfaceTabBar": {
"buttons": [
"cmux.newTerminal",
"cmux.splitRight",
"lint",
{
"action": "scratch-dir",
"tooltip": "cd into a new temp folder"
}
]
}
},
"commands": [
{
"name": "API Stack",
"keywords": [
"api"
],
"workspace": {
"cwd": "./services/api",
"layout": {
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Server",
"command": "go run ./cmd/api"
}
]
}
}
}
}
]
}Nightly-реєстр дій
actions зіставляє стабільні ID із поведінкою, яку можна запустити. Використовуйте вбудовані ID cmux.newTerminal, cmux.newBrowser, cmux.splitRight і cmux.splitDown, щоб перевизначити стандартні дії. Для інструментів проєкту використовуйте власні ID.
palette за замовчуванням має значення true. Установіть false, щоб приховати дію з Command Palette, але залишити її доступною на surface tab bar або через скорочення. 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, тому звичний шаблон відкриває нову вкладку термінала в поточній панелі й запускає там Codex, Claude Code або OpenCode.
Користувацькі дії та Command Palette
Запис actions описує повторно використовувану дію, яку запускає cmux. Використовуйте дії, коли та сама поведінка має бути доступна з Command Palette, панелі вкладок поверхні, скорочень або меню кнопки плюс. Залишайте commands для повторно використовуваних shell-команд і розкладок робочих просторів. Установіть palette у false, якщо дія не має з’являтися в Command Palette.
Типи дій
"command": Запускає shell-текст у терміналі. Використовуйте target, щоб вибрати поточний термінал або нову вкладку в поточній панелі."agent": Запускає підтримуваного кодового агента. Наразі підтримуються codex і claude з необов’язковими аргументами."builtin": Псевдонім для вбудованої дії cmux, наприклад cmux.newTerminal, cmux.newBrowser, cmux.splitRight або cmux.splitDown. Вбудовані дії копіювання: cmux.copyWorkingDirectory копіює робочий каталог термінала, cmux.copyProjectRoot — корінь його git-репозиторію (або робочий каталог поза репозиторієм), а cmux.copyScreen — видимий екран. У робочому просторі SSH, хмари або віддаленого tmux cmux.copyProjectRoot копіює віддалений робочий каталог, бо cmux не може знайти git-репозиторій на іншому хості."workspaceCommand": Запускає іменоване визначення робочого простору з commands. Використовуйте для багатопанельних розкладок, власних робочих каталогів і стартових команд."workspace": Create a workspace from an inline workspace definition, with optional restart behavior. Offered in the new-workspace plus-button menu automatically."setting": Змінює один параметр у вашому глобальному cmux.json, наприклад перемикає параметр true/false або перебирає список значень. Див. розділ «Дії з параметрами» нижче."settingPreset": Застосовує іменовану групу параметрів із settingPresets за один крок.
Поля дії
title: Заголовок рядка Command Palette, підпис кнопки, заголовок пункту меню та заголовок запиту довіри, якщо запис не перевизначає його.subtitle/description: Вторинний текст у Command Palette. description приймається як псевдонім subtitle.keywords: Додаткові пошукові слова для Command Palette.palette: Типово true для користувацьких дій. Установіть false, щоб приховати дію з Command Palette, але залишити її доступною в інших місцях.shortcut: Необов’язкове скорочення дії з тією самою одноразовою або двоетапною chord-синтаксою, що й скорочення налаштувань.target: Лише для дій command і agent. Використовуйте currentTerminal або newTabInCurrentPane.confirm: Запитувати підтвердження перед запуском дії.newWorkspaceMenu: 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 читає розв’язаний реєстр дій. ID користувацьких дій додаються як рядки, коли palette не дорівнює false. Старі commands автоматично додаються як користувацькі рядки, якщо дія з тим самим згенерованим ID ще не існує. Вбудовані команди зберігають звичні назви в палітрі, але перевизначення вбудованого ID, як-от cmux.newTerminal, змінює поведінку за цією спільною точкою входу.
Дії з параметрами
Дія з параметром вказує path параметра й рівно одне з полів: set (записати значення), toggle: true (перемкнути параметр true/false), cycle (перейти до наступного значення зі списку, а після останнього повернутися до першого) або unset: true (видалити ключ із cmux.json, щоб діяло значення з вікна «Параметри» або типове значення). toggle і cycle починають зі значення, яке cmux використовує зараз, зокрема заданого у вікні «Параметри». Дія settingPreset застосовує запис із settingPresets — частковий cmux.json, вкладені об’єкти якого об’єднуються за ключами. Перед збереженням cmux перевіряє кожну зміну за схемою, зберігає ваші коментарі та інші ключі й одразу застосовує зміну. Дії з параметрами та пресети працюють лише з вашого глобального cmux.json і пакетів, на які він посилається; конфігурації проєктів не можуть їх оголошувати.
{
"actions": {
"scroll.cycle": {
"type": "setting",
"title": "Cycle Scroll Speed",
"path": "terminal.scrollSpeed",
"cycle": [1.0, 1.4, 1.8]
},
"editor.wrap": {
"type": "setting",
"title": "Toggle Editor Word Wrap",
"path": "fileEditor.wordWrap",
"toggle": true
},
"sidebar.quiet": {
"type": "settingPreset",
"title": "Quiet Sidebar",
"preset": "sidebar.quiet"
}
},
"settingPresets": {
"sidebar.quiet": {
"sidebar": { "showPorts": false, "showPullRequests": false, "showLog": false }
}
}
}Ті самі зміни можна зробити з термінала: cmux config set terminal.scrollSpeed 1.4, cmux config toggle fileEditor.wordWrap і cmux config preset sidebar.quiet.
З confirm: true cmux запитує підтвердження перед збереженням і показує відповідну команду cmux config. Шляхи розбиваються за кожним символом ".", тому ключ, який сам містить "." (наприклад, запис workspaceGroups.byCwd для ~/src/app.web), так змінити не можна. Відредагуйте його безпосередньо в cmux.json.
Користувацькі дії кнопки плюс
Використовуйте ui.newWorkspace.action, щоб перевизначити дію кнопки плюс. Використовуйте ui.newWorkspace.contextMenu (або alias rightClick), щоб визначити впорядковане меню правого кліку. Пункти меню можуть бути ID дій, об’єктами дій або { "type": "separator" }. Якщо не задано, меню містить cmux.newWorkspace (⌘N), cmux.newCloudWorkspace (⌘Y), cmux.newCloudMachine (⇧⌘Y), cmux.newTerminal (⌘T), cmux.newBrowser (⇧⌘L) з поточними комбінаціями клавіш. Хмарні пункти відображаються лише коли ввімкнено Cloud Machines. New Cloud Workspace використовує машину останнього вибраного робочого простору Cloud, потім першу машину на правій бічній панелі; якщо немає доступної машини, відкриває New Cloud Machine.
{
"actions": {
"worktree-agents": {
"type": "workspaceCommand",
"title": "Agents in New Worktree",
"commandName": "Agents in New Worktree",
"icon": {
"type": "symbol",
"name": "arrow.triangle.branch"
}
}
},
"ui": {
"newWorkspace": {
"action": "worktree-agents",
"contextMenu": [
"worktree-agents",
{
"type": "separator"
},
{
"action": "cmux.newWorkspace",
"title": "Blank Workspace"
},
{
"action": "cmux.newBrowser",
"title": "Browser"
}
]
}
},
"commands": [
{
"name": "Agents in New Worktree",
"description": "Branch off a new Git worktree, then run Codex and Claude Code in it side by side",
"workspace": {
"name": "Worktree",
"layout": {
"direction": "vertical",
"split": 0.7,
"children": [
{
"direction": "horizontal",
"children": [
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Codex",
"command": "marker=\"${TMPDIR:-/tmp}/cmux-wt-${CMUX_WORKSPACE_ID:-local}\"; echo \"Waiting for the worktree...\"; until [ -s \"$marker\" ]; do sleep 0.25; done; cd \"$(cat \"$marker\")\" && exec codex --yolo"
}
]
}
},
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Claude",
"command": "marker=\"${TMPDIR:-/tmp}/cmux-wt-${CMUX_WORKSPACE_ID:-local}\"; echo \"Waiting for the worktree...\"; until [ -s \"$marker\" ]; do sleep 0.25; done; cd \"$(cat \"$marker\")\" && exec claude --dangerously-skip-permissions"
}
]
}
}
]
},
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Setup",
"command": "marker=\"${TMPDIR:-/tmp}/cmux-wt-${CMUX_WORKSPACE_ID:-local}\"; rm -f \"$marker\"; root=$(git rev-parse --show-toplevel) || exit 1; branch=\"wt-$(date +%m%d-%H%M%S)\"; wt=\"$root/../$(basename \"$root\")-$branch\"; git -C \"$root\" worktree add -b \"$branch\" \"$wt\" && printf \"%s\\n\" \"$wt\" > \"$marker\" && cd \"$wt\" && exec \"${SHELL:-/bin/zsh}\" -l",
"focus": true
}
]
}
}
]
}
}
}
]
}У цьому прикладі звичайний клік по плюсу запускає дію worktree-agents. Команда робочого простору з commands використовує видимий термінал налаштування, щоб спочатку створити Git worktree. Codex і Claude запускаються одночасно, чекають файл стану для цього робочого простору, а потім переходять у створений каталог перед 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": {
"pair-review": {
"type": "workspace",
"title": "Pair Review",
"icon": {
"type": "symbol",
"name": "person.2.wave.2"
},
"restart": "ignore",
"newWorkspaceMenu": true,
"workspace": {
"name": "Review",
"cwd": "~/src/app",
"setup": "git pull --ff-only",
"layout": {
"direction": "horizontal",
"split": 0.55,
"children": [
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Diff",
"command": "git log -p -n 5",
"focus": true
}
]
}
},
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Codex",
"command": "codex"
},
{
"type": "terminal",
"name": "Shell"
}
]
}
}
]
}
}
}
}
}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.
Повний приклад
{
"actions": {
"cmux.newTerminal": {
"type": "command",
"title": "Codex",
"command": "codex --yolo",
"shortcut": "cmd+t",
"icon": {
"type": "image",
"path": "./icons/codex.svg"
}
},
"review": {
"type": "agent",
"agent": "claude",
"args": "--permission-mode plan",
"title": "Plan with Claude",
"shortcut": "cmd+shift+p",
"icon": {
"type": "symbol",
"name": "list.bullet.clipboard"
}
},
"storybook": {
"type": "workspaceCommand",
"commandName": "Storybook",
"newWorkspaceMenu": true
},
"typecheck": {
"type": "command",
"title": "Typecheck",
"command": "npx tsc --noEmit",
"target": "newTabInCurrentPane",
"confirm": false,
"icon": {
"type": "emoji",
"value": "🔎"
}
}
},
"ui": {
"surfaceTabBar": {
"buttons": [
"cmux.newTerminal",
"review",
{
"action": "typecheck",
"title": "tsc"
},
"cmux.newBrowser",
"cmux.splitDown"
]
},
"newWorkspace": {
"contextMenu": [
"storybook",
{
"type": "separator"
},
"cmux.newTerminal",
"cmux.newBrowser"
]
}
},
"commands": [
{
"name": "Storybook",
"description": "Component explorer with a live preview beside it",
"keywords": [
"ui",
"components",
"stories"
],
"workspace": {
"name": "Storybook",
"cwd": "./packages/ui",
"color": "#a855f7",
"layout": {
"direction": "horizontal",
"split": 0.4,
"children": [
{
"direction": "vertical",
"split": 0.5,
"children": [
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Storybook",
"command": "npx storybook dev -p 6006 --no-open",
"focus": true
}
]
}
},
{
"pane": {
"surfaces": [
{
"type": "terminal",
"name": "Tests",
"command": "npx vitest --watch",
"env": {
"CI": "false"
}
}
]
}
}
]
},
{
"pane": {
"surfaces": [
{
"type": "browser",
"name": "Preview",
"url": "http://localhost:6006"
}
]
}
}
]
}
}
},
{
"name": "Install Dependencies",
"keywords": [
"install",
"deps"
],
"command": "npm ci",
"confirm": true
},
{
"name": "Open Changelog",
"keywords": [
"changes",
"release"
],
"command": "${EDITOR:-vi} CHANGELOG.md"
}
]
}