From 15af2eefbc2dc9f270875836e9bb404f4ed3d135 Mon Sep 17 00:00:00 2001 From: Dotta Date: Wed, 7 Oct 2026 10:02:22 -0500 Subject: [PATCH] Decode current Runner profiles from the release manifest Co-Authored-By: Paperclip --- .../drivers/acpx/profile-compatibility.test.ts | 12 ++++++++++-- .../src/drivers/acpx/profile-compatibility.ts | 15 +++++++++++---- 2 files changed, 21 insertions(+), 6 deletions(-) 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 56d75a071b..5945a843d9 100644 --- a/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.test.ts +++ b/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.test.ts @@ -1,4 +1,5 @@ import { describe, expect, it } from "vitest"; +import { QUALIFIED_ACPX_PROFILE_DATA } from "./generated-profiles.js"; import { isSupportedAcpxProfileVersion } from "./profile-compatibility.js"; describe("historical ACPX profile decoding", () => { @@ -6,16 +7,23 @@ describe("historical ACPX profile decoding", () => { expect(isSupportedAcpxProfileVersion("cursor", 15)).toBe(true); for (const agent of ["pi", "copilot"]) { expect(isSupportedAcpxProfileVersion(agent, 16)).toBe(true); - expect(isSupportedAcpxProfileVersion(agent, 17)).toBe(false); + const current = QUALIFIED_ACPX_PROFILE_DATA[agent as "pi" | "copilot"].agentProfileVersion; + expect(isSupportedAcpxProfileVersion(agent, current)).toBe(true); + expect(isSupportedAcpxProfileVersion(agent, Math.max(16, current) + 1)).toBe(false); } for (const agent of ["claude", "codex", "grok"]) { expect(isSupportedAcpxProfileVersion(agent, 5)).toBe(true); expect(isSupportedAcpxProfileVersion(agent, 6)).toBe(false); } }); - it.each([0, 16, 1.5, "11", null, undefined, NaN])("rejects invalid revisions: %s", version => { + it.each([0, 1.5, "11", null, undefined, NaN])("rejects invalid revisions: %s", version => { expect(isSupportedAcpxProfileVersion("cursor", version)).toBe(false); }); + it("decodes every current release while retaining exact launch admission separately", () => { + for (const [agent, current] of Object.entries(QUALIFIED_ACPX_PROFILE_DATA)) { + expect(isSupportedAcpxProfileVersion(agent, current.agentProfileVersion)).toBe(true); + } + }); it.each(["unknown", "toString", "__proto__"])("rejects unregistered providers: %s", agent => { expect(isSupportedAcpxProfileVersion(agent, 1)).toBe(false); }); diff --git a/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.ts b/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.ts index 7b7438387f..43c3d37077 100644 --- a/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.ts +++ b/packages/paperclip-runner/src/drivers/acpx/profile-compatibility.ts @@ -1,13 +1,20 @@ +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. */ -export type AcpxProfileVersion = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16; -const historicalVersions: Readonly> = { +type HistoricalAcpxProfileVersion = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16; +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], claude: [1, 2, 3, 4, 5], codex: [1, 2, 3, 4, 5], grok: [1, 2, 3, 4, 5], copilot: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], cursor: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], }; export function isSupportedAcpxProfileVersion(agent: string, value: unknown): value is AcpxProfileVersion { - return Object.hasOwn(historicalVersions, agent) - && historicalVersions[agent]!.includes(value as AcpxProfileVersion); + if (!Object.hasOwn(QUALIFIED_ACPX_PROFILE_DATA, agent)) return false; + const current = QUALIFIED_ACPX_PROFILE_DATA[agent as keyof typeof QUALIFIED_ACPX_PROFILE_DATA]; + return value === current.agentProfileVersion + || historicalVersions[agent]?.includes(value as HistoricalAcpxProfileVersion) === true; }