Skip to content

Instantly share code, notes, and snippets.

@muloka
Last active March 21, 2026 15:14
Show Gist options
  • Select an option

  • Save muloka/d8ad1f8a445c8eac6e038cf3262f1124 to your computer and use it in GitHub Desktop.

Select an option

Save muloka/d8ad1f8a445c8eac6e038cf3262f1124 to your computer and use it in GitHub Desktop.
cmux.dev docs

cmux API Reference

Reverse-engineered API documentation for cmux.dev — a native macOS terminal built on libghostty, designed for multi-agent AI coding workflows.

Started from their published docs, then systematically probed the live socket API to fill in undocumented methods, response schemas, error codes, and behavioral quirks.

Files

File Description
cmux-api-reference.json Core API reference — 131 socket methods across 13 namespaces, plus CLI docs, sidebar metadata, keyboard shortcuts, and code examples
cmux-api-browser.json Browser automation API — 72 working methods + 13 WKWebView stubs, split out to keep the core reference lean

Coverage

144/144 live socket methods documented. Every response schema verified against the running API (protocol version 2).

Namespaces

Namespace Methods Notes
system 4 ping, capabilities, identify, tree
window 5 CRUD + focus
workspace 12 CRUD, navigation, reorder, action dispatcher (12 actions)
pane 9 CRUD, resize, swap, break/join
surface 17 CRUD, split, read/send text, flash, action dispatcher (13 actions)
tab 1 Action dispatcher (shares surface actions)
notification 5 Create, list, clear + surface/target variants
browser 85 DOM, inspection, JS, frames, state, cookies, tabs (13 are WKWebView stubs)
app 2 Focus override, simulate active
auth 1 Login/auth check
markdown 1 Open rendered markdown in split
settings 1 Open settings UI
feedback 2 Open/submit feedback

Also documented

  • Socket protocol (JSON-RPC over Unix socket, newline-terminated)
  • Error envelope with optional data field and 5 error codes
  • Socket path (~/Library/Application Support/cmux/cmux.sock, not /tmp/cmux.sock)
  • CLI --json support matrix
  • Sidebar metadata commands (CLI-only: status pills, progress bar, logs)
  • Sidebar state format
  • Environment variables and detection patterns
  • Keyboard shortcuts
  • ID format system (refs vs UUIDs)
  • Code examples (Python, shell, Claude Code hooks)

Socket protocol

→  {"id":"1","method":"workspace.list","params":{}}\n
←  {"id":"1","ok":true,"result":{"workspaces":[...]}}

Minimal Python client:

import json, socket, os

def rpc(method, params=None):
    s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    s.settimeout(3)  # server keeps connections open — timeout required
    s.connect(os.environ.get('CMUX_SOCKET_PATH',
              os.path.expanduser('~/Library/Application Support/cmux/cmux.sock')))
    s.sendall(json.dumps({'id': 1, 'method': method, 'params': params or {}}).encode() + b'\n')
    return json.loads(s.recv(65536))

How this was built

  1. Fetched published docs from cmux.com
  2. Probed system.capabilities to get the full method list
  3. Hit every method with empty params to discover required fields from error messages
  4. Iterated with parameter variations to map full schemas
  5. Diffed documented vs live responses to find discrepancies
  6. Folded everything into structured JSON

License

This is unofficial documentation created through API probing. Not affiliated with cmux/manaflow.

