diff --git a/packages/server/src/server/session.ts b/packages/server/src/server/session.ts index e7d7d194a..914c64d1d 100644 --- a/packages/server/src/server/session.ts +++ b/packages/server/src/server/session.ts @@ -114,6 +114,7 @@ import type { import { AgentStorage, type StoredAgentRecord } from "./agent/agent-storage.js"; import { buildProjectPlacementForCwd, + checkoutLiteFromGitSnapshot, detectStaleWorkspaces, deriveProjectKind, deriveProjectRootPath, @@ -5406,26 +5407,17 @@ export class Session { projectRecord?: PersistedProjectRecord | null, ): Promise { const base = await this.describeWorkspaceRecord(workspace, projectRecord); - let displayName = workspace.displayName; - try { - const placement = await this.buildProjectPlacement(workspace.cwd); - displayName = deriveWorkspaceDisplayName({ - cwd: workspace.cwd, - checkout: placement.checkout, - }); - } catch { - // Fall back to the persisted label if checkout metadata is unavailable. - } + const snapshot = await this.workspaceGitService.getSnapshot(workspace.cwd); - let snapshot: WorkspaceGitRuntimeSnapshot | null = null; - snapshot = this.workspaceGitService.peekSnapshot(workspace.cwd); + const checkout = checkoutLiteFromGitSnapshot(workspace.cwd, snapshot.git); + const displayName = deriveWorkspaceDisplayName({ cwd: workspace.cwd, checkout }); return { ...base, name: displayName, - diffStat: snapshot?.git.diffStat ?? null, - gitRuntime: snapshot ? this.buildWorkspaceGitRuntimePayload(snapshot) : undefined, - githubRuntime: snapshot ? this.buildWorkspaceGitHubRuntimePayload(snapshot) : undefined, + diffStat: snapshot.git.diffStat ?? null, + gitRuntime: this.buildWorkspaceGitRuntimePayload(snapshot), + githubRuntime: this.buildWorkspaceGitHubRuntimePayload(snapshot), }; } diff --git a/packages/server/src/server/session.workspaces.test.ts b/packages/server/src/server/session.workspaces.test.ts index 5dbb8b140..464c66fb6 100644 --- a/packages/server/src/server/session.workspaces.test.ts +++ b/packages/server/src/server/session.workspaces.test.ts @@ -1845,9 +1845,7 @@ describe("workspace aggregation", () => { }); const workspaceGitService = createNoopWorkspaceGitService(); workspaceGitService.peekSnapshot = vi.fn(() => runtimeSnapshot); - workspaceGitService.getSnapshot = vi.fn(async () => { - throw new Error("fetch_workspaces should not trigger per-workspace refreshes"); - }); + workspaceGitService.getSnapshot = vi.fn(async () => runtimeSnapshot); workspaceGitService.subscribe = vi.fn(async () => ({ initial: runtimeSnapshot, unsubscribe: () => {}, @@ -1901,8 +1899,7 @@ describe("workspace aggregation", () => { | { type: "fetch_workspaces_response"; payload: any } | undefined; - expect(workspaceGitService.peekSnapshot).toHaveBeenCalledWith("/tmp/repo"); - expect(workspaceGitService.getSnapshot).not.toHaveBeenCalled(); + expect(workspaceGitService.getSnapshot).toHaveBeenCalledWith("/tmp/repo"); expect(response?.payload.entries).toEqual([ expect.objectContaining({ id: "/tmp/repo", @@ -1953,9 +1950,7 @@ describe("workspace aggregation", () => { }); const workspaceGitService = createNoopWorkspaceGitService(); workspaceGitService.peekSnapshot = vi.fn(() => runtimeSnapshot); - workspaceGitService.getSnapshot = vi.fn(async () => { - throw new Error("workspace updates should use passive workspace git snapshots"); - }); + workspaceGitService.getSnapshot = vi.fn(async () => runtimeSnapshot); const session = createSessionForWorkspaceTests({ workspaceGitService, @@ -2008,8 +2003,7 @@ describe("workspace aggregation", () => { skipReconcile: true, }); - expect(workspaceGitService.peekSnapshot).toHaveBeenCalledWith("/tmp/repo"); - expect(workspaceGitService.getSnapshot).not.toHaveBeenCalled(); + expect(workspaceGitService.getSnapshot).toHaveBeenCalledWith("/tmp/repo"); expect(emitted).toContainEqual({ type: "workspace_update", payload: { diff --git a/packages/server/src/server/workspace-registry-model.ts b/packages/server/src/server/workspace-registry-model.ts index 43dde14fa..545095e71 100644 --- a/packages/server/src/server/workspace-registry-model.ts +++ b/packages/server/src/server/workspace-registry-model.ts @@ -137,6 +137,50 @@ export function deriveWorkspaceKind(checkout: ProjectCheckoutLitePayload): Persi return checkout.isPaseoOwnedWorktree ? "worktree" : "local_checkout"; } +export function checkoutLiteFromGitSnapshot( + cwd: string, + git: { + isGit: boolean; + currentBranch: string | null; + remoteUrl: string | null; + repoRoot: string | null; + isPaseoOwnedWorktree: boolean; + mainRepoRoot: string | null; + }, +): ProjectCheckoutLitePayload { + if (!git.isGit) { + return { + cwd, + isGit: false, + currentBranch: null, + remoteUrl: null, + worktreeRoot: null, + isPaseoOwnedWorktree: false, + mainRepoRoot: null, + }; + } + if (git.isPaseoOwnedWorktree && git.mainRepoRoot) { + return { + cwd, + isGit: true, + currentBranch: git.currentBranch, + remoteUrl: git.remoteUrl, + worktreeRoot: git.repoRoot ?? cwd, + isPaseoOwnedWorktree: true, + mainRepoRoot: git.mainRepoRoot, + }; + } + return { + cwd, + isGit: true, + currentBranch: git.currentBranch, + remoteUrl: git.remoteUrl, + worktreeRoot: git.repoRoot ?? cwd, + isPaseoOwnedWorktree: false, + mainRepoRoot: null, + }; +} + export async function detectStaleWorkspaces( input: DetectStaleWorkspacesInput, ): Promise> {