From 40c7c39e5eb6c5bd5f347ea6bdba625d5df94179 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 20 Aug 2026 16:30:35 -0700 Subject: [PATCH] fix(sidebar): keep retained agent identity under a bare Terminal title Hoisting titleShowsNoAgent also broadened it to treat any "Terminal N" as evidence of exit, which dropped a pane's retained Codex identity (use-tab-agent-retained-identity). A bare default-shaped title is only exit evidence when it matches the tab's own defaultTitle. --- src/renderer/src/lib/tui-agent-startup.test.ts | 5 ++++- src/shared/shell-process-detection.ts | 11 ++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/renderer/src/lib/tui-agent-startup.test.ts b/src/renderer/src/lib/tui-agent-startup.test.ts index f0b1c74c0d3..59658d0eb3d 100644 --- a/src/renderer/src/lib/tui-agent-startup.test.ts +++ b/src/renderer/src/lib/tui-agent-startup.test.ts @@ -426,7 +426,10 @@ describe('titleShowsNoAgent', () => { it('treats shell names and default Terminal titles as no agent', () => { expect(titleShowsNoAgent('zsh')).toBe(true) expect(titleShowsNoAgent('cmd.exe')).toBe(true) - expect(titleShowsNoAgent('Terminal 1')).toBe(true) + // A bare "Terminal N" is NOT evidence of exit on its own: a pane can carry a + // retained agent identity under that title (use-tab-agent-retained-identity). + // It only means "no agent" when it matches the tab's own default title. + expect(titleShowsNoAgent('Terminal 1')).toBe(false) expect(titleShowsNoAgent('Terminal 1', 'Terminal 1')).toBe(true) }) diff --git a/src/shared/shell-process-detection.ts b/src/shared/shell-process-detection.ts index 12fd5450d89..faf71cdd620 100644 --- a/src/shared/shell-process-detection.ts +++ b/src/shared/shell-process-detection.ts @@ -22,17 +22,10 @@ export function isShellProcess(processName: string): boolean { ) } -const DEFAULT_TERMINAL_TITLE_RE = /^terminal \d+$/i - -/** A shell name or the tab's default Terminal title; blank titles are no evidence. */ +/** A shell name or the tab's own neutral default title; blank titles are no evidence. */ export function titleShowsNoAgent(title: string, defaultTitle?: string): boolean { const trimmed = title.trim() - return ( - trimmed.length > 0 && - (isShellProcess(trimmed) || - trimmed === defaultTitle?.trim() || - DEFAULT_TERMINAL_TITLE_RE.test(trimmed)) - ) + return trimmed.length > 0 && (isShellProcess(trimmed) || trimmed === defaultTitle?.trim()) } // Why: a ConPTY-side buffer clear cannot reach PSReadLine's cached cursor