From 0dd11898ad60c2ad906011ff07ebf7d9970d3281 Mon Sep 17 00:00:00 2001 From: George Hilliard Date: Thu, 30 Apr 2026 05:27:50 -0500 Subject: [PATCH] fix(coding-agent): redo Bun package manager node_modules handling (#3998) * Revert "fix(coding-agent): use alternate logic to find Bun's node_modules (#3861)" This reverts commit c241c6d6d0232fdb594b436e95b82f72accfd58f. The logic is faulty: the original strategy of looking for node_modules by asking the package manager is not incorrect even on bun. Instead, it should learn a different method of asking the package manager for node_modules when the *package manager* is bun, not the *runtime*. * feat(coding-agent): detect bun as package manager and use alternate root query When `"npmCommand": ["bun"]` is configured in settings.json, pi fails to start because it invokes `bun root -g`, which doesn't exist: error: Failed to run bun root -g: error: Script not found "root" Add a (simple) check for Bun being used as package manager, and instead build the relative path starting from Bun's bin directory. --- packages/coding-agent/docs/settings.md | 4 +++- packages/coding-agent/src/core/package-manager.ts | 7 ++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/coding-agent/docs/settings.md b/packages/coding-agent/docs/settings.md index 5e39646b..fd5771f1 100644 --- a/packages/coding-agent/docs/settings.md +++ b/packages/coding-agent/docs/settings.md @@ -153,7 +153,9 @@ When a provider requests a retry delay longer than `retry.provider.maxRetryDelay } ``` -`npmCommand` is used for all npm package-manager operations, including `npm root -g`, installs, uninstalls, and dependency installs inside git packages. Use argv-style entries exactly as the process should be launched. When `npmCommand` is configured, git package dependency installs use plain `install` to avoid npm-specific flags in wrappers or alternate package managers. +`npmCommand` is used for all npm package-manager operations, including installs, uninstalls, and dependency installs inside git packages. Use argv-style entries exactly as the process should be launched. When `npmCommand` is configured, git package dependency installs use plain `install` to avoid npm-specific flags in wrappers or alternate package managers. + +Normally the package manager's global modules location is queried using `root -g`. As a special case, if the first element of `npmCommand` is `"bun"`, the modules location will instead be queried with `pm bin -g`. ### Sessions diff --git a/packages/coding-agent/src/core/package-manager.ts b/packages/coding-agent/src/core/package-manager.ts index 5a25a904..a8cbd5d2 100644 --- a/packages/coding-agent/src/core/package-manager.ts +++ b/packages/coding-agent/src/core/package-manager.ts @@ -27,7 +27,7 @@ import type { Readable } from "node:stream"; import { globSync } from "glob"; import ignore from "ignore"; import { minimatch } from "minimatch"; -import { CONFIG_DIR_NAME, isBunRuntime } from "../config.js"; +import { CONFIG_DIR_NAME } from "../config.js"; import { type GitSource, parseGitUrl } from "../utils/git.js"; import { canonicalizePath, isLocalPath } from "../utils/paths.js"; import { isStdoutTakenOver } from "./output-guard.js"; @@ -1843,8 +1843,9 @@ export class DefaultPackageManager implements PackageManager { if (this.globalNpmRoot && this.globalNpmRootCommandKey === commandKey) { return this.globalNpmRoot; } - if (isBunRuntime) { - const binDir = this.runCommandSync("bun", ["pm", "bin", "-g"]).trim(); + const isBunPackageManager = npmCommand.command === "bun"; + if (isBunPackageManager) { + const binDir = this.runNpmCommandSync(["pm", "bin", "-g"]).trim(); this.globalNpmRoot = join(dirname(binDir), "install", "global", "node_modules"); } else { this.globalNpmRoot = this.runNpmCommandSync(["root", "-g"]).trim();