Spaces:
Paused
Paused
| import type { | |
| ExecutionWorkspaceMode, | |
| ExecutionWorkspaceStrategy, | |
| IssueExecutionWorkspaceSettings, | |
| ProjectExecutionWorkspaceDefaultMode, | |
| ProjectExecutionWorkspacePolicy, | |
| } from "@paperclipai/shared"; | |
| import { asString, parseObject } from "../adapters/utils.js"; | |
| type ParsedExecutionWorkspaceMode = Exclude<ExecutionWorkspaceMode, "inherit" | "reuse_existing">; | |
| function cloneRecord(value: Record<string, unknown> | null | undefined): Record<string, unknown> | null { | |
| if (!value) return null; | |
| return { ...value }; | |
| } | |
| function parseExecutionWorkspaceStrategy(raw: unknown): ExecutionWorkspaceStrategy | null { | |
| const parsed = parseObject(raw); | |
| const type = asString(parsed.type, ""); | |
| if (type !== "project_primary" && type !== "git_worktree" && type !== "adapter_managed" && type !== "cloud_sandbox") { | |
| return null; | |
| } | |
| return { | |
| type, | |
| ...(typeof parsed.baseRef === "string" ? { baseRef: parsed.baseRef } : {}), | |
| ...(typeof parsed.branchTemplate === "string" ? { branchTemplate: parsed.branchTemplate } : {}), | |
| ...(typeof parsed.worktreeParentDir === "string" ? { worktreeParentDir: parsed.worktreeParentDir } : {}), | |
| ...(typeof parsed.provisionCommand === "string" ? { provisionCommand: parsed.provisionCommand } : {}), | |
| ...(typeof parsed.teardownCommand === "string" ? { teardownCommand: parsed.teardownCommand } : {}), | |
| }; | |
| } | |
| export function parseProjectExecutionWorkspacePolicy(raw: unknown): ProjectExecutionWorkspacePolicy | null { | |
| const parsed = parseObject(raw); | |
| if (Object.keys(parsed).length === 0) return null; | |
| const enabled = typeof parsed.enabled === "boolean" ? parsed.enabled : false; | |
| const workspaceStrategy = parseExecutionWorkspaceStrategy(parsed.workspaceStrategy); | |
| const defaultMode = asString(parsed.defaultMode, ""); | |
| const defaultProjectWorkspaceId = | |
| typeof parsed.defaultProjectWorkspaceId === "string" ? parsed.defaultProjectWorkspaceId : undefined; | |
| const allowIssueOverride = | |
| typeof parsed.allowIssueOverride === "boolean" ? parsed.allowIssueOverride : undefined; | |
| const normalizedDefaultMode = (() => { | |
| if ( | |
| defaultMode === "shared_workspace" || | |
| defaultMode === "isolated_workspace" || | |
| defaultMode === "operator_branch" || | |
| defaultMode === "adapter_default" | |
| ) { | |
| return defaultMode as ProjectExecutionWorkspaceDefaultMode; | |
| } | |
| if (defaultMode === "project_primary") return "shared_workspace"; | |
| if (defaultMode === "isolated") return "isolated_workspace"; | |
| return undefined; | |
| })(); | |
| return { | |
| enabled, | |
| ...(normalizedDefaultMode ? { defaultMode: normalizedDefaultMode } : {}), | |
| ...(allowIssueOverride !== undefined ? { allowIssueOverride } : {}), | |
| ...(defaultProjectWorkspaceId ? { defaultProjectWorkspaceId } : {}), | |
| ...(workspaceStrategy ? { workspaceStrategy } : {}), | |
| ...(parsed.workspaceRuntime && typeof parsed.workspaceRuntime === "object" && !Array.isArray(parsed.workspaceRuntime) | |
| ? { workspaceRuntime: { ...(parsed.workspaceRuntime as Record<string, unknown>) } } | |
| : {}), | |
| ...(parsed.branchPolicy && typeof parsed.branchPolicy === "object" && !Array.isArray(parsed.branchPolicy) | |
| ? { branchPolicy: { ...(parsed.branchPolicy as Record<string, unknown>) } } | |
| : {}), | |
| ...(parsed.pullRequestPolicy && typeof parsed.pullRequestPolicy === "object" && !Array.isArray(parsed.pullRequestPolicy) | |
| ? { pullRequestPolicy: { ...(parsed.pullRequestPolicy as Record<string, unknown>) } } | |
| : {}), | |
| ...(parsed.runtimePolicy && typeof parsed.runtimePolicy === "object" && !Array.isArray(parsed.runtimePolicy) | |
| ? { runtimePolicy: { ...(parsed.runtimePolicy as Record<string, unknown>) } } | |
| : {}), | |
| ...(parsed.cleanupPolicy && typeof parsed.cleanupPolicy === "object" && !Array.isArray(parsed.cleanupPolicy) | |
| ? { cleanupPolicy: { ...(parsed.cleanupPolicy as Record<string, unknown>) } } | |
| : {}), | |
| }; | |
| } | |
| export function gateProjectExecutionWorkspacePolicy( | |
| projectPolicy: ProjectExecutionWorkspacePolicy | null, | |
| isolatedWorkspacesEnabled: boolean, | |
| ): ProjectExecutionWorkspacePolicy | null { | |
| if (!isolatedWorkspacesEnabled) return null; | |
| return projectPolicy; | |
| } | |
| export function parseIssueExecutionWorkspaceSettings(raw: unknown): IssueExecutionWorkspaceSettings | null { | |
| const parsed = parseObject(raw); | |
| if (Object.keys(parsed).length === 0) return null; | |
| const workspaceStrategy = parseExecutionWorkspaceStrategy(parsed.workspaceStrategy); | |
| const mode = asString(parsed.mode, ""); | |
| const normalizedMode = (() => { | |
| if ( | |
| mode === "inherit" || | |
| mode === "shared_workspace" || | |
| mode === "isolated_workspace" || | |
| mode === "operator_branch" || | |
| mode === "reuse_existing" || | |
| mode === "agent_default" | |
| ) { | |
| return mode; | |
| } | |
| if (mode === "project_primary") return "shared_workspace"; | |
| if (mode === "isolated") return "isolated_workspace"; | |
| return ""; | |
| })(); | |
| return { | |
| ...(normalizedMode | |
| ? { mode: normalizedMode as IssueExecutionWorkspaceSettings["mode"] } | |
| : {}), | |
| ...(workspaceStrategy ? { workspaceStrategy } : {}), | |
| ...(parsed.workspaceRuntime && typeof parsed.workspaceRuntime === "object" && !Array.isArray(parsed.workspaceRuntime) | |
| ? { workspaceRuntime: { ...(parsed.workspaceRuntime as Record<string, unknown>) } } | |
| : {}), | |
| }; | |
| } | |
| export function defaultIssueExecutionWorkspaceSettingsForProject( | |
| projectPolicy: ProjectExecutionWorkspacePolicy | null, | |
| ): IssueExecutionWorkspaceSettings | null { | |
| if (!projectPolicy?.enabled) return null; | |
| return { | |
| mode: | |
| projectPolicy.defaultMode === "isolated_workspace" | |
| ? "isolated_workspace" | |
| : projectPolicy.defaultMode === "operator_branch" | |
| ? "operator_branch" | |
| : projectPolicy.defaultMode === "adapter_default" | |
| ? "agent_default" | |
| : "shared_workspace", | |
| }; | |
| } | |
| export function issueExecutionWorkspaceModeForPersistedWorkspace( | |
| mode: string | null | undefined, | |
| ): IssueExecutionWorkspaceSettings["mode"] { | |
| if (mode === null || mode === undefined) { | |
| return "agent_default"; | |
| } | |
| if (mode === "isolated_workspace" || mode === "operator_branch" || mode === "shared_workspace") { | |
| return mode; | |
| } | |
| if (mode === "adapter_managed" || mode === "cloud_sandbox") { | |
| return "agent_default"; | |
| } | |
| return "shared_workspace"; | |
| } | |
| export function resolveExecutionWorkspaceMode(input: { | |
| projectPolicy: ProjectExecutionWorkspacePolicy | null; | |
| issueSettings: IssueExecutionWorkspaceSettings | null; | |
| legacyUseProjectWorkspace: boolean | null; | |
| }): ParsedExecutionWorkspaceMode { | |
| const issueMode = input.issueSettings?.mode; | |
| if (issueMode && issueMode !== "inherit" && issueMode !== "reuse_existing") { | |
| return issueMode; | |
| } | |
| if (input.projectPolicy?.enabled) { | |
| if (input.projectPolicy.defaultMode === "isolated_workspace") return "isolated_workspace"; | |
| if (input.projectPolicy.defaultMode === "operator_branch") return "operator_branch"; | |
| if (input.projectPolicy.defaultMode === "adapter_default") return "agent_default"; | |
| return "shared_workspace"; | |
| } | |
| if (input.legacyUseProjectWorkspace === false) { | |
| return "agent_default"; | |
| } | |
| return "shared_workspace"; | |
| } | |
| export function buildExecutionWorkspaceAdapterConfig(input: { | |
| agentConfig: Record<string, unknown>; | |
| projectPolicy: ProjectExecutionWorkspacePolicy | null; | |
| issueSettings: IssueExecutionWorkspaceSettings | null; | |
| mode: ParsedExecutionWorkspaceMode; | |
| legacyUseProjectWorkspace: boolean | null; | |
| }): Record<string, unknown> { | |
| const nextConfig = { ...input.agentConfig }; | |
| const projectHasPolicy = Boolean(input.projectPolicy?.enabled); | |
| const issueHasWorkspaceOverrides = Boolean( | |
| input.issueSettings?.mode || | |
| input.issueSettings?.workspaceStrategy || | |
| input.issueSettings?.workspaceRuntime, | |
| ); | |
| const hasWorkspaceControl = projectHasPolicy || issueHasWorkspaceOverrides || input.legacyUseProjectWorkspace === false; | |
| if (hasWorkspaceControl) { | |
| if (input.mode === "isolated_workspace") { | |
| const strategy = | |
| input.issueSettings?.workspaceStrategy ?? | |
| input.projectPolicy?.workspaceStrategy ?? | |
| parseExecutionWorkspaceStrategy(nextConfig.workspaceStrategy) ?? | |
| ({ type: "git_worktree" } satisfies ExecutionWorkspaceStrategy); | |
| nextConfig.workspaceStrategy = strategy as unknown as Record<string, unknown>; | |
| } else { | |
| delete nextConfig.workspaceStrategy; | |
| } | |
| if (input.mode === "agent_default") { | |
| delete nextConfig.workspaceRuntime; | |
| } else if (input.issueSettings?.workspaceRuntime) { | |
| nextConfig.workspaceRuntime = cloneRecord(input.issueSettings.workspaceRuntime) ?? undefined; | |
| } else if (input.projectPolicy?.workspaceRuntime) { | |
| nextConfig.workspaceRuntime = cloneRecord(input.projectPolicy.workspaceRuntime) ?? undefined; | |
| } | |
| } | |
| return nextConfig; | |
| } | |