COD-106 shared/collaborative remote tmux sessions (window-size latest + shared badge)

Two Codeman clients attaching the same durable remote tmux session at different
viewports would fight: tmux sizes a window to the SMALLEST attached client by
default. Push `window-size latest` to the remote session config so the window
tracks the most-recently-active client instead, letting concurrent clients
coexist; surface the client count for a "shared · N" badge.

Reconciled onto upstream PR #145: #145 moved the durable remote session onto the
dedicated `-L codeman-remote` socket under a `codeman-ssh-` name and scoped every
tmux set-option PER-SESSION (`set -t <name>`, never `-g`) so a shared remote tmux
server's OTHER sessions keep their own prefix/mouse/sizing. The original COD-106
commit added `set -g window-size latest` (GLOBAL) on the old `-L codeman` socket —
a regression against #145's hardening. This commit layers the window-size feature
onto #145's structure as `set -t <name> window-size latest` (per-session, on the
codeman-remote socket). Test assertions updated to the per-session form
(remote-shared-sessions.test.ts) and the byte-identical launch-command test
(remote-ssh-options.test.ts) extended with the window-size line — which supersedes
the separate f09323c9 assertion fix (dropped: it targeted the global form and also
carried unrelated CLAUDE.md doc changes).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Aamer Akhter
2026-07-17 16:03:03 -04:00
co-authored by Claude Opus 4.8
parent 6dba8b5227
commit b2ebdcbf47
7 changed files with 72 additions and 10 deletions
+5 -1
View File
@@ -270,9 +270,13 @@ export function parseRemoteSessionList(stdout: string): RemoteSessionInfo[] {
const created = Number(createdStr);
const windows = Number(windowsStr);
if (!Number.isFinite(created) || !Number.isFinite(windows)) continue;
// COD-106 — `session_attached` is the CLIENT COUNT (not a 0/1 flag); >1 = shared.
const attachedNum = Number(attachedStr.trim());
const attachedClients = Number.isFinite(attachedNum) ? Math.max(0, Math.trunc(attachedNum)) : 0;
out.push({
name,
attached: attachedStr.trim() === '1',
attached: attachedClients > 0,
attachedClients,
created: Math.trunc(created),
windows: Math.trunc(windows),
});