feat(tmux): add TMUX agent-cockpit skill — CMUX parity on Linux and any SSH host - #1658
feat(tmux): add TMUX agent-cockpit skill — CMUX parity on Linux and any SSH host#1658elhoim wants to merge 1 commit into
Conversation
…ny SSH host CMUX is a macOS GUI app and its own SKILL.md says the Linux path is tmux. That path was never built. This is it: same subcommand surface, same recipes, different substrate. Parity: 13 of 16 CMUX capabilities full or better, 2 degraded, 1 absent. Degraded are flash and per-team colour identity, which become display-message plus bell plus border styling rather than GUI chrome. Absent is the in-app browser pane, which tmux has no object for. All three are stated in SKILL.md rather than quietly omitted. Three things tmux does that CMUX cannot: sessions survive disconnection, pane_dead_status gives real exit codes so a crash is distinguishable from a finish, and -F templates return structured topology instead of the regex scraping cmux.ts needs to recover refs from stdout. Every gotcha in SKILL.md was measured on tmux 3.6, several of them after they broke a first attempt: - newlines execute regardless of send mechanism (send-keys and all four paste-buffer variants), so the wrapper validates the payload rather than trusting the transport - -t prefix-matches, so kill-session -t production destroys production-work; teardown is ID-only with a server-generation token - remain-on-exit is a window option and the session-scoped form silently no-ops, taking pane_dead and the exit status with it - capture-pane -S -N is a scrollback offset, not a line count - select-layout tiled ignores the requested grid (1x5 and 5x1 both give 3x2) - naive successive splits fail with 'no space' around 7 panes Verified by a 25-case parity suite against a real server, including the anti-tests: multi-line send refused for the right reason, teardown refusing a prefix name while the neighbouring session survives, and a dead pane retaining exit status 7.
|
Declining this one, and I want to give you the real reason rather than a vague one. The gap you identified is genuine — CMUX says outright that Linux/WSL "is tmux," so there's nothing to argue with there. And the work is substantial and clearly careful. The problem is 2,653 lines of a capability that can't be dogfooded or tested on the machine this project is developed and verified on. Everything LifeOS ships gets exercised daily here; this wouldn't be. Shipping a large surface to every user that nobody upstream can exercise is a maintenance liability we'd be taking on permanently, and "it touches nothing existing" isn't enough on its own to justify it. That's a judgment about what we can responsibly maintain, not about the quality of your work. It lives better as your own skill — installable by anyone who wants it, maintained by someone who actually runs it. |
What this is
CMUXgives LifeOS a scriptable agent cockpit, and it is macOS-only. Its own SKILL.md says where the gap is: "No Linux/WSL — that path is tmux." That path was never built. This is it — same subcommand surface, same recipes, different substrate, so the two skills read alike and muscle memory transfers.Parity with CMUX
13 of 16 capabilities full or better, 2 degraded, 1 absent. The gaps are stated in SKILL.md rather than quietly omitted:
flashand per-team colour identity becomedisplay-message+ terminal bell + border styling instead of GUI chrome, and none of it reaches a detached client.monitor's voice notification through Pulse is the attention mechanism that actually works headless.Three capabilities tmux adds that CMUX cannot do at all: sessions survive disconnection,
#{pane_dead_status}gives real exit codes so a crashed agent is distinguishable from a finished one, and-Ftemplates return structured topology instead of the ~30 lines of regex incmux.tsthat try to recover object refs from human-readable stdout.Gotchas, all measured
Several of these were found because they broke a first attempt. They are in SKILL.md because the next person will hit them too.
send-keys -land all fourpaste-buffervariants ran the payload--enterwas passed. Nothing here claims paste-buffer is safe.-tresolves exact → fnmatch → unambiguous prefixkill-session -t productiondestroysproduction-work, exit 0, no warning. Teardown is ID-only, with a server-generation token so a stale ID cannot retarget after a restart.remain-on-exitis a window option; the session-scoped form silently no-ops-w, an exited pane is destroyed and the exit status goes with it — a crashed agent leaves no evidence.capture-pane -S -Nis a scrollback offset, not a line count-S -and takes the last N.select-layout tiledignores the requested grid1x5and5x1both produce 3×2. Grids are built by explicit row/column splits and the geometry is verified.no space for new panearound 7 panes. Splits the lead each time and re-appliesmain-vertical.pane_current_commandresolves one levelbash run.shreportsbash, so "back to a shell" is a false finish signal.monitorlayers signals and labels the weak one low-confidence in its JSON.-ghooks/options reach sessions you never createdset-hook -gucleanup strips the operator's own. Everything is session-scoped.Verification
A 25-case parity suite against a real tmux 3.6 server, on a private
-Lsocket. 25 passed, 0 failed, including the cases that break naive implementations:The refusal assertions check the reason, not just
ok:false— an earlier version of the suite passed those cases because the command had errored for an unrelated reason, which is exactly the false green this skill is meant to prevent.Tools/Tmux.tstype-checks clean underbun build --target bun. Public-clean grep for identity, home paths and hostnames returns zero matches; remote hosts come fromUSER/CUSTOMIZATIONS/SKILLS/TMUX/fleet.json.Scope note
This does not replace the built-in split-pane teammates.
teammateMode(in-process|auto|tmux|iterm2) already gives visible teammate panes when the leader is running inside tmux, and those teammates inherit the lead's permission mode with prompts bubbling up for approval. This skill is for what that cannot serve: a leader with no attached terminal, work that must outlive the connection, non-Claude processes, and TUIs with no API. SKILL.md states plainly that an agent started by typingclaude ...into a pane is a sibling process outside the session's permission envelope.