with one click
cmux-steer
Read and steer another cmux terminal tab through the Unix socket.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Read and steer another cmux terminal tab through the Unix socket.
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Token-efficient second opinion slash command /advice. Extracts decision point + artifact (≤150 lines), then fans out in parallel: (1) Opus subagent reviewer with fallback chain codex→agy→cursor, (2) /research on the decision topic, (3) /secondo multi-model opinion. Use instead of advisor() which ships the full conversation uncached.
Lazy senior-dev mode — the seven-rung ladder that decides whether to write code at all, whether to reuse code that already exists, and whether to prefer stdlib/platform/installed deps over a new dependency. Use before writing any code, every PR diff, every fix, every feature. Source attribution included.
Use when making any "X is enabled" / "feature X works" / "cache works" claim in a running session — requires runtime probe output from the standard harness startup path, NOT a launchd/cron test that explicitly sets the activation env var.
Pre-flight checklist for self-hosted runner failures. Use when investigating low disk, missing runner, or stuck Green Gate on the jleechanorg/worldarchitect.ai fleet. Always verifies host-level container state, not just GitHub API.
When asked to verify whether a Claude Code feature works (especially slash commands, dialogs, pickers, status indicators), spawn a real interactive TUI session in cmux — never use `claude --print "/feature"` as a test, because --print is non-interactive and will always return "isn't available in this environment" regardless of whether the feature actually works.
Read ~/.hermes/agent-orchestrator.yaml BEFORE declaring an --agent <X> value unsupported. Lists plugin shorthands (wafer, minimax, agy).
| name | cmux-steer |
| description | Read and steer another cmux terminal tab through the Unix socket. |
REQUIRED (2026-06-09): This skill is deprecated for runtime steering. The bare
cmux send+cmux send-key enterpattern documented here does NOT include proof of submission. Use the canonical wrapper instead:python3 -c "from cmux_client import send_and_submit; print(send_and_submit('workspace:N', 'surface:M', 'text'))"and include the returnedproof+proof_tsin your reply. See~/.hermes_prod/skills/cmux-send-submit/SKILL.md. This skill is preserved for socket read operations (workspace.list,surface.read_text,tree,system.ping) only.
Usage: Read and follow this skill directly; no /cmux-steer slash command is defined.
Purpose: Read and steer another agent's terminal pane (e.g. a coding agent) from within cmux, without disrupting the user's active workspace navigation.
# Release build
SOCK="$HOME/Library/Application Support/cmux/cmux.sock"
# Dev builds — find via saved path files or lsof:
cat ~/Library/Application\ Support/cmux/dev-may-18-last-socket-path
# → /tmp/cmux-debug-may-18.sock
lsof -p $(pgrep -f "cmux DEV may-18") | grep -E "\.sock"
# Use CMUX_SOCKET_PATH to target a specific build with the CLI:
CMUX_SOCKET_PATH=/tmp/cmux-debug-may-18.sock cmux list-workspaces
The user can switch workspaces at any time, shifting surface indices. Never hardcode an index. Always look up by the workspace's display name:
# List all workspaces with names
printf "list_workspaces\n" | nc -U $SOCK
# Example output:
# 0: D267DC10-... cmux: ubuntu
# * 1: 9075D919-... exp: statusline ← user is here; doesn't matter
# 2: 258EB4B4-... o: mctrl
# Find target workspace UUID by name
WS_UUID=$(printf "list_workspaces\n" | nc -U $SOCK \
| grep "cmux: ubuntu" | grep -oE '[A-F0-9-]{36}')
# List surfaces in that workspace
printf "list_surfaces $WS_UUID\n" | nc -U $SOCK
# Output:
# * 0: 87DB76A9-... supervisor (cmux)
# 1: F05FCE84-... cmux_coder
# Extract coder surface UUID by label (never by index — indices shift)
CODER_UUID=$(printf "list_surfaces $WS_UUID\n" | nc -U $SOCK \
| grep "cmux_coder" | grep -oE '[A-F0-9-]{36}')
The plain-text send_surface command FAILS cross-workspace. Always use the JSON API:
| Method | Cross-workspace? | Notes |
|---|---|---|
surface.send_text (JSON) | ✅ always works | Include \n in text for enter |
send_surface (plain text) | ❌ fails cross-workspace | Only works if workspace is selected |
read_screen | ❌ current workspace only | Use index, not UUID |
# Single command: type + enter (append \n to submit)
printf '{"method":"surface.send_text","params":{"surface_id":"'"$CODER_UUID"'","text":"your instruction here\\n"}}\n' | nc -U $SOCK
This works from any workspace without switching focus. The \n at end acts as Enter.
# Send a harmless probe — if queued=false and ok=true, surface accepted input
result=$(printf '{"method":"surface.send_text","params":{"surface_id":"'"$CODER_UUID"'","text":""}}\n' | nc -U $SOCK)
# Check result.ok and result.queued
# Create workspace
printf '{"method":"workspace.create","params":{"title":"my-workspace"}}\n' | nc -U $SOCK
# Returns workspace_id
# Rename workspace
printf '{"method":"workspace.rename","params":{"workspace_id":"UUID","title":"new name"}}\n' | nc -U $SOCK
# Add a second tab/surface
printf '{"method":"surface.create","params":{"workspace_id":"UUID"}}\n' | nc -U $SOCK
# Returns surface_id
For key combos, fall back to plain text protocol (requires workspace focus):
printf "send_key_surface $CODER_UUID ctrl-c\n" | nc -U $SOCK
printf "send_key_surface $CODER_UUID ctrl-a\n" | nc -U $SOCK
printf "send_key_surface $CODER_UUID ctrl-k\n" | nc -U $SOCK
Available: ctrl-c, ctrl-d, enter, tab, escape, up, down, left, right
read_screen requires a surface index (not UUID) and only works when the target is in the user's currently focused workspace. Obtain the index from list_surfaces output (e.g. 1: F05FCE84-... cmux_coder → index is 1).
# IDX = index from list_surfaces for the focused workspace (replace with actual value)
IDX=1
printf "read_screen $IDX --lines 40\n" | nc -U $SOCK
printf "read_screen $IDX --lines 80 --scrollback\n" | nc -U $SOCK
If the user is in a different workspace, infer state from the filesystem instead:
cd /path/to/project && git log --oneline -5
ls -lt src/ # recently modified files
SOCK="/tmp/cmux-debug-appclick.sock"
# 1. Find coder surface by workspace name
WS_UUID=$(printf "list_workspaces\n" | nc -U $SOCK \
| grep "cmux: ubuntu" | grep -oE '[A-F0-9-]{36}')
CODER_UUID=$(printf "list_surfaces $WS_UUID\n" | nc -U $SOCK \
| grep "cmux_coder" | grep -oE '[A-F0-9-]{36}')
# 2. Send task headlessly (no workspace switch needed)
printf '{"method":"surface.send_text","params":{"surface_id":"'"$CODER_UUID"'","text":"cargo build && cargo test\\n"}}\n' | nc -U $SOCK
# 3. Monitor progress via filesystem (no read_screen needed)
sleep 30
cd /path/to/project && git log --oneline -3
SOCK="/tmp/cmux-debug-appclick.sock"
# Create workspace
WS=$(printf '{"method":"workspace.create","params":{"title":"my-test"}}\n' | nc -U $SOCK \
| python3 -c "import sys,json; print(json.loads(sys.stdin.read())['result']['workspace_id'])")
# Rename it
printf '{"method":"workspace.rename","params":{"workspace_id":"'"$WS"'","title":"test: a/b"}}\n' | nc -U $SOCK
# Add second tab
TAB2=$(printf '{"method":"surface.create","params":{"workspace_id":"'"$WS"'"}}\n' | nc -U $SOCK \
| python3 -c "import sys,json; print(json.loads(sys.stdin.read())['result']['surface_id'])")
# Get first tab
TAB1=$(printf "list_surfaces $WS\n" | nc -U $SOCK | grep "0:" | grep -oE '[A-F0-9-]{36}')
# Send commands to both tabs headlessly
printf '{"method":"surface.send_text","params":{"surface_id":"'"$TAB1"'","text":"echo tab1\\n"}}\n' | nc -U $SOCK
printf '{"method":"surface.send_text","params":{"surface_id":"'"$TAB2"'","text":"echo tab2\\n"}}\n' | nc -U $SOCK
select_workspace — it switches the user's visible workspace.list_workspaces → grep name → get UUID).surface.send_text works headlessly cross-workspace.\n to text — acts as Enter key submission.read_screen requires being in the right workspace; use git/filesystem for cross-workspace monitoring.workspace.create + surface.create for multi-tab setups.