{
"meta": {
"description": "cmux browser automation API — split from cmux-api-reference.json",
"parent": "cmux-api-reference.json",
"surface_targeting": "Most commands accept surface targeting via positional (cmux browser surface:2 <cmd>), flag (--surface surface:2), or auto-detect via CMUX_SURFACE_ID env var."
},
"navigation": {
"open": {
"cli": "cmux browser open <url>",
"description": "Open a new browser surface with URL"
},
"open_split": {
"cli": "cmux browser open-split <url>",
"method": "browser.open_split",
"description": "Open browser in a split pane alongside current terminal"
},
"navigate": {
"cli": "cmux browser <surface> navigate <url> [--snapshot-after]",
"method": "browser.navigate",
"description": "Navigate existing browser surface to URL",
"example": "cmux browser surface:2 navigate https://example.org/docs --snapshot-after"
},
"back": {
"cli": "cmux browser <surface> back",
"method": "browser.back",
"description": "Navigate back"
},
"forward": {
"cli": "cmux browser <surface> forward",
"method": "browser.forward",
"description": "Navigate forward"
},
"reload": {
"cli": "cmux browser <surface> reload [--snapshot-after]",
"method": "browser.reload",
"description": "Reload current page"
},
"url": {
"cli": "cmux browser <surface> url",
"method": "browser.url.get",
"description": "Returns current page URL"
},
"focus_webview": {
"cli": "cmux browser <surface> focus-webview",
"method": "browser.focus_webview",
"description": "Move focus to the browser webview"
},
"is_webview_focused": {
"cli": "cmux browser <surface> is-webview-focused",
"method": "browser.is_webview_focused",
"description": "Check if browser webview has focus"
},
"identify": {
"cli": "cmux browser identify --surface <surface>",
"description": "Display focused window/workspace/surface context and metadata"
}
},
"waiting": {
"wait": {
"cli": "cmux browser <surface> wait <condition> [--timeout-ms <ms>]",
"method": "browser.wait",
"description": "Block until a condition is met",
"conditions": {
"--load-state complete": "Page fully loaded",
"--selector \"<css>\"": "DOM element present",
"--text \"<string>\"": "Text content appears",
"--url-contains \"<path>\"": "URL fragment matches",
"--function \"<js>\"": "JavaScript expression returns truthy"
},
"examples": [
"cmux browser surface:2 wait --load-state complete --timeout-ms 15000",
"cmux browser surface:2 wait --selector \"#checkout\" --timeout-ms 10000",
"cmux browser surface:2 wait --function \"window.__appReady === true\""
]
}
},
"dom_interaction": {
"click": {
"cli": "cmux browser <surface> click \"<selector>\" [--snapshot-after]",
"method": "browser.click",
"description": "Click element matching CSS selector",
"example": "cmux browser surface:2 click \"button[type='submit']\" --snapshot-after"
},
"dblclick": {
"cli": "cmux browser <surface> dblclick \"<selector>\"",
"method": "browser.dblclick",
"description": "Double-click element"
},
"hover": {
"cli": "cmux browser <surface> hover \"<selector>\"",
"method": "browser.hover",
"description": "Hover over element"
},
"focus": {
"cli": "cmux browser <surface> focus \"<selector>\"",
"method": "browser.focus",
"description": "Focus element"
},
"check": {
"cli": "cmux browser <surface> check \"<selector>\"",
"method": "browser.check",
"description": "Check a checkbox or radio button"
},
"uncheck": {
"cli": "cmux browser <surface> uncheck \"<selector>\"",
"method": "browser.uncheck",
"description": "Uncheck a checkbox"
},
"scroll_into_view": {
"cli": "cmux browser <surface> scroll-into-view \"<selector>\"",
"method": "browser.scroll_into_view",
"description": "Scroll element into viewport"
},
"type": {
"cli": "cmux browser <surface> type \"<selector>\" \"<text>\"",
"method": "browser.type",
"description": "Type text into field (appends to existing content)",
"example": "cmux browser surface:2 type \"#search\" \"cmux\""
},
"fill": {
"cli": "cmux browser <surface> fill \"<selector>\" --text \"<value>\"",
"method": "browser.fill",
"description": "Replace field value entirely (use empty string to clear)",
"example": "cmux browser surface:2 fill \"#email\" --text \"ops@example.com\""
},
"press": {
"cli": "cmux browser <surface> press <key>",
"method": "browser.press",
"description": "Press a keyboard key (e.g. Enter, Tab, Escape)",
"example": "cmux browser surface:2 press Enter"
},
"keydown": {
"cli": "cmux browser <surface> keydown <key>",
"method": "browser.keydown",
"description": "Trigger key down event"
},
"keyup": {
"cli": "cmux browser <surface> keyup <key>",
"method": "browser.keyup",
"description": "Trigger key up event"
},
"select": {
"cli": "cmux browser <surface> select \"<selector>\" \"<value>\"",
"method": "browser.select",
"description": "Select option in dropdown",
"example": "cmux browser surface:2 select \"#region\" \"us-east\""
},
"scroll": {
"cli": "cmux browser <surface> scroll --dy <pixels> [--dx <pixels>] [--selector \"<css>\"] [--snapshot-after]",
"method": "browser.scroll",
"description": "Scroll page or specific element by pixel amount",
"examples": [
"cmux browser surface:2 scroll --dy 800 --snapshot-after",
"cmux browser surface:2 scroll --selector \"#log-view\" --dx 0 --dy 400"
]
}
},
"inspection": {
"snapshot": {
"cli": "cmux browser <surface> snapshot [--interactive] [--compact] [--selector \"<css>\"] [--max-depth <n>]",
"method": "browser.snapshot",
"description": "Capture DOM snapshot for inspection",
"examples": [
"cmux browser surface:2 snapshot --interactive --compact",
"cmux browser surface:2 snapshot --selector \"main\" --max-depth 5"
]
},
"screenshot": {
"cli": "cmux browser <surface> screenshot --out <filepath>",
"method": "browser.screenshot",
"description": "Capture visual screenshot to file",
"example": "cmux browser surface:2 screenshot --out /tmp/page.png"
},
"get": {
"cli": "cmux browser <surface> get <subcommand>",
"methods": {
"title": "browser.get.title",
"url": "browser.url.get",
"text": "browser.get.text",
"html": "browser.get.html",
"value": "browser.get.value",
"attr": "browser.get.attr",
"count": "browser.get.count",
"box": "browser.get.box",
"styles": "browser.get.styles"
},
"description": "Retrieve page/element data",
"subcommands": {
"title": "Page title",
"url": "Current URL",
"text \"<selector>\"": "Element text content",
"html \"<selector>\"": "Element HTML",
"value \"<selector>\"": "Input field value",
"attr \"<selector>\" --attr <name>": "Element attribute value",
"count \"<selector>\"": "Number of matching elements",
"box \"<selector>\"": "Element bounding box",
"styles \"<selector>\" --property <css>": "Computed CSS property"
},
"examples": [
"cmux browser surface:2 get text \"h1\"",
"cmux browser surface:2 get attr \"a.primary\" --attr href",
"cmux browser surface:2 get styles \"#total\" --property color"
]
},
"is": {
"cli": "cmux browser <surface> is <check> \"<selector>\"",
"methods": {
"visible": "browser.is.visible",
"enabled": "browser.is.enabled",
"checked": "browser.is.checked"
},
"description": "Check element state (returns boolean)",
"checks": {
"visible": "Element is visible",
"enabled": "Element is enabled",
"checked": "Checkbox/radio is checked"
},
"examples": [
"cmux browser surface:2 is visible \"#checkout\"",
"cmux browser surface:2 is checked \"#terms\""
]
},
"find": {
"cli": "cmux browser <surface> find <locator>",
"methods": {
"role": "browser.find.role",
"text": "browser.find.text",
"label": "browser.find.label",
"placeholder": "browser.find.placeholder",
"alt": "browser.find.alt",
"title": "browser.find.title",
"testid": "browser.find.testid",
"first": "browser.find.first",
"last": "browser.find.last",
"nth": "browser.find.nth"
},
"description": "Locate elements by various strategies",
"locators": {
"role <role> --name \"<name>\"": "By accessibility role and name",
"text \"<string>\"": "By text content",
"label \"<string>\"": "By label text",
"placeholder \"<string>\"": "By placeholder text",
"alt \"<string>\"": "By alt text",
"title \"<string>\"": "By title attribute",
"testid \"<id>\"": "By test ID (data-testid)",
"first \"<selector>\"": "First match of CSS selector",
"last \"<selector>\"": "Last match of CSS selector",
"nth <index> \"<selector>\"": "Nth match by index"
},
"examples": [
"cmux browser surface:2 find role button --name \"Continue\"",
"cmux browser surface:2 find nth 2 \".row\""
]
},
"highlight": {
"cli": "cmux browser <surface> highlight \"<selector>\"",
"method": "browser.highlight",
"description": "Visually highlight an element on the page"
}
},
"javascript": {
"eval": {
"cli": "cmux browser <surface> eval \"<expression>\" | --script \"<code>\"",
"method": "browser.eval",
"description": "Evaluate JavaScript and return result",
"examples": [
"cmux browser surface:2 eval \"document.title\"",
"cmux browser surface:2 eval --script \"window.location.href\""
]
},
"addinitscript": {
"cli": "cmux browser <surface> addinitscript \"<code>\"",
"method": "browser.addinitscript",
"description": "Inject script that runs on every page load",
"example": "cmux browser surface:2 addinitscript \"window.__cmuxReady = true;\""
},
"addscript": {
"cli": "cmux browser <surface> addscript \"<code>\"",
"method": "browser.addscript",
"description": "Inject and run script immediately on current page",
"example": "cmux browser surface:2 addscript \"document.querySelector('#name')?.focus()\""
},
"addstyle": {
"cli": "cmux browser <surface> addstyle \"<css>\"",
"method": "browser.addstyle",
"description": "Inject CSS stylesheet",
"example": "cmux browser surface:2 addstyle \"#debug-banner { display: none !important; }\""
}
},
"frames": {
"frame": {
"cli": "cmux browser <surface> frame \"<selector>\" | frame main",
"methods": {
"select": "browser.frame.select",
"main": "browser.frame.main"
},
"description": "Enter iframe context by selector. Use 'frame main' to return to top-level.",
"example_flow": [
"cmux browser surface:2 frame \"iframe[name='checkout']\"",
"cmux browser surface:2 click \"#pay-now\"",
"cmux browser surface:2 frame main"
]
}
},
"dialogs": {
"dialog": {
"cli": "cmux browser <surface> dialog <action>",
"methods": {
"accept": "browser.dialog.accept",
"dismiss": "browser.dialog.dismiss"
},
"description": "Handle browser dialogs (alert, confirm, prompt)",
"actions": {
"accept": "Accept dialog",
"accept \"<text>\"": "Accept prompt dialog with input text",
"dismiss": "Dismiss/cancel dialog"
}
}
},
"downloads": {
"download": {
"cli": "cmux browser <surface> download --path <filepath> --timeout-ms <ms>",
"method": "browser.download.wait",
"description": "Wait for and capture a file download (typically follows a click that triggers download)",
"example_flow": [
"cmux browser surface:2 click \"a#download-report\"",
"cmux browser surface:2 download --path /tmp/report.csv --timeout-ms 30000"
]
}
},
"tabs": {
"tab": {
"cli": "cmux browser <surface> tab <subcommand>",
"methods": {
"list": "browser.tab.list",
"new": "browser.tab.new",
"switch": "browser.tab.switch",
"close": "browser.tab.close"
},
"description": "Manage browser tabs",
"subcommands": {
"list": "List all tabs",
"new <url>": "Create new tab with URL",
"switch <index|surface:id>": "Switch tab by index or surface ID",
"close": "Close current tab",
"close surface:<id>": "Close specific tab"
}
}
},
"console_and_errors": {
"console": {
"cli": "cmux browser <surface> console <subcommand>",
"methods": {
"list": "browser.console.list",
"clear": "browser.console.clear"
},
"subcommands": {
"list": "Show all console messages",
"clear": "Clear console history"
}
},
"errors": {
"cli": "cmux browser <surface> errors <subcommand>",
"methods": {
"list": "browser.errors.list"
},
"returns_socket": {
"count": "number",
"errors": ["array of error objects"],
"surface_id": "UUID",
"surface_ref": "surface:N",
"workspace_id": "UUID",
"workspace_ref": "workspace:N"
},
"subcommands": {
"list": "Show all page errors",
"clear": "Clear error log"
}
}
},
"state": {
"cookies": {
"cli": "cmux browser <surface> cookies <subcommand>",
"methods": {
"get": "browser.cookies.get",
"set": "browser.cookies.set",
"clear": "browser.cookies.clear"
},
"subcommands": {
"get": "List all cookies",
"get --name <name>": "Get specific cookie",
"set <name> <value> --domain <domain> --path <path>": "Set a cookie",
"clear --name <name>": "Remove specific cookie",
"clear --all": "Clear all cookies"
}
},
"storage": {
"cli": "cmux browser <surface> storage <type> <subcommand>",
"methods": {
"set": "browser.storage.set",
"get": "browser.storage.get",
"clear": "browser.storage.clear"
},
"types": [
"local",
"session"
],
"subcommands": {
"set <key> <value>": "Set storage value",
"get <key>": "Get storage value",
"clear": "Clear all storage"
},
"example": "cmux browser surface:2 storage local set theme dark"
},
"state_persistence": {
"save": {
"cli": "cmux browser <surface> state save <filepath>",
"method": "browser.state.save",
"description": "Save browser state (cookies, storage) to JSON file"
},
"load": {
"cli": "cmux browser <surface> state load <filepath>",
"method": "browser.state.load",
"description": "Restore browser state from JSON file"
}
}
},
"_wkwebview_stubs": {
"note": "The following methods exist in system.capabilities but return 'not_supported' errors because cmux uses WKWebView (not Chromium/CDP). They are reserved for potential future support.",
"methods": {
"browser.geolocation.set": "Per-tab geolocation spoofing",
"browser.viewport.set": "Programmable viewport emulation",
"browser.offline.set": "Network offline simulation",
"browser.network.requests": "Request interception logs",
"browser.network.route": "Request interception/mocking",
"browser.network.unroute": "Remove request interception",
"browser.input_keyboard": "Raw keyboard injection (use browser.press/keydown/keyup instead)",
"browser.input_mouse": "Raw mouse injection (use browser.click/hover/scroll instead)",
"browser.input_touch": "Raw touch injection",
"browser.screencast.start": "Frame-by-frame screencast capture",
"browser.screencast.stop": "Stop screencast",
"browser.trace.start": "Playwright-style trace recording",
"browser.trace.stop": "Stop trace recording"
}
}
}
{
"meta": {
"product": "cmux",
"version_note": "Docs fetched 2026-03-20, augmented with live API probing. Sidebar metadata commands are CLI-only (no socket equivalents confirmed). Browser automation split to cmux-api-browser.json.",
"description": "Native macOS terminal built on libghostty, designed for multi-agent AI coding workflows",
"website": "https://cmux.com",
"sources": {
"homepage": "https://cmux.com/",
"concepts": "https://cmux.com/docs/concepts",
"configuration": "https://cmux.com/docs/configuration",
"api": "https://cmux.com/docs/api",
"browser_automation": "https://cmux.com/docs/browser-automation",
"notifications": "https://cmux.com/docs/notifications",
"keyboard_shortcuts": "https://cmux.com/docs/keyboard-shortcuts",
"getting_started": "https://cmux.com/docs/getting-started"
},
"fetched": "2026-03-20"
},
"installation": {
"requirements": {
"os": "macOS 14.0 or later",
"arch": "Apple Silicon or Intel"
},
"methods": {
"dmg": "Download from GitHub releases, drag to Applications. Auto-updates via Sparkle.",
"homebrew": {
"install": "brew tap manaflow-ai/cmux && brew install --cask cmux",
"update": "brew upgrade --cask cmux"
}
},
"cli_setup": {
"note": "CLI works automatically inside cmux terminals. For external use, symlink:",
"command": "sudo ln -sf \"/Applications/cmux.app/Contents/Resources/bin/cmux\" /usr/local/bin/cmux"
},
"auto_updates": "Sparkle-based. Update indicator appears in titlebar. Manual: cmux menu > Check for Updates."
},
"concepts": {
"hierarchy": [
"window",
"workspace",
"pane",
"surface",
"panel"
],
"window": "Top-level macOS window. Each has its own sidebar with independent workspaces. Open with \u2318\u21e7N.",
"workspace": "Sidebar entry within a window. Contains one or more split panes. Created with \u2318N. Also called 'tabs' in the UI.",
"pane": "Split region within a workspace. Created with \u2318D (right) or \u2318\u21e7D (down). Each pane holds multiple surfaces.",
"surface": "Tab within a pane. Individual terminal or browser session. Each has its own CMUX_SURFACE_ID. Created with \u2318T.",
"panel": "Internal concept \u2014 the content inside a surface (terminal or browser). Interact via surfaces in the API."
},
"socket": {
"paths": {
"release": "~/Library/Application Support/cmux/cmux.sock",
"legacy_docs_reference": "/tmp/cmux.sock",
"debug": "/tmp/cmux-debug.sock",
"debug_tagged": "/tmp/cmux-debug-<tag>.sock",
"last_socket_path_file": "/tmp/cmux-last-socket-path"
},
"override_env": "CMUX_SOCKET_PATH",
"protocol": {
"format": "Newline-terminated JSON",
"fields": {
"id": "Request identifier (string or number)",
"method": "Method name (e.g. workspace.list)",
"params": "Parameters object (can be empty {})"
},
"request_example": "{\"id\":\"req-1\",\"method\":\"workspace.list\",\"params\":{}}",
"response_envelope": "{\"id\":\"req-1\",\"ok\":true,\"result\":{...}}",
"error_envelope": "{\"id\":\"req-1\",\"ok\":false,\"error\":{\"code\":\"<error_code>\",\"message\":\"<human-readable>\",\"data\":\"(optional, structured context)\"}}",
"error_codes": {
"method_not_found": "Unknown socket method name",
"invalid_params": "Missing or invalid required parameter",
"invalid_state": "Valid request but impossible given current layout (e.g. resize a pane with no split ancestor)",
"not_found": "Resource not found (e.g. file path)",
"not_supported": "Method exists but not available on current platform (e.g. WKWebView limitations)"
},
"cli_errors": "CLI prints 'Error: <code>: <message>' to stderr and exits 1"
},
"access_modes": {
"off": {
"description": "Socket disabled",
"activation": "CMUX_SOCKET_MODE=off or Settings"
},
"cmuxOnly": {
"description": "Only child processes of cmux can connect",
"activation": "Default in Settings"
},
"allowAll": {
"description": "Any local process can connect",
"activation": "CMUX_SOCKET_MODE=allowAll only"
}
}
},
"cli": {
"global_flags": {
"--socket <path>": "Custom socket path",
"--json": "JSON output format",
"--window <id>": "Target window ID",
"--workspace <id>": "Target workspace ID",
"--surface <id>": "Target surface ID",
"--id-format <fmt>": "refs|uuids|both"
}
},
"environment_variables": {
"CMUX_SOCKET_PATH": "Override socket location",
"CMUX_SOCKET_ENABLE": "Force enable/disable (1/0, true/false, on/off)",
"CMUX_SOCKET_MODE": "Access mode override (cmuxOnly, allowAll, off)",
"CMUX_WORKSPACE_ID": "Auto-set in each surface: current workspace ID",
"CMUX_SURFACE_ID": "Auto-set in each surface: current surface ID",
"TERM_PROGRAM": "Set to 'ghostty'",
"TERM": "Set to 'xterm-ghostty'"
},
"detection": {
"socket_available": "[ -S \"${CMUX_SOCKET_PATH:-/tmp/cmux.sock}\" ]",
"cli_available": "command -v cmux &>/dev/null",
"inside_cmux": "[ -n \"${CMUX_WORKSPACE_ID:-}\" ] && [ -n \"${CMUX_SURFACE_ID:-}\" ]",
"distinguish_from_ghostty": "[ \"$TERM_PROGRAM\" = \"ghostty\" ] && [ -n \"${CMUX_WORKSPACE_ID:-}\" ]"
},
"api_methods": {
"system": {
"ping": {
"method": "system.ping",
"cli": "cmux ping",
"description": "Health check",
"params": {},
"returns": {
"pong": true
}
},
"capabilities": {
"method": "system.capabilities",
"cli": "cmux capabilities [--json]",
"description": "Lists available methods and current access mode",
"params": {},
"returns": {
"methods": [
"string (method names, ~120 entries)"
],
"access_mode": "cmuxOnly|allowAll|off",
"version": "number (protocol version, currently 2)",
"protocol": "cmux-socket",
"socket_path": "/tmp/cmux.sock"
}
},
"identify": {
"method": "system.identify",
"cli": "cmux identify [--json]",
"description": "Shows focused window/workspace/pane/surface context",
"params": {},
"returns": {
"socket_path": "/tmp/cmux.sock",
"caller": "null when not called from within a cmux surface, otherwise object with window_ref, workspace_ref, pane_ref, surface_ref, tab_ref, surface_type, is_browser_surface, plus UUID variants",
"focused": "(same shape as caller \u2014 represents the app-wide focused context)"
}
},
"tree": {
"method": "system.tree",
"cli": "cmux tree [--all] [--workspace <id|ref>] [--json]",
"description": "Returns the full window/workspace/pane/surface hierarchy in one call. The single most useful discovery method.",
"params": {
"all": "boolean (optional, include all windows)",
"workspace": "string (optional, limit to specific workspace)"
},
"returns": {
"caller": "(same shape as identify.caller)",
"active": "(same shape as identify.focused)",
"windows": [
{
"ref": "window:N",
"index": "number",
"visible": "boolean",
"key": "boolean",
"workspace_count": "number",
"selected_workspace_ref": "workspace:N",
"workspaces": [
{
"id": "UUID",
"ref": "workspace:N",
"index": "number",
"title": "string",
"selected": "boolean",
"pinned": "boolean",
"panes": [
{
"ref": "pane:N",
"index": "number",
"focused": "boolean",
"surface_count": "number",
"surface_refs": [
"surface:N"
],
"selected_surface_ref": "surface:N",
"surfaces": [
{
"id": "UUID",
"ref": "surface:N",
"type": "terminal|browser",
"title": "string",
"url": "string|null",
"index": "number",
"index_in_pane": "number",
"pane_id": "UUID",
"pane_ref": "pane:N",
"focused": "boolean",
"selected": "boolean",
"selected_in_pane": "boolean"
}
]
}
]
}
]
}
]
}
}
},
"window": {
"list": {
"method": "window.list",
"cli": "cmux list-windows",
"description": "List all windows",
"params": {},
"returns": {
"windows": [
{
"ref": "window:N",
"id": "UUID",
"index": "number",
"visible": "boolean",
"key": "boolean",
"workspace_count": "number",
"selected_workspace_ref": "workspace:N",
"selected_workspace_id": "UUID"
}
]
}
},
"create": {
"method": "window.create",
"cli": "cmux new-window",
"description": "Create a new window",
"params": {}
},
"current": {
"method": "window.current",
"cli": "cmux current-window",
"description": "Get the current window",
"params": {},
"returns": {
"window_id": "UUID",
"window_ref": "window:N"
}
},
"focus": {
"method": "window.focus",
"cli": "cmux focus-window --window <id>",
"description": "Focus a specific window",
"params": {
"window_id": "string"
}
},
"close": {
"method": "window.close",
"cli": "cmux close-window --window <id>",
"description": "Close a window",
"params": {
"window_id": "string"
}
}
},
"workspace": {
"list": {
"method": "workspace.list",
"cli": "cmux list-workspaces",
"description": "List all workspaces",
"params": {},
"returns_cli": "Text format: '* workspace:1 title [selected]' per line",
"returns_socket": {
"window_id": "UUID",
"window_ref": "window:N",
"workspaces": [
{
"ref": "workspace:N",
"id": "UUID",
"index": "number",
"title": "string",
"selected": "boolean",
"active": "boolean",
"pinned": "boolean",
"current_directory": "string (workspace working directory)",
"custom_color": "string (hex color, e.g. '#283593')"
}
]
}
},
"create": {
"method": "workspace.create",
"cli": "cmux new-workspace [--cwd <path>] [--command <text>]",
"description": "Create a new workspace",
"params": {
"cwd": "string (optional, working directory)",
"command": "string (optional, initial command to run)"
},
"returns": {
"workspace_id": "UUID",
"workspace_ref": "workspace:N",
"window_id": "UUID",
"window_ref": "window:N"
}
},
"select": {
"method": "workspace.select",
"cli": "cmux select-workspace --workspace <id>",
"description": "Switch to a workspace",
"params": {
"workspace_id": "string"
}
},
"current": {
"method": "workspace.current",
"cli": "cmux current-workspace",
"description": "Get the current workspace",
"params": {},
"returns_cli": "Raw UUID string",
"returns_socket": {
"workspace_id": "UUID",
"workspace_ref": "workspace:N",
"window_id": "UUID",
"window_ref": "window:N"
}
},
"close": {
"method": "workspace.close",
"cli": "cmux close-workspace --workspace <id>",
"description": "Close a workspace",
"params": {
"workspace_id": "string"
}
},
"rename": {
"method": "workspace.rename",
"cli": "cmux rename-workspace [--workspace <id|ref>] <title>",
"description": "Rename a workspace",
"params": {
"workspace_id": "string",
"title": "string"
}
},
"reorder": {
"method": "workspace.reorder",
"cli": "cmux reorder-workspace --workspace <id|ref|index> (--index <n> | --before <id> | --after <id>)",
"description": "Reorder workspaces in the sidebar",
"params": {
"workspace_id": "string",
"index": "number (optional)",
"before": "string (optional)",
"after": "string (optional)"
}
},
"next": {
"method": "workspace.next",
"cli": "cmux next-window",
"description": "Switch to the next workspace",
"params": {}
},
"previous": {
"method": "workspace.previous",
"cli": "cmux previous-window",
"description": "Switch to the previous workspace",
"params": {}
},
"last": {
"method": "workspace.last",
"cli": "cmux last-window",
"description": "Switch to the last active workspace",
"params": {}
},
"move_to_window": {
"method": "workspace.move_to_window",
"cli": "cmux move-workspace-to-window --workspace <id|ref> --window <id|ref>",
"description": "Move a workspace to a different window",
"params": {
"workspace_id": "string",
"window_id": "string"
}
},
"action": {
"method": "workspace.action",
"cli": null,
"description": "Dispatch a named action on the current workspace",
"params": {
"action": "string (required)",
"title": "string (required for 'rename' action)"
},
"supported_actions": [
"pin",
"unpin",
"rename",
"clear_name",
"move_up",
"move_down",
"move_top",
"close_others",
"close_above",
"close_below",
"mark_read",
"mark_unread"
]
}
},
"pane": {
"list": {
"method": "pane.list",
"cli": "cmux list-panes [--workspace <id|ref>]",
"description": "List panes in the current or specified workspace",
"params": {
"workspace_id": "string (optional)"
},
"returns": {
"workspace_id": "UUID",
"workspace_ref": "workspace:N",
"window_id": "UUID",
"window_ref": "window:N",
"panes": [
{
"ref": "pane:N",
"id": "UUID",
"index": "number",
"focused": "boolean",
"surface_count": "number",
"surface_refs": [
"surface:N"
],
"surface_ids": [
"UUID"
],
"selected_surface_ref": "surface:N",
"selected_surface_id": "UUID"
}
]
}
},
"create": {
"method": "pane.create",
"cli": "cmux new-pane [--type <terminal|browser>] [--direction <left|right|up|down>] [--workspace <id|ref>] [--url <url>]",
"description": "Create a new pane",
"params": {
"type": "terminal|browser (optional, default terminal)",
"direction": "left|right|up|down (optional)",
"workspace_id": "string (optional)",
"url": "string (optional, for browser panes)"
},
"returns": {
"surface_id": "UUID",
"surface_ref": "surface:N",
"type": "terminal|browser",
"pane_id": "UUID (new pane)",
"pane_ref": "pane:N",
"workspace_id": "UUID",
"workspace_ref": "workspace:N",
"window_id": "UUID",
"window_ref": "window:N"
}
},
"focus": {
"method": "pane.focus",
"cli": "cmux focus-pane --pane <id|ref> [--workspace <id|ref>]",
"description": "Focus a specific pane",
"params": {
"pane_id": "string"
}
},
"surfaces": {
"method": "pane.surfaces",
"cli": "cmux list-pane-surfaces [--workspace <id|ref>] [--pane <id|ref>]",
"description": "List surfaces within a specific pane",
"params": {
"pane_id": "string (optional)",
"workspace_id": "string (optional)"
}
},
"resize": {
"method": "pane.resize",
"cli": "cmux resize-pane --pane <id|ref> (-L|-R|-U|-D) [--amount <n>]",
"description": "Resize a pane. Requires a split ancestor in the resize direction.",
"params": {
"pane_id": "string",
"direction": "left|right|up|down",
"amount": "number (optional, pixels)"
}
},
"swap": {
"method": "pane.swap",
"cli": "cmux swap-pane --pane <id|ref> --target-pane <id|ref>",
"description": "Swap two panes",
"params": {
"pane_id": "string",
"target_pane_id": "string"
}
},
"break": {
"method": "pane.break",
"cli": "cmux break-pane [--workspace <id|ref>] [--pane <id|ref>] [--surface <id|ref>] [--no-focus]",
"description": "Break a pane out into its own workspace",
"params": {
"pane_id": "string (optional)",
"no_focus": "boolean (optional)"
}
},
"join": {
"method": "pane.join",
"cli": "cmux join-pane --target-pane <id|ref> [--workspace <id|ref>] [--pane <id|ref>] [--no-focus]",
"description": "Join current pane into another pane",
"params": {
"target_pane_id": "string",
"no_focus": "boolean (optional)"
}
},
"last": {
"method": "pane.last",
"cli": "cmux last-pane [--workspace <id|ref>]",
"description": "Focus the previously active pane",
"params": {}
}
},
"surface": {
"list": {
"method": "surface.list",
"cli": "cmux list-pane-surfaces [--workspace <id|ref>] [--pane <id|ref>]",
"description": "List surfaces in the current pane",
"params": {},
"returns_cli": "Text format: '* surface:1 title [selected]' per line",
"returns_socket": {
"surfaces": [
{
"id": "UUID",
"ref": "surface:N",
"type": "terminal|browser",
"title": "string",
"index": "number",
"index_in_pane": "number",
"pane_id": "UUID",
"pane_ref": "pane:N",
"focused": "boolean",
"selected_in_pane": "boolean"
}
]
}
},
"create": {
"method": "surface.create",
"cli": "cmux new-surface [--type <terminal|browser>] [--pane <id|ref>] [--workspace <id|ref>] [--url <url>]",
"description": "Create a new surface (tab) within a pane",
"params": {
"type": "terminal|browser (optional, default terminal)",
"pane_id": "string (optional)",
"url": "string (optional, for browser surfaces)"
},
"returns": {
"surface_id": "UUID",
"surface_ref": "surface:N",
"type": "terminal|browser",
"pane_id": "UUID",
"pane_ref": "pane:N",
"workspace_id": "UUID",
"workspace_ref": "workspace:N",
"window_id": "UUID",
"window_ref": "window:N"
}
},
"current": {
"method": "surface.current",
"cli": null,
"description": "Get the calling surface's context",
"params": {},
"returns": {
"surface_ref": "surface:N",
"surface_id": "UUID",
"surface_type": "terminal|browser",
"workspace_ref": "workspace:N",
"workspace_id": "UUID",
"window_ref": "window:N",
"window_id": "UUID",
"pane_ref": "pane:N",
"pane_id": "UUID"
}
},
"close": {
"method": "surface.close",
"cli": "cmux close-surface [--surface <id|ref>] [--workspace <id|ref>]",
"description": "Close a surface",
"params": {
"surface_id": "string (optional, defaults to current)"
}
},
"split": {
"method": "surface.split",
"cli": "cmux new-split <direction>",
"description": "Split a pane in a direction",
"params": {
"direction": "left|right|up|down"
},
"returns": {
"surface_id": "UUID",
"surface_ref": "surface:N",
"type": "terminal|browser",
"pane_id": "UUID (new pane)",
"pane_ref": "pane:N (new pane)",
"workspace_id": "UUID",
"workspace_ref": "workspace:N",
"window_id": "UUID",
"window_ref": "window:N"
}
},
"focus": {
"method": "surface.focus",
"cli": "cmux focus-surface --surface <id>",
"description": "Focus a specific surface",
"params": {
"surface_id": "string"
}
},
"move": {
"method": "surface.move",
"cli": "cmux move-surface --surface <id|ref> [--pane <id|ref>] [--before <id|ref>] [--after <id|ref>] [--index <n>]",
"description": "Move a surface to a different pane or position",
"params": {
"surface_id": "string",
"pane_id": "string (optional)",
"index": "number (optional)",
"before": "string (optional)",
"after": "string (optional)"
}
},
"health": {
"method": "surface.health",
"cli": "cmux surface-health [--workspace <id|ref>]",
"description": "List surfaces with health/window membership info",
"params": {},
"returns": {
"workspace_ref": "workspace:N",
"workspace_id": "UUID",
"window_ref": "window:N",
"window_id": "UUID",
"surfaces": [
{
"ref": "surface:N",
"id": "UUID",
"type": "terminal|browser",
"index": "number",
"in_window": "boolean"
}
]
}
},
"read_text": {
"method": "surface.read_text",
"cli": "cmux read-screen [--workspace <id|ref>] [--surface <id|ref>] [--scrollback] [--lines <n>]",
"description": "Read terminal buffer content from a surface. Returns visible screen by default; use --scrollback for history and --lines to limit.",
"params": {
"surface_id": "string (optional, defaults to caller's surface)",
"scrollback": "boolean (optional, include scrollback buffer)",
"lines": "number (optional, limit to N most recent lines)"
},
"returns": {
"surface_ref": "surface:N",
"surface_id": "UUID",
"workspace_ref": "workspace:N",
"workspace_id": "UUID",
"window_ref": "window:N",
"window_id": "UUID",
"text": "string (UTF-8 terminal content)",
"base64": "string (base64-encoded terminal content)"
}
},
"send_text": {
"method": "surface.send_text",
"cli": "cmux send <text> | cmux send-surface --surface <id> <text>",
"description": "Send text input to a surface. Append \\n to execute as command.",
"params": {
"text": "string",
"surface_id": "string (optional, defaults to focused surface)"
},
"quirk": "If surface_id references a non-existent surface, the command silently falls back to the caller's surface instead of returning an error."
},
"send_key": {
"method": "surface.send_key",
"cli": "cmux send-key <key> | cmux send-key-surface --surface <id> <key>",
"description": "Send a key press to a surface",
"params": {
"key": "enter|tab|escape|backspace|delete|up|down|left|right",
"surface_id": "string (optional, defaults to focused surface)"
}
},
"clear_history": {
"method": "surface.clear_history",
"cli": null,
"description": "Clear scrollback history for a surface",
"params": {
"surface_id": "string (optional, defaults to caller's surface)"
},
"returns": "(standard surface context: surface_id/ref, workspace_id/ref, window_id/ref)"
},
"refresh": {
"method": "surface.refresh",
"cli": null,
"description": "Refresh surfaces in the workspace",
"params": {
"surface_id": "string (optional)",
"workspace_id": "string (optional)"
},
"returns": {
"refreshed": "number (count of refreshed surfaces)",
"workspace_id": "UUID",
"workspace_ref": "workspace:N",
"window_id": "UUID",
"window_ref": "window:N"
}
},
"reorder": {
"method": "surface.reorder",
"cli": null,
"description": "Reorder a surface within its pane. Exactly one of index, before_surface_id, or after_surface_id required.",
"params": {
"surface_id": "string (required, accepts UUID or ref)",
"index": "number (optional)",
"before_surface_id": "string (optional)",
"after_surface_id": "string (optional)"
},
"returns": "(standard surface+pane context)"
},
"trigger_flash": {
"method": "surface.trigger_flash",
"cli": null,
"description": "Trigger a visual flash on a surface (e.g. bell indicator)",
"params": {
"surface_id": "string (optional, defaults to caller's surface)",
"color": "hex string (optional, e.g. '#ff0000')"
},
"returns": "(standard surface context)"
},
"drag_to_split": {
"method": "surface.drag_to_split",
"cli": null,
"description": "Programmatically split a surface into a new pane in the given direction. Creates a new pane.",
"params": {
"surface_id": "string (required, accepts UUID or ref)",
"direction": "left|right|up|down (required)"
},
"returns": {
"surface_id": "UUID",
"surface_ref": "surface:N",
"pane_id": "UUID (new pane)",
"pane_ref": "pane:N (new pane)",
"workspace_id": "UUID",
"workspace_ref": "workspace:N",
"window_id": "UUID",
"window_ref": "window:N"
}
},
"action": {
"method": "surface.action",
"cli": null,
"description": "Dispatch a named action on the current surface/tab. surface.action and tab.action share the same action set.",
"params": {
"action": "string (required)",
"title": "string (required for 'rename' action)"
},
"supported_actions": [
"rename",
"clear_name",
"close_left",
"close_right",
"close_others",
"new_terminal_right",
"new_browser_right",
"reload",
"duplicate",
"pin",
"unpin",
"mark_read",
"mark_unread"
]
}
},
"tab": {
"action": {
"method": "tab.action",
"cli": null,
"description": "Dispatch a named action on the current tab. Shares the same action set as surface.action.",
"params": {
"action": "string (required)",
"title": "string (required for 'rename' action)"
},
"supported_actions": [
"rename",
"clear_name",
"close_left",
"close_right",
"close_others",
"new_terminal_right",
"new_browser_right",
"reload",
"duplicate",
"pin",
"unpin",
"mark_read",
"mark_unread"
]
}
},
"notification": {
"create": {
"method": "notification.create",
"cli": "cmux notify --title <title> [--subtitle <subtitle>] --body <body>",
"description": "Create a desktop notification with optional subtitle",
"params": {
"title": "string (required)",
"subtitle": "string (optional)",
"body": "string (required)"
},
"returns": {
"workspace_id": "UUID",
"surface_id": "UUID"
}
},
"list": {
"method": "notification.list",
"cli": "cmux list-notifications",
"description": "List all notifications",
"params": {},
"returns": {
"notifications": [
{
"id": "UUID",
"title": "string",
"subtitle": "string",
"body": "string",
"is_read": "boolean",
"workspace_id": "UUID",
"surface_id": "UUID"
}
]
}
},
"clear": {
"method": "notification.clear",
"cli": "cmux clear-notifications",
"description": "Clear all notifications",
"params": {}
},
"create_for_surface": {
"method": "notification.create_for_surface",
"cli": null,
"description": "Create a notification attributed to a specific surface",
"params": {
"surface_id": "string (required, UUID or ref)",
"title": "string (required)",
"body": "string (required)"
},
"returns": "(standard surface context)"
},
"create_for_target": {
"method": "notification.create_for_target",
"cli": null,
"description": "Create a notification for a specific workspace+surface target",
"params": {
"workspace_id": "string (required)",
"surface_id": "string (required)",
"title": "string (required)",
"body": "string (required)"
},
"returns": "(standard surface context)"
}
},
"sidebar_metadata": {
"_note": "Sidebar metadata commands are CLI-only. No socket method equivalents exist \u2014 confirmed by probing. Use the CLI commands below.",
"set_status": {
"cli": "cmux set-status <key> <text> [--icon <icon>] [--color <hex>] [--workspace <id>]",
"description": "Set a status pill in the sidebar. Unique key allows different tools to manage separate entries without overwriting each other.",
"params": {
"key": "string (unique identifier for this status entry)",
"text": "string (display text)",
"icon": "string (optional, icon name)",
"color": "hex string (optional, e.g. '#ff9500')",
"workspace": "string (optional, defaults to current workspace)"
},
"example": "cmux set-status build \"compiling\" --icon hammer --color \"#ff9500\""
},
"clear_status": {
"cli": "cmux clear-status <key>",
"description": "Remove a status pill by its unique key",
"params": {
"key": "string"
}
},
"list_status": {
"cli": "cmux list-status",
"description": "List all status pills for the current workspace",
"params": {}
},
"set_progress": {
"cli": "cmux set-progress <value> [--label <text>]",
"description": "Set a progress bar in the sidebar (0.0 to 1.0)",
"params": {
"value": "number (0.0 to 1.0)",
"label": "string (optional, display label)"
},
"example": "cmux set-progress 0.5 --label \"Building...\""
},
"clear_progress": {
"cli": "cmux clear-progress",
"description": "Remove the progress bar",
"params": {}
},
"log": {
"cli": "cmux log [--level <level>] [--source <source>] [--] <message>",
"description": "Add a log entry to the sidebar. Use -- before message if it starts with a dash.",
"params": {
"level": "info|progress|success|warning|error (default: info)",
"source": "string (optional, identifies the tool/process)",
"message": "string"
},
"examples": [
"cmux log \"Build started\"",
"cmux log --level error --source build \"Compilation failed\"",
"cmux log --level success -- \"All 42 tests passed\""
]
},
"clear_log": {
"cli": "cmux clear-log",
"description": "Clear all log entries from the sidebar",
"params": {}
},
"list_log": {
"cli": "cmux list-log [--limit <n>]",
"description": "List log entries",
"params": {
"limit": "number (optional, most recent N entries)"
}
},
"sidebar_state": {
"cli": "cmux sidebar-state [--workspace <id>]",
"description": "Dump full sidebar state: git branch, working directory, ports, status pills, progress, logs",
"params": {
"workspace": "string (optional, defaults to current)"
}
}
},
"app": {
"focus_override_set": {
"method": "app.focus_override.set",
"cli": null,
"description": "Override app focus state for automation purposes",
"params": {
"focused": "boolean (optional)",
"state": "active|inactive|clear (optional)"
},
"returns": {
"override": "boolean"
}
},
"simulate_active": {
"method": "app.simulate_active",
"cli": null,
"description": "Simulate app being active (useful for automation to prevent notification suppression)",
"params": {
"active": "boolean (optional)"
},
"returns": {}
}
},
"auth": {
"login": {
"method": "auth.login",
"cli": null,
"description": "Check or trigger authentication",
"params": {
"force": "boolean (optional)"
},
"returns": {
"required": "boolean",
"authenticated": "boolean"
}
}
},
"markdown": {
"open": {
"method": "markdown.open",
"cli": null,
"description": "Open a markdown file in a split pane for rendered viewing",
"params": {
"path": "string (required, absolute path to .md file)",
"title": "string (optional, display title)"
},
"returns": {
"surface_id": "UUID (new surface)",
"surface_ref": "surface:N",
"pane_id": "UUID (new pane)",
"pane_ref": "pane:N",
"target_pane_id": "UUID",
"target_pane_ref": "pane:N",
"source_surface_id": "UUID (calling surface)",
"source_surface_ref": "surface:N",
"source_pane_id": "UUID",
"source_pane_ref": "pane:N",
"path": "string",
"workspace_id": "UUID",
"workspace_ref": "workspace:N",
"window_id": "UUID",
"window_ref": "window:N"
}
}
},
"settings": {
"open": {
"method": "settings.open",
"cli": null,
"description": "Open the settings UI",
"params": {
"section": "string (optional, e.g. 'general'. Note: use 'section' not 'target')"
},
"returns": {
"opened": "boolean",
"target": "string (section name)"
}
}
},
"feedback": {
"open": {
"method": "feedback.open",
"cli": null,
"description": "Open the feedback dialog",
"params": {},
"returns": {
"opened": "boolean"
}
},
"submit": {
"method": "feedback.submit",
"cli": null,
"description": "Submit feedback programmatically",
"params": {
"email": "string (required)",
"body": "string (required)"
},
"returns": {}
}
}
},
"notifications": {
"lifecycle": [
"received",
"unread",
"read",
"cleared"
],
"suppression": "Desktop alerts suppressed when cmux window is focused AND the specific workspace is active, or notification panel is open",
"osc_sequences": {
"osc_777": {
"protocol": "RXVT",
"format": "\\e]777;notify;<title>;<body>\\a",
"example": "printf '\\e]777;notify;My Title;Message body here\\a'"
},
"osc_99": {
"protocol": "Kitty",
"format": "\\e]99;i=<id>;e=1;d=0:<body>\\e\\\\",
"supports": [
"subtitles",
"notification IDs"
],
"example": "printf '\\e]99;i=1;e=1;d=0;p=title:Build Complete\\e\\\\'"
}
},
"custom_command": {
"location": "Settings > App > Notification Command",
"description": "Shell command executed on every notification. Receives context via env vars.",
"env_vars": {
"CMUX_NOTIFICATION_TITLE": "Workspace or app name",
"CMUX_NOTIFICATION_SUBTITLE": "Subtitle text",
"CMUX_NOTIFICATION_BODY": "Body text"
},
"examples": {
"text_to_speech": "say \"$CMUX_NOTIFICATION_BODY\"",
"custom_sound": "afplay /path/to/sound.wav"
}
},
"keyboard_shortcuts": {
"show_panel": "\u2318\u21e7I",
"jump_to_unread": "\u2318\u21e7U"
}
},
"configuration": {
"ghostty_config_paths": [
"~/.config/ghostty/config",
"~/Library/Application Support/com.mitchellh.ghostty/config"
],
"appearance": {
"font-family": "Typeface (e.g., JetBrains Mono, SF Mono)",
"font-size": "Numeric size (e.g., 13, 14)",
"theme": "Predefined theme name (e.g., Dracula, One Dark)",
"background": "Hex color for terminal background",
"foreground": "Hex color for text",
"cursor-color": "Hex color",
"cursor-text": "Hex color for text under cursor",
"selection-background": "Hex color",
"selection-foreground": "Hex color",
"unfocused-split-opacity": "0.0\u20131.0 transparency for inactive splits",
"unfocused-split-fill": "Hex color for unfocused splits",
"split-divider-color": "Hex color between split regions"
},
"behavior": {
"scrollback-limit": "Lines retained in buffer (e.g., 10000, 50000)",
"working-directory": "Default path for new terminals (e.g., ~/Projects)"
},
"in_app_settings": {
"theme_mode": {
"options": [
"system",
"light",
"dark"
],
"description": "System follows macOS appearance"
},
"automation_mode": {
"options": [
"off",
"cmux processes only",
"allowAll"
],
"description": "Controls socket API access"
},
"browser_hosts": "Hosts to open in embedded browser vs default browser",
"http_hosts_allowed": "HTTP sites allowed without warning. Defaults: localhost, 127.0.0.1, ::1, 0.0.0.0, *.localtest.me"
}
},
"keyboard_shortcuts": {
"workspaces": {
"\u2318N": "New workspace",
"\u23181-8": "Jump to workspace 1-8",
"\u23189": "Jump to last workspace",
"\u2318\u21e7W": "Close workspace",
"\u2318\u21e7R": "Rename workspace"
},
"surfaces": {
"\u2318T": "New surface (tab within pane)",
"\u2318\u21e7[": "Previous surface",
"\u2303\u21e7Tab": "Previous surface (alt)",
"\u23031-8": "Jump to surface 1-8",
"\u23039": "Jump to last surface",
"\u2318W": "Close surface"
},
"split_panes": {
"\u2318D": "Split right",
"\u2318\u21e7D": "Split down",
"\u2325\u2318\u2190/\u2192/\u2191/\u2193": "Focus pane directionally",
"\u2325\u2318D": "Split browser right",
"\u2325\u2318\u21e7D": "Split browser down"
},
"browser": {
"\u2318\u21e7L": "Open browser surface",
"\u2318L": "Focus address bar",
"\u2318]": "Forward",
"\u2318R": "Reload page",
"\u2325\u2318I": "Open Developer Tools"
},
"notifications": {
"\u2318\u21e7I": "Show notifications panel",
"\u2318\u21e7U": "Jump to latest unread"
},
"find": {
"\u2318F": "Find",
"\u2318G": "Find next",
"\u2318\u21e7G": "Find previous",
"\u2318\u21e7F": "Hide find bar",
"\u2318E": "Use selection for find"
},
"terminal": {
"\u2318K": "Clear scrollback",
"\u2318C": "Copy (with selection)",
"\u2318V": "Paste",
"\u2318+/\u2318-": "Increase/decrease font size",
"\u23180": "Reset font size"
},
"window": {
"\u2318\u21e7N": "New window",
"\u2318,": "Settings",
"\u2318Q": "Quit"
}
},
"cli_json_support": {
"_note": "Not all CLI commands support --json. For structured data, use the socket API directly.",
"supported": ["cmux capabilities", "cmux identify", "cmux tree"],
"text_only": {
"cmux list-workspaces": "* workspace:1 title [selected]",
"cmux current-workspace": "Raw UUID string",
"cmux list-windows": "Text table",
"cmux list-panes": "Text table",
"cmux list-pane-surfaces": "* surface:1 title [selected]",
"cmux read-screen": "Errors on --json flag",
"cmux sidebar-state": "Key=value format (see sidebar_state_format)",
"cmux list-notifications": "Pipe-delimited text",
"cmux surface-health": "Text table"
}
},
"sidebar_state_format": {
"_note": "cmux sidebar-state returns key=value text, not JSON. Shows full sidebar metadata for a workspace.",
"fields": {
"tab": "UUID",
"color": "#hex",
"cwd": "/path (workspace working directory)",
"focused_cwd": "/path (focused surface cwd)",
"focused_panel": "UUID",
"git_branch": "branch-name|none",
"pr": "number|none",
"pr_label": "label|none",
"ports": "comma-separated|none",
"progress": "value label|none",
"status_count": "N (followed by indented key=value icon=name color=#hex lines)",
"meta_block_count": "N",
"log_count": "N (followed by indented [level] message lines)"
}
},
"code_examples": {
"python_socket_client": {
"description": "Minimal Python client for the Unix socket JSON-RPC API",
"code": "import json, os, socket\n\nSOCKET_PATH = os.environ.get('CMUX_SOCKET_PATH', '/tmp/cmux.sock')\n\ndef rpc(method, params=None, req_id=1):\n payload = {'id': req_id, 'method': method, 'params': params or {}}\n with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as sock:\n sock.connect(SOCKET_PATH)\n sock.sendall(json.dumps(payload).encode() + b'\\n')\n return json.loads(sock.recv(65536).decode())\n\nprint(rpc('workspace.list', req_id='ws'))\nprint(rpc('notification.create', {'title': 'Hello', 'body': 'From Python!'}, req_id='notify'))"
},
"shell_socket_client": {
"description": "Shell function for sending JSON-RPC commands via netcat",
"code": "SOCK=\"${CMUX_SOCKET_PATH:-/tmp/cmux.sock}\"\n\ncmux_cmd() {\n printf \"%s\\n\" \"$1\" | nc -U \"$SOCK\"\n}\n\ncmux_cmd '{\"id\":\"ws\",\"method\":\"workspace.list\",\"params\":{}}'\ncmux_cmd '{\"id\":\"notify\",\"method\":\"notification.create\",\"params\":{\"title\":\"Done\",\"body\":\"Task complete\"}}'"
},
"build_notification": {
"description": "Notify on build success/failure using CLI",
"code": "npm run build\nif [ $? -eq 0 ]; then\n cmux notify --title \"\u2713 Build Success\" --body \"Ready to deploy\"\nelse\n cmux notify --title \"\u2717 Build Failed\" --body \"Check the logs\"\nfi"
},
"claude_code_stop_hook": {
"description": "Claude Code hook that notifies when a session completes",
"code": "#!/bin/bash\n[ -S /tmp/cmux.sock ] || exit 0\nEVENT=$(cat)\nEVENT_TYPE=$(echo \"$EVENT\" | jq -r '.hook_event_name // \"unknown\"')\ncase \"$EVENT_TYPE\" in\n \"Stop\")\n cmux notify --title \"Claude Code\" --body \"Session complete\"\n ;;\nesac"
},
"notify_after_function": {
"description": "Shell function wrapper that notifies after any long-running command",
"code": "notify-after() {\n \"$@\"\n local exit_code=$?\n [ $exit_code -eq 0 ] && cmux notify --title \"\u2713 Complete\" --body \"$1\" || \\\n cmux notify --title \"\u2717 Failed\" --body \"$1\"\n}"
}
},
"browser_automation": {
"_split": "See cmux-api-browser.json for full browser automation reference (~340 lines)",
"file": "cmux-api-browser.json",
"socket_methods_prefix": "browser.*",
"cli_prefix": "cmux browser <surface> <command>"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment