diff --git a/packages/paperclip-runner/scripts/candidate-provider-pack.mjs b/packages/paperclip-runner/scripts/candidate-provider-pack.mjs index 083d8fbb3a4..3d2f73f16c8 100644 --- a/packages/paperclip-runner/scripts/candidate-provider-pack.mjs +++ b/packages/paperclip-runner/scripts/candidate-provider-pack.mjs @@ -1,3 +1,4 @@ +import { materializePinnedCursorDistribution } from "./materialize-cursor-distribution.mjs"; const CANDIDATES = new Set(["cursor", "copilot", "pi"]); export function parseProviderPackArguments(args) { @@ -18,5 +19,11 @@ export function parseProviderPackArguments(args) { /** Closed source-owned builder registry; provider branches add their exact pins. */ export async function materializeCandidateProviderPack({ provider, outputRoot }) { if (!CANDIDATES.has(provider)) throw new Error("Unknown candidate provider"); + if (provider === "cursor") { + const result = await materializePinnedCursorDistribution({ destination: outputRoot }); + return { version: result.version, + profileDigest: "sha256:1157a5d071abbd57ab132f22bace75c65e84cc47a045b0023475488755e14899", + closureDigest: `sha256:${result.closureSha256}` }; + } throw new Error(`The ${provider} candidate distribution builder is not included in this source revision`); } diff --git a/packages/paperclip-runner/src/drivers/acpx/capability-profiles.ts b/packages/paperclip-runner/src/drivers/acpx/capability-profiles.ts index 4a70c22e25b..18f9ad57e8d 100644 --- a/packages/paperclip-runner/src/drivers/acpx/capability-profiles.ts +++ b/packages/paperclip-runner/src/drivers/acpx/capability-profiles.ts @@ -43,7 +43,7 @@ export const ACPX_CAPABILITY_PROFILES: Readonly { - return {}; +export function acpxProfileClientCapabilities(agent: QualifiedAcpxAgent): Record { + return agent === "cursor" ? structuredClone(CURSOR_CLIENT_CAPABILITIES) : {}; } /** Reject an oversized approval document; never silently approve a truncated revision. */ diff --git a/packages/paperclip-runner/src/drivers/acpx/profile-installation.ts b/packages/paperclip-runner/src/drivers/acpx/profile-installation.ts index a78aa47c6c5..4ac92c30880 100644 --- a/packages/paperclip-runner/src/drivers/acpx/profile-installation.ts +++ b/packages/paperclip-runner/src/drivers/acpx/profile-installation.ts @@ -1,8 +1,11 @@ +import { verifyCursorInstallation } from "./cursor-installation.js"; +import { assertCursorWorkspacePolicy } from "./cursor-launch-policy.js"; import type { QualifiedAcpxAgent, QualifiedAcpxProfile } from "./qualified-profiles.js"; import { verifyQualifiedAcpxInstallation, type VerifiedAcpxInstallation } from "./installation-integrity.js"; /** Closed build-owned registry. Provider branches add their pinned installations here. */ export async function verifyAcpxProfileInstallation(profile: QualifiedAcpxProfile): Promise { + if (profile.agent === "cursor") return verifyCursorInstallation(profile); if (profile.agent !== "claude" && profile.agent !== "codex" && profile.agent !== "grok") { throw new Error(`ACPX ${profile.agent} verified candidate distribution is not installed in this build`); } @@ -10,7 +13,9 @@ export async function verifyAcpxProfileInstallation(profile: QualifiedAcpxProfil } /** Provider policy admission is repeated immediately before each process launch. */ -export async function assertAcpxProfileWorkspace(_agent: QualifiedAcpxAgent, _workspace: string): Promise {} +export async function assertAcpxProfileWorkspace(agent: QualifiedAcpxAgent, workspace: string): Promise { + if (agent === "cursor") await assertCursorWorkspacePolicy(workspace); +} /** Candidate branches validate only explicitly bound, sanitized launch credentials. */ export function assertAcpxProfileEnvironment(_agent: QualifiedAcpxAgent, _environment: Readonly): void {}