diff --git a/apps/desktop/src/renderer/stores/tabs/store.ts b/apps/desktop/src/renderer/stores/tabs/store.ts index 8304ebc90d..8e1bcb4977 100644 --- a/apps/desktop/src/renderer/stores/tabs/store.ts +++ b/apps/desktop/src/renderer/stores/tabs/store.ts @@ -1,6 +1,7 @@ import type { MosaicNode } from "react-mosaic-component"; import { updateTree } from "react-mosaic-component"; import { trpcTabsStorage } from "renderer/lib/trpc-storage"; +import { acknowledgedStatus } from "shared/tabs-types"; import { create } from "zustand"; import { devtools, persist } from "zustand/middleware"; import { movePaneToNewTab, movePaneToTab } from "./actions/move-pane"; @@ -325,17 +326,11 @@ export const useTabsStore = create()( const newPanes = { ...state.panes }; let hasChanges = false; for (const paneId of tabPaneIds) { - const currentStatus = newPanes[paneId]?.status; - if (currentStatus === "review") { - // User acknowledged completion - newPanes[paneId] = { ...newPanes[paneId], status: "idle" }; - hasChanges = true; - } else if (currentStatus === "permission") { - // Assume permission granted, agent is now working - newPanes[paneId] = { ...newPanes[paneId], status: "working" }; + const resolved = acknowledgedStatus(newPanes[paneId]?.status); + if (resolved !== (newPanes[paneId]?.status ?? "idle")) { + newPanes[paneId] = { ...newPanes[paneId], status: resolved }; hasChanges = true; } - // "working" status is NOT cleared by click - persists until Stop } set({ @@ -811,7 +806,7 @@ export const useTabsStore = create()( set({ panes: { ...state.panes, - [paneId]: { ...pane, status: "idle" }, + [paneId]: { ...pane, status: acknowledgedStatus(pane.status) }, }, focusedPaneIds: { ...state.focusedPaneIds, @@ -881,17 +876,11 @@ export const useTabsStore = create()( const newPanes = { ...state.panes }; let hasChanges = false; for (const paneId of workspacePaneIds) { - const currentStatus = newPanes[paneId]?.status; - if (currentStatus === "review") { - // User acknowledged completion - newPanes[paneId] = { ...newPanes[paneId], status: "idle" }; - hasChanges = true; - } else if (currentStatus === "permission") { - // Assume permission granted, Claude is now working - newPanes[paneId] = { ...newPanes[paneId], status: "working" }; + const resolved = acknowledgedStatus(newPanes[paneId]?.status); + if (resolved !== (newPanes[paneId]?.status ?? "idle")) { + newPanes[paneId] = { ...newPanes[paneId], status: resolved }; hasChanges = true; } - // "working" status is NOT cleared by click - persists until Stop } if (hasChanges) { diff --git a/apps/desktop/src/shared/tabs-types.ts b/apps/desktop/src/shared/tabs-types.ts index f725b2a429..87bb8564e9 100644 --- a/apps/desktop/src/shared/tabs-types.ts +++ b/apps/desktop/src/shared/tabs-types.ts @@ -68,6 +68,21 @@ export function getHighestPriorityStatus( return highest === "idle" ? null : highest; } +/** + * Resolve what a pane's status should become when the user acknowledges it + * (e.g. clicking a tab, focusing a pane, selecting a workspace). + * + * - "review" → "idle" (user saw the completion) + * - "permission" → "working" (user saw the prompt; assume granted) + * - "working" → unchanged (persists until agent stops) + * - "idle" → unchanged + */ +export function acknowledgedStatus(status: PaneStatus | undefined): PaneStatus { + if (status === "review") return "idle"; + if (status === "permission") return "working"; + return status ?? "idle"; +} + /** * File viewer display modes */