Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions skills/cmux-settings/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
name: cmux-settings
description: "View and edit cmux settings in ~/.config/cmux/cmux.json. Use when the user wants to change cmux preferences (appearance, sidebar, notifications, automation, browser, shortcuts), set a value by JSON path, validate the file, open it in an editor, or look up which keys cmux recognizes. Triggers on '/cmux-settings', 'change cmux setting', 'set <something> in cmux', 'cmux config', 'cmux.json', or 'rebind a cmux shortcut'."
---

# cmux-settings

cmux reads user settings from `~/.config/cmux/cmux.json` (JSONC). The app installs a file watcher; saving the file applies changes immediately, no restart needed. Legacy `~/.config/cmux/settings.json` is read only as a fallback for keys not present in `cmux.json`.

Schema: `https://raw.githubusercontent.com/manaflow-ai/cmux/main/web/data/cmux.schema.json`. The authoritative path list lives in `Sources/CmuxSettingsJSONPathSupport.swift` in the cmux checkout, and the installed skill includes a generated copy in `references/all-keys.md`. Top-level sections are `app`, `terminal`, `notifications`, `sidebar`, `sidebarAppearance`, `workspaceColors`, `automation`, `browser`, and `shortcuts`. Non-settings sections (`actions`, `ui`, `commands`, `vault`, `rightSidebar`) coexist in the same file.

## Helper script

Use the bundled helper for every read/write. It strips JSONC comments, writes atomically, and validates keys against the schema.

```bash
# From a cmux checkout
skills/cmux-settings/scripts/cmux-settings <subcommand>

# From an installed Codex skill
~/.codex/skills/cmux-settings/scripts/cmux-settings <subcommand>
```

For brevity in the rest of this doc, assume the script is on `$PATH` as `cmux-settings`. To make it so for a session from a checkout: `export PATH="$PWD/skills/cmux-settings/scripts:$PATH"`.

Subcommands:

| Command | What it does |
|---|---|
| `cmux-settings path` | Print the config path. |
| `cmux-settings dump` | Print the raw file (preserves comments). |
| `cmux-settings dump --no-comments` | Print the parsed JSON. |
| `cmux-settings get <a.b.c>` | Print value at dotted JSON path. |
| `cmux-settings set <a.b.c> <value>` | Set value. `<value>` is parsed as JSON (`true`, `42`, `"text"`, `[…]`, `{…}`); plain strings without quotes are stored as strings. |
| `cmux-settings unset <a.b.c>` | Delete key, reverting to the in-app default. |
| `cmux-settings list-supported` | List every settings JSON path the app recognizes. |
| `cmux-settings validate` | Parse the file and flag any unknown settings keys. |
| `cmux-settings open` | Open `cmux.json` in `$EDITOR`, VS Code, Cursor, or TextEdit. |

`--file <path>` overrides the target file (useful for `--file ~/.config/cmux/settings.json` when the user keeps things in the legacy file).

## Workflow

1. Confirm the change. If the user named a setting in plain English (e.g. "make the sidebar tint match the terminal background"), look it up first.
```bash
cmux-settings list-supported | rg -i 'sidebar.*terminal|terminal.*sidebar'
```
2. Set the value. JSON literals (`true`, `false`, numbers, arrays, objects) must be valid JSON. Plain words are stored as strings.
```bash
cmux-settings set sidebarAppearance.matchTerminalBackground true
cmux-settings set app.appearance dark
cmux-settings set shortcuts.bindings.toggleSidebar cmd+b
cmux-settings set shortcuts.bindings.newTab '["ctrl+b","c"]'
cmux-settings set browser.hostsToOpenInEmbeddedBrowser '["localhost","*.internal.example"]'
```
3. Verify by reading back and validating.
```bash
cmux-settings get sidebarAppearance.matchTerminalBackground
cmux-settings validate
```
4. Tell the user it auto-reloaded. No app restart. If they want to revert, run `cmux-settings unset <key>`.

