fix(tmux): target windows by id, not by a name tmux reads as an index #105
No reviewers
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
lz/agent-nexus!105
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/tmux-window-targeting"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Independent of the #96 stack (branched off
main), but included in the release candidate — these are live bugs that a production trial would hit.The bug
tmux resolves the window half of a
session:windowtarget as an INDEX first, falling back to a name match only if that fails. Session names are git refs, and1/42are legal refs the create form accepts.Measured on tmux 3.3a with windows
0:workspace 1:alpha 2:"1":Three call sites, not two
artifacts/tmux-nudge.ts— an operator nudge aimed at the session named1was typed into another agent's claude prompt, and Enter pressed. Thelist-windowscall that already verified the window now also carries#{window_id}.terminal/exec-pty.ts— the browser terminal attached to and displayed the wrong session's pane, so the operator typed into an agent they had not picked.VIEW:@idstill leaves the originalnexussession's own active-window pointer untouched, so the grouped-session shape is unchanged.sessions/deleteSession— found by the review pass, and the most destructive:kill-window -t nexus:1killed alpha, SIGHUPing another agent's claude, while the session actually being deleted kept running with an orphaned window.Two silent failures, also fixed
list-windowswas indistinguishable from an absent window: tmux being unreachable reportedno tmux window named "alpha", pointing the operator at a session that is fine.sendNudgeclaimed delivery on a failed send.execInContainerresolves with a non-zeroexitCoderather than throwing, so the originaltry/catchcould never see it — and that value surfaces asprompt_typed: truein the submit API. The operator was told their feedback reached the agent when nothing had.Plus
reject(sock, 500, …)no longer labels itselfHTTP/1.1 500 Bad Request.Guard
tmux-window.test.tsscanssrc/lib/server/**/*.tsand fails on anynexus:${...}target that is not the fixedWORKSPACE_WINDOWconstant (precedent:auth/sealed-columns.test.ts). Negative-controlled — a planted offender fails the test naming the file and the expression. Stated limitation:'nexus:' + nameslips past.Also measured and recorded: tmux never reuses a window id. Kill
@1, create a window, you get@3;-t @1then fails rather than hitting a bystander. That is what makes resolve-then-use safe across the gap between the two execs.Merge note
Conflicts with the #96 stack in
sessions/service.tsandservice.test.ts— both fixdeleteSession, differently. Resolve by deletingresolveSessionWindowIdin favour of the sharedlib/tmux-window.ts. Resolved and gated in the release-candidate branch.Gates
tmux resolves the window half of a `session:window` target as an INDEX first, falling back to a name match only if that fails. Session names are git refs, and `1` / `42` are legal refs the create form accepts, so both remaining name-based targets could act on a different session's window. Measured on tmux 3.3a with windows `0:workspace 1:alpha 2:"1"`: `nexus:1` and `nexus:=1` both resolve to **alpha** (the `=` exact-match prefix does not help), while `@2` is the window actually named `1`. `send-keys -t nexus:1 -l TEXT` was delivered into alpha's pane. - artifacts/tmux-nudge.ts: an operator nudge aimed at the session named `1` was typed into another agent's claude prompt, and Enter pressed. The list-windows call that already verified the window now also carries `#{window_id}`, and the sends target `@N`. The `{delivered:false, reason:'window not found'}` contract is unchanged. - terminal/exec-pty.ts: the browser terminal attached to and displayed the wrong session's pane, so the operator typed into an agent they had not picked. `buildTmuxAttachArgv` stays a pure argv builder and now takes the id; `openTerminalPty` resolves it (one extra exec per terminal-open, not a poll path) and rejects when no window carries the name rather than falling back — handleTerminalUpgradeCore already answers an openPty rejection with `500 failed to open terminal`, so no new failure mode. `VIEW:@ID` still leaves the original `nexus` session's own active-window pointer untouched, so the grouped-session shape is otherwise unchanged. lib/tmux-window.ts holds the shared `-F` format and its parser so the measurement is documented once instead of at each call site.