fix(update): support native pnpm self-updates - #4203
Conversation
Bind pnpm updates to the global installation that owns OpenCodex, verify package trees and generated shims during recovery, and launch through the verified active package. Add manager-aware integrity preflight, focused tests, and documentation while keeping the npm transactional path intact.
|
✅ Deterministic PR hygiene checks passed. |
⏳ DRAFT
What to do
Review readiness checklist
0/4 boxes ticked. This PR stays in draft until every box above is ticked. Hygiene✅ Deterministic PR hygiene checks passed. |
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Ingwannu
left a comment
There was a problem hiding this comment.
The pnpm installation boundary is worth supporting, but the new shared verifier changes npm's existing staging/recovery contract as well.
In src/update/transactional-install.mjs, verifyInstallTree now delegates to dependencyPackageDir/createRequire.resolve. That resolution can find dependencies in ancestor node_modules outside the candidate package tree. The old npm verifier specifically checked the staged package's own node_modules. A candidate missing its own bundled Bun or sentinel dependency must not pass merely because an ancestor installation supplies one; otherwise staging/boot recovery can call a non-self-contained candidate healthy and discard or replace the known-good copy.
Please preserve the strict npm candidate-tree verifier and add an explicit pnpm-aware ownership/graph check for the separate pnpm layout. Cover a missing/truncated candidate Bun with an unrelated ancestor Bun present, a legitimate pnpm virtual-store layout, and the rollback/boot-restore decision. This is not a request to remove Windows/Bun workarounds or loosen the manifest check.
This is a blocking focused finding, not a complete approval of the rest of this large updater change. Package-manager selection, global-prefix ownership, lifecycle stop/recovery, and exact-head full CI still need their own completed review. The reported isolated pnpm smoke is useful but does not establish preservation of the npm recovery invariant.
리뷰 · 우선순위 61 / 80이 PR은 이슈 #4202를 겨냥합니다. 지금 다만 패치 표면이 매우 큽니다(+2500/−200줄대). src/update/index.ts detectInstall - HEAD는 pnpm을 구분하지 않습니다. PR이 Installer에 pnpm을 넣는다면 경로 판별(전역 store vs npm prefix) 오탐이 없는지, Windows에서 특히 확인이 필요합니다. 메인테이너의 판단이 필요한 지점
너의 추천 이 댓글은 grok-bot이 작성했습니다 |
Global pnpm installations cannot self-update: the updater treats every node_modules installation as npm and forwards npm-only flags (--allow-scripts=bun, --no-audit, --no-fund) to pnpm's global add, which rejects them. The failure lands after the proxy has already been stopped. Carried from #4203 by @oliver-mee, restricted to the update, launcher, service and CLI surface. The install detector now recognises pnpm's isolated, store-link, preserved-symlink and hoisted-group layouts; pnpm gets a native global update path that owns its own group, shims and rollback; and registry integrity is checked before the proxy is stopped rather than after. The shared install-tree verifier is split rather than shared, which answers the blocking review on #4203. verifyInstallTree stays confined to the candidate's own tree: Node's resolver walks the ancestor directory chain, so a global npm candidate at <prefix>/lib/node_modules/@scope/pkg could otherwise satisfy its bundled-Bun requirement from <prefix>/lib/node_modules/bun, which belongs to a different package. Three decisions read that verdict - accepting the stage before the swap, rolling back after it, and reaping the only backup at boot - so a non-self-contained candidate called healthy costs the known-good copy. verifyPnpmInstallTree keeps out-of-package resolution, because pnpm legitimately exposes dependencies through a virtual store, a package-root symlink or a hoisted group, but bounds it: the dependency must be reachable through a root this package instance owns, and an enclosing node_modules counts only when pnpm's own bookkeeping (.pnpm or .modules.yaml) claims it. Ownership is probed lexically rather than filtered from require.resolve output, because the resolver reports the realpath of the resolved file and a dependency reached through pnpm's own symlink comes back as a virtual-store path that no lexical ownership test can recognise. Refs #4203 Closes #4202 Co-authored-by: Oliver Mee <102673257+oliver-mee@users.noreply.github.com>
Summary
The published updater treats every global installation as npm. In a pnpm-managed global installation, the host's pnpm guard receives npm-only flags and the update stops after proxy shutdown. This PR adds a manager-aware path that lets pnpm own the global group, dependency tree, shims, and rollback, while preserving npm's existing transactional path. It also performs registry integrity checks before shutdown and uses the verified active launcher for recovery.
Linked issue
Fixes #4202
Type of change
How to test
bun test tests/update/update-pnpm.test.tspassed with 26 tests and 0 failures.bun run typecheck,bun run privacy:scan,bun run skill:surface:check, changed ESM syntax checks,git diff --check, and the layout suite passed.2.48.0-preview.20260908to2.49.0and confirmed the generatedocxshim reported2.49.0.Checklist
The end-to-end update check used isolated XDG and PNPM_HOME directories. The live installation was not modified.
Model used
GPT-5.6-luna via Codex, with GPT-5.6 Sol used for the independent review and findings pass.
🤖 Generated with Codex (GPT-5.6-luna)
🧑💻 Ideated, directed and reviewed by a human, @oliver-mee
Review readiness checklist
This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:
All CI tests are green on my local testing.
I pushed my PR to the latest dev commit.
I resolved all correct Codex and CodeRabbit findings.
My PR is ready for review.