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
Lokalne akcje i polecenia zastępują globalne wpisy o tym samym ID lub nazwie.
Rejestr akcji to funkcja nightly. Zainstaluj najnowszy build nightly przed użyciem actions, shortcut lub ui.surfaceTabBar.buttons.
Akcje lokalne dla projektu od razu pojawiają się na pasku kart powierzchni i w Command Palette. Pierwsze uruchomienie nadal prosi o zaufanie. Zaufanie dotyczy dokładnego fingerprintu akcji, a nie repozytorium. Lokalne dla projektu ikony obrazów pozostają zablokowane, dopóki ta akcja nie zostanie zaufana.
Jeśli konfiguracja projektu lub globalna zawiera błąd schematu, cmux przełącza się na następną poprawną konfigurację i pokazuje w Command Palette wiersz cmux.json Schema Error. Wybierz go, aby otworzyć plik konfiguracji.

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.

cmux.json
{
  "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" }.

cmux.json
{
  "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:

cmux.json
{
  "commands": [
    {
      "name": "Run Tests",
      "keywords": ["test", "check"],
      "command": "npm test",
      "confirm": true
    }
  ]
}

Pola

  • name: Wyświetlane w palecie poleceń (wymagane)
  • description: Opcjonalny opis
  • keywords: Dodatkowe terminy wyszukiwania dla palety poleceń
  • command: Polecenie shell do uruchomienia w sfokusowanym terminalu
  • confirm: 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:

cmux.json
{
  "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 workspace
  • color: Kolor zakładki workspace
  • layout: 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ładki
  • command: Polecenie shell do automatycznego uruchomienia przy tworzeniu (tylko terminal)
  • cwd: Katalog roboczy dla tej powierzchni
  • env: 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

cmux.json
{
  "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
    }
  ]
}