diff --git a/packages/app/src/contexts/session-context.tsx b/packages/app/src/contexts/session-context.tsx index 63238e22d..94a3fd0c8 100644 --- a/packages/app/src/contexts/session-context.tsx +++ b/packages/app/src/contexts/session-context.tsx @@ -34,7 +34,6 @@ import { type Agent, type SessionState, type WorkspaceDescriptor, - mergeWorkspaceSnapshotWithExisting, normalizeWorkspaceDescriptor, } from "@/stores/session-store"; import { useDraftStore } from "@/stores/draft-store"; @@ -348,7 +347,6 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider } const workspaces = new Map(); - const existingWorkspaces = useSessionStore.getState().sessions[serverId]?.workspaces; let cursor: string | null = null; let includeSubscribe = options?.subscribe ?? false; @@ -364,13 +362,7 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider for (const entry of payload.entries) { const workspace = normalizeWorkspaceDescriptor(entry); - workspaces.set( - workspace.id, - mergeWorkspaceSnapshotWithExisting({ - incoming: workspace, - existing: existingWorkspaces?.get(workspace.id), - }), - ); + workspaces.set(workspace.id, workspace); } if (!payload.pageInfo.hasMore || !payload.pageInfo.nextCursor) { diff --git a/packages/app/src/hooks/use-sidebar-workspaces-list.ts b/packages/app/src/hooks/use-sidebar-workspaces-list.ts index effdc312e..abd8def14 100644 --- a/packages/app/src/hooks/use-sidebar-workspaces-list.ts +++ b/packages/app/src/hooks/use-sidebar-workspaces-list.ts @@ -1,7 +1,6 @@ import { useCallback, useEffect, useMemo, useSyncExternalStore } from "react"; import type { WorkspaceDescriptorPayload } from "@server/shared/messages"; import { - mergeWorkspaceSnapshotWithExisting, normalizeWorkspaceDescriptor, useSessionStore, type WorkspaceDescriptor, @@ -274,7 +273,6 @@ export function useSidebarWorkspacesList(options?: { } void (async () => { const next = new Map(); - const existingWorkspaces = useSessionStore.getState().sessions[serverId]?.workspaces; let cursor: string | null = null; try { while (true) { @@ -284,13 +282,7 @@ export function useSidebarWorkspacesList(options?: { }); for (const entry of payload.entries) { const workspace = toWorkspaceDescriptor(entry); - next.set( - workspace.id, - mergeWorkspaceSnapshotWithExisting({ - incoming: workspace, - existing: existingWorkspaces?.get(workspace.id), - }), - ); + next.set(workspace.id, workspace); } if (!payload.pageInfo.hasMore || !payload.pageInfo.nextCursor) { break; diff --git a/packages/app/src/stores/session-store.test.ts b/packages/app/src/stores/session-store.test.ts index 9b6edba4f..47fc3b8ac 100644 --- a/packages/app/src/stores/session-store.test.ts +++ b/packages/app/src/stores/session-store.test.ts @@ -4,7 +4,6 @@ import type { DaemonClient } from "@server/client/daemon-client"; import type { WorkspaceDescriptorPayload } from "@server/shared/messages"; import { - mergeWorkspaceSnapshotWithExisting, normalizeWorkspaceDescriptor, useSessionStore, type WorkspaceDescriptor, @@ -194,6 +193,25 @@ describe("mergeWorkspaces", () => { expect(after.workspaces.get("/repo/a")).not.toBe(beforeA); expect(after.workspaces.get("/repo/b")).toBe(beforeB); }); + + it("uses incoming null diff stat as authoritative", () => { + const store = useSessionStore.getState(); + initializeTestSession(); + const workspace = createWorkspace({ + id: "/repo/main", + diffStat: { additions: 2, deletions: 1 }, + }); + store.mergeWorkspaces("test-server", [workspace]); + const before = getTestSessionReferences(); + + store.mergeWorkspaces("test-server", [{ ...workspace, diffStat: null }]); + const after = getTestSessionReferences(); + + expect(after.sessions).not.toBe(before.sessions); + expect(after.session).not.toBe(before.session); + expect(after.workspaces).not.toBe(before.workspaces); + expect(after.workspaces.get(workspace.id)?.diffStat).toBeNull(); + }); }); describe("setWorkspaces", () => { @@ -215,25 +233,6 @@ describe("setWorkspaces", () => { expect(after.workspaces).toBe(before.workspaces); expect(after.workspaces.get(workspace.id)).toBe(before.workspaces.get(workspace.id)); }); - - it("stores replacement descriptors as-is when diff stat is cleared", () => { - const store = useSessionStore.getState(); - initializeTestSession(); - const workspace = createWorkspace({ - id: "/repo/main", - diffStat: { additions: 2, deletions: 1 }, - }); - store.setWorkspaces("test-server", new Map([[workspace.id, workspace]])); - const before = getTestSessionReferences(); - - store.setWorkspaces("test-server", new Map([[workspace.id, { ...workspace, diffStat: null }]])); - const after = getTestSessionReferences(); - - expect(after.sessions).not.toBe(before.sessions); - expect(after.session).not.toBe(before.session); - expect(after.workspaces).not.toBe(before.workspaces); - expect(after.workspaces.get(workspace.id)?.diffStat).toBeNull(); - }); }); describe("removeWorkspace", () => { @@ -277,34 +276,3 @@ describe("patchWorkspaceScripts", () => { expect(next.get(workspace.id)).toBe(workspace); }); }); - -describe("mergeWorkspaceSnapshotWithExisting", () => { - it("preserves the last known diff stat when a snapshot only has baseline null data", () => { - const existing = createWorkspace({ - id: "/tmp/repo", - diffStat: { additions: 4, deletions: 2 }, - }); - const incoming = createWorkspace({ - id: "/tmp/repo", - diffStat: null, - }); - - expect(mergeWorkspaceSnapshotWithExisting({ incoming, existing })).toEqual({ - ...incoming, - diffStat: { additions: 4, deletions: 2 }, - }); - }); - - it("uses the incoming diff stat when the server provides a known value", () => { - const existing = createWorkspace({ - id: "/tmp/repo", - diffStat: { additions: 4, deletions: 2 }, - }); - const incoming = createWorkspace({ - id: "/tmp/repo", - diffStat: { additions: 0, deletions: 0 }, - }); - - expect(mergeWorkspaceSnapshotWithExisting({ incoming, existing })).toEqual(incoming); - }); -}); diff --git a/packages/app/src/stores/session-store.ts b/packages/app/src/stores/session-store.ts index 5c8f71e87..916132da6 100644 --- a/packages/app/src/stores/session-store.ts +++ b/packages/app/src/stores/session-store.ts @@ -145,21 +145,6 @@ export function normalizeWorkspaceDescriptor( }; } -export function mergeWorkspaceSnapshotWithExisting(input: { - incoming: WorkspaceDescriptor; - existing?: WorkspaceDescriptor | null; -}): WorkspaceDescriptor { - const { incoming, existing } = input; - if (!existing || existing.id !== incoming.id) { - return incoming; - } - - return { - ...incoming, - diffStat: incoming.diffStat ?? existing.diffStat, - }; -} - function preserveWorkspaceDescriptorIdentity( incoming: WorkspaceDescriptor, existing?: WorkspaceDescriptor | null, @@ -1002,11 +987,7 @@ export const useSessionStore = create()( let changed = false; for (const workspace of nextEntries) { const existing = next.get(workspace.id); - const mergedWorkspace = mergeWorkspaceSnapshotWithExisting({ - incoming: workspace, - existing, - }); - const nextWorkspace = preserveWorkspaceDescriptorIdentity(mergedWorkspace, existing); + const nextWorkspace = preserveWorkspaceDescriptorIdentity(workspace, existing); if (existing === nextWorkspace) { continue; }