fix: the live transcript lookup targets the exact tmux session (release review)

list-panes -t '=name' with no colon is a window target to tmux, so a
remote session that is gone resolved to a window of that name or to a
session the name is a prefix of, and the Edit history panel moved to that
session's conversation and stored its diffs. `=name:` is an exact session
match, as src/remote-pane-history.ts already uses. Measured on tmux 3.4.

The fake tmux in the test matched the name as a substring, so it passed
with or without the colon. It now needs the exact token and answers a bare
prefix the way real tmux does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Codeman maintainer committed 2026-11-06 03:49:59 +01:00
1 parent 08d99da5ae
commit 81f8c8e894
2 files changed
+23 -2

No files matched your search

+18 -1
View File
@@ -173,9 +173,20 @@ describe('the transcript lookup on a real shell', () => {
bin = mkdtempSync(join(tmpdir(), 'codeman-fake-tmux-'));
const localBin = join(home, '.local', 'bin');
mkdirSync(localBin, { recursive: true });
// Only the exact `=name:` target reaches the pane. Real tmux (3.4, measured) reads `=name`
// without the colon as a window target too, so it also answers for a window of that name
// or a session the name is a prefix of: the second pattern is that second case.
writeFileSync(
join(localBin, 'tmux'),
'#!/bin/sh\ncase "$*" in *"=codeman-ssh-conv1abc"*) echo 100 ;; *) echo "no such session" >&2; exit 1 ;; esac\n'
[
'#!/bin/sh',
'for a; do',
' case "$a" in =codeman-ssh-conv1abc:|=codeman-ssh-conv1) echo 100; exit 0 ;; esac',
'done',
'echo "no such session" >&2',
'exit 1',
'',
].join('\n')
);
writeFileSync(join(bin, 'ps'), '#!/bin/sh\nprintf " 1 0\\n100 1\\n200 100\\n300 200\\n"\n');
chmodSync(join(localBin, 'tmux'), 0o755);
@@ -210,6 +221,12 @@ describe('the transcript lookup on a real shell', () => {
expect(locateIn(pane)).toBe(join(projects(), 'new', 'conv-1.jsonl'));
});
it('never takes the pane of another tmux session whose name starts with this one', () => {
// codeman-ssh-conv1 is gone, codeman-ssh-conv1abc is alive: its conversation is not ours.
session('{"pid":300,"sessionId":"solo"}');
expect(locateIn({ ...pane, sessionName: 'codeman-ssh-conv1' })).toBe(join(projects(), 'new', 'conv-1.jsonl'));
});
it('reads the live id from the sessions dir under CLAUDE_CONFIG_DIR', () => {
const cfg = join(home, 'alt-config');
mkdirSync(join(cfg, 'sessions'), { recursive: true });