diff --git a/packages/opencode/src/bun/index.ts b/packages/opencode/src/bun/index.ts index e3bddcc22639..516ecb02173b 100644 --- a/packages/opencode/src/bun/index.ts +++ b/packages/opencode/src/bun/index.ts @@ -75,7 +75,7 @@ export namespace BunProc { } else if (version !== "latest" && cachedVersion === version) { return mod } else if (version === "latest") { - const isOutdated = await PackageRegistry.isOutdated(pkg, cachedVersion, Global.Path.cache) + const isOutdated = await PackageRegistry.isOutdated(pkg, cachedVersion) if (!isOutdated) return mod log.info("Cached version is outdated, proceeding with install", { pkg, cachedVersion }) } @@ -86,7 +86,7 @@ export namespace BunProc { "--force", "--exact", // TODO: get rid of this case (see: https://github.com/oven-sh/bun/issues/19936) - ...(proxied() || process.env.CI ? ["--no-cache"] : []), + ...(version === "latest" || proxied() || process.env.CI ? ["--no-cache"] : []), "--cwd", Global.Path.cache, pkg + "@" + version, diff --git a/packages/opencode/src/bun/registry.ts b/packages/opencode/src/bun/registry.ts index a85a6c989c82..61f3b278eb1e 100644 --- a/packages/opencode/src/bun/registry.ts +++ b/packages/opencode/src/bun/registry.ts @@ -1,50 +1,35 @@ import { semver } from "bun" -import { text } from "node:stream/consumers" import { Log } from "../util/log" -import { Process } from "../util/process" export namespace PackageRegistry { const log = Log.create({ service: "bun" }) - function which() { - return process.execPath - } - - export async function info(pkg: string, field: string, cwd?: string): Promise { - const result = Process.spawn([which(), "info", pkg, field], { - cwd, - stdout: "pipe", - stderr: "pipe", - env: { - ...process.env, - BUN_BE_BUN: "1", - }, - }) - - const code = await result.exited - const stdout = result.stdout ? await text(result.stdout) : "" - const stderr = result.stderr ? await text(result.stderr) : "" - - if (code !== 0) { - log.warn("bun info failed", { pkg, field, code, stderr }) + /** + * Query npm registry directly via HTTP instead of `bun info` to avoid + * bun's registry cache returning stale version data. + */ + export async function latest(pkg: string): Promise { + const res = await fetch(`https://registry.npmjs.org/${pkg}/latest`, { + headers: { Accept: "application/vnd.npm.install-v1+json" }, + signal: AbortSignal.timeout(10_000), + }).catch(() => null) + if (!res?.ok) { + log.warn("registry fetch failed", { pkg, status: res?.status }) return null } - - const value = stdout.trim() - if (!value) return null - return value + const data = (await res.json().catch(() => null)) as { version?: string } | null + return data?.version ?? null } - export async function isOutdated(pkg: string, cachedVersion: string, cwd?: string): Promise { - const latestVersion = await info(pkg, "version", cwd) - if (!latestVersion) { - log.warn("Failed to resolve latest version, using cached", { pkg, cachedVersion }) + export async function isOutdated(pkg: string, cached: string): Promise { + const version = await latest(pkg) + if (!version) { + log.warn("failed to resolve latest version, using cached", { pkg, cached }) return false } - const isRange = /[\s^~*xX<>|=]/.test(cachedVersion) - if (isRange) return !semver.satisfies(latestVersion, cachedVersion) + if (/[\s^~*xX<>|=]/.test(cached)) return !semver.satisfies(version, cached) - return semver.order(cachedVersion, latestVersion) === -1 + return semver.order(cached, version) === -1 } } diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 6b4242a225aa..bf7fbe6b3f2c 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -309,7 +309,7 @@ export namespace Config { const targetVersion = Installation.isLocal() ? "latest" : Installation.VERSION if (targetVersion === "latest") { - const isOutdated = await PackageRegistry.isOutdated("@opencode-ai/plugin", depVersion, dir) + const isOutdated = await PackageRegistry.isOutdated("@opencode-ai/plugin", depVersion) if (!isOutdated) return false log.info("Cached version is outdated, proceeding with install", { pkg: "@opencode-ai/plugin",