## Quick reference

- Appearance: `app.appearance` = `"system" | "light" | "dark"`, `app.appIcon`, `app.menuBarOnly`, `app.minimalMode`.
- Sidebar tint: `sidebarAppearance.matchTerminalBackground`, `sidebarAppearance.tintColor`, `sidebarAppearance.tintOpacity` (0..1).
- Sidebar details: `sidebar.hideAllDetails`, `sidebar.showBranchDirectory`, `sidebar.showPullRequests`, `sidebar.showPorts`, `sidebar.showLog`.
- Notifications: `notifications.dockBadge`, `notifications.sound` (enum incl. `"none"`, `"custom_file"`), `notifications.customSoundFilePath`, `notifications.hooks` (array).
- Browser: `browser.defaultSearchEngine`, `browser.theme`, `browser.openTerminalLinksInCmuxBrowser`, `browser.hostsToOpenInEmbeddedBrowser`.
- Automation: `automation.socketControlMode` (`off | cmuxOnly | automation | password | allowAll`), `automation.portBase`, `automation.portRange`.
- Shortcuts: `shortcuts.bindings.<actionId>` = `"cmd+b"`, `["ctrl+b","c"]`, `null`, or `""` to unbind. See `references/shortcut-actions.md`.

For the full list of settings, defaults, and descriptions, run `cmux-settings list-supported` or read [references/all-keys.md](references/all-keys.md).

## Rules

- Only edit `cmux.json`. Never edit `settings.json` unless the user explicitly asks; it is legacy and only read when the key is absent from `cmux.json`.
- Never tell the user to restart cmux to apply a change. The file watcher reloads on save.
- Always validate after a bulk edit: `cmux-settings validate`. Unknown keys mean the user pasted a key the app does not consume.
- Do not blindly overwrite top-level sections (`actions`, `ui`, `commands`, `vault`, `rightSidebar`). They live in the same file and contain non-settings config the user has hand-tuned.
- Shortcut action ids must match the schema enum. Look them up in [references/shortcut-actions.md](references/shortcut-actions.md) before binding.
- Color values must be `#RRGGBB`. Opacities are `0..1`.
- For settings the user expressed in app-level language (e.g. "Settings > Notifications > Dock badge"), translate to the matching JSON path first; the docs page at `web/app/[locale]/docs/configuration/page.tsx` mirrors the schema 1:1.
4 changes: 4 additions & 0 deletions skills/cmux-settings/agents/openai.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
interface:
display_name: "cmux Settings"
short_description: "Inspect, edit, validate, and reload cmux.json settings."
default_prompt: "Use this skill to change cmux settings safely: map user-facing preferences to cmux.json paths, edit with the bundled helper, validate recognized keys, and rely on cmux's live config reload."
140 changes: 140 additions & 0 deletions skills/cmux-settings/references/all-keys.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# All settings keys

Auto-generated from `web/data/cmux.schema.json`. For the rendered docs, see `https://cmux.com/docs/configuration`.

## app

General app preferences from Settings > App.

