fix terminal state key leaking phantom dashboards; fix infinite loop in chat panel resume

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-06 20:39:44 +00:00
co-authored by Claude Opus 4.6
parent 406d8f9e54
commit 8f46f9170a
2 changed files with 20 additions and 4 deletions
@@ -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<ChatSessionSelection | null>('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<string | null>('chat:active-session', null);
const [, setPreviewRefresh] = usePanelChannel<number>('preview:refresh', 0);
const [, setFilesRefresh] = usePanelChannel<number>('files:refresh-signal', 0);
@@ -121,7 +127,7 @@ export const ChatPanelWrapper = () => {
return (
<ChatPanelInner
key={resumeSummary ? `resume-${Date.now()}` : (sessionId ?? 'new')}
key={resumeSummary ? `resume-${resumeKey}` : (sessionId ?? 'new')}
sessionId={sessionId}
model={model}
resumeSummary={resumeSummary}
@@ -13,8 +13,18 @@ export const TerminalWrapper = ({ panelId }: { panelId: string }) => {
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<Record<string, string>>(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<Record<string, string>>(
stateKey,
EMPTY_TERMINALS,
);
const setTerminalsRef = useRef(setTerminals);
setTerminalsRef.current = setTerminals;