From 8f46f9170abb20c39dd7b97a62ffaf2876de265c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Fri, 6 Mar 2026 20:39:44 +0000 Subject: [PATCH] fix terminal state key leaking phantom dashboards; fix infinite loop in chat panel resume Co-Authored-By: Claude Opus 4.6 --- .../officerdev/src/apps/Chat/ChatPanelWrapper.tsx | 10 ++++++++-- .../src/apps/Terminal/TerminalWrapper.tsx | 14 ++++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/workspaces/officerdev/src/apps/Chat/ChatPanelWrapper.tsx b/src/workspaces/officerdev/src/apps/Chat/ChatPanelWrapper.tsx index 05f7bf76..8d35b074 100644 --- a/src/workspaces/officerdev/src/apps/Chat/ChatPanelWrapper.tsx +++ b/src/workspaces/officerdev/src/apps/Chat/ChatPanelWrapper.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useRef } from 'react'; +import { useCallback, useEffect, useRef, useState } from 'react'; import { useWorkspace } from '../../components/Workspace'; import { usePanelChannel } from 'hooks/usePanelChannel'; import { useSavedSessions } from 'state/useSavedSessions'; @@ -97,6 +97,12 @@ export const ChatPanelWrapper = () => { : {}; const [selection] = usePanelChannel('chat:panel-session', null); + const [resumeKey, setResumeKey] = useState(0); + const prevSelectionRef = useRef(selection); + if (selection !== prevSelectionRef.current) { + prevSelectionRef.current = selection; + if (selection?.resumeSummary) setResumeKey((k) => k + 1); + } const [, setActiveSession] = usePanelChannel('chat:active-session', null); const [, setPreviewRefresh] = usePanelChannel('preview:refresh', 0); const [, setFilesRefresh] = usePanelChannel('files:refresh-signal', 0); @@ -121,7 +127,7 @@ export const ChatPanelWrapper = () => { return ( { const { mode } = useTerminalMode(panelId); const hostRoot = root === '~' || root === 'officer.dev'; const sandboxed = !hostRoot && (cwd !== '~' || mode === 'sandboxed'); - const stateKey = dashboardId ? `ws-terminals-${mode}-${dashboardId}` : `ws-terminals-${mode}-default`; - const { value: terminals, setValue: setTerminals } = useDashboardState>(stateKey, EMPTY_TERMINALS); + const stateKey = (() => { + const hostSuffix = mode === 'host' ? 'host-' : ''; + const wsMatch = dashboardId?.match(/^ws-layout-(.+)$/); + if (wsMatch) return `ws-${hostSuffix}terminals-${wsMatch[1]}`; + const projMatch = dashboardId?.match(/^proj-layout-(.+)$/); + if (projMatch) return `proj-${hostSuffix}terminals-${projMatch[1]}`; + return `ws-${hostSuffix}terminals-default`; + })(); + const { value: terminals, setValue: setTerminals } = useDashboardState>( + stateKey, + EMPTY_TERMINALS, + ); const setTerminalsRef = useRef(setTerminals); setTerminalsRef.current = setTerminals;