# 사용자 지정 명령과 액션

cmux.json은 cmux에 나만의 작업 루틴을 가르치는 곳입니다. 자주 실행하는 셸 명령, 터미널과 브라우저가 미리 배치된 채로 열리는 워크스페이스, 단축키나 탭 바 버튼, Command Palette에 연결할 수 있는 액션을 정의할 수 있습니다. 프로젝트 안의 .cmux/cmux.json, 모든 프로젝트에 적용되는 ~/.config/cmux/cmux.json, 또는 두 곳 모두에 둘 수 있습니다.

## cmux가 cmux.json을 읽는 위치

항목은 프로젝트 파일, 사용자 전체 파일, 또는 둘 모두에서 가져올 수 있습니다. 프로젝트 파일의 경우 cmux는 현재 디렉터리에서 시작해 그 위에 있는 상위 디렉터리도 차례로 확인합니다.

-   **프로젝트:** `./.cmux/cmux.json` (작업 디렉터리에서 위쪽으로 검색해 찾으며, 사용자 전체 파일보다 우선합니다)
-   **fallback 로컬:** `./cmux.json` (기존 repo를 위해 계속 지원됩니다)
-   **사용자 전체:** `~/.config/cmux/cmux.json` (모든 프로젝트가 공유하며, 프로젝트 파일에서 정의하지 않은 부분을 채웁니다)

로컬 액션과 명령은 같은 ID 또는 이름을 가진 전역 항목보다 우선합니다.

cmux.json을 편집한 뒤 Cmd+Shift+, 를 누르거나 cmux reload-config를 실행해 변경 사항을 적용하세요.

프로젝트 또는 전역 설정에 스키마 오류가 있으면 cmux는 다음 유효한 설정으로 fallback하고 Command Palette에 **cmux.json Schema Error** 행을 표시합니다. 선택하면 설정 파일을 엽니다.

## 셸 명령

가장 작은 항목은 이름과 명령 문자열뿐입니다. Command Palette에서 이 항목을 선택하면 해당 문자열이 포커스된 터미널에 입력되고 실행됩니다.

cmux.json

