diff --git a/packages/paperclip-runner/README.md b/packages/paperclip-runner/README.md index a1c76089dfd..4ba8686aec5 100644 --- a/packages/paperclip-runner/README.md +++ b/packages/paperclip-runner/README.md @@ -857,7 +857,9 @@ Prepare authentication, skills, and external MCP servers on the execution machin before launching. Runner does not install skills, copy or remove credentials, or rewrite user configuration in this mode. Providers can still refresh credentials and update their own metadata. Runner still supplies the requested -model, task instructions, and its internal task/completion tools. Local permission +model, task instructions, and its internal task/completion tools. Claude session +loads and resumes receive the same native session options as session creation, +including allowed tools and the selected settings sources. Local permission rules and hooks apply. Native Codex tools can read and modify the execution home (read-only for planning); credentials in that home are not isolated from tools. Native Codex separately denies Runner-owned protocol state; ACPX Claude retains diff --git a/packages/paperclip-runner/acpx-profiles.json b/packages/paperclip-runner/acpx-profiles.json index 21191338126..d9fb690f000 100644 --- a/packages/paperclip-runner/acpx-profiles.json +++ b/packages/paperclip-runner/acpx-profiles.json @@ -5,39 +5,39 @@ "protocolVersion": 1, "profiles": { "grok": { - "agentProfileVersion": 10, + "agentProfileVersion": 11, "agentServerPackage": "builtin:grok-acp", "agentServerVersion": "1", "agentRuntimePackage": "native:grok", "agentRuntimeVersion": "1.0.13", - "commandDigest": "sha256:2dccee3800dada11b65692e5cf591e3667a123cba2fbf5629a937f731043b423", + "commandDigest": "sha256:f43a6f5a583972cdcb422784969cd6a97654655b0f135f1cf178317909c404f8", "requiresProviderPolicy": false }, "pi": { - "agentProfileVersion": 32, + "agentProfileVersion": 33, "agentServerPackage": "pi-acp", "agentServerVersion": "0.0.33", "agentRuntimePackage": "@earendil-works/pi-coding-agent", "agentRuntimeVersion": "1.0.0", - "commandDigest": "sha256:ce13b75699331c813f8a42f2803c3e0e0fb1e6d24847452cb12b50d6ed2d0baf", + "commandDigest": "sha256:0260d5810e9247986800ad46c1f9b3511a5abd06cb8f142405d5caacbc3960fc", "requiresProviderPolicy": true }, "cursor": { - "agentProfileVersion": 15, + "agentProfileVersion": 16, "agentServerPackage": "cursor-agent", "agentServerVersion": "2026.09.26-dd393fe", "agentRuntimePackage": null, "agentRuntimeVersion": null, - "commandDigest": "sha256:ac8092119542c8fbe95dae18ba5ef4d3689803fec56b7d2735fa193eea42f59b", + "commandDigest": "sha256:759e7415fea8ed2b6b0e6f362b57652b8768835f9d1fdae4a94c1b5eb3669301", "requiresProviderPolicy": true }, "copilot": { - "agentProfileVersion": 78, + "agentProfileVersion": 79, "agentServerPackage": "@github/copilot", "agentServerVersion": "1.0.88", "agentRuntimePackage": null, "agentRuntimeVersion": null, - "commandDigest": "sha256:f7e7cff356db4b1b37458bd62fd76e9d81aa1cc46795e54b168755fb68bcee8c", + "commandDigest": "sha256:a0e9f339935f6ee616fee644c45cb09353e9aed1d1f22215739f9504153ceca1", "requiresProviderPolicy": true }, "claude": { diff --git a/packages/paperclip-runner/cursor-contract.json b/packages/paperclip-runner/cursor-contract.json index e1d6881b96c..be413ac559e 100644 --- a/packages/paperclip-runner/cursor-contract.json +++ b/packages/paperclip-runner/cursor-contract.json @@ -1,11 +1,11 @@ { "schema": "paperclip.cursor.production-contract.v1", - "profileVersion": 15, + "profileVersion": 16, "sourceSnapshot": "22c78242a4e0c2369fecf0c2dc4e7600fbad6706", "base": "dd868ed125cd709506dd9b29fca640a44d580501", "vendor": "2026.09.26-dd393fe", "nativePatch": "paperclip-cursor-usage-v4", - "acpxPatchSha256": "00d6af17216cb0cad902b48633eb19bf0ec6b05837a984cb24661fca593f09c1", + "acpxPatchSha256": "1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2", "publicSetup": "paperclipai runtime setup cursor", "assets": "public-server-and-provider-pack", "modes": [ @@ -19,5 +19,5 @@ "planAcceptance": "successful-run-open-task-explicit-continuation", "otherProviders": "mainline-gated", "modelSelection": "explicit-provider-verified-startup-and-reconnect", - "commandDigest": "sha256:ac8092119542c8fbe95dae18ba5ef4d3689803fec56b7d2735fa193eea42f59b" + "commandDigest": "sha256:759e7415fea8ed2b6b0e6f362b57652b8768835f9d1fdae4a94c1b5eb3669301" } diff --git a/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs b/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs index 5439fbeb559..94c73c304d2 100644 --- a/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs +++ b/packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs @@ -3246,7 +3246,7 @@ mod tests { #[test] fn pi_profile_matches_published_identity_and_rejects_prior_profiles() { let published: Value = serde_json::from_str(include_str!( - "../../../../test-fixtures/pi-acp/profile-v32-identity.json" + "../../../../test-fixtures/pi-acp/profile-v33-identity.json" )) .unwrap(); let mut value = descriptor("codex"); diff --git a/packages/paperclip-runner/runner/crates/runner-core/src/generated_acpx_profiles.rs b/packages/paperclip-runner/runner/crates/runner-core/src/generated_acpx_profiles.rs index 1be4fa5e3d5..f61400ce917 100644 --- a/packages/paperclip-runner/runner/crates/runner-core/src/generated_acpx_profiles.rs +++ b/packages/paperclip-runner/runner/crates/runner-core/src/generated_acpx_profiles.rs @@ -20,7 +20,7 @@ pub(crate) fn acpx_release_profile(agent: &str) -> Option { agent_runtime_package: Some("native:grok"), agent_runtime_version: Some("1.0.13"), command_digest: - "sha256:2dccee3800dada11b65692e5cf591e3667a123cba2fbf5629a937f731043b423", + "sha256:f43a6f5a583972cdcb422784969cd6a97654655b0f135f1cf178317909c404f8", requires_provider_policy: false, }, "pi" => AcpxReleaseProfile { @@ -29,7 +29,7 @@ pub(crate) fn acpx_release_profile(agent: &str) -> Option { agent_runtime_package: Some("@earendil-works/pi-coding-agent"), agent_runtime_version: Some("1.0.0"), command_digest: - "sha256:ce13b75699331c813f8a42f2803c3e0e0fb1e6d24847452cb12b50d6ed2d0baf", + "sha256:0260d5810e9247986800ad46c1f9b3511a5abd06cb8f142405d5caacbc3960fc", requires_provider_policy: true, }, "cursor" => AcpxReleaseProfile { @@ -38,7 +38,7 @@ pub(crate) fn acpx_release_profile(agent: &str) -> Option { agent_runtime_package: None, agent_runtime_version: None, command_digest: - "sha256:ac8092119542c8fbe95dae18ba5ef4d3689803fec56b7d2735fa193eea42f59b", + "sha256:759e7415fea8ed2b6b0e6f362b57652b8768835f9d1fdae4a94c1b5eb3669301", requires_provider_policy: true, }, "copilot" => AcpxReleaseProfile { @@ -47,7 +47,7 @@ pub(crate) fn acpx_release_profile(agent: &str) -> Option { agent_runtime_package: None, agent_runtime_version: None, command_digest: - "sha256:f7e7cff356db4b1b37458bd62fd76e9d81aa1cc46795e54b168755fb68bcee8c", + "sha256:a0e9f339935f6ee616fee644c45cb09353e9aed1d1f22215739f9504153ceca1", requires_provider_policy: true, }, "claude" => AcpxReleaseProfile { diff --git a/packages/paperclip-runner/runner/crates/runner-core/tests/native_provider_backend.rs b/packages/paperclip-runner/runner/crates/runner-core/tests/native_provider_backend.rs index d1e144de057..b9b58e8e9be 100644 --- a/packages/paperclip-runner/runner/crates/runner-core/tests/native_provider_backend.rs +++ b/packages/paperclip-runner/runner/crates/runner-core/tests/native_provider_backend.rs @@ -17,7 +17,7 @@ use sha2::{Digest, Sha256}; const CODEX_ACPX_DIGEST: &str = "sha256:443491f4e814501a5dc47347e4510e84faeec9c9382e2d4e53bfe69386d5aabc"; const PI_ACPX_DIGEST: &str = - "sha256:ce13b75699331c813f8a42f2803c3e0e0fb1e6d24847452cb12b50d6ed2d0baf"; + "sha256:0260d5810e9247986800ad46c1f9b3511a5abd06cb8f142405d5caacbc3960fc"; fn temporary_directory(label: &str) -> PathBuf { let nonce = SystemTime::now() diff --git a/packages/paperclip-runner/scripts/copilot-profile-identity.mjs b/packages/paperclip-runner/scripts/copilot-profile-identity.mjs index 85f0ca11194..c92ee2ad192 100644 --- a/packages/paperclip-runner/scripts/copilot-profile-identity.mjs +++ b/packages/paperclip-runner/scripts/copilot-profile-identity.mjs @@ -7,9 +7,9 @@ import { fileURLToPath } from "node:url"; import { resolve, dirname } from "node:path"; const root = resolve(dirname(fileURLToPath(import.meta.url)), ".."); -const fixture = resolve(root, "test/fixtures/copilot-profile-v78-identity.json"); +const fixture = resolve(root, "test/fixtures/copilot-profile-v79-identity.json"); const historical = JSON.parse(readFileSync(resolve(root, "test/fixtures/copilot-profile-v12-identity.json"), "utf8")); -const declaration = { ...historical.declaration, agentProfileVersion: 78 }; +const declaration = { ...historical.declaration, agentProfileVersion: 79 }; delete declaration.permissionIdentitySourceSha256; const sources = { displayEventSourceSha256: "src/drivers/acpx/copilot-events.ts", diff --git a/packages/paperclip-runner/scripts/grok-profile-identity.mjs b/packages/paperclip-runner/scripts/grok-profile-identity.mjs index 7ee11031fe5..e0210feb2e2 100644 --- a/packages/paperclip-runner/scripts/grok-profile-identity.mjs +++ b/packages/paperclip-runner/scripts/grok-profile-identity.mjs @@ -7,9 +7,9 @@ import { fileURLToPath } from "node:url"; const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), ".."); const repositoryRoot = resolve(packageRoot, "../.."); -// Versions 1–9 remain decodable historical identities. Versioned fixtures are +// Versions 1–10 remain decodable historical identities. Versioned fixtures are // immutable; advance this version before changing a versioned declaration. -export const GROK_PROFILE_VERSION = 10; +export const GROK_PROFILE_VERSION = 11; // Contract surfaces: ACPX wire patch; sidecar parsing and error translation; // native effort/search/credential admission; host/sandbox/tool-bridge execution; // launcher integrity and platform pins; Rust descriptor writes, session state, diff --git a/packages/paperclip-runner/src/drivers/acpx/copilot-installation.test.ts b/packages/paperclip-runner/src/drivers/acpx/copilot-installation.test.ts index 58ddfd32d60..82812032921 100644 --- a/packages/paperclip-runner/src/drivers/acpx/copilot-installation.test.ts +++ b/packages/paperclip-runner/src/drivers/acpx/copilot-installation.test.ts @@ -87,9 +87,9 @@ vi.mock("./installation-integrity.js", () => ({ verifyNativeAcpxInstallation: vi describe("Copilot build-owned installation", () => { it("admits the current profile with environment launch preparation", () => { - expect(QUALIFIED_ACPX_PROFILES.copilot.agentProfileVersion).toBe(78); + expect(QUALIFIED_ACPX_PROFILES.copilot.agentProfileVersion).toBe(79); expect(QUALIFIED_ACPX_PROFILES.copilot.qualificationStatus).toBeUndefined(); - expect(QUALIFIED_ACPX_PROFILES.copilot.commandDigest).toBe("sha256:f7e7cff356db4b1b37458bd62fd76e9d81aa1cc46795e54b168755fb68bcee8c"); + expect(QUALIFIED_ACPX_PROFILES.copilot.commandDigest).toBe("sha256:a0e9f339935f6ee616fee644c45cb09353e9aed1d1f22215739f9504153ceca1"); }); it("retains the published profile 75 fixture while advancing the event contract", async () => { diff --git a/packages/paperclip-runner/src/drivers/acpx/generated-profiles.ts b/packages/paperclip-runner/src/drivers/acpx/generated-profiles.ts index 240ab6baa28..4512b8cfb92 100644 --- a/packages/paperclip-runner/src/drivers/acpx/generated-profiles.ts +++ b/packages/paperclip-runner/src/drivers/acpx/generated-profiles.ts @@ -9,12 +9,12 @@ export const QUALIFIED_ACPX_PROFILE_DATA = { "protocolVersion": 1, "acpxVersion": "0.13.1", "agent": "grok", - "agentProfileVersion": 10, + "agentProfileVersion": 11, "agentServerPackage": "builtin:grok-acp", "agentServerVersion": "1", "agentRuntimePackage": "native:grok", "agentRuntimeVersion": "1.0.13", - "commandDigest": "sha256:2dccee3800dada11b65692e5cf591e3667a123cba2fbf5629a937f731043b423", + "commandDigest": "sha256:f43a6f5a583972cdcb422784969cd6a97654655b0f135f1cf178317909c404f8", "permissionPolicy": "interactive" }, "pi": { @@ -22,12 +22,12 @@ export const QUALIFIED_ACPX_PROFILE_DATA = { "protocolVersion": 1, "acpxVersion": "0.13.1", "agent": "pi", - "agentProfileVersion": 32, + "agentProfileVersion": 33, "agentServerPackage": "pi-acp", "agentServerVersion": "0.0.33", "agentRuntimePackage": "@earendil-works/pi-coding-agent", "agentRuntimeVersion": "1.0.0", - "commandDigest": "sha256:ce13b75699331c813f8a42f2803c3e0e0fb1e6d24847452cb12b50d6ed2d0baf", + "commandDigest": "sha256:0260d5810e9247986800ad46c1f9b3511a5abd06cb8f142405d5caacbc3960fc", "permissionPolicy": "interactive" }, "cursor": { @@ -35,12 +35,12 @@ export const QUALIFIED_ACPX_PROFILE_DATA = { "protocolVersion": 1, "acpxVersion": "0.13.1", "agent": "cursor", - "agentProfileVersion": 15, + "agentProfileVersion": 16, "agentServerPackage": "cursor-agent", "agentServerVersion": "2026.09.26-dd393fe", "agentRuntimePackage": null, "agentRuntimeVersion": null, - "commandDigest": "sha256:ac8092119542c8fbe95dae18ba5ef4d3689803fec56b7d2735fa193eea42f59b", + "commandDigest": "sha256:759e7415fea8ed2b6b0e6f362b57652b8768835f9d1fdae4a94c1b5eb3669301", "permissionPolicy": "interactive" }, "copilot": { @@ -48,12 +48,12 @@ export const QUALIFIED_ACPX_PROFILE_DATA = { "protocolVersion": 1, "acpxVersion": "0.13.1", "agent": "copilot", - "agentProfileVersion": 78, + "agentProfileVersion": 79, "agentServerPackage": "@github/copilot", "agentServerVersion": "1.0.88", "agentRuntimePackage": null, "agentRuntimeVersion": null, - "commandDigest": "sha256:f7e7cff356db4b1b37458bd62fd76e9d81aa1cc46795e54b168755fb68bcee8c", + "commandDigest": "sha256:a0e9f339935f6ee616fee644c45cb09353e9aed1d1f22215739f9504153ceca1", "permissionPolicy": "interactive" }, "claude": { diff --git a/packages/paperclip-runner/src/drivers/acpx/pi-installation.test.ts b/packages/paperclip-runner/src/drivers/acpx/pi-installation.test.ts index ae80f0e1570..58921588738 100644 --- a/packages/paperclip-runner/src/drivers/acpx/pi-installation.test.ts +++ b/packages/paperclip-runner/src/drivers/acpx/pi-installation.test.ts @@ -210,21 +210,21 @@ describe("Pi installation factory", () => { it("rejects legacy profiles and tampered executable identities", () => { expect(() => assertPiInstallationProfile(candidate())).not.toThrow(); - expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 1 })).toThrow("version 32"); - expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 2 })).toThrow("version 32"); - expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 3 })).toThrow("version 32"); - expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 4 })).toThrow("version 32"); - expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 5 })).toThrow("version 32"); - expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 6 })).toThrow("version 32"); - expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 7 })).toThrow("version 32"); - expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 8 })).toThrow("version 32"); - expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 9 })).toThrow("version 32"); - expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 10 })).toThrow("version 32"); - expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 11 })).toThrow("version 32"); - expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 12 })).toThrow("version 32"); - expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 13 })).toThrow("version 32"); - expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 14 })).toThrow("version 32"); - for (const priorVersion of [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]) expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: priorVersion })).toThrow("version 32"); + expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 1 })).toThrow("version 33"); + expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 2 })).toThrow("version 33"); + expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 3 })).toThrow("version 33"); + expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 4 })).toThrow("version 33"); + expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 5 })).toThrow("version 33"); + expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 6 })).toThrow("version 33"); + expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 7 })).toThrow("version 33"); + expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 8 })).toThrow("version 33"); + expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 9 })).toThrow("version 33"); + expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 10 })).toThrow("version 33"); + expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 11 })).toThrow("version 33"); + expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 12 })).toThrow("version 33"); + expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 13 })).toThrow("version 33"); + expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: 14 })).toThrow("version 33"); + for (const priorVersion of [15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]) expect(() => assertPiInstallationProfile({ ...candidate(), agentProfileVersion: priorVersion })).toThrow("version 33"); for (const changed of [{ agentServerVersion: "latest" }, { commandDigest: `sha256:${"0".repeat(64)}` }, { agentRuntimePackage: "ambient-pi" }]) { expect(() => assertPiInstallationProfile({ ...candidate(), ...changed })).toThrow("trusted declaration"); } diff --git a/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.test.ts b/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.test.ts index 7826bd202c2..57b35807402 100644 --- a/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.test.ts +++ b/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.test.ts @@ -10,7 +10,8 @@ describe("historical ACPX profile decoding", () => { expect(isSupportedAcpxProfileVersion("pi", 18)).toBe(true); expect(isSupportedAcpxProfileVersion("pi", 23)).toBe(true); expect(isSupportedAcpxProfileVersion("cursor", 15)).toBe(true); - expect(isSupportedAcpxProfileVersion("cursor", 16)).toBe(false); + expect(isSupportedAcpxProfileVersion("cursor", 16)).toBe(true); + expect(isSupportedAcpxProfileVersion("cursor", 17)).toBe(false); for (const agent of ["pi", "copilot"]) { expect(isSupportedAcpxProfileVersion(agent, 16)).toBe(true); const current = QUALIFIED_ACPX_PROFILE_DATA[agent as "pi" | "copilot"].agentProfileVersion; diff --git a/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.ts b/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.ts index c68a13527b1..15f892b66c5 100644 --- a/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.ts +++ b/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.ts @@ -2,13 +2,13 @@ import { QUALIFIED_ACPX_PROFILE_DATA } from "./generated-profiles.js"; /** Decodable historical profile revisions, not permission to launch them. * Exact current profile/package/digest admission is checked separately. */ -type HistoricalAcpxProfileVersion = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77; +type HistoricalAcpxProfileVersion = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78; type CurrentAcpxProfileVersion = typeof QUALIFIED_ACPX_PROFILE_DATA[keyof typeof QUALIFIED_ACPX_PROFILE_DATA]["agentProfileVersion"]; export type AcpxProfileVersion = HistoricalAcpxProfileVersion | CurrentAcpxProfileVersion; const historicalVersions: Readonly> = { - pi: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31], claude: [1, 2, 3, 4, 5], codex: [1, 2, 3, 4, 5], - grok: [1, 2, 3, 4, 5, 6, 7, 8, 9], copilot: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77], + pi: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32], claude: [1, 2, 3, 4, 5], codex: [1, 2, 3, 4, 5], + grok: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], copilot: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78], cursor: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], }; diff --git a/packages/paperclip-runner/src/providers/grok/launcher.cjs b/packages/paperclip-runner/src/providers/grok/launcher.cjs index 8bba68652b3..ec47bb32d29 100755 --- a/packages/paperclip-runner/src/providers/grok/launcher.cjs +++ b/packages/paperclip-runner/src/providers/grok/launcher.cjs @@ -1,4 +1,4 @@ -// Grok admission source identity: sha256:1fec0323461ed2e0b1d0172d205237ba23316a7e6a89c325b6eb3be907e373e3 +// Grok admission source identity: sha256:c5a4628adcdd9190c45558f42014b0055698b8f8c7eb301417238f38d913f503 // This launcher is admitted by digest and receives a verified native executable. // Never resolve an executable through PATH or accept command-line overrides. const { isAbsolute, join } = require("node:path"); diff --git a/packages/paperclip-runner/test-fixtures/pi-acp/profile-v33-identity.json b/packages/paperclip-runner/test-fixtures/pi-acp/profile-v33-identity.json new file mode 100644 index 00000000000..2eaf38dcde2 --- /dev/null +++ b/packages/paperclip-runner/test-fixtures/pi-acp/profile-v33-identity.json @@ -0,0 +1,52 @@ +{ + "commandDigest": "sha256:0260d5810e9247986800ad46c1f9b3511a5abd06cb8f142405d5caacbc3960fc", + "declaration": { + "schema": "paperclip.acpx_profile_declaration.v1", + "agent": "pi", + "agentProfileVersion": 33, + "acpxVersion": "0.13.1", + "agentServerVersion": "0.0.33", + "agentRuntimeVersion": "1.0.0", + "nodeVersion": "24.21.0", + "closure": { + "darwin-arm64": "282022db10150c6632b3444df421342e7d534bdf5d5fb1097a2e79d0625a2bcf", + "darwin-x64": "64e251e19009f755c0b04f73ce2138246faab71a961b0f13d75ebfcc34bef12e", + "linux-x64": "713b1fdff42fb56a1518bdc084f181d70bee8ebadc3e4b1d76321ed9108c8410" + }, + "wrapperSha256": "9d129b3d38772e93e97080aa6c4e574ac5df4e47ce5bc331a484a9fbf8188b36", + "helperSha256": "41e0490b617da0d60e0c8ec58ef311236f945129d99f816cff6897f78da7f91d", + "extensionSha256": "f5818573a355702388072b28926897db546a5cf346b5171f646582ce5f9102a4", + "agentFilesBinding": "registered-runtime-context-v1", + "nativeQuestions": "select-confirm-input-editor-v4-root-field-types", + "pathPolicy": "sdk-normalization-v1", + "mcpToolNames": "provider-safe-exact-source-v1", + "acpxPatchSha256": "1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2", + "nativeAssistantMessages": "pi1-rpc-deltas-v3-bound-message-and-tool-receipts", + "nativeNotices": "session-extension-v2-bounded-runtime-failure", + "messageProjectionSha256": "17d1e91b948dfa6a56e1905645add52b502041ad843c8d50a13b07956f22aadd", + "noticeProjectionSha256": "014485adc690998e395d334ea3ae67f72be6060a2fc78a1185df7b8d1da28fbf", + "sharedRuntimeContract": "paperclip.acpx-runtime-contract.v1", + "nativeInputDisposition": "queued-only-v1", + "cacheWarming": "disabled-owned-decision-v1", + "thinkingLevel": { + "supported": [ + "off", + "low", + "high", + "max" + ], + "newConfigurationDefault": "low", + "admission": "explicit-native-effective-before-prompt-v1", + "recovery": "mode-bound-v1" + }, + "modelSelection": "caller-selected-native-verified-v1", + "providerConfigurationSourceSha256": "75a9a13f13f224dc092bd8ebf49e8747162172943761e44476c8eb18d80c52d4", + "credentialEnvironmentSourceSha256": "3a93267146bfc3c489f43262386d6dcb05ec4e3a8b1765414cd43d80d0c64d4a", + "runtimeSandboxSourceSha256": "04a49a24e3828ce8fca908de15e31ae932b8b1b4f7ecec0308627f6a8da9ba20", + "recoveryIdentitySourceSha256": "f74d061cc07b0c7ca04df62ca991d940a733d9ef6594b3362451769fc10030b8", + "nativeCancellation": "acknowledged-cancelled-terminal-preserves-usage-v1", + "dependencySecurityPatchSha256": "5273a195b952f233336122842faaf650193c04f36b9359d20d4d63079b0ce814", + "openRouterAttributionSourceSha256": "1211191529d6073b733b311c3d69cada4973eede0f3e540c46e261f78e0b90f9", + "preparedHarnessHomeSourceSha256": "bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e" + } +} diff --git a/packages/paperclip-runner/test/acpx-model-selection-package-contract.test.mjs b/packages/paperclip-runner/test/acpx-model-selection-package-contract.test.mjs index 5e9b1771b69..ca099899807 100644 --- a/packages/paperclip-runner/test/acpx-model-selection-package-contract.test.mjs +++ b/packages/paperclip-runner/test/acpx-model-selection-package-contract.test.mjs @@ -37,8 +37,8 @@ async function fixture(t, agent, behavior = {}) { options:[{value:'advertised-model',name:'Advertised'},{value:'custom/model[variant=x]',name:'Variant'}]}]; readline.createInterface({input:process.stdin}).on('line',line=>{ const m=JSON.parse(line); - if(m.method==='initialize') send({id:m.id,result:{protocolVersion:1,agentCapabilities:{loadSession:true},authMethods:[]}}); - else if(m.method==='session/new'||m.method==='session/load') send({id:m.id,result:{sessionId:'session-1', + if(m.method==='initialize') send({id:m.id,result:{protocolVersion:1,agentCapabilities:${JSON.stringify({loadSession:true,...(behavior.resume ? {sessionCapabilities:{resume:{}}} : {})})},authMethods:[]}}); + else if(m.method==='session/new'||m.method==='session/load'||m.method==='session/resume') send({id:m.id,result:{sessionId:'session-1', ...(${JSON.stringify(response === "missing")} ? {} : {configOptions:config(${JSON.stringify(behavior.currentModel ?? "default")}), models:{currentModelId:${JSON.stringify(behavior.currentModel ?? "default")},availableModels:[{modelId:'advertised-model',name:'Advertised'},{modelId:'custom/model[variant=x]',name:'Variant'}]}})}}); else if(m.method==='session/set_config_option') { @@ -72,7 +72,7 @@ async function fixture(t, agent, behavior = {}) { async open() { const runtime = createAcpRuntime(options), owner = { runtime, handle: null }; runtimes.push(owner); - owner.handle = await runtime.ensureSession({ sessionKey: "model-selection", agent, mode: "persistent", cwd, sessionOptions: { model: selectedModel } }); + owner.handle = await runtime.ensureSession({ sessionKey: "model-selection", agent, mode: "persistent", cwd, sessionOptions: { model: selectedModel, ...behavior.sessionOptions } }); return owner; }, async prompt(owner) { @@ -143,3 +143,28 @@ test("Cursor command detection never expands a model into an advertised variant" assert.equal((await f.prompt(owner)).status, "completed"); assert.deepEqual(f.selected(), [selectedModel]); }); + +for (const includeUserSettings of [false, true]) for (const resume of [false, true]) test(`Claude ${resume ? "resume" : "load"} preserves native session options (user settings ${includeUserSettings})`, { timeout: 10_000 }, async t => { + const prior = process.env.ACPX_CLAUDE_INCLUDE_USER_SETTINGS; + if (includeUserSettings) process.env.ACPX_CLAUDE_INCLUDE_USER_SETTINGS = "1"; + else delete process.env.ACPX_CLAUDE_INCLUDE_USER_SETTINGS; + t.after(() => { if (prior === undefined) delete process.env.ACPX_CLAUDE_INCLUDE_USER_SETTINGS; else process.env.ACPX_CLAUDE_INCLUDE_USER_SETTINGS = prior; }); + const f = await fixture(t, "claude", { + resume, agentCommand: "/paperclip-verified/claude-agent-acp", + sessionOptions: { allowedTools: ["mcp__fixture__*"], maxTurns: 5, systemPrompt: { append: "Fixture instructions" } }, + }); + const first = await f.open(); + assert.equal((await f.prompt(first)).status, "completed"); + await f.close(first); + const second = await f.open(); + assert.equal((await f.prompt(second)).status, "completed"); + const created = f.requests.find(r => r.method === "session/new"); + const restored = f.requests.find(r => r.method === (resume ? "session/resume" : "session/load")); + assert.ok(restored, "the provider session reconnects"); + assert.equal(created.params._meta.claudeCode.options.model, selectedModel); + assert.equal(created.params._meta.claudeCode.options.maxTurns, 5); + assert.deepEqual(created.params._meta.systemPrompt, { append: "Fixture instructions" }); + assert.deepEqual(created.params._meta.claudeCode.options.allowedTools, ["mcp__fixture__*"]); + assert.deepEqual(created.params._meta.claudeCode.options.settingSources, includeUserSettings ? ["user", "project", "local"] : ["project", "local"]); + assert.deepEqual(restored.params._meta, created.params._meta, "reconnect must preserve the requested native launch settings"); +}); diff --git a/packages/paperclip-runner/test/fixtures/copilot-profile-v79-identity.json b/packages/paperclip-runner/test/fixtures/copilot-profile-v79-identity.json new file mode 100644 index 00000000000..27835e067e9 --- /dev/null +++ b/packages/paperclip-runner/test/fixtures/copilot-profile-v79-identity.json @@ -0,0 +1,88 @@ +{ + "commandDigest": "sha256:a0e9f339935f6ee616fee644c45cb09353e9aed1d1f22215739f9504153ceca1", + "declaration": { + "schema": "paperclip.acpx_profile_declaration.v1", + "agent": "copilot", + "agentProfileVersion": 79, + "acpxVersion": "0.13.1", + "agentServerVersion": "1.0.88", + "protocolPolicyRevision": "copilot-agent-manual-v1", + "acpxPatchSha256": "1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2", + "policySha256": "a4be69be43db84052560420a3ca546a665c9165573c24d543eb33d144ba138a3", + "distributionSourceSha256": "c0a65e247fc47b263bd369a3d5ab505c4b323d4e6493be8a9ecbeb0e9dbb9107", + "agentFilesBinding": "registered-runtime-context-v1", + "systemInstructionDelivery": "COPILOT_HOME/copilot-instructions.md:replace-under-lifetime-lease-before-launch:v1", + "sharedRuntimeContract": "paperclip.acpx-runtime-contract.v1", + "innerDistributionSourceSha256": "9bb08347eed01f1ab44e065c8b06ead9be3a25973d6e6329dc4c0a099096279a", + "upstreamAppSha256": "7b48282a19b5b0814a0c96ad5e3a125173d792cc55f9525b2effea962f6063c0", + "patchedAppSha256": "61f8eebe0c30cc03b311c6818b2acb158a6d16ca58c8bfac5ebd42db095c2679", + "messageIdentityContract": "copilot-native-message-id-v1", + "ownedDistributionDelivery": "COPILOT_CLI_DIST_DIR:lease-owned-guarded-inner-distribution:v1", + "permissionContextContract": "copilot-edit-permission-context-v1", + "permissionContextSourceSha256": "de2d38d702b3c574161af0c0c04790fb6f6347916eb3916ce7a131a8c229121b", + "permissionAdapterSourceSha256": "ee5929ed2ee647ad0369465dee9d51a00b2dd28e1ff735b43e969ddc9c164668", + "permissionLocationsSourceSha256": "f39a81da395b6e23aa2a1a45572a28846e5e81bfd3d764d9a456f74a79c752e9", + "permissionRedactionSourceSha256": "ad6770c69269087951790e2e87e22ac088e3d432769adf17ebc865ed512e6c4f", + "permissionClassifierSourceSha256": "1161eabd82e26133e3b3db3ab567f65d52808b03f176e93497e02c8330349fb4", + "semanticToolReceiptContract": "paperclip.semantic_tool_receipt.v2", + "semanticReceiptSourceSha256": "b2795726b2234a663fec1a6ca11f0551ae69882fe9e82aa39686e952d036e791", + "semanticBridgeSourceSha256": "8764b8c9032fdc7d1415b01e75a9fc57c550e7a5e11da4bed7d9100082872ae5", + "toolEvidenceSourceSha256": "6eef5039afc75bb851eaf9cd82a6f099e4bd398ca2deb59dd66f5b2a81a7a706", + "semanticNormalizedInputContract": "validated-forwarded-input-commit-v1", + "semanticSidecarSourceSha256": "7d6e948b7cff4df52a9afc916db46ace0f42b4b2d3134ba0c21ee0a928857e62", + "semanticDirectDriverSourceSha256": "d683429427dd8a1a5efe50952018ea486f808bdbf0a92fc5946ee267fe2c72ee", + "semanticValidationSourceSha256": "02fbb92681c78c5de5d2f1aae25aabc25a0e5df6b0ff4baccac652192a8da975", + "semanticNormalizationSourceSha256": "8b628b82e8eacc91cdcc6fdca2210ba4cf282f01e9c6f74e95ff271655b5047e", + "semanticCompletionContractSourceSha256": "f49398b682a5623812f5d3c33d6bb9a749008e47cc0ed969072041615f66df59", + "semanticValidatorsSourceSha256": "b20ec8ee6e7165117233ce4421a975bb9d3f276220ce31655c0b9a717cb2d9cb", + "semanticSchemaBundleSourceSha256": "81ef98ca7b34896a0f76390ac7af3dd8ef7609fe6f38d54bd6a69373d50fe40b", + "semanticSidecarProtocolSourceSha256": "26dd0cfbef8b2b401de6b7862a4af7f243fb703e23678a1a5ed8fa68d4784d42", + "semanticSidecarReceiptCommitContract": "correlated-tool-resolve-v1", + "displayEventSourceSha256": "d72f9a6035c247bc6a42c067c05753076c54322c4b58984e93922f3325dc6877", + "displayProjectionSourceSha256": "75952606b26dd93bbc582c1f0a4424487377272ea745fb3a27ceae031fd5dc7e", + "configuredEnvironmentSourceSha256": "5c9008d121979a3a8987e6b8a5752172eafdc4a2b5d725a73f3bbb8fb83be8ff", + "configuredEnvironmentRustSourceSha256": "85c87fae62b8a9377e4f0a4c00302c7519fae4397b1c48253f8f2b7ba7faf994", + "profileActivitySourceSha256": "4fdb6b0f9125fd8372ba6f27945fa5c8a3d3b2ec891df544092e3dc7a75d5282", + "profileExtensionsSourceSha256": "a80ddc95eb4505095bfdbbf85c758199949ab20be9c84b34c77f762eb7180571", + "profileInstallationSourceSha256": "3e61c4cdd4b78e38fcb16eaadae4f1fd65ce3c7127184ea7a80948c8e5d77f88", + "attachmentPolicySourceSha256": "4f7638b7cc64e18f6a4ba33fd46de2b3d49225e32aeab41f5c695b268fa4f8e2", + "singleReadEvidenceSourceSha256": "4069393405089bde613cecec04f5123c426594811da4c668bd96f0e7e283550f", + "nativeSessionRuntimeSourceSha256": "1fe6fa9e6b96d84d70432b85a57c473f833606d4a521563d5022b4d3c41576ce", + "nativeRuntimeContextSourceSha256": "71607f80dbb8dc5cc6c123d0b8f3995d6c5407277695a8c82cbedc90fb8f4842", + "nativeRuntimePromptsSourceSha256": "fff5755dba9b7dce8a5f10ff6ac6d5ed06b92ed079ce1e0a44ac72f2ce7869c1", + "nativeSessionContractSourceSha256": "22a8c96ce41ba4f03e976fc37f0cc7c5d05cee99fa789941da31ee1dab440b90", + "harnessSessionContractSourceSha256": "baba1a210b863518f01e0c875606ed37f9467c433222251438578bd999bc43b5", + "harnessBackendSourceSha256": "dc827e281ae6731545b166ee4d709a4f67f594a556dcbe63c70fe8f1aca26249", + "harnessSessionSourceSha256": "81361733e86b56dd5a66415aefc6f72e69be24acc8d3417370154ebb7fef6e94", + "transportContractSourceSha256": "03fca93d36a89b0cc0917335e293ad097fdf04356d21b307827bb0ea4c13f523", + "nativeBackendSourceSha256": "7495d9898d22dca1ebf6336361d332bafefc4498f6e49f1135025fad846c8586", + "nativeBackendFactorySourceSha256": "7e431c926b76d53c4c08e3a4105353dcd34bd940f6588a1a68f79631f6feeb44", + "nativeInstructionsSourceSha256": "82ac6e5f7275b4ef79fb166c7330efc504e80cab3d7e9081e4e40a8b570bc50b", + "providerLaunchSourceSha256": "c744235b3067ea75973523f78f1e13399337bc155f1775af694e34782d5c9bef", + "launchPreparationStoreSourceSha256": "ff6025568bbc0aa6ce545772d73dfca2d3da226740bd3a7b386b069e76cff296", + "runtimeRequestBridgeSourceSha256": "93a631b8439df1590b0cf442cf84a9b05f004f12bfee90291651ccfc0861effe", + "runtimeRequestFacadeSourceSha256": "d0ed28e0c5ddad34db8f437e704c8a755eb0b47f27e08e44185f66d1d2205295", + "runtimeRequestNotificationSourceSha256": "6196c6175f11c69295dc00fc773201f4fdeca26c500653870253c43b81e65211", + "guardedInstallationSourceSha256": "56a177d3e702914818dca4ca50e061f0d25f988bfc4c0582c36ce23c1696d82f", + "nativeExecutionSourceSha256": "d60b8ea63bad975c0144f0702b2749d7db9a7da50680a6147f20d4d11f2d5297", + "profileCompatibilitySourceSha256": "aa36385c5ed723b7f2bd5c96ff70db4587a040151f1ee70f5669b7f46f408713", + "installationSourceSha256": "a1c7c6f103b898216973e77ffbac0ef7572e250aa574d1a4065270e9dfa0dc2d", + "assetOwnershipSourceSha256": "1785e3f31e5dad5a13b53e25d8cf9482a9bd89a27b6c127830aed6b81acc605c", + "assetInstallerSourceSha256": "d3bd9514e5920d0cc3567aa50487fb534c57a6f66b8da0d3f22c5f6e499c841f", + "credentialBindingSourceSha256": "3a93267146bfc3c489f43262386d6dcb05ec4e3a8b1765414cd43d80d0c64d4a", + "admissionDiagnosticsSourceSha256": "df8f1aa4f2d1bc63b2635bdd09cb8165c8b7681ddcc2618435c7c08ca90475af", + "grokAdmissionSourceSha256": "f1e46cf2e1e36b7704bd797b678e3db8db2003f97bdb9d827cfa3d7662698777", + "sidecarErrorSourceSha256": "17948ad74350dc487ab20d24a0fb89daf0b426b98396454fff0e3856e922d82c", + "profileSourceSha256": "f5538b3dbefa7634a332b87d5ededcefb56aa7e5790cede1c7a0d948a548a456", + "metadataProbeSourceSha256": "be4c8416edd27061109bc1f33d0c26071b4facbb3f651beaae6b3c0275cce727", + "permissionToolIdentitySourceSha256": "770b47305e571a81f344883057d0e4a482a1cd59ac77d045836593a8e739deb1", + "semanticContinuationSourceSha256": "c9cc0fd516b3df92a6655f56ee9bef37615a889c371e2e137d8ac5c1176de811", + "preparedHarnessHomeSourceSha256": "bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e", + "runtimeHostSourceSha256": "13f9ac382a279a67adb8974c36bbed38fe43d9b93b87bd7a05e879ead7f03d63", + "runtimeAdapterSourceSha256": "7c47c05306ebe7d1ca6b5d046a96f5726a48adec4d27e7c16788f505f25b5db2", + "runtimeSandboxSourceSha256": "04a49a24e3828ce8fca908de15e31ae932b8b1b4f7ecec0308627f6a8da9ba20", + "cancellationSourceSha256": "a07d1a9e982dec0ae130c1ad1efa5bc75c6a39e013b730ba3ee45256f09ceeca", + "agentFilesSourceSha256": "fb32f6badc13dfa22f231479509b631b2f0eba0c99b1ab9f3cd5c0c601aa03ba", + "nativeDistributionSourceSha256": "aed327c389e957483a503cb1bb8b247ee7cd7ff4b528fb4567c39bcb4577690b" + } +} diff --git a/packages/paperclip-runner/test/fixtures/grok-profile-v11-identity.json b/packages/paperclip-runner/test/fixtures/grok-profile-v11-identity.json new file mode 100644 index 00000000000..78206d5b3f1 --- /dev/null +++ b/packages/paperclip-runner/test/fixtures/grok-profile-v11-identity.json @@ -0,0 +1,35 @@ +{ + "commandDigest": "sha256:f43a6f5a583972cdcb422784969cd6a97654655b0f135f1cf178317909c404f8", + "sourceDigest": "sha256:c5a4628adcdd9190c45558f42014b0055698b8f8c7eb301417238f38d913f503", + "declaration": { + "schema": "paperclip.grok-profile-identity.v1", + "agent": "grok", + "agentProfileVersion": 11, + "agentServerPackage": "builtin:grok-acp", + "agentServerVersion": "1", + "agentRuntimePackage": "native:grok", + "agentRuntimeVersion": "1.0.13", + "requiresProviderPolicy": false, + "acpxVersion": "0.13.1", + "sources": { + "patches/acpx@0.13.1.patch": "sha256:1e7dae8c83bf8620f53f2bea13c175eeff95e7e955783f6f529bb1dcbdcdb6d2", + "packages/paperclip-runner/src/cli/acpx-runtime-sidecar.ts": "sha256:7d6e948b7cff4df52a9afc916db46ace0f42b4b2d3134ba0c21ee0a928857e62", + "packages/paperclip-runner/src/cli/acpx-sidecar-input.ts": "sha256:17948ad74350dc487ab20d24a0fb89daf0b426b98396454fff0e3856e922d82c", + "packages/paperclip-runner/src/drivers/acpx/admission-diagnostics.ts": "sha256:df8f1aa4f2d1bc63b2635bdd09cb8165c8b7681ddcc2618435c7c08ca90475af", + "packages/paperclip-runner/src/drivers/acpx/grok-effort.ts": "sha256:f1e46cf2e1e36b7704bd797b678e3db8db2003f97bdb9d827cfa3d7662698777", + "packages/paperclip-runner/src/drivers/acpx/grok-web-search.ts": "sha256:754b5ca2345c045421f6007f34999508d996e1cea035f0f1952b3d5f00072b9c", + "packages/paperclip-runner/src/drivers/acpx/grok-credentials.ts": "sha256:1c4ff0be6da798b6fcc604d20a9198dcc8523a3806d563b5b5345b7260549f73", + "packages/paperclip-runner/src/drivers/acpx/codex-runtime-adapter.ts": "sha256:7c47c05306ebe7d1ca6b5d046a96f5726a48adec4d27e7c16788f505f25b5db2", + "packages/paperclip-runner/src/drivers/acpx/runtime-host.ts": "sha256:13f9ac382a279a67adb8974c36bbed38fe43d9b93b87bd7a05e879ead7f03d63", + "packages/paperclip-runner/src/drivers/preconfigured-home.ts": "sha256:bb286f7ddc6e9597c56d46bf7ff6e3b556c5b680d7e147fd46518724432b083e", + "packages/paperclip-runner/src/drivers/acpx/runtime-sandbox.ts": "sha256:04a49a24e3828ce8fca908de15e31ae932b8b1b4f7ecec0308627f6a8da9ba20", + "packages/paperclip-runner/src/drivers/acpx/sidecar-protocol.ts": "sha256:26dd0cfbef8b2b401de6b7862a4af7f243fb703e23678a1a5ed8fa68d4784d42", + "packages/paperclip-runner/src/drivers/acpx/native-distribution-integrity.ts": "sha256:aed327c389e957483a503cb1bb8b247ee7cd7ff4b528fb4567c39bcb4577690b", + "packages/paperclip-runner/src/providers/grok/launcher.cjs": "sha256:f0b698395a3704ed2ffaf84ea19bdb20c36c8a0a70b7c629c7b6ffe144e59e55", + "packages/paperclip-runner/src/providers/grok/platforms.json": "sha256:931eed3abbf2bf041e6c72e6e9486d976f4352613cf069b216ddf010c9a8e704", + "packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_backend.rs": "sha256:326deadb929e7c134da407bd3fa4d0853732e37d407c92d404979e7625c6c7cf", + "packages/paperclip-runner/runner/crates/runner-core/src/acpx_provider_session.rs": "sha256:e97a7c4d2cf9be9c6e0ada78076a5551b01401518597ab81cb6fbd5a1faf4a5e", + "packages/paperclip-runner/runner/crates/runner-core/src/acpx_sidecar_transport.rs": "sha256:f711428ec3bb9bcf723a5fd1382a3d266ed14e7ed5340b8a32eafe7357940144" + } + } +} diff --git a/patches/acpx@0.13.1.patch b/patches/acpx@0.13.1.patch index bfc33c0eb2d..1ed192d4f31 100644 --- a/patches/acpx@0.13.1.patch +++ b/patches/acpx@0.13.1.patch @@ -561,21 +561,52 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js })); result = claudeAcp ? await withTimeout(createPromise, resolveClaudeAcpSessionCreateTimeoutMs()) : await createPromise; } catch (error) { -@@ -4589,6 +4808,13 @@ - } catch (error) { +@@ -4454,6 +4673,7 @@ + } + async loadSessionWithOptions(sessionId, cwd = this.options.cwd, options = {}) { + const connection = this.getConnection(); ++ const { command, args } = resolveAgentCommandParts(this.options.agentCommand, this.options.agentArgv); + const sessionCwd = await resolveAgentSessionCwd(cwd, this.options.agentCommand); + const previousSuppression = this.applySessionUpdateSuppression(Boolean(options.suppressReplayUpdates)); + let response; +@@ -4461,7 +4681,9 @@ + response = await this.runConnectionRequest(() => connection.loadSession({ + sessionId, + cwd: sessionCwd, +- mcpServers: this.options.mcpServers ?? [] ++ mcpServers: this.options.mcpServers ?? [], ++ _meta: isClaudeAcpCommand(command, args) ++ ? buildClaudeCodeOptionsMeta(this.options.sessionOptions, true) : void 0 + })); + await this.waitForSessionUpdateDrain(options.replayIdleMs ?? REPLAY_IDLE_MS, options.replayDrainTimeoutMs ?? REPLAY_DRAIN_TIMEOUT_MS); + } finally { +@@ -4474,11 +4696,14 @@ + } + async resumeSession(sessionId, cwd = this.options.cwd) { + const connection = this.getConnection(); ++ const { command, args } = resolveAgentCommandParts(this.options.agentCommand, this.options.agentArgv); + const sessionCwd = await resolveAgentSessionCwd(cwd, this.options.agentCommand); + const response = await this.runConnectionRequest(() => connection.resumeSession({ + sessionId, + cwd: sessionCwd, +- mcpServers: this.options.mcpServers ?? [] ++ mcpServers: this.options.mcpServers ?? [], ++ _meta: isClaudeAcpCommand(command, args) ++ ? buildClaudeCodeOptionsMeta(this.options.sessionOptions, true) : void 0 + })); + this.loadedSessionId = sessionId; + const result = toReconnectedSessionResult(response); +@@ -4590,15 +4815,17 @@ throw maybeWrapSessionControlError("session/set_config_option", error, `for "${configId}"="${value}"`); } -+ } + } + async requestExtension(method, params) { + closedExtensionMethods([method]); + const payload = boundedExtensionRecord(params); + const connection = this.getConnection(); + const result = await this.runConnectionRequest(() => connection.extMethod(method, payload)); + return boundedExtensionRecord(result); - } - async setSessionModel(sessionId, modelId, controlOverride) { - const control = this.resolveModelControl(sessionId, controlOverride); -@@ -4593,12 +4819,7 @@ ++ } async setSessionModel(sessionId, modelId, controlOverride) { const control = this.resolveModelControl(sessionId, controlOverride); if (!control) throw new RequestedModelUnsupportedError(`Cannot set model "${modelId}": the ACP session did not advertise a model config option or legacy session/set_model support.`, "missing-capability"); @@ -589,7 +620,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js } async setSessionModelThroughConfig(sessionId, modelId, configId) { const connection = this.getConnection(); -@@ -4608,7 +4829,9 @@ +@@ -4608,7 +4835,9 @@ configId, value: modelId })); @@ -600,7 +631,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js return response; } catch (error) { return this.throwSessionModelError("session/set_config_option", modelId, error); -@@ -4864,7 +5087,7 @@ +@@ -4864,7 +5093,7 @@ } selectAuthMethod(methods) { for (const method of methods) { @@ -609,7 +640,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js if (envCredential) return { methodId: method.id, credential: envCredential, -@@ -4890,7 +5113,7 @@ +@@ -4890,7 +5119,7 @@ } readAgentSpecificEnvCredential(methodId) { if (!this.isGrokBuildAcpCommand() || methodId !== "xai.api_key") return; @@ -618,7 +649,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js return typeof value === "string" && value.trim().length > 0 ? value : void 0; } selectAgentManagedAuthMethod(methodId) { -@@ -4915,9 +5138,9 @@ +@@ -4915,9 +5144,9 @@ await connection.authenticate({ methodId: selected.methodId }); this.log(`authenticated with method ${selected.methodId} (${selected.source})`); } @@ -630,7 +661,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js if (hostResponse) return hostResponse; const { response, recorded } = await this.resolvePermissionRequestFromMode(params); if (!recorded) { -@@ -4926,14 +5149,81 @@ +@@ -4926,14 +5155,81 @@ } return response; } @@ -714,7 +745,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js })).then((response) => ({ kind: "response", response -@@ -4970,7 +5260,7 @@ +@@ -4970,7 +5266,7 @@ isElicitationSessionCancelling(sessionId) { return this.closing || this.cancellingSessionIds.has(sessionId); } @@ -723,7 +754,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js if (!this.options.onPermissionRequest) return; const signal = this.cancellationSignalForSession(params.sessionId); try { -@@ -4978,7 +5268,7 @@ +@@ -4978,7 +5274,7 @@ sessionId: params.sessionId, raw: params, inferredKind: inferToolKind(params) @@ -732,7 +763,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js return this.hostPermissionDecisionResponse(params, signal, decision); } catch (error) { return this.hostPermissionErrorResponse(params, signal, error); -@@ -5028,6 +5318,12 @@ +@@ -5028,6 +5324,12 @@ attachAgentLifecycleObservers(child) { child.once("exit", (exitCode, signal) => { this.recordAgentExit("process_exit", exitCode, signal); @@ -745,7 +776,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js }); child.once("close", (exitCode, signal) => { this.recordAgentExit("process_close", exitCode, signal); -@@ -5100,6 +5396,9 @@ +@@ -5100,6 +5402,9 @@ return await this.filesystem.readTextFile(params); } catch (error) { this.recordPermissionError(params.sessionId, error); @@ -755,7 +786,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js throw error; } } -@@ -5239,6 +5538,7 @@ +@@ -5239,6 +5544,7 @@ record.cumulative_token_usage = conversation.cumulative_token_usage; record.cumulative_cost = conversation.cumulative_cost; record.request_token_usage = conversation.request_token_usage; @@ -763,7 +794,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js } //#endregion //#region src/runtime/engine/session-options.ts -@@ -5701,7 +6001,8 @@ +@@ -5701,7 +6007,8 @@ updated_at: conversation.updated_at, cumulative_token_usage: deepClone(conversation.cumulative_token_usage ?? {}), cumulative_cost: cloneUsageCost(conversation.cumulative_cost), @@ -773,7 +804,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js }; } function cloneUsageCost(cost) { -@@ -5771,10 +6072,20 @@ +@@ -5771,10 +6078,20 @@ trimConversationForRuntime(conversation); return acpx; } @@ -796,7 +827,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js updateConversationTimestamp(conversation, timestamp); trimConversationForRuntime(conversation); return true; -@@ -6136,6 +6447,7 @@ +@@ -6136,6 +6453,7 @@ pendingAgentSessionId = loadState.pendingAgentSessionId; sessionModels = loadState.sessionModels; const preferenceReplay = await replayFreshSessionPreferences({ @@ -804,7 +835,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js client, record, createdFreshSession, -@@ -6193,14 +6505,16 @@ +@@ -6193,14 +6511,16 @@ if (shouldReconnect) process.stderr.write(`[acpx] saved session pid ${record.pid} is dead; respawning agent and attempting session reconnect\n`); } async function replayFreshSessionPreferences(params) { @@ -823,7 +854,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js client: params.client, sessionId: params.sessionId, desiredModeId: params.desiredModeId, -@@ -6219,7 +6533,7 @@ +@@ -6219,7 +6539,7 @@ verbose: params.verbose, suppressWarnings: params.suppressWarnings }); @@ -832,7 +863,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js client: params.client, record: params.record, sessionId: params.sessionId, -@@ -6435,6 +6749,27 @@ +@@ -6435,6 +6755,27 @@ //#region src/runtime/engine/prompt-turn.ts const SESSION_REPLY_IDLE_MS = 1e3; const SESSION_REPLY_DRAIN_TIMEOUT_MS = 5e3; @@ -860,7 +891,7 @@ diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js async function runPromptTurn(params) { try { const promptPromise = params.client.prompt(params.sessionId, params.prompt, params.onPromptRequestStarted, params.onElicitation); -@@ -6444,7 +6779,23 @@ +@@ -6444,7 +6785,23 @@ idleMs: SESSION_REPLY_IDLE_MS, timeoutMs: SESSION_REPLY_DRAIN_TIMEOUT_MS }).catch(() => {}); diff --git a/scripts/pi-public-install-probe.mjs b/scripts/pi-public-install-probe.mjs index ed3e018a6b2..525a38772f4 100644 --- a/scripts/pi-public-install-probe.mjs +++ b/scripts/pi-public-install-probe.mjs @@ -52,8 +52,8 @@ assert.equal(JSON.parse(await readFile(join(server, 'package.json'), 'utf8')).na const { resolvePaperclipRunnerBinary } = await import(pathToFileURL(join(server, 'dist/services/native-runtime/native-codex-runner.js'))); const { createCapabilityRunnerdCodexTransport } = await import(pathToFileURL(join(server, 'dist/vendor/paperclip-runner/live/runnerd-codex-transport.js'))); const { QUALIFIED_ACPX_PROFILES } = await import(pathToFileURL(join(server, 'dist/vendor/paperclip-runner/drivers/acpx/qualified-profiles.js'))); -assert.equal(QUALIFIED_ACPX_PROFILES.pi.agentProfileVersion, 32); -assert.equal(QUALIFIED_ACPX_PROFILES.pi.commandDigest, 'sha256:ce13b75699331c813f8a42f2803c3e0e0fb1e6d24847452cb12b50d6ed2d0baf'); +assert.equal(QUALIFIED_ACPX_PROFILES.pi.agentProfileVersion, 33); +assert.equal(QUALIFIED_ACPX_PROFILES.pi.commandDigest, 'sha256:0260d5810e9247986800ad46c1f9b3511a5abd06cb8f142405d5caacbc3960fc'); assert.equal(Object.hasOwn(QUALIFIED_ACPX_PROFILES.pi, 'qualificationModel'), false); assert.equal(Object.hasOwn(QUALIFIED_ACPX_PROFILES.pi, 'reportedModelId'), false); const daemon = resolvePaperclipRunnerBinary();