feat(env): add corepack to the default shims tool list#1808
Conversation
|
✅ Staging deployment successful! Preview: https://viteplus-staging.void.app/ |
✅ Deploy Preview for viteplus-preview canceled.
|
35b7365 to
cf0e351
Compare
Manual verification checklistShim creation and upgrade paths
Resolution order
corepack enable / disable
Old/new version compatibility
Hardening added after the initial list
Modes and overrides
CI
|
|
@cursor review |
|
@codex review |
|
Codex Review: Didn't find any major issues. Keep them coming! ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
vp env setup now creates a corepack shim alongside node/npm/npx. The shim resolves corepack in this order: a vp-managed global install (vp install -g corepack), the copy bundled with the project-resolved Node.js (Node.js <= 24), and finally an automatic managed install on Node.js 25+ where corepack is no longer bundled. The auto-install links only the corepack bin so it never conflicts with vp-managed package managers like an existing vp install -g pnpm. corepack enable/disable without an explicit --install-directory get --install-directory ~/.vite-plus/bin injected so the pnpm/yarn launchers land on PATH. Vite+-owned shims (npm/npx and vp install -g binaries) are restored with a warning if corepack removes or replaces them, and vp remove -g corepack keeps the default shim in place. Closes #1309 Closes #858
- Persist the auto-install bin restriction in package metadata (bins_restricted) so vp update -g cannot re-expose corepack's pnpm/pnpx/yarn/yarnpkg launchers or fail with a binary conflict - Fall back to the Node-bundled corepack when the vp-managed install is unusable (stale metadata) instead of failing every invocation - Snapshot Vite+-owned shims before corepack enable/disable and restore only entries corepack actually removed or replaced, including links created by the npm install -g interception - Guard npm uninstall -g link cleanup and dry-run output with a shared is_protected_shim helper so stale Npm BinConfigs cannot delete default shims; vp env setup now drops such stale BinConfigs - Remove corepack's .ps1 launchers on Windows (PowerShell resolves .ps1 ahead of the trampoline .exe) and detect them in shim checks - Print the auto-install notice to stderr to keep corepack's stdout parseable; check the cheap enable/disable arg match before resolving the bin dir and warn instead of silently skipping the injection - Share the package-binary invocation logic with dispatch_package_binary and reuse locate_tool in vp env which; add corepack.exe and vpr.exe to the install.ps1 stale trampoline cleanup; isolate corepack snap tests from a leftover managed corepack
The corepack shim now makes corepack enable work out of the box, and the created pnpm launcher resolves varlet's pinned packageManager version (pnpm@9.15.9) instead of installing the latest pnpm globally. This also exercises the new corepack enable interception in a real e2e run. The sfw TLS test in ci.yml keeps vp i -g pnpm@9.15.0 on purpose: it exists to force vp's own registry-fetch path through the TLS proxy.
'corepack is not bundled with Node.js 20.18.0' is inaccurate when the bundled copy was removed (e.g. npm uninstall -g corepack) rather than never shipped. Say 'not available for' to cover both Node.js 25+ and damaged Node.js <= 24 installs.
f3abd36 to
4b4fd16
Compare
- Capture the original npm-link target in the restore snapshot and fall back to locate_tool (per-OS layout, validated) instead of hand-building a Unix-only path that broke restored links on Windows and custom npm prefixes; only claim 'restored' after the restore succeeded - Self-heal default shims still holding a corepack launcher from a previous interrupted run by including them in the restore snapshot - Stop aborting the whole restore loop when current_exe fails; only core-shim restores need it - Preserve a previous unrestricted corepack install's shape when the shim reinstalls it, so the stale-bin cleanup cannot silently delete the user's exposed pnpm/yarn launcher shims - Handle the corepack '--' separator: subcommand detection stops at it and --install-directory is injected before it - create_package_shim: extend the conflict guard to vpx/vpr (their dispatch never routes to packages) and keep resolvable absolute-target vp shims from external/dev layouts instead of replacing them with a dangling relative symlink - vp env which corepack falls back to the bundled copy when managed state is unusable, matching dispatch - Clean corepack-written launcher files on plain vp env setup (Windows) - Point the unusable-managed-corepack hint at vp remove -g corepack; print a note when npm install -g corepack is skipped; surface the real error when post-auto-install resolution fails - Avoid double-statting node in package_binary_invocation and loading package metadata twice in the install finalize loop
Cursor Bugbot: the Node.js 25+ first-use auto-install printed install()'s info/success/Bins lines to stdout, polluting captured corepack output like $(corepack --version). install() gains a progress_to_stderr option used by the corepack shim; regular vp install -g output is unchanged.
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit ab6347b. Configure here.
Round-three review findings: - install_one's npm-failure dump now honors progress_to_stderr, closing the last stdout leak in the corepack shim auto-install path - vite_js_runtime version warnings (invalid version, unsatisfied engines constraint) move to stderr so no shim pollutes wrapped stdout - PackageBackup::create tolerates rename ENOENT: concurrent installs of the same package raced between the existence check and the rename, failing with a raw 'No such file or directory' error - command-env-global-install-multiple-fail uses a unique nonexistent package name so it cannot race command-env-install-fail on the shared VP_HOME during parallel snap runs (the race intermittently recorded the ENOENT error instead of npm's E404 output) - Add output::info_stderr/success_stderr to vite_shared and fold install()'s seven positional params into a named InstallOptions struct
Replace the per-call progress_to_stderr threading with a process-wide output mode in vite_shared::output, enabled once at shim-dispatch entry: a shim's stdout belongs to the wrapped tool, so vp's info/note/success/ raw output moves to stderr for every shim flow. This also covers the paths the flag could not reach (nested uninstall in the force path, create_bin_link's Linked message from the restore arm, the npm interception note). Also: ensure_installed returns the node binary path it already builds, collapsing five ensure+locate call pairs; share the is_vp_shim_target predicate between create_package_shim and the corepack restore snapshot; exec with the caller's arg slice when there are no leading args; locate the bundled corepack before ensuring the runtime; reuse help.rs's help-flag detection; and make vp env which corepack print the same unusable-managed-corepack warning as dispatch when falling back. Snap outputs are unchanged (npm-global-*, shim-*, and corepack fixtures regenerated with zero diffs).
…package The create_package_shim guard exempted corepack by bin name only, and the finalize loop wrote BinConfig ownership regardless of whether the shim was skipped, so any package declaring a corepack bin could take BinConfig ownership and win the corepack shim's resolution order. Filter disallowed protected bin names in the finalize loop before conflict detection, shim creation, BinConfig ownership, and metadata recording, via a shared package_may_own_bin predicate that allows the corepack bin only for the corepack package itself. create_package_shim keeps the same predicate as defense in depth. This also stops packages declaring core-shim names (node/npm/npx) from writing stray BinConfigs.
|
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 75c5f98. Configure here.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 75c5f98d4d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Codex review: the Windows npm_link_intact check only tested that <name>.cmd exists, so a link overwritten by corepack enable (which writes its own .cmd launcher) was treated as intact and never restored. Check the .cmd content against vp's fixed three-line wrapper shape instead, and clean corepack's launcher trio before rewriting the link during restore so no .ps1/extensionless file shadows it. Also regenerate command-env-install-conflict: bins a package must not own are now filtered before metadata recording, so 'node' no longer appears in the recorded bin list.
|
@codex review |
|
Codex Review: Didn't find any major issues. Can't wait for the next one! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
vite-plus
@voidzero-dev/vite-plus-core
@voidzero-dev/vite-plus-prompts
@voidzero-dev/vite-plus-test
@voidzero-dev/vite-plus-cli-darwin-arm64
@voidzero-dev/vite-plus-cli-darwin-x64
@voidzero-dev/vite-plus-cli-linux-arm64-gnu
@voidzero-dev/vite-plus-cli-linux-arm64-musl
@voidzero-dev/vite-plus-cli-linux-x64-gnu
@voidzero-dev/vite-plus-cli-linux-x64-musl
@voidzero-dev/vite-plus-cli-win32-arm64-msvc
@voidzero-dev/vite-plus-cli-win32-x64-msvc
@voidzero-dev/vite-plus-darwin-arm64
@voidzero-dev/vite-plus-darwin-x64
@voidzero-dev/vite-plus-linux-arm64-gnu
@voidzero-dev/vite-plus-linux-arm64-musl
@voidzero-dev/vite-plus-linux-x64-gnu
@voidzero-dev/vite-plus-linux-x64-musl
@voidzero-dev/vite-plus-win32-arm64-msvc
@voidzero-dev/vite-plus-win32-x64-msvc
commit: |
Release vite-plus v0.2.0. Vite+ now consumes upstream Vitest directly (no wrapper), raises the minimum supported Node.js version to 22.18.0, and ships corepack and devEngines support. ### Highlights - **`vp test` now runs upstream Vitest directly (breaking)**: Vite+ used to ship `@voidzero-dev/vite-plus-test`, a rebundled copy of Vitest that lagged upstream releases. That package is removed; `vp test` now runs the real upstream `vitest`, which is installed automatically as a dependency of `vite-plus` (you no longer add `vitest` or `@vitest/*` yourself, and `vite` still resolves to `@voidzero-dev/vite-plus-core` via package-manager overrides). Your `import ... from 'vite-plus/test'` code keeps working unchanged and `vp migrate` updates existing projects ([#1588](#1588)), by @Brooooooklyn - **Minimum supported Node.js version raised to `^22.18.0 || >=24.11.0` (breaking)**: Node 20 reached end-of-life and the bundled tsdown already required `^22.18.0`, so the published engines range now matches what `vp pack` can actually deliver; `vp exec` / `vp run` / `vp dlx` reject projects resolving an older Node with the existing incompatibility error ([#1813](#1813)), by @fengmk2 - **Corepack now works under Vite+**: `corepack` is a default `vp env setup` shim, resolved managed-global, then Node-bundled (Node <= 24), then auto-installed (Node 25+, which dropped corepack); `corepack enable` / `disable` land their pnpm/yarn launchers on PATH and Vite+-owned shims are restored if corepack replaces them ([#1808](#1808)), by @fengmk2 - **devEngines support for runtime and package-manager selection**: Vite+ reads `devEngines.runtime` (ranked above `engines.node`) and `devEngines.packageManager`; auto-pin and `vp migrate` write `devEngines.packageManager`, `vp env pin` / `unpin` target `devEngines.runtime`, and `vp env doctor` reports conflicts instead of silently resolving them ([#1760](#1760)), by @fengmk2 ### Features - `vp pm approve-builds`: forward to npm's new `approve-scripts` / `deny-scripts` (npm >= 11.16.0) instead of the previous no-op, matching `pnpm approve-builds` / `bun pm trust`; mixed approve+deny is rejected with actionable guidance and npm's advisory-only caveat is surfaced ([#1733](#1733)), by @fengmk2 - `vp create`: support local monorepo templates declared in `create.templates` in `vite.config.ts`; `vp create vite:generator` scaffolds a Bingo generator and auto-registers it in the picker, replacing the old package.json-keyword inference ([#1777](#1777)), by @fengmk2 - `vp create`: detect direct dependencies whose build scripts the package manager gated (e.g. native builds like `better-sqlite3`) and act on them; prompt to approve each (default off) interactively, point at `vp pm approve-builds` non-interactively, or build them with `--approve-builds` ([#1828](#1828)), by @fengmk2 - `vp config`: add `--no-hooks` and `--no-agent` opt-outs to skip git-hook installation and coding-agent instruction updates ([#1842](#1842)), by @leno23 - `vp list -g`: sort the global package list output so entries appear in a stable order ([#1748](#1748)), by @liangmiQwQ - Upgrade upstream dependencies: rolldown `1.0.3 -> 1.1.1`, tsdown `0.22.1 -> 0.22.3`, oxlint `1.67.0 -> 1.70.0`, oxfmt `0.52.0 -> 0.55.0`, vitest `4.1.8 -> 4.1.9`, and the oxc toolchain `0.133.0 -> 0.136.0` ([#1749](#1749), [#1767](#1767), [#1812](#1812), [#1834](#1834), [#1855](#1855)), by @voidzero-guard[bot] ### Fixes & Enhancements - Security: resolve open Rust Dependabot advisories by bumping transitive `openssl` `0.10.76 -> 0.10.80` (`openssl-sys` `0.9.112 -> 0.9.116`), fixing five high-severity rust-openssl issues (buffer overflows in key derivation, AES key wrap, and digest finalization; an unchecked PSK/cookie trampoline length leaking adjacent memory; and OCSP-responder undefined behavior: [GHSA-pqf5-4pqq-29f5](GHSA-pqf5-4pqq-29f5), [GHSA-8c75-8mhr-p7r9](GHSA-8c75-8mhr-p7r9), [GHSA-ghm9-cr32-g9qj](GHSA-ghm9-cr32-g9qj), [GHSA-hppc-g8h3-xhp3](GHSA-hppc-g8h3-xhp3), [GHSA-xp3w-r5p5-63rr](GHSA-xp3w-r5p5-63rr)), and drop the unmaintained, unsound `libyml` ([GHSA-gfxp-f68g-8x78](GHSA-gfxp-f68g-8x78), high) by removing dead `serde_yml` code ([#1742](#1742)), by @fengmk2 - Security (docs site): update `mermaid` `11.13.0 -> 11.15.0` to fix improper `classDef` sanitization in state diagrams that allowed HTML injection ([CVE-2026-41149](https://nvd.nist.gov/vuln/detail/CVE-2026-41149) / [GHSA-ghcm-xqfw-q4vr](GHSA-ghcm-xqfw-q4vr), medium severity; `<script>` tags are stripped so it does not reach XSS) ([#1745](#1745)), by @renovate[bot] - `vp check --fix` / `vp staged`: create/migrate now wrap inline Vite `plugins: [...]` arrays with `lazyPlugins(...)` so plugin factories aren't eagerly executed (and don't hang on open handles) during lint/format/check config loading ([#1752](#1752)), by @jong-kyung - `vp migrate`: complete pending migration work for projects that already have `vite-plus` installed (scripts, imports, tsconfig types, ESLint/Prettier, legacy hooks, package-manager settings) instead of treating `vite-plus` as migration-complete; fully migrated projects stay idempotent ([#1821](#1821)), by @jong-kyung - `vp create` / `vp migrate`: detect shorthand `fmt,` / `lint,` config keys so a duplicate inline block is no longer injected ([#1843](#1843)), by @fengmk2 - IDE oxlint/oxfmt wrappers: set `VP_COMMAND` so `lazyPlugins()` skips framework plugins during LSP config reads, preventing a stray `.svelte-kit` (and similar) directory at the monorepo root ([#1764](#1764)), by @jong-kyung - `vp lint` / `vp run -r lint` on Windows: keep the absolute `tsgolint` path for workspace lint runs instead of downgrading it to a wrong cwd-relative path ([#1758](#1758)), by @semimikoh - oxlint wrapper: set the `tsgolint` path so type-aware lint resolves it ([#1811](#1811)), by @jong-kyung - `vp install -g`: use a unique backup directory and treat stale-backup cleanup as best-effort so a locked Windows binary no longer fails an otherwise successful reinstall ([#1753](#1753)), by @fengmk2 - `vp install -g`: remove stale managed binary shims when a reinstalled package drops a bin from its `package.json#bin` ([#1765](#1765)), by @liangmiQwQ - `vp create --git`: surface git's actual stdout/stderr when the initial commit fails instead of always blaming `user.name` / `user.email` ([#1819](#1819)), by @fengmk2 - `vp create vite:generator`: reject `--git` / `--no-git`, since adding a generator to an existing monorepo does not initialize git ([#1788](#1788)), by @jong-kyung - Global CLI: harden `find_system_tool` against a self-exec loop (skip the running executable's own bin directory) and fix two `vite_global_cli` tests that could hang ([#1820](#1820)), by @fengmk2 - CLI help: unify alias display ([#1832](#1832)), show supported `run` options ([#1797](#1797)), show `--fail-if-no-match` in `exec` help ([#1798](#1798)), add the `implode` documentation link ([#1796](#1796)), and handle nested-command typo help ([#1803](#1803)), by @jong-kyung ### Docs - Document `vp create` opt-out options ([#1790](#1790)), by @jong-kyung - Document `vp upgrade` options ([#1847](#1847)), by @jong-kyung - Align the config overview with the sidebar ([#1846](#1846)), by @jong-kyung - Sync the documented command lists with the help output ([#1850](#1850)), by @jong-kyung - Clarify lazy plugin side effects ([#1841](#1841)), by @leno23 - Add JongKyung's X profile ([#1844](#1844)) and update Christoph's X profile ([#1845](#1845)) on the team page, by @jong-kyung ### Refactor - Remove the CLI tips system; the shortcuts it printed on `vp install` are already covered by the help system and added unnecessary complexity ([#1799](#1799)), by @cpojer ### Chore - Re-enable Renovate dependency updates with a targeted ignore-list ([#1744](#1744)), by @fengmk2 - Keep generated NAPI bindings during upgrade-deps ([#1759](#1759)), by @fengmk2 - Remove the `vite_glob` dependency from vite-plus ([#1763](#1763)), by @wan9chi - Keep `sync-remote` from churning `pnpm-workspace.yaml` (dedupe `minimumReleaseAgeExclude`, preserve comments) ([#1787](#1787)), by @fengmk2 - Make unix `just test` runnable ([#1755](#1755)), by @situ2001 - CI: reuse `just lint` and `just test` as the single source of truth ([#1809](#1809)), pin `cargo-zigbuild` to a git rev to fix the aarch64-musl link failure ([#1815](#1815)), and keep upgrade-deps green when rolldown bumps oxc ([#1833](#1833)), by @fengmk2 - Update Rust to nightly-2026-06-10 ([#1725](#1725)), typos to v1.47.1 / v1.47.2 ([#1772](#1772), [#1775](#1775)), GitHub Actions ([#1778](#1778), [#1829](#1829)), and npm packages ([#1779](#1779)), by @renovate[bot] - Bump `oxc-project/setup-node` to v1.3.1 ([#1792](#1792)), by @Boshen - Refresh trusted stack stats on the docs homepage ([#1786](#1786), [#1837](#1837)), by @voidzero-guard[bot] ### Bundled Versions | Tool | Version | Source | | --- | --- | --- | | vite | `8.0.16` | [`f94df87`](vitejs/vite@f94df87) | | rolldown | `1.1.1` | [`d7f919c`](rolldown/rolldown@d7f919c) | | tsdown | `0.22.3` | [npm](https://npmx.dev/package/tsdown/v/0.22.3) | | vitest | `4.1.9` | [npm](https://npmx.dev/package/vitest/v/4.1.9) | | oxlint | `1.70.0` | [npm](https://npmx.dev/package/oxlint/v/1.70.0) | | oxlint-tsgolint | `0.23.0` | [npm](https://npmx.dev/package/oxlint-tsgolint/v/0.23.0) | | oxfmt | `0.55.0` | [npm](https://npmx.dev/package/oxfmt/v/0.55.0) | ### Upgrading from 0.1.24 to 0.2.0 This release has two breaking changes. For most projects the upgrade is `vp upgrade`, bump the project's `vite-plus`, then `vp migrate`. #### 1. Update the CLI ```bash vp upgrade ``` #### 2. Node.js 20 is no longer supported The minimum supported Node.js version is now `^22.18.0 || >=24.11.0` (Node 20 reached end-of-life). If you are still on Node 20: - Check your version: `node --version` (or `vp env doctor`) - Move to a supported release: `vp env pin 22.18.0` (or a newer LTS), or update your `.node-version` / `devEngines.runtime` `vp exec` / `vp run` / `vp dlx` now refuse to run against a project that resolves Node < 22.18.0. #### 3. Vitest is now upstream (the wrapper is gone) `@voidzero-dev/vite-plus-test` has been removed; Vite+ consumes upstream `vitest` directly. Bump `vite-plus` first, then migrate: ```bash vp update vite-plus --latest # project's vite-plus -> 0.2.0 (ignores the old range, updates the lockfile); monorepo: add -r vp migrate # local vite-plus is now 0.2.0, so the new migration runs ``` `vp update --latest` re-resolves `vite-plus` to the newest release regardless of the old semver range, so the lockfile cannot pin you back to 0.1.24. The project's local `vite-plus` is then 0.2.0, and since the global `vp` delegates `migrate` to the project's local install, `vp migrate` runs the new migration. - Your `import { vi, ... } from 'vite-plus/test'` code is unchanged. `vp migrate` rewrites any leftover `vitest` / `@vitest/*` imports and normalizes stale `vitest: npm:@voidzero-dev/vite-plus-test@*` aliases. - You no longer add `vitest` or `@vitest/*` yourself; they arrive transitively through `vite-plus`. ### New Contributors Welcome to our new contributor @situ2001! 🎉 **Full Changelog**: v0.1.24...v0.2.0 --- Merging this PR will trigger the release workflow. --------- Co-authored-by: voidzero-guard[bot] <278573678+voidzero-guard[bot]@users.noreply.github.com> Co-authored-by: MK <fengmk2@gmail.com>
Closes #1309
Closes #858
Without a system Node.js, corepack is unreachable under Vite+ even though Node.js <= 24 bundles it, and Node.js 25+ removed it entirely. This adds
corepackto the default shims created byvp env setup.How it works
vp install -g corepack) > Node-bundled corepack (Node.js <= 24) > auto-install as a managed global package (Node.js 25+). The auto-install links only thecorepackbin, so it never conflicts with an existingvp install -g pnpm(the corepack package also declares pnpm/yarn launcher bins).corepack enable/disablewithout an explicit--install-directoryget--install-directory ~/.vite-plus/bininjected, so the created pnpm/yarn launchers land on PATH and still resolve the project Node.js version. Vite+-owned shims (npm/npx,vp install -gbinaries) are restored with a warning if corepack removes or replaces them.vp remove -g corepackkeeps the default shim;vp env doctorandvp env which corepackcover the new shim.RFC updates in
rfcs/env-command.md(new Corepack Shim section),rfcs/trampoline-exe-for-shims.md, andrfcs/upgrade-command.mddescribe the design.Testing
shim-corepack-bundled(real bundled corepack via Node 20.18.0) andshim-corepack-enable-install-directory(hermetic test for the install-directory injection and npm shim restore).corepackbin linked), managed-first precedence,vp remove -g corepackfallback, and a realcorepack enable/disablecycle (yarn --versionworks through the launcher, vp-managed pnpm restored).Note:
just lintcurrently fails on main due to a pre-existingclippy::unused_async_trait_implwarning injs_executor.rsfrom the nightly-2026-06-10 bump, unrelated to this change.Note
High Risk
Changes core shim dispatch, global bin ownership, and auto-install side effects on first
corepackuse; mistakes could break npm/corepack on PATH or corrupt bin layout on Windows.Overview
Adds
corepackas a default env shim (setup, install scripts, docs, E2E varlet matrix usescorepack enableinstead ofvp i -g pnpm).New dedicated corepack dispatch resolves in order:
vp install -g corepack→ Node-bundled corepack → auto-install as a managed global (Node 25+), with optionalonly_binsso auto-install links onlycorepack(not pnpm/yarn launchers).bins_restrictedmetadata preserves that restriction acrossvp update -g.corepack enable/disabledefault--install-directorytoVP_HOME/bin, then restore Vite+-owned shims (default npm/npx,vp install -g, npm links) if corepack clobbers them; Windows setup also strips conflicting.ps1/legacy launchers.Global install/refactor:
InstallOptionsreplaces positional args;is_protected_shim/package_may_own_binguard default shims (corepack only ownable by thecorepackpackage); protected shims survive uninstall/dry-run;ensure_installedreturns the node path.Shim UX:
route_user_output_to_stderrduring shim/vp env execdispatch so wrapped tools keep parseable stdout; version warnings and npm install log routing follow the same rule.Tests/docs: snap tests for bundled corepack and enable install-directory; RFCs updated for corepack design.
Reviewed by Cursor Bugbot for commit 75c5f98. Configure here.