| Key | Type | Default | Description |
|---|---|---|---|
| `app.language` | `"system"` or `"en"` or `"ar"` or `"bs"` or `"zh-Hans"` or `"zh-Hant"` or `"da"` or `"de"` or `"es"` or `"fr"` or `"it"` or `"ja"` or `"ko"` or `"nb"` or `"pl"` or `"pt-BR"` or `"ru"` or `"th"` or `"tr"` | `"system"` | Preferred app language. |
| `app.appearance` | `"system"` or `"light"` or `"dark"` | `"system"` | App appearance mode. |
| `app.appIcon` | `"automatic"` or `"light"` or `"dark"` | `"automatic"` | Dock and app switcher icon style. |
| `app.menuBarOnly` | boolean | `false` | Hide the Dock icon and app switcher entry while keeping cmux available from the menu bar. |
| `app.newWorkspacePlacement` | `"top"` or `"afterCurrent"` or `"end"` | `"afterCurrent"` | Where new workspaces are inserted in the sidebar. |
| `app.workspaceInheritWorkingDirectory` | boolean | `true` | When true, new workspaces inherit the current workspace working directory. When false, new workspaces leave the working directory unset so Ghostty's working-directory setting can provide the default. |
| `app.minimalMode` | boolean | `false` | Hide the workspace title bar and move controls into the sidebar. |
| `app.keepWorkspaceOpenWhenClosingLastSurface` | boolean | `false` | When true, closing the last surface keeps the workspace open. |
| `app.focusPaneOnFirstClick` | boolean | `true` | When cmux is inactive, the first click can activate and focus the clicked pane. |
| `app.preferredEditor` | string | `""` | Custom editor command used when Cmd-click file previews are disabled or a file is unsupported. Leave empty to use the default. |
| `app.openSupportedFilesInCmux` | boolean | `true` | When enabled, Cmd-clicking readable local files opens supported previews in cmux, including text, code, PDFs, images, audio, video, and Quick Look files. Preview headers include an Open With menu based on the user's default and compatible macOS apps for that file. |
| `app.openMarkdownInCmuxViewer` | boolean | `false` | When enabled together with openSupportedFilesInCmux, Cmd-clicking .md/.markdown/.mkd/.mdx files opens the rendered cmux markdown viewer panel (with live reload) instead of the generic file preview. |
| `app.reorderOnNotification` | boolean | `true` | Move workspaces with new notifications toward the top. |
| `app.iMessageMode` | boolean | `false` | Move a workspace to the top and show the submitted message when sending an agent prompt. |
| `app.sendAnonymousTelemetry` | boolean | `true` | Allow anonymous telemetry. |
| `app.warnBeforeQuit` | boolean | `true` | Show a confirmation before quitting cmux. |
| `app.warnBeforeClosingTab` | boolean | `true` | Show a confirmation before closing a tab. |
| `app.renameSelectsExistingName` | boolean | `true` | Select the current name when opening rename flows. |
| `app.commandPaletteSearchesAllSurfaces` | boolean | `false` | Search every surface in the command palette switcher instead of only the active workspace. |

## terminal

Terminal presentation settings from Settings > Terminal.

| Key | Type | Default | Description |
|---|---|---|---|
| `terminal.showScrollBar` | boolean | `true` | Show the right-edge terminal scroll bar when scrollback is available. cmux automatically suppresses it for alternate-screen style TUI surfaces. |
| `terminal.autoResumeAgentSessions` | boolean | `true` | Automatically run agent resume commands for restored terminal sessions when cmux reopens after quit. Set false to restore panes while keeping Claude Code, Codex, OpenCode, and other saved agent sessions idle until you resume them manually. |

## notifications

Notification behavior from Settings > Notifications.

| Key | Type | Default | Description |
|---|---|---|---|
| `notifications.dockBadge` | boolean | `true` | Show the unread count in the Dock tile. |
| `notifications.showInMenuBar` | boolean | `true` | Show the menu bar extra. |
| `notifications.unreadPaneRing` | boolean | `true` | Highlight panes with unread notifications. |
| `notifications.paneFlash` | boolean | `true` | Flash the focused pane when requested. |
| `notifications.sound` | `"default"` or `"Basso"` or `"Blow"` or `"Bottle"` or `"Frog"` or `"Funk"` or `"Glass"` or `"Hero"` or `"Morse"` or `"Ping"` or `"Pop"` or `"Purr"` or `"Sosumi"` or `"Submarine"` or `"Tink"` or `"custom_file"` or `"none"` | `"default"` | Notification sound preset. |
| `notifications.customSoundFilePath` | string | `""` | Local path to the custom notification sound file. |
| `notifications.command` | string | `""` | Optional shell command to run alongside notification delivery. |
| `notifications.hooksMode` | `"append"` or `"replace"` | `"append"` | Controls whether project-local notification hooks append to inherited hooks or replace them. |
| `notifications.hooks` | array<object> | `[]` | Composable shell hooks that receive notification policy JSON on stdin and return updated policy JSON on stdout. |

