Skip to content

fix(cli): expose vpr as a package bin#1988

Open
kvnwolf wants to merge 1 commit into
voidzero-dev:mainfrom
kvnwolf:resolve-issue-1827
Open

fix(cli): expose vpr as a package bin#1988
kvnwolf wants to merge 1 commit into
voidzero-dev:mainfrom
kvnwolf:resolve-issue-1827

Conversation

@kvnwolf

@kvnwolf kvnwolf commented Jun 29, 2026

Copy link
Copy Markdown

Summary

vpr (the vp run shorthand) only existed as a global PATH shim created by vp env setup. The vite-plus npm package shipped only vp, oxfmt, and oxlint bins, so a clean install without the global shims (Vercel build image, generic CI runners) failed with vpr: command not found (exit 127).

This is the maintainer-preferred Option 1 from #1827.

  • Add packages/cli/bin/vpr — a Node ESM shim that injects run into argv and delegates to the existing CLI entry. It splices run before a dynamic await import('../dist/bin.js') so the entry reads the spliced argv and dispatches the run subcommand (a static import would be hoisted and run before the splice).
  • Register "vpr": "./bin/vpr" in the package bin map, so a normal install creates node_modules/.bin/vpr. The files array already includes bin/, so no change there.
  • Add a local command-vpr snap fixture mirroring the existing global one (snap-tests-global/command-vpr).

The binding consumes args explicitly and never inspects the invoked binary name, so prepending run is byte-for-byte the vp run path.

Why not vpx

A collaborator asked whether vpx should be shipped the same way. It should not: vpx is a full npx-equivalent whose resolution chain (local .bin → global vp-installed packages → system PATH → vp dlx fallback) lives only in the global CLI crate with no JS entrypoint. A splice trick can't reproduce it; that's a separate change.

Test plan

  • package.json bin.vpr === "./bin/vpr"; files untouched
  • bin/vpr is executable (mode 755, matching bin/vp); splice precedes the dynamic import
  • command-vpr fixture inputs byte-identical to the global fixture
  • CI: pnpm -F vite-plus snap-test-local command-vpr generates snap.txt and confirms vpr -h shows vp run help, vpr hello runs the script, vpr greet --arg1 value1 forwards args, vpr nonexistent exits 1 (could not run locally — vite/ source tree absent, so dist + NAPI binding can't be built)

Closes #1827

`vpr` (the `vp run` shorthand) only existed as a global PATH shim created
by `vp env setup`. The npm package shipped only `vp`, `oxfmt`, and `oxlint`
bins, so clean CI installs without the global shims (Vercel build image,
generic CI runners) failed with `vpr: command not found` (exit 127).

Add a `bin/vpr` Node shim that injects `run` into argv and delegates to the
existing CLI entry, and register it in the package `bin` map so a normal
install creates `node_modules/.bin/vpr`. The shim splices `run` before a
dynamic `await import('../dist/bin.js')` so the entry reads the spliced
argv and dispatches the `run` subcommand — byte-for-byte equivalent to
`vp run`.

`vpx` is intentionally not shipped this way: its npx-equivalent resolution
chain lives only in the global CLI crate with no JS entrypoint.

Closes voidzero-dev#1827
@netlify

netlify Bot commented Jun 29, 2026

Copy link
Copy Markdown

Deploy Preview for viteplus-preview canceled.

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

vpr is a global-only shim and is unusable in CI (Vercel etc.) — expose it as a package bin or document vp run as the CI path

1 participant