- name
- pi-cmux
- description
- Control cmux terminal multiplexer from pi — read other terminal screens, send commands to other workspaces, manage panes/splits, set sidebar status/progress, send notifications, and open browser surfaces. Use when asked to: check what's running in another terminal, send a command to another pane, split the workspace, show progress in the sidebar, notify the user, open a URL in a browser pane, orchestrate multi-workspace workflows, or interact with cmux in any way. Triggers on: 'cmux', 'other terminal', 'other workspace', 'read screen', 'send command to', 'split pane', 'sidebar status', 'progress bar', 'notify', 'browser pane', 'terminal multiplexer'.
- disable-model-invocation
- true
# cmux Integration for Pi
Pi runs inside cmux with full access to the cmux CLI via three extension tools: `cmux`, `cmux_status`, and `cmux_notify`. The cmux extension also automatically manages sidebar status (Running/Idle/Needs input) through pi lifecycle hooks.
## Naming discipline
When starting meaningful work or pivoting the core workstream, use the `cmux-workspace-naming` skill. Name the broad workspace theme in short Human Case, optionally with one useful emoji. Do not rename for tiny substeps.
For multi-tab, multi-session, or multi-subagent workspaces:
- Workspace/session name = umbrella theme shared by all lanes.
- Tab/surface/child-session name = stable lane/role, only when helpful.
- Parent/orchestrator owns workspace naming; child agents should not clobber it.
- Use sidebar status/progress/log rows for live state instead of renaming tabs every time something starts/stops.
- Keep the sidebar calm: avoid bouncy `Running`, `Checking`, `Fixing`, `Almost Done` title churn.
- For 4-10 agents, boring is good: `Parent`, `Research 1`, `Research 2`, `Reviewer`, `Worker`, `CI Watch`.
- Split into a new workspace/session when the lane becomes an independent workstream.
Required flow:
```
cmux action="identify"
cmux action="rename-workspace" args=["--workspace", "workspace:45", "🧭 cmux Naming Rules"]
cmux action="focus-panel" args=["--workspace", "workspace:45", "--panel", "surface:80"]
cmux action="tree" args=["--workspace", "workspace:45"]
```
Use the discovered refs, not guessed refs. Do not type rename commands into the active Pi terminal with `send`; that turns into user input instead of an operator command. Use the cmux tool or run the cmux CLI from a shell tool.
## Concepts
**Refs** — cmux uses short refs to identify objects: `workspace:1`, `pane:2`, `surface:3`, `window:1`. Run `cmux identify` for the caller/focused refs, or `cmux tree` for layout discovery, before targeting specific surfaces.
**Surfaces** — a surface is a single terminal or browser tab inside a pane. Each pane can have multiple surfaces (shown as tabs). Each workspace has one or more panes (splits).
**Environment** — cmux auto-sets `CMUX_WORKSPACE_ID`, `CMUX_SURFACE_ID`, and `CMUX_SOCKET_PATH` in local terminal surfaces. In `cmux ssh` remote sessions, Pi subprocesses may not inherit those variables; the extension discovers `~/.cmux/bin/cmux` and the relay socket automatically. Commands default to the caller's workspace/surface when flags are omitted where cmux exposes caller context.
## Tools
### `cmux` — Workspace, Pane, and Surface Control
The main tool for multiplexer operations. Takes an `action` and optional `args` array.
#### Discover layout
```
cmux action="tree"
cmux action="tree" args=["--all"]
cmux action="identify"
cmux action="remote-status"
cmux action="diagnose"
cmux action="capabilities"
cmux action="list-workspaces"
cmux action="current-workspace"
cmux action="list-panes"
cmux action="list-panes" args=["--workspace", "workspace:2"]
```
#### Read another terminal's screen
```
cmux action="read-screen" args=["--surface", "surface:1", "--lines", "50"]
cmux action="read-screen" args=["--surface", "surface:3", "--scrollback"]
cmux action="read-screen" args=["--workspace", "workspace:2"]
```
Use `--scrollback` to include scrollback buffer. Use `--lines N` to limit output. Without `--surface`, reads the focused surface of the specified workspace (or caller's workspace).
#### Send text or keys to another terminal
```
cmux action="send" args=["--surface", "surface:1", "npm run build\n"]
cmux action="send-key" args=["--surface", "surface:1", "Enter"]
cmux action="send-key" args=["--surface", "surface:2", "C-c"]
```
**Important**: Append `\n` to text to "press Enter". Use `send-key` for special keys: `Enter`, `C-c` (Ctrl+C), `C-d`, `Up`, `Down`, `Left`, `Right`, `Tab`, `Escape`, `BSpace` (backspace).
#### Create workspaces, panes, splits
```
cmux action="new-workspace" args=["--cwd", "/path/to/project"]
cmux action="new-split" args=["right"]
cmux action="new-split" args=["down", "--workspace", "workspace:1"]
cmux action="new-pane" args=["--type", "terminal", "--direction", "right"]
cmux action="new-pane" args=["--type", "browser", "--url", "http://localhost:3000"]
```
Split directions: `left`, `right`, `up`, `down`.
#### Navigate and manage
```
cmux action="select-workspace" args=["--workspace", "workspace:3"]
cmux action="rename-workspace" args=["--workspace", "workspace:3", "🚢 Course Builder Deploys"]
cmux action="focus-pane" args=["--pane", "pane:2"]
cmux action="close-surface" args=["--surface", "surface:5"]
cmux action="close-workspace" args=["--workspace", "workspace:4"]
```
### `cmux_status` — Sidebar Status, Progress, and Logs
Control the cmux sidebar for the current workspace. In `cmux ssh` remote relay mode, current stable cmux may support notifications and remote status but not sidebar mutation commands (`set-status`, `set-progress`, `log`). If unsupported, the tool returns a clear error and lifecycle status writes no-op instead of failing the Pi session. Use `cmux action="diagnose"` first when local/remote behavior looks odd.
#### Status entries
```
cmux_status action="set-status" key="build" value="Compiling..." icon="hammer.fill" color="#FF9500" priority=10
cmux_status action="set-status" key="tests" value="14/20 passing" icon="checkmark.circle" color="#34C759" priority=10
cmux_status action="clear-status" key="build"
cmux_status action="sidebar-state"
```
Icons are SF Symbol names. Common ones:
- `bolt.fill` — running/active
- `pause.circle.fill` — idle/paused
- `checkmark.circle` — success
- `xmark.circle` — error/failure
- `hammer.fill` — building
- `magnifyingglass` — searching
- `arrow.down.circle` — downloading
- `bell.fill` — attention needed
- `circle.dashed` — pending
Colors are hex: `#4C8DFF` (blue), `#34C759` (green), `#FF3B30` (red), `#FF9500` (orange), `#8E8E93` (gray).
`priority` controls sidebar ordering. Higher appears first; use negative priority for low-priority background rows.
#### Progress bar
```
cmux_status action="set-progress" value="0.45" label="Deploying..."
cmux_status action="set-progress" value="1.0" label="Complete"
cmux_status action="clear-progress"
```
Value is 0.0 to 1.0.
#### Log entries
```
cmux_status action="log" value="Build started" level="info"
cmux_status action="log" value="Test failed: auth.test.ts" level="error"
cmux_status action="log" value="Deprecated API usage" level="warn"
cmux_status action="clear-log"
```
### `cmux_notify` — Native Notifications
Send macOS notifications via cmux. Appears in Notification Center.
```
cmux_notify title="Build Complete" body="All 47 tests passing" subtitle="my-project"
cmux_notify title="Deploy Failed" body="Error: connection timeout on staging"
cmux_notify title="pi" body="Task finished — ready for review"
```
## Common Patterns
### Check what's running in another workspace
```
# 1. Find the workspace
cmux action="tree"
# 2. Read its screen
cmux action="read-screen" args=["--workspace", "workspace:2", "--lines", "30"]
```
### Run a command in another terminal and check output
```
# Send the command
cmux action="send" args=["--surface", "surface:1", "npm test 2>&1\n"]
# Wait a moment, then read the result
cmux action="read-screen" args=["--surface", "surface:1", "--lines", "50"]
```
### Multi-workspace orchestration
```
# Create a new workspace for the task
cmux action="new-workspace" args=["--cwd", "/path/to/project"]
# Split it for parallel work
cmux action="new-split" args=["right"]
# Run frontend in one pane, backend in the other
cmux action="send" args=["--surface", "surface:7", "npm run dev\n"]
cmux action="send" args=["--surface", "surface:8", "npm run api\n"]
# Show progress
cmux_status action="set-progress" value="0.5" label="Starting services..."
# Open browser to preview
cmux action="new-pane" args=["--type", "browser", "--url", "http://localhost:3000"]
```
### Long task with progress tracking
```
# Set status at start
cmux_status action="set-status" key="task" value="Processing..." icon="bolt.fill" color="#4C8DFF"
cmux_status action="set-progress" value="0.0" label="Step 1/5"
# Update as you go
cmux_status action="set-progress" value="0.4" label="Step 3/5"
cmux_status action="log" value="Completed migration step 3"
# Finish
cmux_status action="set-progress" value="1.0" label="Done"
cmux_status action="set-status" key="task" value="Complete" icon="checkmark.circle" color="#34C759"
cmux_notify title="Task Complete" body="All 5 steps finished successfully"
# Clean up
cmux_status action="clear-progress"
cmux_status action="clear-status" key="task"
```
### Open a browser pane for preview
```
cmux action="new-pane" args=["--type", "browser", "--url", "http://localhost:3000"]
```
## Automatic Lifecycle Status
The cmux extension automatically manages Pi sidebar metadata:
- `pi_model` — current provider/model/thinking level
- `pi_usage` — context usage, token totals, and cost
- pane stack rows — active cmux panes/surfaces, with the running Pi pane annotated
- lifecycle status — Idle/Running/Needs input shown on the active pane row
| Pi Event | Sidebar Status | Icon | Color | Tab Indicator |
|----------|---------------|------|-------|---------------|
| Session start | Idle + session name (if resuming) | `pause.circle.fill` / `text.bubble` | gray | mark-read, clear notifications |
| Agent starts working | Running | `bolt.fill` | blue | mark-read, clear notifications |
| Tool execution | Live activity (e.g. "Reading ~/.zshrc") | `bolt.fill` | blue | — |
| Agent turn complete | Needs input + turn summary | `bell.fill` | blue | **mark-unread** + notification |
| Session shutdown | *all cleared* | — | — | mark-read, clear notifications |
Session naming is opt-in via `PI_CMUX_SESSION_NAMING=1`. When enabled, the session name appears as a sidebar status entry — the workspace label is never modified by the extension and is left to the operator.
**Live tool activity**: Every tool execution updates the active pane row with what pi is doing (e.g. "Reading ~/.zshrc", "Running grep", "Editing auth.ts"). This is always on and visible from other workspaces — useful for monitoring pi while focused elsewhere.
**Attention cycle**: When the agent finishes a turn, the workspace tab is marked unread (lights up) and a cmux notification fires. When the user provides input and the agent starts working again, the tab is marked read and notifications are cleared. This gives a clean read/unread signal across workspaces.
## Allowed Actions
The `cmux` tool allows these actions: `tree`, `identify`, `list-workspaces`, `current-workspace`, `read-screen`, `send`, `send-key`, `new-workspace`, `new-split`, `new-pane`, `new-surface`, `select-workspace`, `close-surface`, `close-workspace`, `list-panes`, `list-pane-surfaces`, `focus-pane`, `rename-workspace`, `surface-health`.
For browser control, use `new-pane` with `--type browser` to create browser surfaces. For advanced browser automation, use the `agent-browser` skill or `cmux browser` subcommands via bash.
## Extension Safety: Fork-Bomb Prevention
The cmux extension spawns helper `pi -p` subprocesses for session naming and turn summaries. Without proper guards, each child process loads the cmux extension again, fires the same hooks, and spawns another child — exponential process explosion.
**Three-layer defense (all required):**
View on GitHub