fix(tmux): isolate sessions on a dedicated socket + raise pane nofile limit (fixes new-session crash after tmux upgrade)#96
Merged
Conversation
added 2 commits
May 25, 2026 20:14
Remove the per-session `tmuxSocket` field that recorded which tmux server
each session lived on (default vs the `codeman` socket). That field was a
persisted cache of physical reality and could drift — causing live sessions
to be wrongly marked dead ("tab shows no session found") and spawning
duplicate "Restored:" tabs.
All Codeman sessions now live on one process-wide socket (`tmux -L codeman`,
overridable via CODEMAN_TMUX_SOCKET), exposed via TmuxManager.muxSocket on
the TerminalMultiplexer interface. reconcileSessions() collapses from a
multi-socket scan (locate / re-pin / cross-socket dedup) to a single
`list-panes` query. loadSessions() strips the obsolete field from on-disk
records so it stops being written back.
Also fix two sibling bare-`tmux` call sites the unification would otherwise
leave broken (same Ark0N#80 regression class — bare tmux hits the user's default
server and never finds a session on the codeman socket):
- session.ts queryTmuxWindowSize(): add `-L <socket>` (was silently falling
back to 120x40 on re-attach, losing scrollback)
- session-routes.ts send-key (Shift+Enter / Ctrl+Enter newline): route
through ctx.mux.muxSocket
SSH chooser scripts (tmux-manager.sh, tmux-chooser.sh) route every tmux call
through `tmux -L $CODEMAN_TMUX_SOCKET`, matching the TS default.
Owner
|
Thank you very much for this — it's an excellent, thorough fix. 🙏 I reviewed the full diff and it's in great shape:
One tiny non-blocking nit for a future pass: the Merging now. Thanks again for the careful work and detailed write-up! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Symptom
After upgrading tmux to the latest version, opening a new conversation immediately errored out — the freshly spawned CLI process exited right away, so no session could start.
Root cause
Under macOS launchd, the newer tmux hands panes a low soft
nofilelimit (256). Recent Claude Code exits immediately when it inherits such a low file-descriptor limit, so every newly spawned session died on startup.Separately, Codeman's sessions lived on the default tmux server intermixed with the user's own tmux sessions, and carried a per-session
tmuxSockettag that could drift from physical reality — causing live sessions to be wrongly marked dead ("tab shows no session found") and duplicate "Restored:" tabs.Fix
nofilelimit (ulimit -Sn) before launching the CLI, so the new tmux + launchd combo no longer crashes Claude Code on spawn.tmux -L codeman), fully separated from the user's default tmux server.tmuxSocketfield.reconcileSessions()collapses from a multi-socket scan to a singlelist-panesquery;loadSessions()strips the obsolete field. Socket name exposed asTmuxManager.muxSocket, overridable viaCODEMAN_TMUX_SOCKET.tmuxcall sites through the socket (same regression class):queryTmuxWindowSize()(was silently falling back to 120×40 on re-attach, losing scrollback) and thesend-keyroute (Shift+Enter / Ctrl+Enter newline).tmux-manager.sh,tmux-chooser.sh) route every tmux call throughtmux -L $CODEMAN_TMUX_SOCKET.Test plan
tsc --noEmitcleannpm test -- test/tmux-manager.test.ts test/tmux-window-size-query.test.ts→ 46 passing🤖 Generated with Claude Code