Two related gaps, offered as a design proposal rather than an unsolicited large PR. Happy to send either as a PR if the shape is wanted.
1. setTabState() has no tmux backend
hooks/lib/tab-setter.ts states the contract in its own header — one env-detecting setter, and "all hooks call setTabState() instead of directly running terminal commands." It detects cmux and Kitty. Under tmux it does nothing, so a tmux user gets no tab state at all.
tmux is straightforward to add: $TMUX_PANE is exported into every process tmux spawns, so a hook can always resolve which pane it is in via tmux display-message -p -t $TMUX_PANE '#{session_id}', and #{session_id} ($N) is stable across renames.
2. The canonical session name has no fan-out
MEMORY/STATE/session-names.json is the authority, but each surface is written by hand at the point the name is decided — work.json here, the transcript row there. Adding a surface means editing whoever decides the name, and a name set from anywhere else (SessionRename.ts, an out-of-band edit) reaches nothing.
A small renderSessionName(sessionId, name) that reconciles the surfaces would make the write sites one-liners and remove the class. Reconciling rather than pushing also covers the case where a session is renamed from another pane and never gets another prompt of its own.
One correctness note if this is implemented: only the session the process is running inside may resolve its tmux session from the ambient $TMUX_PANE. For any other session that env var names the caller's pane, and trusting it renames the wrong session. A persisted uuid → #{session_id} map handles the rest.
Related: #1878 fixes the transcript surface, which is currently dead for a different reason.
Two related gaps, offered as a design proposal rather than an unsolicited large PR. Happy to send either as a PR if the shape is wanted.
1.
setTabState()has no tmux backendhooks/lib/tab-setter.tsstates the contract in its own header — one env-detecting setter, and "all hooks call setTabState() instead of directly running terminal commands." It detects cmux and Kitty. Under tmux it does nothing, so a tmux user gets no tab state at all.tmux is straightforward to add:
$TMUX_PANEis exported into every process tmux spawns, so a hook can always resolve which pane it is in viatmux display-message -p -t $TMUX_PANE '#{session_id}', and#{session_id}($N) is stable across renames.2. The canonical session name has no fan-out
MEMORY/STATE/session-names.jsonis the authority, but each surface is written by hand at the point the name is decided — work.json here, the transcript row there. Adding a surface means editing whoever decides the name, and a name set from anywhere else (SessionRename.ts, an out-of-band edit) reaches nothing.A small
renderSessionName(sessionId, name)that reconciles the surfaces would make the write sites one-liners and remove the class. Reconciling rather than pushing also covers the case where a session is renamed from another pane and never gets another prompt of its own.One correctness note if this is implemented: only the session the process is running inside may resolve its tmux session from the ambient
$TMUX_PANE. For any other session that env var names the caller's pane, and trusting it renames the wrong session. A persisted uuid →#{session_id}map handles the rest.Related: #1878 fixes the transcript surface, which is currently dead for a different reason.