```
{
  "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 Palette에서 선택할 때 쓰는 필수 레이블(빈 값 불가)
-   `command`: cmux가 포커스된 터미널에 입력하고 실행하는 셸 텍스트
-   `description`: 항목 옆에 표시되는 선택적 보조 텍스트
-   `keywords`: Command Palette에서 검색할 때 이 항목과 일치해야 하는 추가 단어
-   `confirm`: true로 설정하면 실행할 때마다 먼저 확인 프롬프트가 표시됩니다

셸 명령은 포커스된 터미널이 그 시점에 있는 위치에서 실행됩니다. 명령에 예측 가능한 시작 위치가 필요하다면 맨 앞에 `cd "$(git rev-parse --show-toplevel)" &&` 명령을 붙여 Git 저장소의 최상위로 이동하거나, `cd /some/folder &&` 명령을 붙여 고정된 폴더에서 시작하게 하세요.

## 워크스페이스를 여는 명령

명령에 명령 문자열 대신 workspace 객체를 지정하면 새 워크스페이스를 여는 명령이 됩니다. 워크스페이스는 터미널과 브라우저를 담은 분할 패널의 트리로 배치됩니다. 각 항목에는 둘 중 정확히 하나만 있어야 합니다.

cmux.json

```
{
  "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 16진수 값이나 워크스페이스 색상 이름으로 지정합니다
-   `env`: Environment variables inherited by every shell in the workspace
-   `setup`: Bootstrap command sent to the workspace's first terminal before that terminal's own command

### 워크스페이스가 이미 열려 있을 때

명령에 restart를 설정하면 같은 이름의 워크스페이스가 이미 있을 때의 동작을 정할 수 있습니다:

-   `"new"`: 새 워크스페이스 만들기 (기본값)
-   `"confirm"`: 먼저 묻고, 동의하면 교체
-   `"recreate"`: 묻지 않고 즉시 교체
-   `"ignore"`: 기존 워크스페이스로 전환

## 레이아웃 기술하기

레이아웃은 트리입니다. 모든 내부 노드는 자기 영역을 둘로 나누고, 모든 리프는 탭을 담는 패널입니다.

### 분할 노드

분할은 자기 영역을 두 부분으로 나눕니다:

-   `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`: 워크스페이스 디렉터리 뒤에 이어 붙습니다
-   `.` 또는 설정하지 않음: 워크스페이스 디렉터리를 이어받습니다

## 파일 구조

액션 레지스트리는 nightly 기능입니다. `actions`, `shortcut`, `ui.surfaceTabBar.buttons`를 사용하기 전에 최신 nightly 빌드를 설치하세요.

`commands`는 계속 재사용 가능한 shell 명령과 workspace 레이아웃을 정의합니다. Nightly 빌드는 `actions` 레지스트리를 추가합니다. 액션은 surface 탭 바, Command Palette, 액션 단위 shortcut이 공유하는 공개 ID입니다.

cmux.json

```
{
  "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`로 설정하면 surface 탭 바나 shortcut에서는 계속 사용할 수 있지만 Command Palette에서는 숨깁니다. `shortcut`은 설정 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을 주고 싶을 때 버튼 객체를 사용하세요. 해석된 버튼 제목은 신뢰 확인 제목으로도 사용됩니다.

승인 또는 권한 플래그는 실제로 실행하려는 명령 문자열에 직접 넣으세요. 기본 액션 대상은 `newTabInCurrentPane`이므로 일반적인 패턴은 현재 pane에 새 terminal 탭을 열고 그 안에서 Codex, Claude Code, OpenCode를 시작하는 것입니다.

프로젝트 로컬 액션은 surface 탭 바와 Command Palette에 즉시 표시됩니다. 첫 실행 시에는 여전히 신뢰 확인이 표시됩니다. 신뢰는 저장소 단위가 아니라 정확히 일치하는 액션 fingerprint 단위입니다. 프로젝트 로컬 이미지 아이콘은 해당 액션을 신뢰할 때까지 잠겨 있습니다.

## 사용자 지정 액션과 Command Palette

`actions` 항목은 cmux가 실행하는 재사용 가능한 동작입니다. 같은 동작을 Command Palette, 서피스 탭 바, 단축키 또는 플러스 버튼 메뉴에서 사용할 때 액션을 사용하세요. 재사용 가능한 셸 명령과 워크스페이스 레이아웃에는 `commands`를 계속 사용하세요. Command Palette에서 숨길 액션은 `palette`를 false로 설정합니다.

### 액션 유형

-   `"command"`: 터미널에서 셸 텍스트를 실행합니다. target으로 현재 터미널 또는 현재 패널의 새 탭을 선택합니다.
-   `"agent"`: 지원되는 코딩 에이전트를 시작합니다. 현재 codex와 claude를 지원하며 선택적 인수를 줄 수 있습니다.
-   `"builtin"`: cmux.newTerminal, cmux.newBrowser, cmux.splitRight, cmux.splitDown 같은 내장 cmux 액션의 별칭입니다. 복사용 내장 동작: cmux.copyWorkingDirectory는 터미널의 작업 디렉터리를, cmux.copyProjectRoot는 Git 저장소의 루트(저장소 밖에서는 작업 디렉터리)를, cmux.copyScreen은 보이는 화면을 복사합니다. SSH, 클라우드, 원격 tmux 워크스페이스에서는 cmux가 다른 호스트의 Git 저장소를 확인할 수 없으므로 cmux.copyProjectRoot가 원격 작업 디렉터리를 복사합니다.
-   `"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`: 선택적 액션 단축키입니다. 설정 단축키와 같은 단일 입력 또는 2단계 코드 구문을 사용합니다.
-   `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는 해석된 액션 레지스트리를 읽습니다. `palette`가 false가 아니면 사용자 지정 액션 ID가 행으로 추가됩니다. 기존 `commands`는 같은 생성 ID를 가진 액션이 이미 없을 때 자동으로 사용자 지정 행으로 추가됩니다. 내장 명령은 일반 팔레트 레이블을 유지하지만 `cmux.newTerminal` 같은 내장 ID를 재정의하면 그 공용 진입점 뒤의 동작이 바뀝니다.

### 설정 액션

설정 액션은 설정 `path`와 다음 중 정확히 하나를 지정합니다: `set`(값 쓰기), `toggle: true`(true/false 설정 전환), `cycle`(목록의 다음 값으로 이동하고 마지막 값 다음에는 처음으로 돌아감), `unset: true`(cmux.json에서 키를 제거해 설정 창의 값이나 기본값이 적용되게 함). toggle과 cycle은 설정 창에서 지정한 값을 포함해 cmux가 현재 사용 중인 값에서 시작합니다. settingPreset 액션은 `settingPresets`의 항목을 적용합니다. 각 항목은 부분 cmux.json이며 중첩 객체는 키 단위로 병합됩니다. cmux는 저장하기 전에 모든 변경을 스키마로 검사하고, 주석과 다른 키는 그대로 두며, 변경을 즉시 적용합니다. 설정 액션과 프리셋은 전역 cmux.json과 그 파일이 참조하는 팩에서만 실행되며, 프로젝트 설정에서는 선언할 수 없습니다.

~/.config/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 명령을 보여줍니다. 경로는 모든 "."에서 나뉘므로 키 자체에 "."가 들어 있으면(예: ~/src/app.web에 대한 `workspaceGroups.byCwd` 항목) 이 방법으로 변경할 수 없습니다. cmux.json에서 직접 편집하세요.

## 플러스 버튼 사용자 지정 액션

`ui.newWorkspace.action`으로 플러스 버튼의 동작을 재정의합니다. `ui.newWorkspace.contextMenu`(또는 `rightClick` alias)로 정렬된 right-click 메뉴를 정의합니다. 메뉴 항목은 액션 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을 엽니다.

cmux.json

```
{
  "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:

cmux.json

```
{
  "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`.

## 전체 예시

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"
    }
  ]
}
```

Canonical: https://cmux.com/ko/docs/custom-commands

Documentation index: https://cmux.com/llms.txt
