diff --git a/src/renderer/src/store/slices/agent-status-drop.test.ts b/src/renderer/src/store/slices/agent-status-drop.test.ts index af9f9eaa7ed..5a4b86838c2 100644 --- a/src/renderer/src/store/slices/agent-status-drop.test.ts +++ b/src/renderer/src/store/slices/agent-status-drop.test.ts @@ -186,7 +186,9 @@ describe('dropAgentStatus + retention suppressor', () => { expect(s.tabsByWorktree['wt-1']?.some((tab) => tab.id === 'tab-closed')).toBe(false) expect(s.agentStatusByPaneKey['tab-closed:0']).toBeUndefined() expect(s.agentStatusByPaneKey['tab-orphan:0']).toBeUndefined() - expect(s.retentionSuppressedPaneKeys['tab-orphan:0']).toBe(true) + // No suppressor for the orphan: its tab is already gone, so retention sync + // never re-surfaces it and a suppressor would leak permanently. + expect(s.retentionSuppressedPaneKeys['tab-orphan:0']).toBeUndefined() expect(s.agentStatusByPaneKey['tab-active-child:0']).toBeDefined() expect(s.agentStatusByPaneKey['tab-live:0']).toBeDefined() expect(s.agentStatusByPaneKey['tab-other-orphan:0']).toBeDefined() diff --git a/src/renderer/src/store/slices/agent-status.ts b/src/renderer/src/store/slices/agent-status.ts index 80be0c22e3a..52809ebaa2c 100644 --- a/src/renderer/src/store/slices/agent-status.ts +++ b/src/renderer/src/store/slices/agent-status.ts @@ -1895,7 +1895,13 @@ export const createAgentStatusSlice: StateCreator !(k in s.retentionSuppressedPaneKeys)) + // + // Skip completed-orphan keys: their tab is already gone, so retention + // sync never snapshots them and no live→gone transition ever fires to + // consume the suppressor — planting one would leak permanently. + const suppressorAdds = liveKeys.filter( + (k) => !completedOrphanKeySet.has(k) && !(k in s.retentionSuppressedPaneKeys) + ) let nextRetentionSuppressedPaneKeys = s.retentionSuppressedPaneKeys if (suppressorAdds.length > 0) { nextRetentionSuppressedPaneKeys = { ...s.retentionSuppressedPaneKeys }