From 1d1c6da582e1bf76c188ff44e5f11ca05fb350e4 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Mon, 26 Oct 2026 15:56:28 -0700 Subject: [PATCH] fix(terminal): a parked local tab whose process exits closes as a pty-exit, not a user close (#34083) The parked watcher passes only hostCloseReason 'pty-exit' (so the pinned guard still applies), and the local branch then let closeTab default the reason to 'user': a process exit wrote a user tombstone and retired the session. The local close now carries the pty-exit reason. Co-authored-by: Claude --- .../terminal-tab-actions-unrouted-close.test.ts | 11 +++++++++++ .../src/components/terminal/terminal-tab-actions.ts | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/renderer/src/components/terminal/terminal-tab-actions-unrouted-close.test.ts b/src/renderer/src/components/terminal/terminal-tab-actions-unrouted-close.test.ts index cf27db5cc07..bbd50608ffd 100644 --- a/src/renderer/src/components/terminal/terminal-tab-actions-unrouted-close.test.ts +++ b/src/renderer/src/components/terminal/terminal-tab-actions-unrouted-close.test.ts @@ -88,4 +88,15 @@ describe('closeTerminalTab before the worktree catalog names a host', () => { expect(onClosed).toHaveBeenCalled() expect(closeWebRuntimeSessionTabMock).not.toHaveBeenCalled() }) + + it('closes a parked local tab whose process exited as a pty-exit, never a user close', () => { + // A user close would tombstone the tab and retire its session (verify-15a 5e). + isWebRuntimeSessionActiveMock.mockReturnValue(false) + const closeTab = vi.fn() + getStateMock.mockReturnValue(unhydratedState('pty-1', closeTab)) + + closeTerminalTab('tab-1', { hostCloseReason: 'pty-exit', lifecyclePtyId: 'pty-1' }) + + expect(closeTab).toHaveBeenCalledWith('tab-1', expect.objectContaining({ reason: 'pty-exit' })) + }) }) diff --git a/src/renderer/src/components/terminal/terminal-tab-actions.ts b/src/renderer/src/components/terminal/terminal-tab-actions.ts index 12747726d96..bc6b7de2cf1 100644 --- a/src/renderer/src/components/terminal/terminal-tab-actions.ts +++ b/src/renderer/src/components/terminal/terminal-tab-actions.ts @@ -199,7 +199,8 @@ export function closeTerminalTab( } closeLocalTerminalTabState(terminalTabId, { - reason: options?.reason, + // A parked tab's process exit carries only the host reason, to keep the pin guard above. + reason: options?.reason ?? (options?.hostCloseReason === 'pty-exit' ? 'pty-exit' : undefined), ...(options?.captureRecentlyClosed !== undefined ? { captureRecentlyClosed: options.captureRecentlyClosed } : {}),