Benutzerdefinierte Befehle
Definieren Sie benutzerdefinierte Befehle und Workspace-Layouts, indem Sie eine cmux.json-Datei in Ihr Projektstammverzeichnis oder ~/.config/cmux/ hinzufügen. Befehle erscheinen in der Befehlspalette.
Dateispeicherorte
cmux sucht an zwei Stellen nach Konfiguration:
- Projektspezifisch:
./.cmux/cmux.json- liegt in Ihrem Projektverzeichnis, hat Vorrang - Lokaler Fallback:
./cmux.json- wird für bestehende Repos weiterhin unterstützt - Globale Konfiguration:
~/.config/cmux/cmux.json- gilt für alle Projekte, ergänzt lokal nicht definierte Befehle
actions, shortcut oder ui.surfaceTabBar.buttons verwendest.Bearbeite cmux.json und drücke dann Cmd+Shift+, oder führe cmux reload-config aus, um Änderungen anzuwenden.
Konfigurationsschema
commands definieren weiterhin wiederverwendbare Shell-Befehle und Workspace-Layouts. Nightly-Builds fügen ein actions-Register hinzu. Aktionen sind die öffentlichen IDs, die von Surface-Tableiste, Command Palette und aktionsbezogenen Kurzbefehlen gemeinsam genutzt werden.
{
"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-Aktionsregister
actions ordnet stabile IDs ausführbarem Verhalten zu. Verwende die eingebauten IDs cmux.newTerminal, cmux.newBrowser, cmux.splitRight und cmux.splitDown, um die Standardwerte zu überschreiben. Verwende eigene IDs für projektspezifische Tools.
palette ist standardmäßig true. Setze es auf false, um eine Aktion aus der Command Palette auszublenden, sie aber weiterhin für die Surface-Tableiste oder einen Kurzbefehl verfügbar zu halten. shortcut verwendet dieselbe Syntax wie Einstellungs-Kurzbefehle, zum Beispiel cmd+shift+c oder ["cmd+k", "cmd+c"].
ui.surfaceTabBar.buttons ersetzt die Standard-Buttonliste, wenn es vorhanden ist. Lasse eine eingebaute ID aus, um sie zu verbergen. Icons verwenden immer eine Objektform: { "type": "symbol", "name": "play.circle" }, { "type": "emoji", "value": "🧪", "scale": 0.9 } oder { "type": "image", "path": "./icons/codex.svg" }. Bildpfade sind relativ zur Konfigurationsdatei. Emoji-scale ist optional und standardmäßig 1. SVG, PDF, PNG, JPEG, GIF, TIFF, BMP, HEIC, HEIF, WebP, AVIF, ICO und ICNS werden unterstützt.
Jeder Buttoneintrag kann entweder eine Aktions-ID als String oder ein Buttonobjekt sein. Verwende ein Buttonobjekt, wenn dieselbe Aktion ein anderes Surface-Label, Icon oder Tooltip erhalten soll. Der aufgelöste Buttontitel wird auch als Titel der Vertrauensabfrage verwendet.
Setze alle Approval- oder Permission-Flags direkt in die Befehlszeichenfolge, die du tatsächlich ausführen möchtest. Das Standardziel einer Aktion ist newTabInCurrentPane, daher öffnet das übliche Muster einen neuen Terminaltab im aktuellen Pane und startet dort Codex, Claude Code oder OpenCode.
Benutzerdefinierte Aktionen und Command Palette
Ein actions-Eintrag ist die wiederverwendbare Aktion, die cmux ausführt. Verwende Aktionen, wenn dasselbe Verhalten in Command Palette, Oberflächen-Tableiste, Kurzbefehlen oder dem Plus-Menü verfügbar sein soll. Nutze commands weiter für wiederverwendbare Shell-Befehle und Workspace-Layouts. Setze palette auf false, wenn eine Aktion nicht in Command Palette erscheinen soll.
Aktionstypen
"builtin": Alias für eine eingebaute cmux-Aktion wie cmux.newTerminal, cmux.newBrowser, cmux.splitRight oder cmux.splitDown."command": Führt Shell-Text in einem Terminal aus. Verwende target, um das aktuelle Terminal oder einen neuen Tab im aktuellen Bereich auszuwählen."agent": Startet einen unterstützten Coding-Agenten. Aktuell werden codex und claude mit optionalen Argumenten unterstützt."workspaceCommand": Führt eine benannte Workspace-Definition aus commands aus. Nutze dies für Multi-Pane-Layouts, eigene Arbeitsverzeichnisse und Startbefehle.
Aktionsfelder
title: Titel der Command-Palette-Zeile, Beschriftung der Oberflächenschaltfläche, Menütitel und Titel des Trust-Dialogs, sofern kein Eintrag ihn überschreibt.subtitle/description: Sekundärtext in Command Palette. description wird als Alias für subtitle akzeptiert.keywords: Zusätzliche Suchbegriffe für Command Palette.palette: Standardmäßig true für benutzerdefinierte Aktionen. Setze false, um die Aktion aus Command Palette auszublenden, sie aber anderswo aufrufbar zu lassen.shortcut: Optionaler Aktionskurzbefehl mit derselben Einzel- oder Akkord-Syntax wie Einstellungs-Kurzbefehle.target: Nur für command- und agent-Aktionen. Verwende currentTerminal oder newTabInCurrentPane.confirm: Vor dem Ausführen der Aktion nachfragen.
Verhalten der Command Palette
Command Palette liest das aufgelöste Aktionsregister. Benutzerdefinierte Aktions-IDs werden als Zeilen hinzugefügt, wenn palette nicht false ist. Alte commands werden automatisch als benutzerdefinierte Zeilen hinzugefügt, sofern nicht bereits eine Aktion mit derselben generierten ID existiert. Eingebaute Befehle behalten ihre normalen Palettennamen, aber das Überschreiben einer eingebauten ID wie cmux.newTerminal ändert das Verhalten hinter diesem gemeinsamen Einstiegspunkt.
Benutzerdefinierte Aktionen für den Plus-Button
Verwende ui.newWorkspace.action, um zu überschreiben, was der Plus-Button ausführt. Verwende ui.newWorkspace.contextMenu (oder den Alias rightClick), um das geordnete Rechtsklickmenü zu definieren. Menüeinträge können Aktions-IDs, Aktionsobjekte oder { "type": "separator" } sein.
{
"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"
}
]
}
}
]
}
]
}
}
}
]
}Dieses Beispiel lässt den normalen Plus-Klick die Aktion worktree-agents ausführen. Der Workspace-Befehl aus commands nutzt ein sichtbares Setup-Terminal, um zuerst den Git-worktree zu erstellen. Codex und Claude starten gleichzeitig, warten auf die workspace-spezifische Statusdatei und wechseln dann vor exec in das erstellte Verzeichnis.
Einfache Befehle
Ein einfacher Befehl führt einen Shell-Befehl im aktuell fokussierten Terminal aus:
{
"commands": [
{
"name": "Run Tests",
"keywords": ["test", "check"],
"command": "npm test",
"confirm": true
}
]
}Felder
name: Wird in der Befehlspalette angezeigt (erforderlich)description: Optionale Beschreibungkeywords: Zusätzliche Suchbegriffe für die Befehlspalettecommand: Shell-Befehl, der im fokussierten Terminal ausgeführt wirdconfirm: Bestätigungsdialog vor der Ausführung anzeigen
Einfache Befehle werden im aktuellen Arbeitsverzeichnis des fokussierten Terminals ausgeführt. Wenn Ihr Befehl projektrelative Pfade benötigt, stellen Sie cd "$(git rev-parse --show-toplevel)" && voran, um vom Repository-Stammverzeichnis auszuführen, oder cd /your/path && für ein beliebiges Verzeichnis.
Workspace-Befehle
Ein Workspace-Befehl erstellt einen neuen Workspace mit einem benutzerdefinierten Layout aus Aufteilungen, Terminals und Browser-Fenstern:
{
"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-Felder
name: Name des Workspace-Tabs (Standard ist Befehlsname)cwd: Arbeitsverzeichnis für den Workspacecolor: Farbe des Workspace-Tabslayout: Layout-Baum, der Aufteilungen und Fenster definiert
Neustart-Verhalten
Steuert, was passiert, wenn bereits ein Workspace mit demselben Namen existiert:
"new": Neuen Workspace erstellen (Standard)"ignore": Zum vorhandenen Workspace wechseln"recreate": Schließen und ohne Rückfrage neu erstellen"confirm": Benutzer vor der Neuerstellung fragen
Layout-Baum
Der Layout-Baum definiert, wie Fenster mithilfe rekursiver Aufteilungsknoten angeordnet werden:
Aufteilungsknoten
Teilt den Platz in zwei Kindelemente auf:
direction:"horizontal"oder"vertical"split: Teilerposition von 0.1 bis 0.9 (Standard 0.5)children: Genau zwei Kindknoten (Aufteilung oder Fenster)
Fensterknoten
Ein Blattknoten, der eine oder mehrere Oberflächen enthält (Tabs innerhalb des Fensters).
Oberflächendefinition
Jede Oberfläche in einem Fenster kann ein Terminal oder ein Browser sein:
type:"terminal"oder"browser"name: Benutzerdefinierter Tab-Titelcommand: Shell-Befehl, der bei der Erstellung automatisch ausgeführt wird (nur Terminal)cwd: Arbeitsverzeichnis für diese Oberflächeenv: Umgebungsvariablen als Schlüssel-Wert-Paareurl: URL zum Öffnen (nur Browser)focus: Diese Oberfläche nach der Erstellung fokussieren
Arbeitsverzeichnis-Auflösung
.oder weggelassen: Workspace-Arbeitsverzeichnis./subdir: relativ zum Workspace-Arbeitsverzeichnis~/path: auf Home-Verzeichnis erweitert- Absoluter Pfad: wird unverändert verwendet
Vollständiges Beispiel
{
"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
}
]
}