diff --git a/src/renderer/src/store/slices/store-cascades.test.ts b/src/renderer/src/store/slices/store-cascades.test.ts index bd710db7de5..71e20fc34d8 100644 --- a/src/renderer/src/store/slices/store-cascades.test.ts +++ b/src/renderer/src/store/slices/store-cascades.test.ts @@ -472,4 +472,33 @@ describe('setActiveWorktree', () => { expect(s.activeTabTypeByWorktree[backgroundWt]).toBe('browser') expect(s.activeBrowserTabIdByWorktree[backgroundWt]).toBe(browserTab.id) }) + + it('restores terminal surface when switching to a worktree that was last on a terminal tab with open files', () => { + const store = createTestStore() + const wt = 'repo1::/path/wt1' + const fileId = '/path/wt1/src/index.ts' + + seedStore(store, { + worktreesByRepo: { + repo1: [makeWorktree({ id: wt, repoId: 'repo1', path: '/path/wt1' })] + }, + activeWorktreeId: null, + tabsByWorktree: { + [wt]: [makeTab({ id: 'terminal-1', worktreeId: wt })] + }, + openFiles: [makeOpenFile({ id: fileId, worktreeId: wt, filePath: fileId })], + activeFileIdByWorktree: { [wt]: fileId }, + // User was on the terminal, not the editor + activeTabTypeByWorktree: { [wt]: 'terminal' }, + refreshGitHubForWorktree: vi.fn() + }) + + store.getState().setActiveWorktree(wt) + + const s = store.getState() + expect(s.activeWorktreeId).toBe(wt) + expect(s.activeTabType).toBe('terminal') + // File ID should still be tracked for background state + expect(s.activeFileId).toBe(fileId) + }) }) diff --git a/src/renderer/src/store/slices/worktrees.ts b/src/renderer/src/store/slices/worktrees.ts index 1e61bf9ac80..2407252f40a 100644 --- a/src/renderer/src/store/slices/worktrees.ts +++ b/src/renderer/src/store/slices/worktrees.ts @@ -309,11 +309,21 @@ export const createWorktreeSlice: StateCreator ? browserTabs.some((tab) => tab.id === restoredBrowserTabId) : false - // If restored file is gone, fall back to another open file for this worktree + // Why: restore the visible tab surface the user last had active in this + // worktree. The 'terminal' case must be handled explicitly — without it, + // the fallback branches below see that a file is still open and promote + // the surface to 'editor', so the user always lands on a file tab instead + // of the terminal they were working in. let activeFileId: string | null let activeBrowserTabId: string | null let activeTabType: WorkspaceVisibleTabType - if (restoredTabType === 'browser' && browserTabStillOpen) { + if (restoredTabType === 'terminal') { + activeFileId = fileStillOpen ? restoredFileId : null + activeBrowserTabId = browserTabStillOpen + ? restoredBrowserTabId + : (browserTabs[0]?.id ?? null) + activeTabType = 'terminal' + } else if (restoredTabType === 'browser' && browserTabStillOpen) { activeFileId = fileStillOpen ? restoredFileId : null activeBrowserTabId = restoredBrowserTabId activeTabType = 'browser'