Merge pull request #1687 from can1357/farm/802d1a6a/update-bypass-bun-manifest-cache

fix(update): bypass bun manifest cache so omp update sees fresh releases
This commit is contained in:
Can Bölük
2026-06-02 09:22:33 +03:00
committed by GitHub
3 changed files with 57 additions and 3 deletions
+1
View File
@@ -21,6 +21,7 @@
- Fixed `omp --resume <id>` crashing with an uncaught exception when an interactive user declined the cross-project fork prompt. `createSessionManager` now returns `undefined` for that cancellation, while non-interactive invocations still fail with a diagnostic when they cannot answer the fork prompt ([#1668](https://github.com/can1357/oh-my-pi/issues/1668)).
- Fixed `history.db` never recording the originating session id: the `session_id` column documented for 15.6.0 was missing from the shipped storage layer, so the column was never created/populated on the write path and every prompt row had `session_id` `NULL`. Restored the `session_id` column, schema migration (`ALTER TABLE history ADD COLUMN session_id` for pre-existing databases), and `HistoryEntry.sessionId`; wired interactive mode to register `setSessionResolver(...)` so prompts are stamped with the session active at submission time (tracking fork/resume switches); and re-enabled prompt-history ranking in the `--resume` and in-session session pickers via `HistoryStorage.matchingSessionIds()`.
- Fixed `/quit` shutdown leaving the parent shell prompt at the top of the viewport after the final TUI teardown render on Linux terminals ([#1620](https://github.com/can1357/oh-my-pi/issues/1620)).
- Fixed `omp update` failing with `No version matching "X" found for specifier "@oh-my-pi/pi-coding-agent" (but package exists)` when bun saw an older catalog than the update check did. The version is resolved by querying `https://registry.npmjs.org/` directly, but `bun install -g` would then consult its on-disk manifest snapshot or a configured npm mirror (corporate proxy, Taobao, …) that hadn't replicated the release. The bun install step now runs with `--no-cache --registry=https://registry.npmjs.org/` so it hits exactly the registry the version check used ([#1686](https://github.com/can1357/oh-my-pi/issues/1686)).
## [15.7.6] - 2026-06-01
### Added
+35 -2
View File
@@ -14,6 +14,18 @@ import { theme } from "../modes/theme/theme";
const REPO = "can1357/oh-my-pi";
const PACKAGE = "@oh-my-pi/pi-coding-agent";
/**
* Official npm registry origin.
*
* Pinned across both the version check and the bun install step so the two
* agree on which catalog they are talking to. A user's bun may be pointed at
* an unofficial mirror (corporate proxy, Taobao, etc.) that lags the upstream
* registry by minutes-to-hours, in which case `getLatestRelease` would resolve
* a version the mirror has not yet replicated and the install would fail with
* `No version matching "X" found for specifier "<pkg>" (but package exists)`.
* See #1686.
*/
const NPM_REGISTRY = "https://registry.npmjs.org/";
interface ReleaseInfo {
tag: string;
@@ -130,7 +142,7 @@ async function resolveUpdateTarget(): Promise<UpdateTarget> {
* Uses npm instead of GitHub API to avoid unauthenticated rate limiting.
*/
async function getLatestRelease(): Promise<ReleaseInfo> {
const response = await fetch(`https://registry.npmjs.org/${PACKAGE}/latest`);
const response = await fetch(`${NPM_REGISTRY}${PACKAGE}/latest`);
if (!response.ok) {
throw new Error(`Failed to fetch release info: ${response.statusText}`);
}
@@ -292,12 +304,33 @@ export async function replaceBinaryForUpdate(options: BinaryReplacementOptions):
}
}
/**
* Build the bun argv used to globally install a specific omp version.
*
* The version is selected by hitting {@link NPM_REGISTRY} directly in
* {@link getLatestRelease}, so the install MUST observe the same catalog:
*
* - `--registry=${NPM_REGISTRY}` pins the install to the official registry
* regardless of the user's bunfig/`.npmrc`. A mirror (corporate proxy,
* Taobao, …) that hasn't yet replicated the release would otherwise reject
* a version the upstream registry already advertises.
* - `--no-cache` tells bun to ignore its on-disk manifest snapshot so it
* re-fetches metadata from that registry on every invocation.
*
* Together these two flags make `omp update` produce exactly the registry
* lookup the version check just performed. See #1686.
*/
export function buildBunInstallArgs(expectedVersion: string): string[] {
return ["install", "-g", "--no-cache", `--registry=${NPM_REGISTRY}`, `${PACKAGE}@${expectedVersion}`];
}
/**
* Update via bun package manager.
*/
async function updateViaBun(expectedVersion: string): Promise<void> {
console.log(chalk.dim("Updating via bun..."));
const result = await $`bun install -g ${PACKAGE}@${expectedVersion}`.nothrow();
const args = buildBunInstallArgs(expectedVersion);
const result = await $`bun ${args}`.nothrow();
if (result.exitCode !== 0) {
throw new Error(`bun install failed with exit code ${result.exitCode}`);
}
+21 -1
View File
@@ -2,7 +2,7 @@ import { afterEach, describe, expect, it } from "bun:test";
import * as fs from "node:fs/promises";
import * as os from "node:os";
import * as path from "node:path";
import { replaceBinaryForUpdate, resolveUpdateMethodForTest } from "../src/cli/update-cli";
import { buildBunInstallArgs, replaceBinaryForUpdate, resolveUpdateMethodForTest } from "../src/cli/update-cli";
const tempDirs: string[] = [];
@@ -35,6 +35,26 @@ describe("update-cli install target detection", () => {
});
});
describe("update-cli bun install command", () => {
it("pins the official npm registry and bypasses the manifest cache so a stale mirror or snapshot cannot mask a freshly published version", () => {
// Regression: omp queries https://registry.npmjs.org/<pkg>/latest directly.
// The install MUST hit the same registry, otherwise:
// - a lagging mirror (corp proxy, Taobao, …) rejects the version with
// `No version matching "X" (but package exists)`,
// - or bun's local manifest snapshot does the same when the user's bun
// 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([
"install",
"-g",
"--no-cache",
"--registry=https://registry.npmjs.org/",
"@oh-my-pi/pi-coding-agent@15.7.6",
]);
});
});
describe("update-cli binary replacement", () => {
it("restores the previous binary when the replacement fails verification", async () => {
const dir = await makeTempDir();