Commandes personnalisées
Définissez des commandes personnalisées et des mises en page d'espace de travail en ajoutant un fichier cmux.json à la racine de votre projet ou ~/.config/cmux/. Les commandes apparaissent dans la palette de commandes.
Emplacements des fichiers
cmux recherche la configuration à deux endroits :
- Par projet :
./.cmux/cmux.json- se trouve dans votre répertoire de projet, a la priorité - Repli local :
./cmux.json- toujours pris en charge pour les dépôts existants - Global :
~/.config/cmux/cmux.json- s'applique à tous les projets, complète les commandes non définies localement
actions, shortcut ou ui.surfaceTabBar.buttons.Modifiez cmux.json, puis appuyez sur Cmd+Shift+, ou exécutez cmux reload-config pour appliquer les changements.
Schéma
commands définit toujours les commandes shell réutilisables et les dispositions de workspace. Les builds nightly ajoutent un registre actions. Les actions sont les ID publics partagés par la barre d’onglets de surface, Command Palette et les raccourcis d’action.
{
"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": { ... }
}
]
}Registre d’actions nightly
actions associe des ID stables à des comportements exécutables. Utilise les ID intégrés cmux.newTerminal, cmux.newBrowser, cmux.splitRight et cmux.splitDown pour remplacer les valeurs par défaut. Utilise tes propres ID pour les outils propres au projet.
palette vaut true par défaut. Mets-le à false pour masquer une action dans Command Palette tout en la gardant disponible dans la barre d’onglets de surface ou via un raccourci. shortcut utilise la même syntaxe que les raccourcis des paramètres, par exemple cmd+shift+c ou ["cmd+k", "cmd+c"].
ui.surfaceTabBar.buttons remplace la liste de boutons par défaut lorsqu’il est présent. Omettre un ID intégré permet de le masquer. Les icônes utilisent toujours une forme objet : { "type": "symbol", "name": "play.circle" }, { "type": "emoji", "value": "🧪", "scale": 0.9 } ou { "type": "image", "path": "./icons/codex.svg" }. Les chemins d’image sont relatifs au fichier de configuration. Le scale d’un emoji est facultatif et vaut 1 par défaut. SVG, PDF, PNG, JPEG, GIF, TIFF, BMP, HEIC, HEIF, WebP, AVIF, ICO et ICNS sont pris en charge.
Chaque entrée de bouton peut être une chaîne d’ID d’action ou un objet bouton. Utilise un objet bouton lorsque tu veux la même action avec un autre libellé de surface, une autre icône ou une autre infobulle. Le titre résolu du bouton sert aussi de titre à la demande d’approbation.
Place les flags d’approbation ou de permission directement dans la chaîne de commande que tu veux réellement exécuter. La cible d’action par défaut est newTabInCurrentPane, donc le schéma courant consiste à ouvrir un nouvel onglet de terminal dans le panneau actuel et à y démarrer Codex, Claude Code ou OpenCode.
Actions personnalisées et Command Palette
Une entrée actions est l’élément réutilisable exécuté par cmux. Utilisez les actions quand le même comportement doit être disponible depuis Command Palette, la barre d’onglets de surface, les raccourcis ou le menu du bouton plus. Gardez commands pour les commandes shell réutilisables et les dispositions d’espace de travail. Définissez palette sur false quand une action ne doit pas apparaître dans Command Palette.
Types d’action
"builtin": Crée un alias vers une action cmux intégrée comme cmux.newTerminal, cmux.newBrowser, cmux.splitRight ou cmux.splitDown."command": Exécute du texte shell dans un terminal. Utilisez target pour choisir le terminal courant ou un nouvel onglet dans le panneau courant."agent": Lance un agent de codage pris en charge. Aujourd’hui, codex et claude sont pris en charge, avec des arguments optionnels."workspaceCommand": Exécute une définition d’espace de travail nommée depuis commands. Utilisez-le pour les dispositions multi-panneaux, les dossiers de travail personnalisés et les commandes de démarrage.
Champs d’action
title: Titre de ligne dans Command Palette, libellé du bouton, titre de l’élément de menu et titre de l’invite de confiance, sauf si une entrée le remplace.subtitle/description: Texte secondaire dans Command Palette. description est accepté comme alias de subtitle.keywords: Termes de recherche supplémentaires pour Command Palette.palette: Vaut true par défaut pour les actions personnalisées. Définissez false pour masquer l’action dans Command Palette tout en la laissant appelable ailleurs.shortcut: Raccourci d’action optionnel, avec la même syntaxe de touche unique ou d’accord en deux temps que les raccourcis des réglages.target: Pour les actions command et agent uniquement. Utilisez currentTerminal ou newTabInCurrentPane.confirm: Demande confirmation avant d’exécuter l’action.
Comportement de Command Palette
Command Palette lit le registre d’actions résolu. Les ID d’actions personnalisées sont ajoutés comme lignes quand palette n’est pas false. Les anciens commands sont ajoutés automatiquement comme lignes personnalisées, sauf si une action avec le même ID généré existe déjà. Les commandes intégrées gardent leurs libellés habituels, mais remplacer un ID intégré comme cmux.newTerminal change le comportement derrière ce point d’entrée partagé.
Actions personnalisées du bouton plus
Utilise ui.newWorkspace.action pour remplacer ce que fait le bouton plus. Utilise ui.newWorkspace.contextMenu (ou l’alias rightClick) pour définir le menu contextuel ordonné. Les entrées de menu peuvent être des ID d’action, des objets d’action ou { "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"
}
]
}
}
]
}
]
}
}
}
]
}Cet exemple fait exécuter l’action worktree-agents par le clic normal sur le bouton plus. La commande d’espace de travail de commands utilise un terminal de préparation visible pour créer d’abord le worktree Git. Codex et Claude démarrent en même temps, attendent le fichier d’état propre à l’espace de travail, puis se placent dans le dossier créé avant exec.
Commandes simples
Une commande simple exécute une commande shell dans le terminal actuellement focalisé :
{
"commands": [
{
"name": "Run Tests",
"keywords": ["test", "check"],
"command": "npm test",
"confirm": true
}
]
}Champs
name: Affiché dans la palette de commandes (requis)description: Description optionnellekeywords: Termes de recherche supplémentaires pour la palette de commandescommand: Commande shell à exécuter dans le terminal focaliséconfirm: Afficher une boîte de dialogue de confirmation avant l'exécution
Les commandes simples s'exécutent dans le répertoire de travail actuel du terminal ciblé. Si votre commande utilise des chemins relatifs au projet, préfixez avec cd "$(git rev-parse --show-toplevel)" && pour exécuter depuis la racine du dépôt, ou cd /your/path && pour n'importe quel répertoire spécifique.
Commandes d'espace de travail
Une commande d'espace de travail crée un nouvel espace de travail avec une mise en page personnalisée de divisions, terminaux et panneaux de navigateur :
{
"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" }
}
]
}
}
]
}
}
}
]
}Champs de l'espace de travail
name: Nom de l'onglet de l'espace de travail (par défaut, nom de la commande)cwd: Répertoire de travail de l'espace de travailcolor: Couleur de l'onglet de l'espace de travaillayout: Arbre de mise en page définissant les divisions et panneaux
Comportement au redémarrage
Contrôle ce qui se passe lorsqu'un espace de travail du même nom existe déjà :
"new": Créer un nouveau workspace (par défaut)"ignore": Basculer vers le workspace existant"recreate": Fermer et recréer sans demander"confirm": Demander à l’utilisateur avant de recréer
Arbre de mise en page
L'arbre de mise en page définit comment les panneaux sont disposés à l'aide de nœuds de division récursifs :
Nœud de division
Divise l'espace en deux enfants :
direction:"horizontal"ou"vertical"split: Position du séparateur de 0.1 à 0.9 (par défaut 0.5)children: Exactement deux nœuds enfants (division ou panneau)
Nœud de panneau
Un nœud feuille contenant une ou plusieurs surfaces (onglets dans le panneau).
Définition de surface
Chaque surface dans un panneau peut être un terminal ou un navigateur :
type:"terminal"ou"browser"name: Titre d'onglet personnalisécommand: Commande shell à exécuter automatiquement à la création (terminal uniquement)cwd: Répertoire de travail pour cette surfaceenv: Variables d'environnement sous forme de paires clé-valeururl: URL à ouvrir (navigateur uniquement)focus: Focaliser cette surface après la création
Résolution du répertoire de travail
.ou omis: répertoire de travail de l'espace de travail./subdir: relatif au répertoire de travail de l'espace de travail~/path: développé vers le répertoire personnel- Chemin absolu: utilisé tel quel
Exemple complet
{
"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
}
]
}