Merge branch 'main' into dev

# Conflicts:
#	packages/server/src/server/session.ts
This commit is contained in:
Mohamed Boudra
2026-04-14 13:41:01 +07:00
12 changed files with 138 additions and 29 deletions
+7
View File
@@ -113,6 +113,7 @@ import type { StoredAgentRecord } from "./agent/agent-storage.js";
import type { AgentStorage } from "./agent/agent-storage.js";
import { AGENT_PROVIDER_IDS } from "./agent/provider-manifest.js";
import {
checkoutLiteFromGitSnapshot,
normalizeWorkspaceId as normalizePersistedWorkspaceId,
deriveWorkspaceId,
deriveProjectRootPath,
@@ -5716,8 +5717,14 @@ export class Session {
if (!snapshot) {
return base;
}
const checkout = checkoutLiteFromGitSnapshot(workspace.cwd, snapshot.git);
const displayName = deriveWorkspaceDisplayName({ cwd: workspace.cwd, checkout });
return {
...base,
name: displayName,
diffStat: snapshot.git.diffStat ?? null,
gitRuntime: this.buildWorkspaceGitRuntimePayload(snapshot) ?? undefined,
githubRuntime: this.buildWorkspaceGitHubRuntimePayload(snapshot),
};
@@ -1890,9 +1890,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: () => {},
@@ -1946,8 +1944,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",
@@ -1998,9 +1995,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,
@@ -2053,8 +2048,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: {
@@ -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<Set<string>> {