diff --git a/packages/coding-agent/src/cli/update-cli.ts b/packages/coding-agent/src/cli/update-cli.ts index 591a4fb2b..3a46d4861 100644 --- a/packages/coding-agent/src/cli/update-cli.ts +++ b/packages/coding-agent/src/cli/update-cli.ts @@ -372,19 +372,26 @@ async function resolveBunInstallCacheDir(): Promise { } } -async function resolveBunGlobalNodeModulesDir(): Promise { +export function resolveBunGlobalNodeModulesDirFromLocations( + globalBinDir: string | undefined, + cacheDir: string | undefined, +): string | undefined { + if (globalBinDir && globalBinDir.length > 0) { + return path.join(path.dirname(globalBinDir), "install", "global", "node_modules"); + } + if (cacheDir && cacheDir.length > 0) { + return path.join(path.dirname(cacheDir), "global", "node_modules"); + } + return undefined; +} + +async function resolveBunGlobalNodeModulesDir(cacheDir: string): Promise { try { - const result = await $`bun pm ls -g`.quiet().nothrow(); - if (result.exitCode !== 0) return undefined; - const output = result.text(); - const firstLineEnd = output.indexOf("\n"); - const firstLine = (firstLineEnd === -1 ? output : output.slice(0, firstLineEnd)).trim(); - const marker = " node_modules "; - const markerIndex = firstLine.lastIndexOf(marker); - if (markerIndex === -1) return undefined; - return path.join(firstLine.slice(0, markerIndex), "node_modules"); + const result = await $`bun pm bin -g`.quiet().nothrow(); + const globalBinDir = result.exitCode === 0 ? result.text().trim() : undefined; + return resolveBunGlobalNodeModulesDirFromLocations(globalBinDir, cacheDir); } catch { - return undefined; + return resolveBunGlobalNodeModulesDirFromLocations(undefined, cacheDir); } } @@ -406,7 +413,7 @@ async function collectInstalledPackageNames(nodeModulesDir: string): Promise { const cacheDir = await resolveBunInstallCacheDir(); if (!cacheDir) return undefined; - const globalNodeModulesDir = await resolveBunGlobalNodeModulesDir(); + const globalNodeModulesDir = await resolveBunGlobalNodeModulesDir(cacheDir); const packageNames = globalNodeModulesDir ? await collectInstalledPackageNames(globalNodeModulesDir) : new Set(); diff --git a/packages/coding-agent/test/update-cli.test.ts b/packages/coding-agent/test/update-cli.test.ts index 3be104fac..746617a87 100644 --- a/packages/coding-agent/test/update-cli.test.ts +++ b/packages/coding-agent/test/update-cli.test.ts @@ -6,6 +6,7 @@ import { buildBunInstallArgs, pruneBunInstallCache, replaceBinaryForUpdate, + resolveBunGlobalNodeModulesDirFromLocations, resolveUpdateMethodForTest, } from "../src/cli/update-cli"; @@ -58,6 +59,15 @@ describe("update-cli bun install command", () => { "@oh-my-pi/pi-coding-agent@15.7.6", ]); }); + + it("derives global node_modules from supported bun global locations", () => { + expect(resolveBunGlobalNodeModulesDirFromLocations(path.join("home", ".bun", "bin"), undefined)).toBe( + path.join("home", ".bun", "install", "global", "node_modules"), + ); + expect( + resolveBunGlobalNodeModulesDirFromLocations(undefined, path.join("home", ".bun", "install", "cache")), + ).toBe(path.join("home", ".bun", "install", "global", "node_modules")); + }); }); describe("update-cli bun cache pruning", () => {