## sidebar

Sidebar content and metadata visibility from Settings > Sidebar.

| Key | Type | Default | Description |
|---|---|---|---|
| `sidebar.hideAllDetails` | boolean | `false` | Hide all per-workspace detail rows. |
| `sidebar.showWorkspaceDescription` | boolean | `true` | Show custom workspace descriptions in the sidebar. |
| `sidebar.branchLayout` | `"vertical"` or `"inline"` | `"vertical"` | Show git branch details stacked vertically or inline. |
| `sidebar.showNotificationMessage` | boolean | `true` | Show the latest notification text in the sidebar. |
| `sidebar.showBranchDirectory` | boolean | `true` | Show the workspace working directory. |
| `sidebar.showPullRequests` | boolean | `true` | Show pull request metadata in the sidebar. |
| `sidebar.makePullRequestsClickable` | boolean | `true` | Allow sidebar pull request metadata to open links when clicked. |
| `sidebar.openPullRequestLinksInCmuxBrowser` | boolean | `true` | Open sidebar pull request links in the embedded cmux browser. |
| `sidebar.openPortLinksInCmuxBrowser` | boolean | `true` | Open sidebar port links in the embedded cmux browser. |
| `sidebar.showSSH` | boolean | `true` | Show SSH connection details. |
| `sidebar.showPorts` | boolean | `true` | Show listening ports. |
| `sidebar.showLog` | boolean | `true` | Show recent log snippets. |
| `sidebar.showProgress` | boolean | `true` | Show progress indicators. |
| `sidebar.showCustomMetadata` | boolean | `true` | Show custom metadata pills. |

## workspaceColors

Workspace tab and badge colors from Settings > Workspace Colors.

| Key | Type | Default | Description |
|---|---|---|---|
| `workspaceColors.indicatorStyle` | `"leftRail"` or `"solidFill"` or `"rail"` or `"border"` or `"wash"` or `"lift"` or `"typography"` or `"washRail"` or `"blueWashColorRail"` | `"leftRail"` | Active workspace indicator style. Legacy aliases are accepted and normalized. |
| `workspaceColors.selectionColor` | colorHexOrNull | `null` | Override the selected workspace background color. |
| `workspaceColors.notificationBadgeColor` | colorHexOrNull | `null` | Override the unread notification badge color. |
| `workspaceColors.colors` | object | `{"Red": "#C0392B", "Crimson": "#922B21", "Orange": "#A04000", "Amber": "#7D6608", "Olive": "#4A5C18", "Green": "#196F3D", "Teal": "#006B6B", "Aqua": "#0E6B8C", "Blue": "#1565C0", "Navy": "#1A5276", "Indigo": "#283593", "Purple": "#6A1B9A", "Magenta": "#AD1457", "Rose": "#880E4F", "Brown": "#7B3F00", "Charcoal": "#3E4B5E"}` | Full named workspace color palette. Include built-in entries you want to keep, remove keys to remove colors, and add more named entries to extend the picker. |
| `workspaceColors.paletteOverrides` | object | `{}` | Legacy workspace color overrides for built-in palette names. Prefer workspaceColors.colors for new configs. |
| `workspaceColors.customColors` | array<colorHex> | `[]` | Legacy list of custom workspace colors. Prefer workspaceColors.colors for new configs. |

## sidebarAppearance

Sidebar tint settings from Settings > Sidebar Appearance.

