From e910f63081336f7a404fc1ae07e78044f41f6eaf Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Wed, 12 Aug 2026 20:00:40 -0700 Subject: [PATCH] fix(dashboard): clear orphaned chat pane state --- .../native-chat-launch-draft-teardown.test.ts | 13 ++++++++++++- .../src/store/slices/terminal-orphan-helpers.ts | 6 ++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/renderer/src/store/slices/native-chat-launch-draft-teardown.test.ts b/src/renderer/src/store/slices/native-chat-launch-draft-teardown.test.ts index 08408c343fc..22514d22b52 100644 --- a/src/renderer/src/store/slices/native-chat-launch-draft-teardown.test.ts +++ b/src/renderer/src/store/slices/native-chat-launch-draft-teardown.test.ts @@ -64,7 +64,8 @@ function seedDrafts(store: ReturnType): void { nativeChatLaunchDraftByTabId: { [TAB1]: draft(TAB1, 'https://github.com/o/r/issues/1'), [TAB2]: draft(TAB2, 'https://github.com/o/r/issues/2') - } + }, + runtimeNativeChatLeafIdByTabId: { [TAB1]: 'leaf-1', [TAB2]: 'leaf-2' } }) } @@ -96,6 +97,16 @@ describe('nativeChatLaunchDraftByTabId teardown', () => { expect(s.nativeChatLaunchDraftByTabId[TAB2]).toBeDefined() }) + it('orphan cleanup drops runtime chat ownership for the removed tab only', () => { + const store = createTestStore() + seedDrafts(store) + + const patch = buildOrphanTerminalCleanupPatch(store.getState(), WT1, new Set([TAB1])) + + expect(patch.runtimeNativeChatLeafIdByTabId[TAB1]).toBeUndefined() + expect(patch.runtimeNativeChatLeafIdByTabId[TAB2]).toBe('leaf-2') + }) + it('single removeWorktree drops drafts for the removed worktree only', async () => { const store = createTestStore() seedDrafts(store) diff --git a/src/renderer/src/store/slices/terminal-orphan-helpers.ts b/src/renderer/src/store/slices/terminal-orphan-helpers.ts index 45445f530bd..e761babc621 100644 --- a/src/renderer/src/store/slices/terminal-orphan-helpers.ts +++ b/src/renderer/src/store/slices/terminal-orphan-helpers.ts @@ -39,6 +39,7 @@ type OrphanTerminalCleanupState = Pick< | 'tabsByWorktree' | 'ptyIdsByTabId' | 'runtimePaneTitlesByTabId' + | 'runtimeNativeChatLeafIdByTabId' | 'expandedPaneByTabId' | 'canExpandPaneByTabId' | 'terminalLayoutsByTabId' @@ -91,6 +92,7 @@ export function buildOrphanTerminalCleanupPatch( | 'tabsByWorktree' | 'ptyIdsByTabId' | 'runtimePaneTitlesByTabId' + | 'runtimeNativeChatLeafIdByTabId' | 'expandedPaneByTabId' | 'canExpandPaneByTabId' | 'terminalLayoutsByTabId' @@ -111,6 +113,7 @@ export function buildOrphanTerminalCleanupPatch( tabsByWorktree: state.tabsByWorktree, ptyIdsByTabId: state.ptyIdsByTabId, runtimePaneTitlesByTabId: state.runtimePaneTitlesByTabId, + runtimeNativeChatLeafIdByTabId: state.runtimeNativeChatLeafIdByTabId, expandedPaneByTabId: state.expandedPaneByTabId, canExpandPaneByTabId: state.canExpandPaneByTabId, terminalLayoutsByTabId: state.terminalLayoutsByTabId, @@ -133,6 +136,7 @@ export function buildOrphanTerminalCleanupPatch( ) const nextPtyIdsByTabId = { ...state.ptyIdsByTabId } const nextRuntimePaneTitlesByTabId = { ...state.runtimePaneTitlesByTabId } + const nextRuntimeNativeChatLeafIdByTabId = { ...state.runtimeNativeChatLeafIdByTabId } const nextExpandedPaneByTabId = { ...state.expandedPaneByTabId } const nextCanExpandPaneByTabId = { ...state.canExpandPaneByTabId } const nextTerminalLayoutsByTabId = { ...state.terminalLayoutsByTabId } @@ -160,6 +164,7 @@ export function buildOrphanTerminalCleanupPatch( for (const orphanTabId of orphanTerminalIds) { delete nextPtyIdsByTabId[orphanTabId] delete nextRuntimePaneTitlesByTabId[orphanTabId] + delete nextRuntimeNativeChatLeafIdByTabId[orphanTabId] delete nextExpandedPaneByTabId[orphanTabId] delete nextCanExpandPaneByTabId[orphanTabId] delete nextTerminalLayoutsByTabId[orphanTabId] @@ -191,6 +196,7 @@ export function buildOrphanTerminalCleanupPatch( }, ptyIdsByTabId: nextPtyIdsByTabId, runtimePaneTitlesByTabId: nextRuntimePaneTitlesByTabId, + runtimeNativeChatLeafIdByTabId: nextRuntimeNativeChatLeafIdByTabId, expandedPaneByTabId: nextExpandedPaneByTabId, canExpandPaneByTabId: nextCanExpandPaneByTabId, terminalLayoutsByTabId: nextTerminalLayoutsByTabId,