Skip to content

feat(env): add corepack to the default shims tool list#1808

Merged
fengmk2 merged 14 commits into
mainfrom
feat/corepack-default-shim
Jun 13, 2026
Merged

feat(env): add corepack to the default shims tool list#1808
fengmk2 merged 14 commits into
mainfrom
feat/corepack-default-shim

Conversation

@fengmk2

@fengmk2 fengmk2 commented Jun 10, 2026

Copy link
Copy Markdown
Member

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 corepack to the default shims created by vp env setup.

How it works

  • Resolution order: vp-managed global install (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 the corepack bin, so it never conflicts with an existing vp install -g pnpm (the corepack package also declares pnpm/yarn launcher bins).
  • corepack enable/disable without an explicit --install-directory get --install-directory ~/.vite-plus/bin injected, so the created pnpm/yarn launchers land on PATH and still resolve the project Node.js version. Vite+-owned shims (npm/npx, vp install -g binaries) are restored with a warning if corepack removes or replaces them.
  • vp remove -g corepack keeps the default shim; vp env doctor and vp env which corepack cover the new shim.

RFC updates in rfcs/env-command.md (new Corepack Shim section), rfcs/trampoline-exe-for-shims.md, and rfcs/upgrade-command.md describe the design.

Testing

  • New snap tests: shim-corepack-bundled (real bundled corepack via Node 20.18.0) and shim-corepack-enable-install-directory (hermetic test for the install-directory injection and npm shim restore).
  • Verified manually: bundled dispatch, auto-install on Node 25 (corepack 0.34.7, only corepack bin linked), managed-first precedence, vp remove -g corepack fallback, and a real corepack enable/disable cycle (yarn --version works through the launcher, vp-managed pnpm restored).

Note: just lint currently fails on main due to a pre-existing clippy::unused_async_trait_impl warning in js_executor.rs from 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 corepack use; mistakes could break npm/corepack on PATH or corrupt bin layout on Windows.

Overview
Adds corepack as a default env shim (setup, install scripts, docs, E2E varlet matrix uses corepack enable instead of vp 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 optional only_bins so auto-install links only corepack (not pnpm/yarn launchers). bins_restricted metadata preserves that restriction across vp update -g.

corepack enable/disable default --install-directory to VP_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: InstallOptions replaces positional args; is_protected_shim / package_may_own_bin guard default shims (corepack only ownable by the corepack package); protected shims survive uninstall/dry-run; ensure_installed returns the node path.

Shim UX: route_user_output_to_stderr during shim/vp env exec dispatch 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.

@fengmk2 fengmk2 self-assigned this Jun 10, 2026
@github-actions

github-actions Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

✅ Staging deployment successful!

Preview: https://viteplus-staging.void.app/
Commit: d3e07e7

@netlify

netlify Bot commented Jun 10, 2026

Copy link
Copy Markdown

Deploy Preview for viteplus-preview canceled.

Name Link
🔨 Latest commit d3e07e7
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/6a2bceb0bc26e200085bbde0

@fengmk2 fengmk2 force-pushed the feat/corepack-default-shim branch from 35b7365 to cf0e351 Compare June 11, 2026 01:03
@fengmk2

fengmk2 commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

Manual verification checklist

Shim creation and upgrade paths

  • Fresh install via install.sh: ~/.vite-plus/bin/corepack symlink exists and corepack --version works without a system Node.js
  • Upgrade from a pre-corepack vp (vp upgrade): corepack shim is created by the automatic env setup --refresh
  • Plain vp env setup (no --refresh) on an existing install: corepack shim is created while node/npm/npx are reported as skipped
  • vp env doctor: corepack listed under Shims and under PATH checks
  • Windows: vp env setup creates corepack.exe trampoline; corepack --version works from PowerShell, cmd.exe, and Git Bash

Resolution order

  • Node <= 24 project (e.g. .node-version 20.18.0): corepack --version runs the bundled corepack (0.29.3); vp env which corepack shows the js_runtime path
  • vp install -g corepack: managed copy wins afterwards on every Node version; vp env which corepack shows the package path
  • Node 25+ project, no managed corepack: first corepack --version auto-installs (notice on stderr, Bins: corepack only); second invocation runs without reinstalling
  • Shim stdout stays parseable: on Node 25+ the very first v=$(corepack --version) captures only the version; all vp progress/notices (including the one-time auto-install) go to stderr (fixed by the process-wide shim output routing)
  • Corrupt ~/.vite-plus/bins/corepack.json (e.g. truncate it): corepack warns about unusable managed state and falls back to the bundled copy instead of exiting 1
  • Node 25+ offline with no managed corepack: clear error with the vp install -g corepack hint

corepack enable / disable

  • corepack enable: pnpm/yarn launchers land in ~/.vite-plus/bin (injected --install-directory); yarn --version works and resolves the project Node.js
  • corepack enable --install-directory /custom/dir: explicit directory respected, nothing written to vp bin
  • corepack disable: launchers removed again
  • With vp install -g pnpm present: corepack enable restores vp-managed pnpm/pnpx shims with a warning; corepack disable preserves them. On Unix this may restore with a warning, while on Windows the .exe trampolines remain intact without a warning
  • With a pnpm link created via npm install -g pnpm interception: corepack disable restores the link with a warning
  • After deliberately deleting ~/.vite-plus/bin/npm: corepack enable does NOT resurrect it and prints no restore warning
  • corepack enable npm: npm shim is restored with a warning; npm --version still resolves per project
  • corepack enable --help: prints help, touches no files
  • Windows PowerShell: after corepack enable npm + restore, npm resolves the vp trampoline (no leftover npm.ps1/npm.cmd/extensionless wrapper)

Old/new version compatibility

  • Existing vp install -g corepack (the old workaround) survives the upgrade: still wins over bundled, vp env setup --refresh keeps its BinConfig
  • Pre-PR npm install -g corepack user: after upgrade + vp env setup, the stale Npm BinConfig is dropped and a later npm uninstall -g corepack does NOT delete the default shim
  • vp remove -g corepack: package removed, default shim kept, resolution falls back to bundled; --dry-run marks the shim as (kept: default shim)
  • Auto-installed corepack then vp update -g (when a newer corepack exists): still links only the corepack bin, no pnpm/yarn shims appear, no BinaryConflict with a vp-managed pnpm
  • Explicit vp install -g corepack after an auto-install: resets the restriction and exposes the package's launcher bins (conflict semantics with --force unchanged)
  • Old metadata files without the binsRestricted field load fine (vp list -g works after upgrade)
  • Windows downgrade via old install.ps1: stale corepack.exe/vpr.exe trampolines are removed
  • vp upgrade --rollback to a pre-corepack version: corepack shim remains in bin but old vp reports "Binary 'corepack' not found" (known behavior, confirm acceptable)

Hardening added after the initial list

  • A package other than corepack declaring a corepack bin (e.g. a test package with "bin": {"corepack": ...}) does NOT take ownership: warn + skipped, corepack still resolves bundled/managed, no BinConfig written
  • corepack enable -- pnpm style invocations: --install-directory is injected before the -- separator; corepack -- enable is passed through untouched
  • With corepack package state broken (corrupt bins/corepack.json or deleted package dir): both the shim AND vp env which corepack print the same "unusable vp-managed corepack" warning and fall back to the bundled copy
  • vp update -g on an auto-installed (restricted) corepack keeps linking only the corepack bin; explicit vp install -g corepack resets to the full bin list (BinaryConflict against a vp-managed pnpm is expected then)
  • Windows: with an npm-interception-linked yarn, corepack enable overwrites the .cmd launcher and the restore detects it via content check, rewriting vp's wrapper and removing corepack's .ps1/extensionless files

Modes and overrides

  • vp env off (system-first) with a system corepack installed: shim prefers the system corepack; vp env on restores managed behavior
  • VP_BYPASS=1 corepack --version bypasses the shim
  • vp env use 20 vs vp env use 25 in the same shell: corepack switches between bundled and managed/auto-install resolution
  • vp env exec corepack --version works (shim mode without --node)

CI

  • snap tests green: shim-corepack-bundled, shim-corepack-enable-install-directory, command-env-which, command-env-setup-external-vp, cli-helper-message

@fengmk2

fengmk2 commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

@cursor review

@fengmk2

fengmk2 commented Jun 11, 2026

Copy link
Copy Markdown
Member Author

@codex review

Comment thread crates/vite_global_cli/src/shim/corepack.rs
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

ℹ️ 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".

fengmk2 added 5 commits June 11, 2026 23:42
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.
@fengmk2 fengmk2 force-pushed the feat/corepack-default-shim branch from f3abd36 to 4b4fd16 Compare June 11, 2026 15:49
fengmk2 added 4 commits June 12, 2026 08:39
- 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.
@fengmk2

fengmk2 commented Jun 12, 2026

Copy link
Copy Markdown
Member Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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.

@fengmk2 fengmk2 marked this pull request as ready for review June 12, 2026 06:07
@fengmk2 fengmk2 requested a review from cpojer June 12, 2026 06:07
fengmk2 added 4 commits June 12, 2026 16:29
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.
@fengmk2

fengmk2 commented Jun 12, 2026

Copy link
Copy Markdown
Member Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ 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.

@fengmk2

fengmk2 commented Jun 12, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread crates/vite_global_cli/src/shim/corepack.rs Outdated
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.
@fengmk2

fengmk2 commented Jun 12, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: d3e07e7a35

ℹ️ 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".

@pkg-pr-new

pkg-pr-new Bot commented Jun 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

vite-plus

npm i https://pkg.pr.new/voidzero-dev/vite-plus@1808

@voidzero-dev/vite-plus-core

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-core@1808

@voidzero-dev/vite-plus-prompts

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-prompts@1808

@voidzero-dev/vite-plus-test

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-test@1808

@voidzero-dev/vite-plus-cli-darwin-arm64

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-darwin-arm64@1808

@voidzero-dev/vite-plus-cli-darwin-x64

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-darwin-x64@1808

@voidzero-dev/vite-plus-cli-linux-arm64-gnu

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-linux-arm64-gnu@1808

@voidzero-dev/vite-plus-cli-linux-arm64-musl

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-linux-arm64-musl@1808

@voidzero-dev/vite-plus-cli-linux-x64-gnu

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-linux-x64-gnu@1808

@voidzero-dev/vite-plus-cli-linux-x64-musl

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-linux-x64-musl@1808

@voidzero-dev/vite-plus-cli-win32-arm64-msvc

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-win32-arm64-msvc@1808

@voidzero-dev/vite-plus-cli-win32-x64-msvc

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-cli-win32-x64-msvc@1808

@voidzero-dev/vite-plus-darwin-arm64

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-darwin-arm64@1808

@voidzero-dev/vite-plus-darwin-x64

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-darwin-x64@1808

@voidzero-dev/vite-plus-linux-arm64-gnu

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-linux-arm64-gnu@1808

@voidzero-dev/vite-plus-linux-arm64-musl

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-linux-arm64-musl@1808

@voidzero-dev/vite-plus-linux-x64-gnu

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-linux-x64-gnu@1808

@voidzero-dev/vite-plus-linux-x64-musl

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-linux-x64-musl@1808

@voidzero-dev/vite-plus-win32-arm64-msvc

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-win32-arm64-msvc@1808

@voidzero-dev/vite-plus-win32-x64-msvc

npm i https://pkg.pr.new/voidzero-dev/vite-plus/@voidzero-dev/vite-plus-win32-x64-msvc@1808

commit: d3e07e7

@fengmk2 fengmk2 merged commit b48e0a0 into main Jun 13, 2026
174 checks passed
@fengmk2 fengmk2 deleted the feat/corepack-default-shim branch June 13, 2026 06:01
@fengmk2 fengmk2 mentioned this pull request Jun 17, 2026
fengmk2 added a commit that referenced this pull request Jun 17, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Vite+ and corepack-like functionality Shim for pnpm & yarn

2 participants