| Key | Type | Default | Description |
|---|---|---|---|
| `sidebarAppearance.matchTerminalBackground` | boolean | `false` | Use the terminal background instead of the sidebar tint. |
| `sidebarAppearance.tintColor` | colorHex | `"#000000"` | Base sidebar tint color used when light/dark overrides are not set. |
| `sidebarAppearance.lightModeTintColor` | colorHexOrNull | `null` | Sidebar tint override for light appearance. |
| `sidebarAppearance.darkModeTintColor` | colorHexOrNull | `null` | Sidebar tint override for dark appearance. |
| `sidebarAppearance.tintOpacity` | number | `0.03` | Sidebar tint opacity from 0 to 1. Note: this only controls the sidebar tint, not terminal/window transparency. For terminal background transparency or blur, set `background-opacity` and `background-blur` in `~/.config/ghostty/config` and run `cmux reload-config`. |

## automation

Socket control and automation settings from Settings > Automation.

| Key | Type | Default | Description |
|---|---|---|---|
| `automation.socketControlMode` | `"off"` or `"cmuxOnly"` or `"automation"` or `"password"` or `"allowAll"` or `"openAccess"` or `"fullOpenAccess"` or `"notifications"` or `"full"` | `"cmuxOnly"` | Socket control mode. Legacy aliases are accepted and normalized. |
| `automation.socketPassword` | string or null | `""` | Password for password-mode socket access. Use null or an empty string to clear it. |
| `automation.claudeCodeIntegration` | boolean | `true` | Enable cmux integration hooks for Claude Code. |
| `automation.claudeBinaryPath` | string | `""` | Custom path to the claude binary. |
| `automation.cursorIntegration` | boolean | `true` | Enable cmux integration hooks for Cursor. |
| `automation.geminiIntegration` | boolean | `true` | Enable cmux integration hooks for Gemini. |
| `automation.portBase` | integer | `9100` | Starting value for workspace CMUX_PORT assignments. |
| `automation.portRange` | integer | `10` | Number of ports reserved per workspace. |

## browser

Embedded browser settings from Settings > Browser.

| Key | Type | Default | Description |
|---|---|---|---|
| `browser.defaultSearchEngine` | `"google"` or `"duckduckgo"` or `"bing"` or `"kagi"` or `"startpage"` | `"google"` | Default search engine for non-URL queries. |
| `browser.showSearchSuggestions` | boolean | `true` | Show omnibar search suggestions. |
| `browser.theme` | `"system"` or `"light"` or `"dark"` | `"system"` | Embedded browser theme. |
| `browser.openTerminalLinksInCmuxBrowser` | boolean | `true` | Open clicked terminal links in the embedded browser. |
| `browser.interceptTerminalOpenCommandInCmuxBrowser` | boolean | `true` | Intercept terminal open http(s) commands and route them through the embedded browser. |
| `browser.hostsToOpenInEmbeddedBrowser` | array<string> | `[]` | Allowlist of hosts that should stay inside the embedded browser. |
| `browser.urlsToAlwaysOpenExternally` | array<string> | `[]` | Rules that always open matching URLs in the system browser. |
| `browser.insecureHttpHostsAllowedInEmbeddedBrowser` | array<string> | `["localhost", "*.localhost", "127.0.0.1", "::1", "0.0.0.0", "*.localtest.me"]` | HTTP hosts allowed in the embedded browser without a warning prompt. |
| `browser.showImportHintOnBlankTabs` | boolean | `true` | Show the browser import hint on blank tabs. |
| `browser.reactGrabVersion` | string | `"0.1.29"` | Pinned react-grab version for the browser toolbar helper. |

## shortcuts

Keyboard shortcut settings from Settings > Keyboard Shortcuts.

| Key | Type | Default | Description |
|---|---|---|---|
| `shortcuts.bindings` | object | `{}` | Shortcut overrides keyed by cmux action id. Use a string for a single shortcut, an array for a chord, null, an empty string, none, clear, unbound, or disabled to unbind. |
Loading
Loading