import { describe, expect, it } from "vitest"; import { buildExecutionWorkspaceAdapterConfig, defaultIssueExecutionWorkspaceSettingsForProject, gateProjectExecutionWorkspacePolicy, parseIssueExecutionWorkspaceSettings, parseProjectExecutionWorkspacePolicy, resolveExecutionWorkspaceMode, } from "../services/execution-workspace-policy.ts"; describe("execution workspace policy helpers", () => { it("defaults new issue settings from enabled project policy", () => { expect( defaultIssueExecutionWorkspaceSettingsForProject({ enabled: true, defaultMode: "isolated_workspace", }), ).toEqual({ mode: "isolated_workspace" }); expect( defaultIssueExecutionWorkspaceSettingsForProject({ enabled: true, defaultMode: "shared_workspace", }), ).toEqual({ mode: "shared_workspace" }); expect(defaultIssueExecutionWorkspaceSettingsForProject(null)).toBeNull(); }); it("prefers explicit issue mode over project policy and legacy overrides", () => { expect( resolveExecutionWorkspaceMode({ projectPolicy: { enabled: true, defaultMode: "shared_workspace" }, issueSettings: { mode: "isolated_workspace" }, legacyUseProjectWorkspace: false, }), ).toBe("isolated_workspace"); }); it("falls back to project policy before legacy project-workspace compatibility flag", () => { expect( resolveExecutionWorkspaceMode({ projectPolicy: { enabled: true, defaultMode: "isolated_workspace" }, issueSettings: null, legacyUseProjectWorkspace: false, }), ).toBe("isolated_workspace"); expect( resolveExecutionWorkspaceMode({ projectPolicy: null, issueSettings: null, legacyUseProjectWorkspace: false, }), ).toBe("agent_default"); }); it("applies project policy strategy and runtime defaults when isolation is enabled", () => { const result = buildExecutionWorkspaceAdapterConfig({ agentConfig: { workspaceStrategy: { type: "project_primary" }, }, projectPolicy: { enabled: true, defaultMode: "isolated_workspace", workspaceStrategy: { type: "git_worktree", baseRef: "origin/main", provisionCommand: "bash ./scripts/provision-worktree.sh", }, workspaceRuntime: { services: [{ name: "web", command: "pnpm dev" }], }, }, issueSettings: null, mode: "isolated_workspace", legacyUseProjectWorkspace: null, }); expect(result.workspaceStrategy).toEqual({ type: "git_worktree", baseRef: "origin/main", provisionCommand: "bash ./scripts/provision-worktree.sh", }); expect(result.workspaceRuntime).toEqual({ services: [{ name: "web", command: "pnpm dev" }], }); }); it("clears managed workspace strategy when issue opts out to project primary or agent default", () => { const baseConfig = { workspaceStrategy: { type: "git_worktree", branchTemplate: "{{issue.identifier}}" }, workspaceRuntime: { services: [{ name: "web" }] }, }; expect( buildExecutionWorkspaceAdapterConfig({ agentConfig: baseConfig, projectPolicy: { enabled: true, defaultMode: "isolated_workspace" }, issueSettings: { mode: "shared_workspace" }, mode: "shared_workspace", legacyUseProjectWorkspace: null, }).workspaceStrategy, ).toBeUndefined(); const agentDefault = buildExecutionWorkspaceAdapterConfig({ agentConfig: baseConfig, projectPolicy: null, issueSettings: { mode: "agent_default" }, mode: "agent_default", legacyUseProjectWorkspace: null, }); expect(agentDefault.workspaceStrategy).toBeUndefined(); expect(agentDefault.workspaceRuntime).toBeUndefined(); }); it("parses persisted JSON payloads into typed project and issue workspace settings", () => { expect( parseProjectExecutionWorkspacePolicy({ enabled: true, defaultMode: "isolated", workspaceStrategy: { type: "git_worktree", worktreeParentDir: ".paperclip/worktrees", provisionCommand: "bash ./scripts/provision-worktree.sh", teardownCommand: "bash ./scripts/teardown-worktree.sh", }, }), ).toEqual({ enabled: true, defaultMode: "isolated_workspace", workspaceStrategy: { type: "git_worktree", worktreeParentDir: ".paperclip/worktrees", provisionCommand: "bash ./scripts/provision-worktree.sh", teardownCommand: "bash ./scripts/teardown-worktree.sh", }, }); expect( parseIssueExecutionWorkspaceSettings({ mode: "project_primary", }), ).toEqual({ mode: "shared_workspace", }); }); it("disables project execution workspace policy when the instance flag is off", () => { expect( gateProjectExecutionWorkspacePolicy( { enabled: true, defaultMode: "isolated_workspace" }, false, ), ).toBeNull(); expect( gateProjectExecutionWorkspacePolicy( { enabled: true, defaultMode: "isolated_workspace" }, true, ), ).toEqual({ enabled: true, defaultMode: "isolated_workspace" }); }); });