name: boss-cmux description: Drive cmux — the terminal multiplexer / agent-surface control CLI — from natural language. Use this whenever a prompt asks you to open, inspect, prompt, read, or tear down cmux windows, workspaces, panes, surfaces, or agent sessions. Prefix orchestration prompts with /boss-cmux. argument-hint: "[what to do in cmux]" allowed-tools: Bash
boss-cmux
Purpose
You are driving cmux, a CLI + socket for controlling terminal surfaces (and the agents running inside them). Every window, workspace, pane, and surface is a real, addressable object you can spawn, prompt, read, and close from the command line.
Prerequisites
cmux is a native macOS terminal (built on Ghostty) distributed as a Homebrew cask. The skill triggers anywhere, but only functions on a Mac with cmux installed.
- Install:
brew tap manaflow-ai/cmux && brew install --cask cmux(macOS 14+ Sonoma). Validated against cmux0.64.17. - CLI on PATH (optional): so
cmuxworks outside the app,sudo ln -sf "/Applications/cmux.app/Contents/Resources/bin/cmux" /usr/local/bin/cmux. - Notification hooks: run
cmux hooks setuponce sopi/codex/geminiemit a turn-stop event you can wait on (see Wait for agents via notification events). Claude Code has no such hook — cmux instead bridges Claude's own model-initiatedPushNotificationtool call, which only fires if the model decides to call it (see the caveat under Wait for agents via notification events). - Socket control (orchestrator outside cmux): set
automation.socketControlModetoallowAll(or password) in~/.config/cmux/cmux.jsonso an orchestrator running in a plain terminal can drive the socket. The socket lives at~/.local/state/cmux/cmux.sock(CMUX_SOCKET_PATH). Enabling this is a genuine security surface (any local process can then drive the app) — confirm with the user before flipping it, the way you would for any other risky config change.- Reload bootstrap problem: if the app is currently
cmuxOnlyand you edit the file toallowAll,cmux reload-config(and every other socket command) still fails withFailed to write to socket (Broken pipe, errno 32)until the running app re-reads the file — butreload-configitself needs socket access, so the CLI can't bootstrap its own permission change. There's no signal-based or file-watch reload from outside; ask the user to reload manually inside the app (⌘⇧, / "reload configuration") or quit and reopen cmux, then retry.
- Reload bootstrap problem: if the app is currently
- Editing cmux settings safely:
cmux docs settingsprints the schema/paths. Before editing~/.config/cmux/cmux.json, copy it to a timestamped.bakbeside it so the user can revert; after editing, runcmux reload-config(reloads bothcmux.jsonand Ghostty's~/.config/ghostty/configin place — no app restart). App behavior (sidebar, notifications, automation, workspace colors, cmux shortcuts) lives incmux.json; terminal rendering (font, cursor, theme, scrollback,background-opacity,background-blur) belongs in the Ghostty config.
Only the repo-local skill is required to drive cmux. For the deeper published skill set
(browser automation, settings, diagnostics, markdown viewer, etc.) install the vendor
skills globally: npx skills add manaflow-ai/cmux -g -y.
This skill installs as
agent-harness:boss-cmux. If you alsonpx skills addthe vendorcmuxskill globally, the namespaces keep them distinct.
Instructions
Discover commands first (--help)
Before doing anything, run:
cmux --help
Then drill into any subcommand you intend to use:
cmux <command> --help # e.g. cmux workspace --help, cmux send --help
cmux evolves; trust --help over memory. Never guess flags — confirm them.
Understand the hierarchy
Everything nests in one tree. Learn the boxes and the verbs fall out:
- Window → a top-level OS window.
- Workspace → a sidebar entry ("tab") inside a window.
- Pane → a split region within a workspace.
- Surface → a tab within a pane (a terminal or a browser).
Use cmux tree --all (or cmux workspace list / cmux list-pane-surfaces) to see
the current state before you act.
Create a workspace and inject credentials (--env-file)
Create a workspace and capture BOTH refs in one call. --json returns the
workspace_ref and the initial surface_ref — grab and thread them; never guess
positional refs.
cmux workspace create --name <name> --cwd <dir> --env-file .env --json
-
cmux workspace createsupports--env-file, which loads that file's environment variables into every surface in the workspace — so an agent launched in a pane (claude,pi,codex,gemini) comes up already authenticated, no manualexportneeded. -
Default
--env-fileto.env(the repo's.env) unless told otherwise:--env-file .env. That is the canonical source forOPENROUTER_API_KEY,ANTHROPIC_API_KEY, etc. -
Pair it with
--layout <compact-json>to boot a whole multi-pane team declaratively in one call (each pane'scommandauto-launches its agent). -
Don't inject over a working login. If an agent is already authenticated (e.g. Claude Code), don't push a placeholder key over it via
--env-file; scope credential injection to the agents that actually need it. -
Assume the keys are already set up — and never read their values. By default, just point
--env-fileat.envand proceed; do notcat .env,echo $OPENROUTER_API_KEY, orread-screena surface to capture a key. Only if an agent actually fails to authenticate should you validate, and do it safely:cmux workspace env --workspace <ref> --maskshows that a var is present without revealing it, and[ -n "$VAR" ]confirms it is non-empty. Report the masked/presence result, never the secret itself. -
Subscribe to events immediately, before sending any prompt. The
--jsonoutput gives you the workspace'sworkspace_idright away — start thecmux eventslistener for it in the background now, not when you're about to wait on an agent. Late subscription is how you miss a turn-done signal:WS=<workspace_id from --json> cmux events --name notification.requested --no-heartbeat --no-ack > /tmp/cmux-$WS.ev &See Wait for agents via notification events below for the full pattern — including why Claude Code needs a different completion signal than pi/codex/gemini.
The control loop
You operate surfaces the way a person would, but over the CLI:
cmux send --surface <ref> "<text>"— type text into a surface.cmux send-key --surface <ref> enter— submit it (press a key).sendtypes;send-keysubmits — they are separate steps.cmux read-screen --surface <ref>— read what's on screen (add--scrollbackfor history). This is your eyes.cmux close-surface --surface <ref>— end a surface cleanly.
Wait for agents via notification events (don't busy-poll) — pi/codex/gemini only
Instead of looping on read-screen, subscribe to cmux's push channel and block
until an agent finishes its turn. This is deterministic for pi and codex — read
the next section before relying on it for Claude Code.
cmux events is the wait channel — not cmux wait-for. cmux wait-for <name>
is an unrelated named-token rendezvous (a manual semaphore you signal yourself);
it does not know when an agent finishes. The agent-completion signal is the
notification event category.
Prerequisite — install the notification hooks once:
cmux hooks setup # installs for every supported agent found on PATH
cmux hooks setup <agent> # or: cmux hooks setup --agent <agent>
cmux hooks <agent> install --yes # (re)install one agent's integration directly
cmux hooks <agent> uninstall --yes # remove one agent's integration
Supported agent names: codex, grok, opencode, pi, omp, amp, cursor,
gemini, kimi, kiro, rovodev (or rovo), copilot, codebuddy, factory,
qoder. These agents get a hook that fires deterministically on every turn-stop.
cmux hooks setup silently skips any agent whose binary isn't on PATH — if an
agent you expect to notify stays silent, don't assume setup already covered it; run
cmux hooks <agent> install --yes to (re)install that one agent directly (this is also
the fix if a hook install goes stale — uninstall first if you're about to hand-edit its
generated config file). Without a working hook, an agent stays silent and you're back
to polling. Claude Code is not in this list and is not covered by cmux hooks setup — see the next section. Full per-agent integration matrix (installed files,
session-restore command, Feed bridge):
https://github.com/manaflow-ai/cmux/blob/main/docs/agent-hooks.md
What an agent emits when its turn ends — one event per completed turn:
{ "name": "notification.requested", "category": "notification",
"workspace_id": "120FC732-…", "surface_id": null, "seq": 1512, … }
Match on workspace_id — for hook-emitted notifications surface_id is usually
null, but workspace_id is always set. The title/body are redacted in the
event (you get the signal, not the text), so once it fires, read-screen that
workspace's surface for the actual reply. Filter to --name notification.requested;
a sibling notification.clear_requested fires when a surface gains focus and is just
noise.
Block until a specific agent finishes (capture its workspace_id first via
cmux list-workspaces --json --id-format both) — you should already have this
listener running from Create a workspace above, started before the first prompt:
WS=<agent-workspace-uuid>
# Listener already started at workspace-creation time (see above). If not, start it now,
# BEFORE sending the prompt:
cmux events --name notification.requested --no-heartbeat --no-ack > /tmp/cmux.ev &
EV=$!
cmux send --surface <ref> "<task>"; cmux send-key --surface <ref> enter
# wait (bounded) for this workspace's turn-done event
until grep -q "\"workspace_id\":\"$WS\"" /tmp/cmux.ev; do sleep 1; done
kill $EV
cmux read-screen --surface <ref> --scrollback --lines 40 # now read the reply
Pitfall: a cmux events | jq … & pipeline in a one-liner can stall on stdout
buffering — stream to a file and poll the file (above), or pass
jq --unbuffered. For a durable cursor across reconnects use
cmux events --cursor-file <path> --reconnect.
Claude Code: use a completion marker, not the notification event
Claude Code has no deterministic turn-stop hook like pi/codex/gemini, so
cmux hooks setup doesn't cover it. Instead, cmux bridges Claude's own
model-initiated PushNotification tool call through a PostToolUse hook into a cmux
notification — see cmux's agent-hooks.md.
That means a notification only appears if both are true: "Claude Code
integration" is enabled in cmux's app Settings, and the model itself decides to
call PushNotification during that turn. A scripted, task-oriented sub-agent that's
never told to proactively "notify the user" typically never calls it — so
cmux events shows heartbeats only, with no notification.requested ever arriving.
That's expected behavior, not a broken integration — don't spend time debugging hooks
setup for it.
Default to a printed completion marker for Claude Code — the same contract
agent-harness:boss-cmux-team already uses for its workers:
-
Tell the agent, in its prompt, to end with one distinctive line when truly done, e.g.
TASK-DONE: <summary>. -
Poll
read-screenfor that marker on a bounded loop (still fine to race it against the notification listener as a free early exit — just don't make the loop's exit condition depend on the notification alone):for i in $(seq 1 60); do cmux read-screen --surface <ref> --lines 5 | grep -q "TASK-DONE:" && break sleep 5 done cmux read-screen --surface <ref> --scrollback --lines 40 -
If the marker never appears within the bound, treat it as "possibly slow, or the model never got to it," not "cmux is broken" —
read-screento see what's actually on screen before deciding.
Separately: a Claude Code notification, when it does fire, still doesn't mean the task succeeded — see the caveat under Launching Claude Code below.
Launching the pi agent
pi is an interactive TUI agent — launch it as pi --model … "<task>".
- Launch it inside a pane (via
cmux send+send-key enter), not from your own non-interactive/batch shell.
Launching Codex — run it in yolo / auto mode
When launching Codex in a pane, start it unattended so it doesn't stall on approval prompts (it's running inside cmux, driven by an orchestrator). Pass the flag at launch — do not edit Codex's global config:
- Yolo (full, no sandbox):
codex --dangerously-bypass-approvals-and-sandbox "<task>"— skips every approval prompt and the sandbox. Use only because the run is orchestrated/observed. - Auto (sandboxed):
codex --full-auto "<task>"— automatic execution inside a workspace-write sandbox; safer when full access isn't needed.
Default to yolo for hands-off fleet runs; reach for --full-auto when you want a
sandbox. These are per-launch flags, so they never change the user's global Codex setup.
Always launch Codex with the gpt-5.5 model unless a prompt specifies otherwise —
pass -m gpt-5.5 at launch, e.g. codex -m gpt-5.5 --dangerously-bypass-approvals-and-sandbox "<task>".
If a prompt names a different Codex model/effort, use that instead; gpt-5.5 is just the default.
Launching Claude Code — use cc bypass mode
Plain claude launches in ask-for-permission mode: it will decline to run
Bash/edits and instead print instructions, then end its turn. For a hands-off fleet
agent, launch it the same way you yolo Codex — bypass permissions at launch:
- cc bypass:
claude --dangerously-skip-permissions "<task>"— Claude's equivalent of Codex yolo. The composer then shows⏵⏵ bypass permissions onand it executes shell/edits without prompting. (--dangerously-skip-permissionsis a per-launch flag; it doesn't change global Claude settings.)
Caveat verified in testing: on the rare turn where a Claude Code notification does
fire, it fires on turn-completion even when Claude refused to do the work — so if
you only watch events, you can mistake a "declined, nothing happened" turn for success.
Always read-screen (or check the artifacts), don't trust the event alone. More
fundamentally, Claude Code's cmux notification is bridged from a model-initiated
PushNotification tool call, not a deterministic turn-stop hook, so most turns emit no
notification at all — default to the completion-marker pattern instead; see
Claude Code: use a completion marker, not the notification event above.
Best practices
--helpbefore every unfamiliar verb. Confirm the subcommand and flags exist.- Look before you leap. Inspect with
tree/list/read-screenbefore sending or closing anything. - Refs are positional and renumber.
surface:N/workspace:Nshift as things open and close. Re-read the tree right before you act; for anything long-lived, anchor to a stable window UUID, not a positional ref. - Type then submit. A prompt isn't sent until you
send-key enter. Give agents a beat before youread-screentheir reply. - Read back to verify. After sending a command,
read-screento confirm it actually ran and got the result you expected — don't assume. - Close scoped, never broad. Close only surfaces you just created or explicitly identified. Never loop a close over the whole
tree— you'll kill things you didn't mean to.close/close-windowmay no-op while a live agent occupies a pane; useclose-surfaceper pane. - One window per team. Keep a unit of work to a single window so it stays monitorable and tearable as a unit.
- Never print secrets. If a surface has credentials/keys loaded, read results back without echoing the secret values.
- Prefer push over poll for pi/codex/gemini; use a completion marker for Claude Code. Subscribe to
cmux events --category notificationthe instant the workspace is created (before the first prompt), matched onworkspace_id. This is a deterministic turn-stop signal for pi/codex/gemini (install hooks first:cmux hooks setup) — but Claude Code has no such hook, so default to the printed-marker pattern for it instead of waiting on the event (see Claude Code: use a completion marker, not the notification event).cmux wait-foris a manual named-token semaphore, not an agent-finished signal, for either case.
Workflows
Drive a surface end-to-end
The default loop for any single-surface task: discover, inspect, act, verify, report.
cmux --help(and per-subcommand--help) to confirm the verbs.- Inspect current state (
tree --all/workspace list). - Take the action (create / send + send-key / read).
- Read back to verify the result.
- Report concisely what happened, citing the surfaces/refs involved.
Topology & routing
Beyond the send/read/close control loop, cmux has a full set of placement verbs for
deterministic multi-pane layouts — move-surface, reorder-surface, split-off,
new-surface --type terminal|browser, focus-pane/focus-panel, surface-health,
and --id-format uuids|both for stable UUID output. Surface identity is stable across
move/reorder/split-off. See the deep-dive references below.
Note: some verbs come in two forms — a namespaced cmux workspace <verb> (e.g. workspace create, workspace list) used above, and flat aliases (new-workspace, list-workspaces,
select-workspace, close-workspace) used in the references. Both work; when in doubt,
confirm the exact spelling with --help (which is authoritative over either form here).
Deep-Dive References
| Reference | When to Use |
|-----------|-------------|
| references/handles-and-identify.md | Handle syntax, self-identify, caller targeting, --id-format output shaping |
| references/windows-workspaces.md | Window/workspace lifecycle and reorder/move |
| references/panes-surfaces.md | Splits, surfaces, move/reorder, focus routing |
| references/trigger-flash-and-health.md | Flash cue and surface health checks |
For team orchestration (spawn/orient/drive a multi-agent team), see the
agent-harness:boss-cmux-team skill.
Report Format
Report concisely in plain English: what you did, the surfaces/refs involved, and
what read-screen confirmed. Cite refs (e.g. workspace:2 / surface:3) and never
echo secret values.
Next.js App Router Expert
Development
A skill that turns Claude into a Next.js App Router expert.
README Generator
Development
Creates professional and comprehensive README.md files for your projects.
API Documentation Writer
Development
Generates comprehensive API documentation in OpenAPI/Swagger format.