Now liveThe Skillselion MCP - thousands of ranked skills, loaded into your agent mid-task. No install.Get it →
joelhooks avatar

Pi Cmux

  • 2 installs
  • 11 repo stars
  • Updated August 4, 2026
  • joelhooks/pi-cmux

Control the cmux terminal multiplexer from pi: read other panes, send commands, split panes, set sidebar status, notify, and open browser surfaces.

About

Controls the cmux terminal multiplexer from pi to read other terminals, send commands, manage panes, and set sidebar status. A developer uses it to orchestrate multi-workspace terminal workflows.

  • Three extension tools (cmux, cmux_status, cmux_notify) plus auto-managed sidebar status
  • Read other panes' screens, send commands, split panes, and open browser surfaces

Pi Cmux by the numbers

  • 2 all-time installs (skills.sh)
  • Ranked #445 of 550 CLI & Terminal skills by installs in the Skillselion catalog
  • Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/joelhooks/pi-cmux --skill pi-cmux

Add your badge

Show developers this skill is listed on Skillselion. Paste this into your README.

Listed on Skillselion
Installs2
repo stars11
Last updatedAugust 4, 2026
Repositoryjoelhooks/pi-cmux

What it does

Control the cmux terminal multiplexer from pi: read other panes, send commands, split panes, set sidebar status, notify, and open browser surfaces.

Files

SKILL.mdMarkdownGitHub ↗

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.

Concepts

Refs — cmux uses short refs to identify objects: workspace:1, pane:2, surface:3, window:1. Always run cmux tree first to discover current refs 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 every terminal it manages. Commands default to the caller's workspace/surface when flags are omitted.

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="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=["my-project"]
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.

Status entries
cmux_status action="set-status" key="build" value="Compiling..." icon="hammer.fill" color="#FF9500"
cmux_status action="set-status" key="tests" value="14/20 passing" icon="checkmark.circle" color="#34C759"
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).

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 a pi_agent sidebar status entry:

Pi EventSidebar StatusIconColorTab Indicator
Session startIdle + session name (if resuming)pause.circle.fill / text.bubblegraymark-read, clear notifications
Agent starts workingRunningbolt.fillbluemark-read, clear notifications
Tool executionLive activity (e.g. "Reading ~/.zshrc")bolt.fillblue
Agent turn completeNeeds input + turn summarybell.fillbluemark-unread + notification
Session shutdownall clearedmark-read, clear notifications

The session name appears as a sidebar status entry (key session) — the workspace label is never modified by the extension and is left to the operator.

Live tool activity: Every tool execution updates the sidebar status 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):

1. `--no-extensions` flag on every pi -p spawn — prevents the child from loading any extensions, including cmux itself. This is the critical flag; --no-tools/--no-skills alone are not enough.

2. `--no-session` flag — prevents the child from creating session files, which would compound the recursion with disk I/O.

3. `PI_CMUX_CHILD` env guard — the extension sets PI_CMUX_CHILD=1 in the child's environment and bails out at the top of cmuxExtension() if that var is set. Belt-and-suspenders defense in case --no-extensions is somehow bypassed.

// Top of extension — bail if we're a helper subprocess
if (process.env[CMUX_CHILD_ENV] === "1") return;

// Every pi subprocess spawn must include:
spawn("pi", [
  "-p",
  "--model", NAMING_MODEL,
  "--no-session",      // ← no session files
  "--no-extensions",   // ← THE critical flag — prevents self-recursion
  "--no-tools",
  "--no-skills",
  "--no-prompt-templates",
  "--system-prompt", "...",
], {
  env: { ...process.env, [CMUX_CHILD_ENV]: "1" },  // ← env guard
});

State resets on lifecycle events:

  • session_start: reset _pendingSessionName and _hasNamedSession
  • session_shutdown: reset both to prevent stale state across /continue sessions

Related skills

This week in AI coding

Five minutes, every Monday - the tools, releases and tactics for developers.

unsubscribe anytime.