From 46a6bced9660a4889a55c626c508880d85000646 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Mon, 13 Jul 2026 01:05:24 +0200 Subject: [PATCH] fix(app): preserve sync state across retries --- packages/app/src/contexts/session-context.tsx | 6 ++++- packages/app/src/panels/agent-panel.tsx | 6 ++++- .../screens/workspace/workspace-screen.tsx | 2 +- .../agent-directory-reconciliation.test.ts | 10 +++++-- .../utils/agent-directory-reconciliation.ts | 27 ++++++++++--------- 5 files changed, 33 insertions(+), 18 deletions(-) diff --git a/packages/app/src/contexts/session-context.tsx b/packages/app/src/contexts/session-context.tsx index 3b0e4771ea..6e7128d704 100644 --- a/packages/app/src/contexts/session-context.tsx +++ b/packages/app/src/contexts/session-context.tsx @@ -412,7 +412,11 @@ function finalizeTimelineApplication(input: { } if (result.clearInitializing) { markAgentHistorySynchronized(serverId, agentId); - getHostRuntimeStore().drainQueuedAgentMessage(serverId, agentId); + const session = useSessionStore.getState().sessions[serverId]; + const agent = session?.agents.get(agentId) ?? session?.agentDetails.get(agentId); + if (agent && agent.status !== "running") { + getHostRuntimeStore().drainQueuedAgentMessage(serverId, agentId); + } } } diff --git a/packages/app/src/panels/agent-panel.tsx b/packages/app/src/panels/agent-panel.tsx index 77f2535530..bb67272f61 100644 --- a/packages/app/src/panels/agent-panel.tsx +++ b/packages/app/src/panels/agent-panel.tsx @@ -908,7 +908,11 @@ function ChatAgentContent({ return; } if (agentState.id && hasAppliedAuthoritativeHistory) { - if (missingAgentState.kind === "resolving" || missingAgentState.kind === "not_found") { + if ( + missingAgentState.kind === "resolving" || + missingAgentState.kind === "not_found" || + missingAgentState.kind === "error" + ) { setMissingAgentState(reconcileMissingAgentStateWithPresentAgent); } return; diff --git a/packages/app/src/screens/workspace/workspace-screen.tsx b/packages/app/src/screens/workspace/workspace-screen.tsx index c7a55aefb6..49eb175594 100644 --- a/packages/app/src/screens/workspace/workspace-screen.tsx +++ b/packages/app/src/screens/workspace/workspace-screen.tsx @@ -2023,7 +2023,7 @@ function WorkspaceScreenContent({ layout: workspaceLayout, tabs: uiTabs, routeFocused: isRouteFocused, - focusedPaneOnly: isMobile || isFocusModeEnabled, + focusedPaneOnly: isMobile || isFocusModeEnabled || !supportsDesktopPaneSplits(), }), [isFocusModeEnabled, isMobile, isRouteFocused, uiTabs, workspaceLayout], ); diff --git a/packages/app/src/utils/agent-directory-reconciliation.test.ts b/packages/app/src/utils/agent-directory-reconciliation.test.ts index cb52bf69da..7fa313c04c 100644 --- a/packages/app/src/utils/agent-directory-reconciliation.test.ts +++ b/packages/app/src/utils/agent-directory-reconciliation.test.ts @@ -113,6 +113,11 @@ describe("agent directory reconciliation", () => { }); it("keeps newer page metadata when a stale buffered upsert arrives", () => { + const snapshotEntry = entry("agent", "running"); + const staleProject = { + ...snapshotEntry.project, + projectName: "stale project", + }; const result = reconcileAgentDirectory({ previous: new Map([["agent", replica("agent", "running")]]), snapshot: [ @@ -133,7 +138,7 @@ describe("agent directory reconciliation", () => { title: "stale live", updatedAt: "2026-07-12T11:00:00.000Z", }, - project: entry("agent", "idle").project, + project: staleProject, }, ], }); @@ -141,8 +146,9 @@ describe("agent directory reconciliation", () => { expect({ title: result.entries[0]?.agent.title, status: result.entries[0]?.agent.status, + projectName: result.entries[0]?.project.projectName, stopped: result.stoppedRunningAgentIds, - }).toEqual({ title: "newer page", status: "running", stopped: [] }); + }).toEqual({ title: "newer page", status: "running", projectName: "repo", stopped: [] }); }); it("accepts usage from a stale buffered upsert without regressing metadata", () => { diff --git a/packages/app/src/utils/agent-directory-reconciliation.ts b/packages/app/src/utils/agent-directory-reconciliation.ts index 14587cca9f..ecbd936afc 100644 --- a/packages/app/src/utils/agent-directory-reconciliation.ts +++ b/packages/app/src/utils/agent-directory-reconciliation.ts @@ -33,22 +33,23 @@ export function reconcileAgentDirectory(input: { } statuses.set(delta.agent.id, acceptedAgent.status); const previousProject = previousEntry?.project; + const acceptedProject = + acceptedAgent === delta.agent ? (delta.project ?? previousProject) : previousProject; entries.set(delta.agent.id, { agent: acceptedAgent, - project: delta.project ?? - previousProject ?? { - projectKey: delta.agent.cwd, - projectName: /[^/]+$/.exec(delta.agent.cwd)?.[0] ?? delta.agent.cwd, - checkout: { - cwd: delta.agent.cwd, - isGit: false, - currentBranch: null, - remoteUrl: null, - worktreeRoot: null, - isPaseoOwnedWorktree: false, - mainRepoRoot: null, - }, + project: acceptedProject ?? { + projectKey: delta.agent.cwd, + projectName: /[^/]+$/.exec(delta.agent.cwd)?.[0] ?? delta.agent.cwd, + checkout: { + cwd: delta.agent.cwd, + isGit: false, + currentBranch: null, + remoteUrl: null, + worktreeRoot: null, + isPaseoOwnedWorktree: false, + mainRepoRoot: null, }, + }, }); }