diff --git a/src/services/tmux.js b/src/services/tmux.js index 6ed7ebf..d080675 100644 --- a/src/services/tmux.js +++ b/src/services/tmux.js @@ -3,6 +3,7 @@ import { basename } from 'node:path'; import { runProcess } from '../process.js'; const PANE_FORMAT = '#{session_name}\t#{window_index}\t#{window_name}\t#{pane_id}\t#{pane_current_command}\t#{pane_current_path}'; +const WEB_TERMINAL_SESSION_PATTERN = /^web-\d+-\d+$/; const ENGINE_BY_COMMAND = { claude: 'claude', @@ -21,7 +22,9 @@ export function parseTmuxPanes(output) { .map((line) => { const [session, windowIndex, windowName, paneId, command, cwd] = line.split('\t'); const engine = ENGINE_BY_COMMAND[command]; - if (!engine || !paneId) return null; + // Web terminal sessions only link an existing pane into a temporary view. + // They are not additional agents and must not be enumerated in Live Agents. + if (!engine || !paneId || WEB_TERMINAL_SESSION_PATTERN.test(session)) return null; return { engine, session, windowIndex: Number(windowIndex), windowName, paneId, cwd }; }) .filter(Boolean); diff --git a/test/tmux.test.js b/test/tmux.test.js index 815dafd..5c936fc 100644 --- a/test/tmux.test.js +++ b/test/tmux.test.js @@ -36,6 +36,33 @@ test('parseTmuxPanes drops unrelated commands', () => { assert.deepEqual(parseTmuxPanes(output), []); }); +test('parseTmuxPanes hides temporary web terminal sessions', () => { + const output = [ + 'main\t1\tcodex:kanban\t%5\tnode\t/home/gahow/projects/kanban', + 'web-1234-5678\t1\tcodex:kanban\t%5\tnode\t/home/gahow/projects/kanban', + 'web-development\t2\tcodex:web\t%6\tnode\t/home/gahow/projects/web' + ].join('\n'); + + assert.deepEqual(parseTmuxPanes(output), [ + { + engine: 'codex', + session: 'main', + windowIndex: 1, + windowName: 'codex:kanban', + paneId: '%5', + cwd: '/home/gahow/projects/kanban' + }, + { + engine: 'codex', + session: 'web-development', + windowIndex: 2, + windowName: 'codex:web', + paneId: '%6', + cwd: '/home/gahow/projects/web' + } + ]); +}); + test('parseTmuxPanes handles empty output', () => { assert.deepEqual(parseTmuxPanes(''), []); assert.deepEqual(parseTmuxPanes(null), []);