fix(projects): preserve placement reshape compatibility

This commit is contained in:
Mohamed Boudra
2026-07-17 06:28:31 +00:00
parent 373280bcd8
commit 287ba4babc
3 changed files with 129 additions and 59 deletions

View File

@@ -26,6 +26,8 @@ import {
createPersistedWorkspaceRecord,
type PersistedProjectRecord,
type PersistedWorkspaceRecord,
type ProjectRegistry,
type WorkspaceRegistry,
} from "../workspace-registry.js";
import type {
CreateScheduleInput,
@@ -53,6 +55,7 @@ import { PARENT_AGENT_ID_LABEL } from "@getpaseo/protocol/agent-labels";
import type { BrowserToolsBroker, BrowserToolsExecuteInput } from "../browser-tools/broker.js";
import type { BrowserToolsResponsePayload } from "../browser-tools/errors.js";
import { readPaseoWorktreeMetadata } from "../../utils/worktree-metadata.js";
import { createWorkspaceProvisioningService } from "../session/workspace-provisioning/workspace-provisioning-service.js";
const REPO_CWD = resolvePath("/tmp/repo");
const TARGET_CWD = resolvePath("/tmp/target");
@@ -659,13 +662,68 @@ function createPaseoWorktreeForMcpTest(options: {
paseoHome: options.paseoHome,
deps: { github },
});
const workspaceRegistry = {
const projectRegistry: ProjectRegistry = {
initialize: async () => {},
existsOnDisk: async () => true,
list: async () => Array.from(projects.values()),
get: async (projectId) => projects.get(projectId) ?? null,
getOrCreateActiveByRoot: async (allocation) => {
const existing = Array.from(projects.values()).find(
(project) =>
areEquivalentPaths(project.rootPath, allocation.rootPath) && !project.archivedAt,
);
if (existing) return existing;
const project = createPersistedProjectRecord({
projectId: `prj_test_${projects.size + 1}`,
rootPath: allocation.rootPath,
kind: allocation.kind,
displayName: allocation.displayName,
createdAt: allocation.timestamp,
updatedAt: allocation.timestamp,
});
projects.set(project.projectId, project);
return project;
},
upsert: async (record) => {
projects.set(record.projectId, record);
},
archive: async (projectId, archivedAt) => {
const project = projects.get(projectId);
if (project) projects.set(projectId, { ...project, archivedAt });
},
remove: async (projectId) => {
projects.delete(projectId);
},
};
const workspaceRegistry: WorkspaceRegistry = {
initialize: async () => {},
existsOnDisk: async () => true,
get: async (workspaceId: string) => workspaces.get(workspaceId) ?? null,
list: async () => Array.from(workspaces.values()),
update: async (workspaceId, updater) => {
const workspace = workspaces.get(workspaceId);
if (!workspace) return null;
const updated = updater(workspace);
workspaces.set(workspaceId, updated);
return updated;
},
upsert: async (record: PersistedWorkspaceRecord) => {
workspaces.set(record.workspaceId, record);
},
archive: async (workspaceId, archivedAt) => {
const workspace = workspaces.get(workspaceId);
if (workspace) workspaces.set(workspaceId, { ...workspace, archivedAt });
},
remove: async (workspaceId) => {
workspaces.delete(workspaceId);
},
};
const workspaceProvisioning = createWorkspaceProvisioningService({
projectRegistry,
workspaceRegistry,
workspaceGitService,
logger: createTestLogger(),
});
const workspaceAutoName = new WorkspaceAutoName({
agentManager: buildAgentManagerSpies() as unknown as AgentManager,
workspaceRegistry,
@@ -699,32 +757,8 @@ function createPaseoWorktreeForMcpTest(options: {
...(workflowOptions?.resolveDefaultBranch
? { resolveDefaultBranch: workflowOptions.resolveDefaultBranch }
: {}),
projectRegistry: {
get: async (projectId) => projects.get(projectId) ?? null,
getOrCreateActiveByRoot: async (allocation) => {
const existing = Array.from(projects.values()).find(
(project) =>
areEquivalentPaths(project.rootPath, allocation.rootPath) &&
!project.archivedAt,
);
if (existing) return existing;
const project = createPersistedProjectRecord({
projectId: `prj_test_${projects.size + 1}`,
rootPath: allocation.rootPath,
kind: allocation.kind,
displayName: allocation.displayName,
createdAt: allocation.timestamp,
updatedAt: allocation.timestamp,
});
projects.set(project.projectId, project);
return project;
},
upsert: async (record) => {
projects.set(record.projectId, record);
},
},
workspaceRegistry,
workspaceGitService,
workspaceProvisioning,
}),
warmWorkspaceGitData: async () => {},
autoNameWorkspaceBranchForFirstAgent: (autoNameInput) =>

View File

@@ -179,7 +179,7 @@ export function checkoutFromPersistedWorkspacePlacement(input: {
...checkout,
isGit: true,
isPaseoOwnedWorktree: false,
mainRepoRoot: workspace.mainRepoRoot,
mainRepoRoot: workspace.mainRepoRoot ?? null,
};
}

View File

@@ -36,6 +36,8 @@ import {
createPersistedProjectRecord,
type PersistedProjectRecord,
type PersistedWorkspaceRecord,
type ProjectRegistry,
type WorkspaceRegistry,
} from "./workspace-registry.js";
import type { GitHubService } from "../services/github-service.js";
import { areEquivalentPaths } from "../utils/path.js";
@@ -46,6 +48,7 @@ import {
import { WorkspaceGitServiceImpl } from "./workspace-git-service.js";
import type { WorkspaceGitService } from "./workspace-git-service.js";
import { isPlatform } from "../test-utils/platform.js";
import { createWorkspaceProvisioningService } from "./session/workspace-provisioning/workspace-provisioning-service.js";
interface LegacyCreateWorktreeTestOptions {
branchName: string;
@@ -276,6 +279,70 @@ function createPaseoWorktreeForTest(options: {
github: createGitHubServiceStub(),
},
});
const projectRegistry: ProjectRegistry = {
initialize: async () => {},
existsOnDisk: async () => true,
list: async () => Array.from(projects.values()),
get: async (projectId) => projects.get(projectId) ?? null,
getOrCreateActiveByRoot: async (allocation) => {
const existing = Array.from(projects.values()).find(
(project) =>
areEquivalentPaths(project.rootPath, allocation.rootPath) && !project.archivedAt,
);
if (existing) return existing;
const project = createPersistedProjectRecord({
projectId: `prj_test_${projects.size + 1}`,
rootPath: allocation.rootPath,
kind: allocation.kind,
displayName: allocation.displayName,
createdAt: allocation.timestamp,
updatedAt: allocation.timestamp,
});
projects.set(project.projectId, project);
return project;
},
upsert: async (record) => {
options.events?.push(`project:${record.projectId}`);
projects.set(record.projectId, record);
},
archive: async (projectId, archivedAt) => {
const project = projects.get(projectId);
if (project) projects.set(projectId, { ...project, archivedAt });
},
remove: async (projectId) => {
projects.delete(projectId);
},
};
const workspaceRegistry: WorkspaceRegistry = {
initialize: async () => {},
existsOnDisk: async () => true,
list: async () => Array.from(workspaces.values()),
get: async (workspaceId) => workspaces.get(workspaceId) ?? null,
update: async (workspaceId, updater) => {
const workspace = workspaces.get(workspaceId);
if (!workspace) return null;
const updated = updater(workspace);
workspaces.set(workspaceId, updated);
return updated;
},
upsert: async (record) => {
options.events?.push(`workspace:${record.workspaceId}`);
workspaces.set(record.workspaceId, record);
},
archive: async (workspaceId, archivedAt) => {
const workspace = workspaces.get(workspaceId);
if (workspace) workspaces.set(workspaceId, { ...workspace, archivedAt });
},
remove: async (workspaceId) => {
workspaces.delete(workspaceId);
},
};
const workspaceProvisioning = createWorkspaceProvisioningService({
projectRegistry,
workspaceRegistry,
workspaceGitService,
logger: createLogger(),
});
return (input, serviceOptions) => {
return createPaseoWorktreeService(input, {
@@ -283,39 +350,8 @@ function createPaseoWorktreeForTest(options: {
...(serviceOptions?.resolveDefaultBranch
? { resolveDefaultBranch: serviceOptions.resolveDefaultBranch }
: {}),
projectRegistry: {
get: async (projectId) => projects.get(projectId) ?? null,
getOrCreateActiveByRoot: async (allocation) => {
const existing = Array.from(projects.values()).find(
(project) =>
areEquivalentPaths(project.rootPath, allocation.rootPath) && !project.archivedAt,
);
if (existing) return existing;
const project = createPersistedProjectRecord({
projectId: `prj_test_${projects.size + 1}`,
rootPath: allocation.rootPath,
kind: allocation.kind,
displayName: allocation.displayName,
createdAt: allocation.timestamp,
updatedAt: allocation.timestamp,
});
projects.set(project.projectId, project);
return project;
},
upsert: async (record) => {
options.events?.push(`project:${record.projectId}`);
projects.set(record.projectId, record);
},
},
workspaceRegistry: {
get: async (workspaceId) => workspaces.get(workspaceId) ?? null,
list: async () => Array.from(workspaces.values()),
upsert: async (record) => {
options.events?.push(`workspace:${record.workspaceId}`);
workspaces.set(record.workspaceId, record);
},
},
workspaceGitService,
workspaceProvisioning,
});
};
}