Niestandardowe polecenia
Definiuj niestandardowe polecenia i układy workspace, dodając plik cmux.json do katalogu głównego projektu lub ~/.config/cmux/. Polecenia pojawiają się w palecie poleceń.
Lokalizacje plików
cmux szuka konfiguracji w dwóch miejscach:
- Per projekt:
./.cmux/cmux.json- znajduje się w katalogu projektu, ma pierwszeństwo - Lokalna konfiguracja awaryjna:
./cmux.json- nadal obsługiwana dla istniejących repozytoriów - Globalna:
~/.config/cmux/cmux.json- stosuje się do wszystkich projektów, uzupełnia polecenia niezdefiniowane lokalnie
actions, shortcut lub ui.surfaceTabBar.buttons.Edytuj cmux.json, a następnie naciśnij Cmd+Shift+, albo uruchom cmux reload-config, aby zastosować zmiany.
Schemat
commands nadal definiuje wielokrotnego użytku polecenia shell i układy workspace. Buildy nightly dodają rejestr actions. Akcje to publiczne ID współdzielone przez pasek kart powierzchni, Command Palette i skróty na poziomie akcji.
{
"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": { ... }
}
]
}Rejestr akcji nightly
actions mapuje stabilne ID na uruchamialne zachowanie. Użyj wbudowanych ID cmux.newTerminal, cmux.newBrowser, cmux.splitRight i cmux.splitDown, aby nadpisać wartości domyślne. Użyj własnych ID dla narzędzi specyficznych dla projektu.
palette domyślnie ma wartość true. Ustaw false, aby ukryć akcję w Command Palette, ale pozostawić ją dostępną z paska kart powierzchni lub skrótu. shortcut używa tej samej składni co skróty ustawień, na przykład cmd+shift+c albo ["cmd+k", "cmd+c"].
ui.surfaceTabBar.buttons zastępuje domyślną listę przycisków, gdy jest obecne. Pomiń wbudowane ID, aby je ukryć. Ikony zawsze używają kształtu obiektu: { "type": "symbol", "name": "play.circle" }, { "type": "emoji", "value": "🧪", "scale": 0.9 } albo { "type": "image", "path": "./icons/codex.svg" }. Ścieżki obrazów są względne wobec pliku konfiguracji. Emoji scale jest opcjonalne i domyślnie wynosi 1. Obsługiwane są SVG, PDF, PNG, JPEG, GIF, TIFF, BMP, HEIC, HEIF, WebP, AVIF, ICO i ICNS.
Każdy wpis przycisku może być ciągiem ID akcji albo obiektem przycisku. Użyj obiektu przycisku, gdy chcesz tę samą akcję z inną etykietą powierzchni, ikoną lub tooltipem. Rozwiązany tytuł przycisku jest też używany jako tytuł prośby o zaufanie.
Umieść wszystkie flagi approval lub permission bezpośrednio w ciągu polecenia, które faktycznie chcesz uruchomić. Domyślnym celem akcji jest newTabInCurrentPane, więc typowy wzorzec to otwarcie nowej karty terminala w bieżącym panelu i uruchomienie tam Codex, Claude Code lub OpenCode.
Akcje niestandardowe i Command Palette
Wpis actions to wielokrotnego użytku działanie uruchamiane przez cmux. Używaj akcji, gdy to samo zachowanie ma być dostępne z Command Palette, paska kart powierzchni, skrótów lub menu przycisku plus. Zachowaj commands dla wielokrotnego użytku poleceń shell i układów obszarów roboczych. Ustaw palette na false, gdy akcja nie powinna pojawiać się w Command Palette.
Typy akcji
"builtin": Alias wbudowanej akcji cmux, takiej jak cmux.newTerminal, cmux.newBrowser, cmux.splitRight lub cmux.splitDown."command": Uruchamia tekst shell w terminalu. Użyj target, aby wybrać bieżący terminal albo nową kartę w bieżącym panelu."agent": Uruchamia obsługiwanego agenta programistycznego. Obecnie obsługuje codex i claude, z opcjonalnymi argumentami."workspaceCommand": Uruchamia nazwaną definicję obszaru roboczego z commands. Używaj do układów wielopanelowych, własnych katalogów roboczych i poleceń startowych.
Pola akcji
title: Tytuł wiersza Command Palette, etykieta przycisku, tytuł elementu menu i tytuł prośby o zaufanie, chyba że wpis go zastępuje.subtitle/description: Tekst pomocniczy w Command Palette. description jest akceptowane jako alias dla subtitle.keywords: Dodatkowe hasła wyszukiwania dla Command Palette.palette: Domyślnie true dla akcji niestandardowych. Ustaw false, aby ukryć akcję w Command Palette, pozostawiając ją dostępną gdzie indziej.shortcut: Opcjonalny skrót akcji, używający tej samej składni pojedynczego skrótu lub dwustopniowego chordu co skróty ustawień.target: Tylko dla akcji command i agent. Użyj currentTerminal albo newTabInCurrentPane.confirm: Pytaj przed uruchomieniem akcji.
Zachowanie Command Palette
Command Palette czyta rozstrzygnięty rejestr akcji. ID akcji niestandardowych są dodawane jako wiersze, gdy palette nie jest false. Starsze commands są automatycznie dodawane jako wiersze niestandardowe, chyba że istnieje już akcja z tym samym wygenerowanym ID. Wbudowane polecenia zachowują zwykłe etykiety, ale zastąpienie wbudowanego ID, takiego jak cmux.newTerminal, zmienia zachowanie wspólnego punktu wejścia.
Niestandardowe akcje przycisku plus
Użyj ui.newWorkspace.action, aby nadpisać działanie przycisku plus. Użyj ui.newWorkspace.contextMenu (lub aliasu rightClick), aby zdefiniować uporządkowane menu prawego kliknięcia. Wpisami menu mogą być ID akcji, obiekty akcji albo { "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"
}
]
}
}
]
}
]
}
}
}
]
}Ten przykład sprawia, że zwykłe kliknięcie plus uruchamia akcję worktree-agents. Polecenie obszaru roboczego z commands używa widocznego terminala przygotowującego, aby najpierw utworzyć Git worktree. Codex i Claude startują jednocześnie, czekają na plik stanu dla obszaru roboczego, a następnie przechodzą do utworzonego katalogu przed exec.
Proste polecenia
Proste polecenie uruchamia polecenie shell w aktualnie sfokusowanym terminalu:
{
"commands": [
{
"name": "Run Tests",
"keywords": ["test", "check"],
"command": "npm test",
"confirm": true
}
]
}Pola
name: Wyświetlane w palecie poleceń (wymagane)description: Opcjonalny opiskeywords: Dodatkowe terminy wyszukiwania dla palety poleceńcommand: Polecenie shell do uruchomienia w sfokusowanym terminaluconfirm: Pokaż okno dialogowe potwierdzenia przed uruchomieniem
Proste polecenia są uruchamiane w bieżącym katalogu roboczym aktywnego terminala. Jeśli polecenie wymaga ścieżek względnych do projektu, dodaj prefiks cd "$(git rev-parse --show-toplevel)" && aby uruchomić z katalogu głównego repozytorium, lub cd /your/path && dla dowolnego konkretnego katalogu.
Polecenia workspace
Polecenie workspace tworzy nowy workspace z niestandardowym układem podziałów, terminali i paneli przeglądarki:
{
"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" }
}
]
}
}
]
}
}
}
]
}Pola workspace
name: Nazwa zakładki workspace (domyślnie nazwa polecenia)cwd: Katalog roboczy workspacecolor: Kolor zakładki workspacelayout: Drzewo układu definiujące podziały i panele
Zachowanie przy restarcie
Kontroluje co się dzieje, gdy workspace o tej samej nazwie już istnieje:
"new": Utwórz nowy workspace (domyślnie)"ignore": Przełącz do istniejącego workspace"recreate": Zamknij i odtwórz bez pytania"confirm": Zapytaj użytkownika przed odtworzeniem
Drzewo układu
Drzewo układu definiuje jak panele są rozmieszczone za pomocą rekurencyjnych węzłów podziału:
Węzeł podziału
Dzieli przestrzeń na dwoje dzieci:
direction:"horizontal"lub"vertical"split: Pozycja dzielnika od 0.1 do 0.9 (domyślnie 0.5)children: Dokładnie dwa węzły podrzędne (podział lub panel)
Węzeł panelu
Węzeł liścia zawierający jedną lub więcej powierzchni (zakładki wewnątrz panelu).
Definicja powierzchni
Każda powierzchnia w panelu może być terminalem lub przeglądarką:
type:"terminal"lub"browser"name: Niestandardowy tytuł zakładkicommand: Polecenie shell do automatycznego uruchomienia przy tworzeniu (tylko terminal)cwd: Katalog roboczy dla tej powierzchnienv: Zmienne środowiskowe jako pary klucz-wartośćurl: URL do otwarcia (tylko przeglądarka)focus: Sfokusuj tę powierzchnię po utworzeniu
Rozwiązanie katalogu roboczego
.lub pominięty: katalog roboczy workspace./subdir: względem katalogu roboczego workspace~/path: rozwinięty do katalogu domowego- Ścieżka bezwzględna: używana bez zmian
Pełny przykład
{
"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
}
]
}