mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-23 09:07:46 +02:00
Restrict reusable workspace candidates
This commit is contained in:
1 parent
4c9219559a
commit
e35daf5256
2 files changed
+80
-1
No files matched your search
@@ -343,6 +343,83 @@ describeEmbeddedPostgres("executionWorkspaceService.getCloseReadiness", () => {
|
||||
expect(readExecutionWorkspaceConfig(byId.get(untouchedWorkspaceId) ?? null)).toBeNull();
|
||||
});
|
||||
|
||||
it("limits reusable summaries to open non-shared execution workspaces", async () => {
|
||||
const companyId = randomUUID();
|
||||
const projectId = randomUUID();
|
||||
const openWorkspaceId = randomUUID();
|
||||
const sharedWorkspaceId = randomUUID();
|
||||
const closedWorkspaceId = randomUUID();
|
||||
|
||||
await db.insert(companies).values({
|
||||
id: companyId,
|
||||
name: "Paperclip",
|
||||
issuePrefix: "PAP",
|
||||
requireBoardApprovalForNewAgents: false,
|
||||
});
|
||||
await db.insert(projects).values({
|
||||
id: projectId,
|
||||
companyId,
|
||||
name: "Reusable workspaces",
|
||||
status: "in_progress",
|
||||
executionWorkspacePolicy: {
|
||||
enabled: true,
|
||||
},
|
||||
});
|
||||
await db.insert(executionWorkspaces).values([
|
||||
{
|
||||
id: openWorkspaceId,
|
||||
companyId,
|
||||
projectId,
|
||||
mode: "isolated_workspace",
|
||||
strategyType: "git_worktree",
|
||||
name: "Open isolated workspace",
|
||||
status: "idle",
|
||||
providerType: "git_worktree",
|
||||
cwd: "/tmp/open-workspace",
|
||||
branchName: "paperclip/open",
|
||||
},
|
||||
{
|
||||
id: sharedWorkspaceId,
|
||||
companyId,
|
||||
projectId,
|
||||
mode: "shared_workspace",
|
||||
strategyType: "project_primary",
|
||||
name: "Shared session",
|
||||
status: "active",
|
||||
providerType: "local_fs",
|
||||
cwd: "/tmp/project-primary",
|
||||
},
|
||||
{
|
||||
id: closedWorkspaceId,
|
||||
companyId,
|
||||
projectId,
|
||||
mode: "isolated_workspace",
|
||||
strategyType: "git_worktree",
|
||||
name: "Closed isolated workspace",
|
||||
status: "active",
|
||||
providerType: "git_worktree",
|
||||
cwd: "/tmp/closed-workspace",
|
||||
closedAt: new Date("2026-05-23T20:00:00.000Z"),
|
||||
},
|
||||
]);
|
||||
|
||||
const summaries = await svc.listSummaries(companyId, {
|
||||
projectId,
|
||||
reuseEligible: true,
|
||||
});
|
||||
|
||||
expect(summaries).toEqual([
|
||||
expect.objectContaining({
|
||||
id: openWorkspaceId,
|
||||
name: "Open isolated workspace",
|
||||
mode: "isolated_workspace",
|
||||
status: "idle",
|
||||
cwd: "/tmp/open-workspace",
|
||||
branchName: "paperclip/open",
|
||||
}),
|
||||
]);
|
||||
});
|
||||
|
||||
it("warns about dirty and unmerged git worktrees and reports cleanup actions", async () => {
|
||||
const repoRoot = await createTempRepo();
|
||||
tempDirs.add(repoRoot);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { execFile } from "node:child_process";
|
||||
import fs from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
import { and, desc, eq, inArray } from "drizzle-orm";
|
||||
import { and, desc, eq, inArray, isNull } from "drizzle-orm";
|
||||
import type { Db } from "@paperclipai/db";
|
||||
import { executionWorkspaces, issues, projects, projectWorkspaces, workspaceRuntimeServices } from "@paperclipai/db";
|
||||
import type {
|
||||
@@ -418,6 +418,8 @@ export function executionWorkspaceService(db: Db) {
|
||||
}
|
||||
if (filters?.reuseEligible) {
|
||||
conditions.push(inArray(executionWorkspaces.status, ["active", "idle", "in_review"]));
|
||||
conditions.push(isNull(executionWorkspaces.closedAt));
|
||||
conditions.push(inArray(executionWorkspaces.mode, ["isolated_workspace", "operator_branch", "adapter_managed", "cloud_sandbox"]));
|
||||
}
|
||||
return conditions;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user