skills/golem-powers/cmux/SKILL.md
Use when running inside cmux terminal to control panes, splits, browser, sidebar, and send agent-to-agent messages. Covers split panes, notifications, browser automation, terminal reads, delivery verification. NOT for: regular terminal operations (use Bash), non-cmux sessions, agent lifecycle management (use cmux-agents).
npx skillsauth add etanhey/golems cmuxInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Teach agents to drive cmux: split panes, notify, open browser, coordinate with other agents.
For agent workflows, prefer /cmux-agents and the agent-based MCP tools (spawn_agent, send_to_agent, wait_for, list_agents, my_agents, get_agent_state, stop_agent). This skill stays primitive-first on purpose: panes, tabs, browser surfaces, raw terminal delivery, and low-level inspection.
Always check first — skip gracefully if not in cmux:
if ! command -v cmux &>/dev/null || ! cmux identify --json &>/dev/null; then
echo "Not in cmux — skipping cmux operations"
exit 0
fi
# Get your own location
cmux identify --json
# → { "surface_ref": "surface:4", "pane_ref": "pane:5", "workspace_ref": "workspace:2" }
# Get your current surface/pane/workspace refs
cmux identify
# List all workspaces
cmux list-workspaces
# List panes in current workspace
cmux list-panes
# List surfaces (tabs) in a pane
cmux list-pane-surfaces --pane pane:1
# Split current surface left/right/up/down
cmux new-split right # adds a right split in current workspace
cmux new-split down
# Get the new surface ref after splitting
cmux list-pane-surfaces --pane pane:1
# Close a surface
cmux close-surface --surface surface:5
# New workspace (new sidebar tab)
cmux new-workspace
# Focus a workspace
cmux focus-pane --pane pane:2
# Rename the tab label
cmux rename-tab --surface surface:3 "🤖 Agent Name"
# Send text (as if typed) to a surface
cmux send --surface surface:3 "cd ~/Gits/golems && claude 'prompt here'\n"
# Send a single key
cmux send-key --surface surface:3 Return
# Note: \n at end of send = auto-press Enter to run
Compound commands can split across PTY buffer writes. Separate source and launch:
# SAFE: separate commands
cmux send --surface surface:N "source ~/.zshrc\n"
sleep 3
cmux send --surface surface:N "cd ~/Gits/repo && claude -s\n"
# UNSAFE: long compound — may corrupt shell parsing
# cmux send --surface surface:N "source ~/.zshrc && cd ~/Gits/repo && claude -s\n"
# Notification ring (tab lights up in sidebar)
cmux notify "Title" "Body text"
# Workspace-action for custom sidebar label
cmux workspace-action --action set-title --title "🤖 orcClaude"
# Open browser pane (splits alongside terminal)
cmux new-pane --type browser --direction right --url "http://localhost:3000"
# Navigate existing browser surface
cmux browser navigate "http://localhost:3000/new-page"
# Browser tab management
cmux browser tab new "https://docs.example.com"
cmux browser tab list
# Send text to another agent's surface
cmux send --surface surface:6 "STATUS: done with auth module, ready for review"
# Envelope format for deterministic messaging:
# [FROM=surface:A TO=surface:B TYPE=TYPE] key=val
cmux send --surface surface:6 \
"[FROM=surface:1 TO=surface:6 TYPE=TASK] repo=golems task=fix-tests"
# 1. Identify self
MY_SURFACE=$(cmux identify | jq -r '.caller.surface_ref')
MY_WS=$(cmux identify | jq -r '.caller.workspace_ref')
# 2. Spawn 3 splits, each running claude on different repos
for repo in brainlayer golems voicelayer; do
NEW_SURFACE=$(cmux new-split right --workspace "$MY_WS" | awk '{print $2}')
cmux rename-tab --surface "$NEW_SURFACE" "🤖 $repo"
sleep 0.5
cmux send --surface "$NEW_SURFACE" "cd ~/Gits/$repo && claude 'your task here'\n"
done
Future reference only — golem-terminal is not yet built.
These cmux patterns are the reference implementation for golem-terminal's UDS API. The golem-terminal equivalents:
| cmux | golem-terminal |
|------|---------------|
| cmux split | orchestrate.py split <slot> |
| cmux notify | HTTP POST localhost:3847/notify |
| cmux sidebar set | UDS status command |
| cmux send | UDS send_input command |
| cmux open-browser | Built into sidebar pane |
After ANY cmux restart, every lead VERIFIES before reporting worker liveness:
checkpoint → restart → VERIFY (list_agents + read_screen) → report from evidence
list_agents with read_screen scrollback on each worker you claim is alive.Full protocol: /cmux-agents Post-Restart Truth-vs-Display.
Delivery fields lie. boot_prompt_delivered, submit_verified, parsed working-status, and token_count are untrusted — seven post-#478 catches proved doc-only mitigation is insufficient (observer tallies vary 3/4/5/7; no canonical ledger; cure = cmuxlayer code fix D6).
Ground truth: prompt text in SCROLLBACK above the working line. Text after the › marker = unsubmitted.
Rules:
read_screen ≤15s after every dispatch.'Queued follow-up inputs' on a working worker → full scrollback read (anomaly).send_command (atomic) or send_input + verified status flip.Full doctrine: /cmux-agents Composer-Wedge Runtime Doctrine.
send_input returns ok:true even on frozen terminals. Never trust submit_verified or boot_prompt_delivered either — see Composer-Wedge doctrine above.
# Claude takes 8-15s to boot + MCP init
sleep 15
cmux read-screen --surface surface:N --lines 5
# "❯" with "0 tokens" → Claude ready, send prompt
# "zsh%" or bare shell prompt → Claude didn't start, retry launch
# Blank screen → wait longer, re-read in 5s
sleep 8
cmux read-screen --surface surface:N --lines 5
# Check: did token count jump? Is there new output?
# If token count SAME after 2 checks → terminal frozen → kill → new_split → resend
Stuck-state detection cheat sheet:
"Press up to edit queued messages" → STUCK — send Enter key to unblock"Twisting/Channelling + timer" → THINKING (verify with token count delta)"❯" prompt with 0 tokens → boot not complete, wait longer"zsh%" or bare shell prompt → agent didn't boot, retry launch command"tools not available" or "MCP connection failed" → MCP server down, don't proceedread_screen is terminal text inspection, not a screenshot. When Etan asks to see something or asks for a screenshot, use Computer Use screenshot and deliver the image. After interactive probes, screenshot proactively when the result is visual or user-facing.
Before pressing Enter in any TUI menu, verify the highlighted row first. Use Computer Use screenshot when the user needs to see the state; use read_screen only when the selected row is explicit in terminal text.
Default for agent monitoring: lines: 50, scrollback: true — NOT 15.
Bottom 15 lines = status bars and thinking indicators. Actual work (file edits, tool calls, decisions) is ABOVE the fold. Use 50+ lines to see what's really happening.
Exception: Post-send verification (checking token count jumped) → 5 lines is fine.
"Run /mcp, reconnect brainlayer, verify with brain_search('test')."/cmux-agents — visible worker spawning, spawn_agent / send_to_agent / wait_for lifecycle, and recovery protocols/orc — orchestration decisions, design iteration gates, collab protocolstools
The human-eval UX contract for Phoenix views: turn-by-turn scrollable replay (not a scorecard), hide-but-copyable IDs, collapsed thinking, identity chips, tool filters, tiny frozen starter datasets, mark-wrong-in-thread, mobile-first. Use when: building or reviewing ANY Phoenix/eval view, annotation UI, session replay, or human-grading surface. Triggers: phoenix view, eval UI, annotation view, session replay, human eval UX, grading interface. NOT for: Phoenix data pipelines/ingest (capture scripts have their own specs).
tools
macOS systems specialist — AppKit NSPanel architecture, launchd services, socket activation, MCP bridge resilience, syspolicyd, and high-frequency SwiftUI dashboards. Use when building menu-bar apps, LaunchAgents, debugging syspolicyd/Gatekeeper/TCC, resilient UDS/MCP bridges, or SwiftUI dashboards at 10Hz+.
development
Bulk LLM-judging protocol for fleet-dispatched verdict runs (KG cluster, eval harness). Use when: dispatching or running judge workers (J1/J2/RT), planning bulk-apply from verdict JSONL, or triaging evidence_degraded outputs. Triggers: judge fleet, bulk judge, R3 verdicts, kg-judge, RT gate, evidence_degraded. NOT for: single-item code review, Phoenix view UX (use phoenix-human-view), or non-judge eval pipelines.
development
Quiet-down protocol for sprint close: when the fleet wraps, delete ALL polling crons and monitors, send ONE final dashboard + ONE message, then go SILENT. Use when: fleet wraps, all workers done, overnight queue exhausted, sprint close, Etan asleep/away with nothing approved left. Triggers: fleet wrap, wrap the fleet, stand down, going quiet, sprint close. NOT for: mid-sprint monitoring (keep your loops), spawning a successor (use /session-handoff first).