From 32f07b24f76b2c1451a523e6ada72c287dfc33b2 Mon Sep 17 00:00:00 2001 From: roboomp Date: Thu, 4 Jun 2026 06:52:31 +0000 Subject: [PATCH] fix(coding-agent): sync pi-natives on omp update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit bun install -g @ did not reliably re-resolve transitive optionalDependencies, so @oh-my-pi/pi-natives and the platform leaf @oh-my-pi/pi-natives- stayed at the previous version while @oh-my-pi/pi-coding-agent moved. The loader’s validateLoadedBindings then aborted because the .node file exposed the old __piNativesV sentinel instead of __piNativesV. buildBunInstallArgs now pins @oh-my-pi/pi-natives and (when the running tag is one the release pipeline publishes) the platform leaf to the same version it installs for @oh-my-pi/pi-coding-agent, so bun replaces all three in lock-step. The leaf is gated by the same SUPPORTED_PLATFORMS set the loader uses, so unsupported tags still surface the original 'no matching version' diagnostic instead of EBADPLATFORM. Fixes #1824 --- packages/coding-agent/CHANGELOG.md | 4 ++ packages/coding-agent/src/cli/update-cli.ts | 59 ++++++++++++++++++- packages/coding-agent/test/update-cli.test.ts | 28 ++++++++- 3 files changed, 88 insertions(+), 3 deletions(-) diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index dcbd68a54..4bc1f94e9 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Fixed `omp update` leaving `@oh-my-pi/pi-natives` and the platform-specific `@oh-my-pi/pi-natives-` leaf at the previous version on `bun install -g` updates, so the next launch loaded a stale `.node` file and aborted at `validateLoadedBindings` with `The .node file on disk is from a different release than this loader`. `omp update` now pins the native addon core and the platform leaf to the same version it installs for `@oh-my-pi/pi-coding-agent` ([#1824](https://github.com/can1357/oh-my-pi/issues/1824)). + ## [15.9.0] - 2026-06-04 ### Breaking Changes diff --git a/packages/coding-agent/src/cli/update-cli.ts b/packages/coding-agent/src/cli/update-cli.ts index 8593a957b..310837cea 100644 --- a/packages/coding-agent/src/cli/update-cli.ts +++ b/packages/coding-agent/src/cli/update-cli.ts @@ -27,6 +27,33 @@ const PACKAGE = "@oh-my-pi/pi-coding-agent"; */ const NPM_REGISTRY = "https://registry.npmjs.org/"; +/** + * Core native addon package. Bumped in lock-step with {@link PACKAGE} so the + * version sentinel the loader looks up at runtime matches the `.node` on + * disk; see {@link buildBunInstallArgs} for why this must be installed + * explicitly rather than inherited as a transitive dependency. + */ +const NATIVES_PACKAGE = "@oh-my-pi/pi-natives"; + +/** + * Platform tags the release pipeline publishes as + * `@oh-my-pi/pi-natives-` leaves. Mirrors `SUPPORTED_PLATFORMS` in + * `packages/natives/native/loader-state.js` and `LEAF_TARGETS` in + * `packages/natives/scripts/gen-npm-packages.ts`; kept here as the local + * source of truth so the update path stays free of cross-package imports. + */ +const SUPPORTED_NATIVE_TAGS: ReadonlySet = new Set([ + "linux-x64", + "linux-arm64", + "darwin-x64", + "darwin-arm64", + "win32-x64", +]); + +function currentNativeTag(): string { + return `${process.platform}-${process.arch}`; +} + interface ReleaseInfo { tag: string; version: string; @@ -319,9 +346,37 @@ export async function replaceBinaryForUpdate(options: BinaryReplacementOptions): * * Together these two flags make `omp update` produce exactly the registry * lookup the version check just performed. See #1686. + * + * Also pins {@link NATIVES_PACKAGE} and the platform-specific + * `@oh-my-pi/pi-natives-` leaf to `expectedVersion`. `bun install -g` + * does not reliably refresh transitive `optionalDependencies` when the + * top-level package is the only one bumped, so the native addon and its + * version sentinel can drift out of sync with the freshly installed + * `@oh-my-pi/pi-coding-agent` and the loader aborts at + * `validateLoadedBindings` on the next launch + * (`The .node file on disk is from a different release than this loader`). + * Listing the natives explicitly forces bun to replace them in lock-step. + * The leaf is added only on tags the release pipeline actually publishes + * ({@link SUPPORTED_NATIVE_TAGS}) so unsupported platforms still fail with + * the original "no matching version" message instead of `EBADPLATFORM`. + * See #1824. */ -export function buildBunInstallArgs(expectedVersion: string): string[] { - return ["install", "-g", "--no-cache", `--registry=${NPM_REGISTRY}`, `${PACKAGE}@${expectedVersion}`]; +export function buildBunInstallArgs( + expectedVersion: string, + nativeTag: string = currentNativeTag(), +): string[] { + const args = [ + "install", + "-g", + "--no-cache", + `--registry=${NPM_REGISTRY}`, + `${PACKAGE}@${expectedVersion}`, + `${NATIVES_PACKAGE}@${expectedVersion}`, + ]; + if (SUPPORTED_NATIVE_TAGS.has(nativeTag)) { + args.push(`${NATIVES_PACKAGE}-${nativeTag}@${expectedVersion}`); + } + return args; } /** diff --git a/packages/coding-agent/test/update-cli.test.ts b/packages/coding-agent/test/update-cli.test.ts index 038fcba15..cbc127aa5 100644 --- a/packages/coding-agent/test/update-cli.test.ts +++ b/packages/coding-agent/test/update-cli.test.ts @@ -45,7 +45,8 @@ describe("update-cli bun install command", () => { // is already pointed at the official registry but its cache predates // the release. // See https://github.com/can1357/oh-my-pi/issues/1686. - expect(buildBunInstallArgs("15.7.6")).toEqual([ + const args = buildBunInstallArgs("15.7.6", "linux-x64"); + expect(args.slice(0, 5)).toEqual([ "install", "-g", "--no-cache", @@ -53,6 +54,31 @@ describe("update-cli bun install command", () => { "@oh-my-pi/pi-coding-agent@15.7.6", ]); }); + + it("pins the native addon core and the platform-specific leaf to the same version so the loader sentinel cannot drift on supported tags", () => { + // Regression: bun install -g @ would update only the top-level + // package, leaving @oh-my-pi/pi-natives and @oh-my-pi/pi-natives- + // at their previous version. The next launch then loaded a stale .node + // file and aborted at validateLoadedBindings with `The .node file on + // disk is from a different release than this loader`. See + // https://github.com/can1357/oh-my-pi/issues/1824. + for (const tag of ["linux-x64", "linux-arm64", "darwin-x64", "darwin-arm64", "win32-x64"]) { + const args = buildBunInstallArgs("15.9.0", tag); + expect(args).toContain("@oh-my-pi/pi-natives@15.9.0"); + expect(args).toContain(`@oh-my-pi/pi-natives-${tag}@15.9.0`); + } + }); + + it("omits the leaf on unsupported platform tags so an EBADPLATFORM swap does not mask the underlying `no matching version` error", () => { + // Defensive: an unsupported tag (e.g. linux-arm32) still installs the + // core natives package — which will fail at module load if the platform + // truly is unsupported — but we never request a leaf the release + // pipeline doesn't publish, otherwise bun aborts with EBADPLATFORM + // and hides the real diagnostic from `loadNative`'s aggregated error. + const args = buildBunInstallArgs("15.9.0", "linux-arm"); + expect(args).toContain("@oh-my-pi/pi-natives@15.9.0"); + expect(args.some(arg => arg.startsWith("@oh-my-pi/pi-natives-"))).toBe(false); + }); }); describe("update-cli binary replacement", () => {