diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index 9337ac979..b513e7a2f 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -39,6 +39,7 @@ - Fixed Windows paths being compared case-sensitively. When the working directory and home directory differed only in drive-letter casing (`c:\Users\me` vs `C:\Users\me`), skills in `~/.agents/skills` loaded twice, as project and user skills, and were reported as name collisions. The same mismatch also re-asked for saved project trust, hid sessions in a custom session directory from `--continue` and `/resume`, and stopped `pi remove` from matching configured local packages ([#10488](https://github.com/earendil-works/pi/issues/10488)) - Fixed paths next to the home directory being shown with a broken `~` prefix, for example `/home/me2/project` shown as `~2/project` when home is `/home/me` - Fixed `pi mcp login -l` and `pi mcp logout -l` failing with `Unknown option --local.` although `pi mcp add` and `pi mcp remove` accept `-l`. With `-l`, they now require the server to be a project server. Unknown options are now reported as typed, and a mistyped server name gets a suggestion, for example `Did you mean "gurker"?` +- Fixed `pi update` naming pnpm for installs that only live under `PNPM_HOME`, for example a wrapper under `$PNPM_HOME/global-nub/`. pi said "not managed by a global pnpm install"; it now names the package manager only when that manager owns the install ([#7756](https://github.com/earendil-works/pi/issues/7756)) ## [1.4.0] - 2026-10-21 diff --git a/packages/coding-agent/src/config.ts b/packages/coding-agent/src/config.ts index 61dd63f38..381747620 100644 --- a/packages/coding-agent/src/config.ts +++ b/packages/coding-agent/src/config.ts @@ -345,11 +345,10 @@ export function getSelfUpdateUnavailableInstruction( return `Download from: https://github.com/earendil-works/pi/releases/latest`; } const command = getSelfUpdateCommandForMethod(method, packageName, target, npmCommand); - if (command) { - if (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) { - return `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`; - } - return `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`; + // Path-based detection also matches installs that only live under a package manager's directory, + // such as a wrapper under PNPM_HOME, so name the package manager only when it owns the install. + if (command && isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) { + return `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`; } return `Update ${target.installSpec} using the package manager, wrapper, or source checkout that provides this installation.`; } diff --git a/packages/coding-agent/test/config.test.ts b/packages/coding-agent/test/config.test.ts index ff652cae3..236e26986 100644 --- a/packages/coding-agent/test/config.test.ts +++ b/packages/coding-agent/test/config.test.ts @@ -182,6 +182,33 @@ describe("detectInstallMethod", () => { ); }); + // Issue #7756 + test("does not name pnpm for unmanaged installs under PNPM_HOME", () => { + tempDir = mkdtempSync(join(tmpdir(), "pi-pnpm-home-")); + const packageDir = join( + tempDir, + ".local", + "share", + "pnpm", + "global-nub", + "5", + "node_modules", + "@earendil-works", + "pi-coding-agent", + ); + mkdirSync(packageDir, { recursive: true }); + process.env.PI_PACKAGE_DIR = packageDir; + process.env.PATH = ""; + process.argv[1] = join(packageDir, "dist", "cli.js"); + setExecPath(join(packageDir, "dist", "cli.js")); + + expect(detectInstallMethod()).toBe("pnpm"); + expect(getSelfUpdateCommand("@earendil-works/pi-coding-agent")).toBeUndefined(); + expect(getSelfUpdateUnavailableInstruction("@earendil-works/pi-coding-agent")).toBe( + "Update @earendil-works/pi-coding-agent using the package manager, wrapper, or source checkout that provides this installation.", + ); + }); + test("self-updates npm installs from custom prefixes", () => { const { prefix } = createNpmPrefixInstall();