From 49d7ed31c67293ffcaeb8eb7909fb80e0f45129c Mon Sep 17 00:00:00 2001 From: OrcaWin Date: Fri, 25 Sep 2026 22:47:44 -0700 Subject: [PATCH] fix(native-chat): keep chat visible when detaching its pane (#23096) * fix(native-chat): persist current pane ownership across lifecycle events * fix(native-chat): retain ownership when client chat rendering is disabled * fix(native-chat): preserve chat mode when detaching its pane --------- Co-authored-by: m4air --- .../terminal-pane-tab-detach.test.ts | 25 +++++++++++++++++++ .../terminal-pane/terminal-pane-tab-detach.ts | 1 + 2 files changed, 26 insertions(+) diff --git a/src/renderer/src/components/terminal-pane/terminal-pane-tab-detach.test.ts b/src/renderer/src/components/terminal-pane/terminal-pane-tab-detach.test.ts index 209ac9dd5e9..8586db21e41 100644 --- a/src/renderer/src/components/terminal-pane/terminal-pane-tab-detach.test.ts +++ b/src/renderer/src/components/terminal-pane/terminal-pane-tab-detach.test.ts @@ -271,6 +271,31 @@ describe('resolveTerminalTabStripDropTarget', () => { }) describe('detachTerminalPaneToTab', () => { + it.each([LEAF_1, LEAF_2])('moves chat mode only with its owning leaf %s', (chatLeafId) => { + const store = createStore({ ...splitLayout(), chatLeafId }) + detachTerminalPaneToTab({ + getStore: () => store, + manager: { + getPanes: () => [{ id: 1 }, { id: 2 }], + getLeafId: () => LEAF_2, + detachPaneForExternalMove: () => true + }, + persistLayoutSnapshot: vi.fn(), + sourcePaneId: 2, + sourceTabId: SOURCE_TAB_ID, + targetGroupId: TARGET_GROUP_ID, + worktreeId: WORKTREE_ID + }) + const options = vi.mocked(store.createTab).mock.calls[0]?.[3] + expect(options?.viewMode ?? 'terminal').toBe(chatLeafId === LEAF_2 ? 'chat' : 'terminal') + expect(store.terminalLayoutsByTabId['tab-detached']?.chatLeafId).toBe( + chatLeafId === LEAF_2 ? LEAF_2 : undefined + ) + expect(store.terminalLayoutsByTabId[SOURCE_TAB_ID]?.chatLeafId).toBe( + chatLeafId === LEAF_1 ? LEAF_1 : undefined + ) + }) + it('creates a new terminal tab with the detached leaf layout and PTY id', () => { const store = createStore() const manager = { diff --git a/src/renderer/src/components/terminal-pane/terminal-pane-tab-detach.ts b/src/renderer/src/components/terminal-pane/terminal-pane-tab-detach.ts index ed63e48c2a8..27c97538d2d 100644 --- a/src/renderer/src/components/terminal-pane/terminal-pane-tab-detach.ts +++ b/src/renderer/src/components/terminal-pane/terminal-pane-tab-detach.ts @@ -140,6 +140,7 @@ export function detachTerminalPaneToTab(args: { )?.shellOverride const tab = latestStore.createTab(args.worktreeId, args.targetGroupId, sourceShellOverride, { activate: true, + ...(detachedLayout.chatLeafId ? { viewMode: 'chat' as const } : {}), initialPtyId: ptyId ?? undefined, ...(!ptyId ? {