From b991b35f33f15a6b5c1d5bb2ce25d0f34047ddfa Mon Sep 17 00:00:00 2001 From: Matt Toohey Date: Tue, 14 Jul 2026 15:54:40 +1000 Subject: [PATCH] fix(desktop): normalize ACP lock tarball URLs to the public npm registry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit acp-tools.lock.json pinned Block's internal Artifactory host in all 24 tarball URL fields — internal infrastructure leaked into an OSS repo, and anyone regenerating the lock against a different registry churned every URL in the diff even when no pin changed. The URLs are informational only: ensure-acp-tools.sh installs via the developer's ambient npm registry and validates the registry-agnostic sha512 integrity from npm's package-lock, so no install path dereferences them. Normalize at write time instead: update-acp-tools-lock.mjs rebuilds every tarball URL on https://registry.npmjs.org from the resolved package name plus the registry-reported tarball basename (the basename is not derivable from name@version alone — @openai/codex native tarballs carry a platform suffix like codex-0.144.1-darwin-arm64.tgz). A dist.tarball with no /-/ segment fails loudly rather than writing an unnormalizable URL. The usage text documents the normalization, and the committed lock is regenerated: the diff is exactly the 24 tarball fields; every version and integrity hash is byte-identical. Addresses the internal-Artifactory-URL finding from the bundling-series code review (review 2ed3d00d on b52a665a). Verification (ambient registry = Block Artifactory, proving normalization against an internal mirror): - Full regeneration: versions/integrity byte-identical to the previous lock; only tarball hosts changed. - Partial --target aarch64-apple-darwin rerun on the normalized lock: byte-identical output (preserved + fresh entries agree). - All normalized URL shapes probe live on registry.npmjs.org (303 CDN redirect), including the platform-suffixed codex native tarball. - ensure-acp-tools.sh with the new lock: validates and no-op stages, exit 0 (the freshness stamp does not compare tarball fields, so no spurious re-install). - pnpm exec biome check on the script: clean. Co-Authored-By: Claude Fable 5 Signed-off-by: Matt Toohey --- desktop/acp-tools.lock.json | 48 +++++++++++------------ desktop/scripts/update-acp-tools-lock.mjs | 30 +++++++++++++- 2 files changed, 53 insertions(+), 25 deletions(-) diff --git a/desktop/acp-tools.lock.json b/desktop/acp-tools.lock.json index d2361a3b6..6ef4947bf 100644 --- a/desktop/acp-tools.lock.json +++ b/desktop/acp-tools.lock.json @@ -7,7 +7,7 @@ "package": "@agentclientprotocol/claude-agent-acp", "version": "0.58.1", "integrity": "sha512-F1/W6EJdoYbrEUluRUknx0Nn0MAKDOkn2C/9YcP/joVkmdFUGTAxlGDpwdYu239TOkpc8Qm4+ffGsQjPZdryTg==", - "tarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@agentclientprotocol/claude-agent-acp/-/claude-agent-acp-0.58.1.tgz", + "tarball": "https://registry.npmjs.org/@agentclientprotocol/claude-agent-acp/-/claude-agent-acp-0.58.1.tgz", "target": "aarch64-apple-darwin", "npmOs": "darwin", "npmCpu": "arm64", @@ -15,13 +15,13 @@ "dependencyPackage": "@anthropic-ai/claude-agent-sdk", "dependencyVersion": "0.3.205", "dependencyIntegrity": "sha512-ft6iBw9kXudsusiXNpeybIPBJ07Z3tqp1ROSg5cEJqgA+9i+JJj2sRfQth+QD+lyenbbAU8yPieLxIimvfBhtw==", - "dependencyTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.205.tgz", + "dependencyTarball": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.205.tgz", "claudeCodeVersion": "2.1.205", "nativePackage": "@anthropic-ai/claude-agent-sdk-darwin-arm64", "nativePackageName": "@anthropic-ai/claude-agent-sdk-darwin-arm64", "nativeVersion": "0.3.205", "nativeIntegrity": "sha512-lrfJ4eVtzfPkCpbSkBOGSMQCBbvmW6nbPzgHE4IwMN3scZlpuFMUFqh2aaJa/X2SAcWD9H2S0t2WWvSRgM7BjA==", - "nativeTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.205.tgz", + "nativeTarball": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-arm64/-/claude-agent-sdk-darwin-arm64-0.3.205.tgz", "nativeExecutable": "claude" }, { @@ -31,7 +31,7 @@ "package": "@agentclientprotocol/claude-agent-acp", "version": "0.58.1", "integrity": "sha512-F1/W6EJdoYbrEUluRUknx0Nn0MAKDOkn2C/9YcP/joVkmdFUGTAxlGDpwdYu239TOkpc8Qm4+ffGsQjPZdryTg==", - "tarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@agentclientprotocol/claude-agent-acp/-/claude-agent-acp-0.58.1.tgz", + "tarball": "https://registry.npmjs.org/@agentclientprotocol/claude-agent-acp/-/claude-agent-acp-0.58.1.tgz", "target": "aarch64-unknown-linux-gnu", "npmOs": "linux", "npmCpu": "arm64", @@ -40,13 +40,13 @@ "dependencyPackage": "@anthropic-ai/claude-agent-sdk", "dependencyVersion": "0.3.205", "dependencyIntegrity": "sha512-ft6iBw9kXudsusiXNpeybIPBJ07Z3tqp1ROSg5cEJqgA+9i+JJj2sRfQth+QD+lyenbbAU8yPieLxIimvfBhtw==", - "dependencyTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.205.tgz", + "dependencyTarball": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.205.tgz", "claudeCodeVersion": "2.1.205", "nativePackage": "@anthropic-ai/claude-agent-sdk-linux-arm64", "nativePackageName": "@anthropic-ai/claude-agent-sdk-linux-arm64", "nativeVersion": "0.3.205", "nativeIntegrity": "sha512-CXzySK3PV3EizCRPXnxPqeaAtgrBFDnMFOVpMe36oC3U16yDb1b1tAJGqZi/7uFrVvAiaXvnSFxhUWnDDSaO+A==", - "nativeTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.205.tgz", + "nativeTarball": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-arm64/-/claude-agent-sdk-linux-arm64-0.3.205.tgz", "nativeExecutable": "claude" }, { @@ -56,7 +56,7 @@ "package": "@agentclientprotocol/claude-agent-acp", "version": "0.58.1", "integrity": "sha512-F1/W6EJdoYbrEUluRUknx0Nn0MAKDOkn2C/9YcP/joVkmdFUGTAxlGDpwdYu239TOkpc8Qm4+ffGsQjPZdryTg==", - "tarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@agentclientprotocol/claude-agent-acp/-/claude-agent-acp-0.58.1.tgz", + "tarball": "https://registry.npmjs.org/@agentclientprotocol/claude-agent-acp/-/claude-agent-acp-0.58.1.tgz", "target": "x86_64-apple-darwin", "npmOs": "darwin", "npmCpu": "x64", @@ -64,13 +64,13 @@ "dependencyPackage": "@anthropic-ai/claude-agent-sdk", "dependencyVersion": "0.3.205", "dependencyIntegrity": "sha512-ft6iBw9kXudsusiXNpeybIPBJ07Z3tqp1ROSg5cEJqgA+9i+JJj2sRfQth+QD+lyenbbAU8yPieLxIimvfBhtw==", - "dependencyTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.205.tgz", + "dependencyTarball": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.205.tgz", "claudeCodeVersion": "2.1.205", "nativePackage": "@anthropic-ai/claude-agent-sdk-darwin-x64", "nativePackageName": "@anthropic-ai/claude-agent-sdk-darwin-x64", "nativeVersion": "0.3.205", "nativeIntegrity": "sha512-G6ETPmL5mNzJ2DFsWxG3jmsmrXgZX1N2ZCJvxaGUUpjTsKZJ4Tup1cWYvcd/m7o5fYZmx9REmgzTwsAIc1fdPQ==", - "nativeTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.205.tgz", + "nativeTarball": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-darwin-x64/-/claude-agent-sdk-darwin-x64-0.3.205.tgz", "nativeExecutable": "claude" }, { @@ -80,7 +80,7 @@ "package": "@agentclientprotocol/claude-agent-acp", "version": "0.58.1", "integrity": "sha512-F1/W6EJdoYbrEUluRUknx0Nn0MAKDOkn2C/9YcP/joVkmdFUGTAxlGDpwdYu239TOkpc8Qm4+ffGsQjPZdryTg==", - "tarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@agentclientprotocol/claude-agent-acp/-/claude-agent-acp-0.58.1.tgz", + "tarball": "https://registry.npmjs.org/@agentclientprotocol/claude-agent-acp/-/claude-agent-acp-0.58.1.tgz", "target": "x86_64-unknown-linux-gnu", "npmOs": "linux", "npmCpu": "x64", @@ -89,13 +89,13 @@ "dependencyPackage": "@anthropic-ai/claude-agent-sdk", "dependencyVersion": "0.3.205", "dependencyIntegrity": "sha512-ft6iBw9kXudsusiXNpeybIPBJ07Z3tqp1ROSg5cEJqgA+9i+JJj2sRfQth+QD+lyenbbAU8yPieLxIimvfBhtw==", - "dependencyTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.205.tgz", + "dependencyTarball": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk/-/claude-agent-sdk-0.3.205.tgz", "claudeCodeVersion": "2.1.205", "nativePackage": "@anthropic-ai/claude-agent-sdk-linux-x64", "nativePackageName": "@anthropic-ai/claude-agent-sdk-linux-x64", "nativeVersion": "0.3.205", "nativeIntegrity": "sha512-siS+1iNqBSlGFZZvJY6+mhzZ/6/ec/TbX9GMuwmTF0E6fxGhIIp797jJxR1q8r6FAq7d39mEoRNhC0Ffo60uNQ==", - "nativeTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.205.tgz", + "nativeTarball": "https://registry.npmjs.org/@anthropic-ai/claude-agent-sdk-linux-x64/-/claude-agent-sdk-linux-x64-0.3.205.tgz", "nativeExecutable": "claude" }, { @@ -105,7 +105,7 @@ "package": "@agentclientprotocol/codex-acp", "version": "1.1.2", "integrity": "sha512-qE/R1WdqJJ9OFHsHGvbmVmS2j9iCMZzpWT3g2XIViXrGHu1fLOALLINBIlW+WzKDllCh131aB6cqcIWSt0otbw==", - "tarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@agentclientprotocol/codex-acp/-/codex-acp-1.1.2.tgz", + "tarball": "https://registry.npmjs.org/@agentclientprotocol/codex-acp/-/codex-acp-1.1.2.tgz", "target": "aarch64-apple-darwin", "npmOs": "darwin", "npmCpu": "arm64", @@ -113,12 +113,12 @@ "dependencyPackage": "@openai/codex", "dependencyVersion": "0.144.1", "dependencyIntegrity": "sha512-Xir1zqPfpenhdoAoshN53uonzbBXj18COyzRkFlVZpSNyEl5XtkuYu9oddELePFN7K/0sXUcSO34Ad5IeCXPbw==", - "dependencyTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@openai/codex/-/codex-0.144.1.tgz", + "dependencyTarball": "https://registry.npmjs.org/@openai/codex/-/codex-0.144.1.tgz", "nativePackage": "@openai/codex-darwin-arm64", "nativePackageName": "@openai/codex", "nativeVersion": "0.144.1-darwin-arm64", "nativeIntegrity": "sha512-dABeDK+ATqMG54MGBd3VjpKfh5EOoqx9PKVQB2QYDaEXx3F6CdUCXue5QIMfr4OxziUj8pUcLAQyd+KFqiTUFw==", - "nativeTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@openai/codex/-/codex-0.144.1-darwin-arm64.tgz", + "nativeTarball": "https://registry.npmjs.org/@openai/codex/-/codex-0.144.1-darwin-arm64.tgz", "nativeExecutable": "vendor/aarch64-apple-darwin/bin/codex" }, { @@ -128,7 +128,7 @@ "package": "@agentclientprotocol/codex-acp", "version": "1.1.2", "integrity": "sha512-qE/R1WdqJJ9OFHsHGvbmVmS2j9iCMZzpWT3g2XIViXrGHu1fLOALLINBIlW+WzKDllCh131aB6cqcIWSt0otbw==", - "tarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@agentclientprotocol/codex-acp/-/codex-acp-1.1.2.tgz", + "tarball": "https://registry.npmjs.org/@agentclientprotocol/codex-acp/-/codex-acp-1.1.2.tgz", "target": "aarch64-unknown-linux-gnu", "npmOs": "linux", "npmCpu": "arm64", @@ -137,12 +137,12 @@ "dependencyPackage": "@openai/codex", "dependencyVersion": "0.144.1", "dependencyIntegrity": "sha512-Xir1zqPfpenhdoAoshN53uonzbBXj18COyzRkFlVZpSNyEl5XtkuYu9oddELePFN7K/0sXUcSO34Ad5IeCXPbw==", - "dependencyTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@openai/codex/-/codex-0.144.1.tgz", + "dependencyTarball": "https://registry.npmjs.org/@openai/codex/-/codex-0.144.1.tgz", "nativePackage": "@openai/codex-linux-arm64", "nativePackageName": "@openai/codex", "nativeVersion": "0.144.1-linux-arm64", "nativeIntegrity": "sha512-451o15+XtaXCCb35t/KCyyPqXHnTPxPxtdqEYOnE3e4sH5AfnI/uVJwfdjOksMG6vRLy6R+fLvSDOMguRFLmQw==", - "nativeTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@openai/codex/-/codex-0.144.1-linux-arm64.tgz", + "nativeTarball": "https://registry.npmjs.org/@openai/codex/-/codex-0.144.1-linux-arm64.tgz", "nativeExecutable": "vendor/aarch64-unknown-linux-musl/bin/codex" }, { @@ -152,7 +152,7 @@ "package": "@agentclientprotocol/codex-acp", "version": "1.1.2", "integrity": "sha512-qE/R1WdqJJ9OFHsHGvbmVmS2j9iCMZzpWT3g2XIViXrGHu1fLOALLINBIlW+WzKDllCh131aB6cqcIWSt0otbw==", - "tarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@agentclientprotocol/codex-acp/-/codex-acp-1.1.2.tgz", + "tarball": "https://registry.npmjs.org/@agentclientprotocol/codex-acp/-/codex-acp-1.1.2.tgz", "target": "x86_64-apple-darwin", "npmOs": "darwin", "npmCpu": "x64", @@ -160,12 +160,12 @@ "dependencyPackage": "@openai/codex", "dependencyVersion": "0.144.1", "dependencyIntegrity": "sha512-Xir1zqPfpenhdoAoshN53uonzbBXj18COyzRkFlVZpSNyEl5XtkuYu9oddELePFN7K/0sXUcSO34Ad5IeCXPbw==", - "dependencyTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@openai/codex/-/codex-0.144.1.tgz", + "dependencyTarball": "https://registry.npmjs.org/@openai/codex/-/codex-0.144.1.tgz", "nativePackage": "@openai/codex-darwin-x64", "nativePackageName": "@openai/codex", "nativeVersion": "0.144.1-darwin-x64", "nativeIntegrity": "sha512-K2g3Q3tNxzFhV0SuzO6HcsYK7EQrp/o4HyeReyhkwVrwwUPoYwyIbB0IRjHIiDzRhbKriDccid2iyF5aPqdTcg==", - "nativeTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@openai/codex/-/codex-0.144.1-darwin-x64.tgz", + "nativeTarball": "https://registry.npmjs.org/@openai/codex/-/codex-0.144.1-darwin-x64.tgz", "nativeExecutable": "vendor/x86_64-apple-darwin/bin/codex" }, { @@ -175,7 +175,7 @@ "package": "@agentclientprotocol/codex-acp", "version": "1.1.2", "integrity": "sha512-qE/R1WdqJJ9OFHsHGvbmVmS2j9iCMZzpWT3g2XIViXrGHu1fLOALLINBIlW+WzKDllCh131aB6cqcIWSt0otbw==", - "tarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@agentclientprotocol/codex-acp/-/codex-acp-1.1.2.tgz", + "tarball": "https://registry.npmjs.org/@agentclientprotocol/codex-acp/-/codex-acp-1.1.2.tgz", "target": "x86_64-unknown-linux-gnu", "npmOs": "linux", "npmCpu": "x64", @@ -184,12 +184,12 @@ "dependencyPackage": "@openai/codex", "dependencyVersion": "0.144.1", "dependencyIntegrity": "sha512-Xir1zqPfpenhdoAoshN53uonzbBXj18COyzRkFlVZpSNyEl5XtkuYu9oddELePFN7K/0sXUcSO34Ad5IeCXPbw==", - "dependencyTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@openai/codex/-/codex-0.144.1.tgz", + "dependencyTarball": "https://registry.npmjs.org/@openai/codex/-/codex-0.144.1.tgz", "nativePackage": "@openai/codex-linux-x64", "nativePackageName": "@openai/codex", "nativeVersion": "0.144.1-linux-x64", "nativeIntegrity": "sha512-HNGVI+BulrOaC/0IzBvd6EL62j7LrlbFKibrhw6hZjjCjAeUYzRB2jB4qDzXN1NfqDi6Xrvniof3kwbwab24lg==", - "nativeTarball": "https://global.block-artifacts.com/artifactory/api/npm/square-npm/@openai/codex/-/codex-0.144.1-linux-x64.tgz", + "nativeTarball": "https://registry.npmjs.org/@openai/codex/-/codex-0.144.1-linux-x64.tgz", "nativeExecutable": "vendor/x86_64-unknown-linux-musl/bin/codex" } ] diff --git a/desktop/scripts/update-acp-tools-lock.mjs b/desktop/scripts/update-acp-tools-lock.mjs index dcadaf9b7..f80091c21 100755 --- a/desktop/scripts/update-acp-tools-lock.mjs +++ b/desktop/scripts/update-acp-tools-lock.mjs @@ -91,6 +91,13 @@ const NPM_TARGET_CONFIG = { }, }; +// Tarball URLs in the lock are informational — ensure-acp-tools.sh installs +// via the ambient npm registry and validates the registry-agnostic sha512 +// integrity. Normalize them to the public registry so regenerating against an +// internal mirror (e.g. Artifactory) neither leaks internal hosts into the +// committed lock nor churns every URL in the diff. +const PUBLIC_NPM_REGISTRY = "https://registry.npmjs.org"; + const npmViewCache = new Map(); const execFileAsync = promisify(execFile); @@ -106,6 +113,10 @@ A --target run regenerates only the selected targets; the existing lock's entries for every other target are preserved verbatim, so a partial bump never drops another target's pins. +Tarball URLs are normalized to ${PUBLIC_NPM_REGISTRY} regardless of the +registry that resolved the metadata, so regeneration is deterministic across +environments and internal mirror hosts never land in the committed lock. + Supported targets: ${SUPPORTED_TARGETS.join("\n ")} @@ -178,10 +189,27 @@ function requireString(value, label) { return value; } +// Rebuild the tarball URL on PUBLIC_NPM_REGISTRY, keeping the registry's +// `/-/.tgz` path (the basename is not always derivable +// from name@version — @openai/codex native tarballs carry a platform suffix). +function normalizeTarballUrl(tarball, packageName, label) { + const separator = "/-/"; + const separatorIndex = tarball.lastIndexOf(separator); + if (separatorIndex === -1) { + throw new Error(`Cannot normalize ${label} tarball URL: ${tarball}`); + } + const basename = tarball.slice(separatorIndex + separator.length); + return `${PUBLIC_NPM_REGISTRY}/${packageName}/-/${basename}`; +} + function packageDist(metadata, label) { const dist = metadata?.dist; return { - tarball: requireString(dist?.tarball, `${label} dist.tarball`), + tarball: normalizeTarballUrl( + requireString(dist?.tarball, `${label} dist.tarball`), + requireString(metadata?.name, `${label} name`), + label, + ), integrity: requireString(dist?.integrity, `${label} dist.integrity`), }; }