From 0636ad13b8b99e0ec549b7eb5fa3b955f1164f74 Mon Sep 17 00:00:00 2001 From: Liang Mi Date: Mon, 29 Jun 2026 16:58:43 +0800 Subject: [PATCH] docs: update RFC env var prefixes --- .claude/skills/add-ecosystem-ci/SKILL.md | 4 +- crates/vite_shared/src/home.rs | 2 +- rfcs/cli-output-polish.md | 14 +-- rfcs/dev-engines.md | 6 +- rfcs/env-command.md | 132 +++++++++++------------ rfcs/exec-command.md | 8 +- rfcs/global-cli-rust-binary.md | 24 ++--- rfcs/implode-command.md | 2 +- rfcs/js-runtime.md | 4 +- rfcs/merge-global-and-local-cli.md | 2 +- rfcs/trampoline-exe-for-shims.md | 34 +++--- rfcs/vpx-command.md | 2 +- 12 files changed, 117 insertions(+), 117 deletions(-) diff --git a/.claude/skills/add-ecosystem-ci/SKILL.md b/.claude/skills/add-ecosystem-ci/SKILL.md index 7d47a706f0..e3252a7659 100644 --- a/.claude/skills/add-ecosystem-ci/SKILL.md +++ b/.claude/skills/add-ecosystem-ci/SKILL.md @@ -27,7 +27,7 @@ Fetch the repository's root to check if the main package.json is in a subdirecto ### 2.2 Check if Project Already Uses Vite-Plus -Check the project's root `package.json` for `vite-plus` in `dependencies` or `devDependencies`. If the project already uses vite-plus, set `forceFreshMigration: true` in `repo.json`. This tells `patch-project.ts` to set `VITE_PLUS_FORCE_MIGRATE=1` so `vp migrate` forces full dependency rewriting instead of skipping with "already using Vite+". +Check the project's root `package.json` for `vite-plus` in `dependencies` or `devDependencies`. If the project already uses vite-plus, set `forceFreshMigration: true` in `repo.json`. This tells `patch-project.ts` to set `VP_FORCE_MIGRATE=1` so `vp migrate` forces full dependency rewriting instead of skipping with "already using Vite+". ### 2.3 Auto-detect Commands from GitHub Workflows @@ -145,5 +145,5 @@ vp run build - The `directory` field is optional - only add it if the package.json is not in the project root - If `directory` is specified in repo.json, it must also be specified in the workflow matrix - `patch-project.ts` automatically handles running `vp migrate` in the correct directory -- `forceFreshMigration` is required for projects that already have `vite-plus` in their package.json — it sets `VITE_PLUS_FORCE_MIGRATE=1` so `vp migrate` forces full dependency rewriting instead of skipping +- `forceFreshMigration` is required for projects that already have `vite-plus` in their package.json — it sets `VP_FORCE_MIGRATE=1` so `vp migrate` forces full dependency rewriting instead of skipping - OS exclusions are added to the existing `exclude` section in the workflow matrix diff --git a/crates/vite_shared/src/home.rs b/crates/vite_shared/src/home.rs index dd8cc9e800..8edbc0e34b 100644 --- a/crates/vite_shared/src/home.rs +++ b/crates/vite_shared/src/home.rs @@ -107,7 +107,7 @@ mod tests { std::env::set_var("PATH", &new_path); } - // Clear any existing VITE_PLUS_HOME env var by using a test config without it + // Clear any existing VP_HOME env var by using a test config without it EnvConfig::test_scope(EnvConfig::for_test(), || { // Test: get_vp_home should return /tmp/xxx/.vite-plus let home = get_vp_home().unwrap(); diff --git a/rfcs/cli-output-polish.md b/rfcs/cli-output-polish.md index 97427add66..b9a6ecb75b 100644 --- a/rfcs/cli-output-polish.md +++ b/rfcs/cli-output-polish.md @@ -143,12 +143,12 @@ info( Where `VITE_PLUS_VERSION` is the vite-plus package version, injected via: - A new constant in `vite/packages/vite/src/node/constants.ts`, or -- Read from an environment variable set by the Rust CLI before spawning vite (e.g., `VITE_PLUS_VERSION`) +- Read from an environment variable set by the Rust CLI before spawning vite (e.g., `VP_VERSION`) -**Recommended approach:** Environment variable injection. The Rust NAPI binding in `packages/cli/binding/src/cli.rs` already merges environment variables when spawning sub-tools via `merge_resolved_envs()`. We add `VITE_PLUS_VERSION` to the env map, and read it in vite: +**Recommended approach:** Environment variable injection. The Rust NAPI binding in `packages/cli/binding/src/cli.rs` already merges environment variables when spawning sub-tools via `merge_resolved_envs()`. We add `VP_VERSION` to the env map, and read it in vite: ```javascript -const VITE_PLUS_VERSION = process.env.VITE_PLUS_VERSION || VERSION; +const VITE_PLUS_VERSION = process.env.VP_VERSION || VERSION; ``` This is clean: the vite source change is minimal (reads an env var with fallback), and the version injection happens in the Rust layer that already owns this responsibility. @@ -307,11 +307,11 @@ Historical context (no longer applies): Vitest was bundled (not cloned source) v After `bundleVitest()` copies vitest files to `dist/`, a `brandVitest()` step patches the cac chunk (`dist/chunks/cac.*.js`) with string replacements: 1. `cac("vitest")` → `cac("vp test")` — CLI name shown in banner and help output -2. `var version = ""` → `var version = process.env.VITE_PLUS_VERSION || ""` — runtime version injection via env var +2. `var version = ""` → `var version = process.env.VP_VERSION || ""` — runtime version injection via env var 3. `/^vitest\/\d+\.\d+\.\d+$/` regex → `/^vp test\/[\d.]+$/` — so the help callback can still find the banner line 4. `$ vitest --help --expand-help` → `$ vp test --help --expand-help` — hardcoded help text -The Rust NAPI binding injects `VITE_PLUS_VERSION` env var (same mechanism used for vite build/dev/preview commands), so `vp test -h` shows `vp test/`. +The Rust NAPI binding injects `VP_VERSION` env var (same mechanism used for vite build/dev/preview commands), so `vp test -h` shows `vp test/`. #### 3.3 Remaining `vite` → `vp` branding in CLI output @@ -379,7 +379,7 @@ Migrate JS-side code (`migration/bin.ts`, `create/bin.ts`) to use these shared f ### D3: Inject version via environment variable -**Decision:** The Rust CLI sets `VITE_PLUS_VERSION` env var before spawning vite. The modified vite source reads it with a fallback. +**Decision:** The Rust CLI sets `VP_VERSION` env var before spawning vite. The modified vite source reads it with a fallback. **Rationale:** This avoids hardcoding the version in vite source (which would require updating on every release). The Rust CLI already manages environment variables for sub-tool spawning via `merge_resolved_envs()`. The env var approach is the minimal-touch change to vite. @@ -429,7 +429,7 @@ These are internal identifiers, API references, or project name references: ### Phase 1: vite Rebranding -1. Add `VITE_PLUS_VERSION` env var injection in `packages/cli/binding/src/cli.rs` for vite commands (build, dev, preview) +1. Add `VP_VERSION` env var injection in `packages/cli/binding/src/cli.rs` for vite commands (build, dev, preview) 2. Modify `vite/packages/vite/src/node/cli.ts` — read env var, change banner text 3. Modify `vite/packages/vite/src/node/build.ts` — change build banner text 4. Modify `vite/packages/vite/src/node/logger.ts` — change default prefix diff --git a/rfcs/dev-engines.md b/rfcs/dev-engines.md index abd6e37ea5..e4a1ff2c2d 100644 --- a/rfcs/dev-engines.md +++ b/rfcs/dev-engines.md @@ -53,7 +53,7 @@ Spec semantics that matter for this RFC: **Node.js resolution chain** (`crates/vite_global_cli/src/commands/env/config.rs`, `crates/vite_js_runtime/src/runtime.rs`): -1. `VITE_PLUS_NODE_VERSION` env var (session) +1. `VP_NODE_VERSION` env var (session) 2. `~/.vite-plus/.session-node-version` (session) 3. `.node-version` (walk up) 4. `package.json#engines.node` (walk up) @@ -127,7 +127,7 @@ Parsing rules: Proposed chain (change marked): -1. `VITE_PLUS_NODE_VERSION` env var (session) +1. `VP_NODE_VERSION` env var (session) 2. `.session-node-version` (session) 3. `.node-version` (walk up) 4. **`package.json#devEngines.runtime[name="node"]` (walk up)** (moved above `engines.node`) @@ -373,7 +373,7 @@ A small shared Rust helper (in `vite_shared`) will own "edit one field in packag - Managing non-Node runtimes (`deno`, `bun` as a runtime) via `devEngines.runtime`. - Validating `devEngines.os` / `cpu` / `libc`. - Acting as a general enforcement layer for arbitrary package manager names beyond pnpm / yarn / npm / bun. -- Changing session-override behavior (`vp env use`, `VITE_PLUS_NODE_VERSION`). +- Changing session-override behavior (`vp env use`, `VP_NODE_VERSION`). ## Deferred / Future Work diff --git a/rfcs/env-command.md b/rfcs/env-command.md index 5377c226bf..cf751cdf0f 100644 --- a/rfcs/env-command.md +++ b/rfcs/env-command.md @@ -22,9 +22,9 @@ This RFC proposes adding a `vp env` command that provides system-wide, IDE-safe A shim-based approach where: -- `VITE_PLUS_HOME/bin/` directory is added to PATH (system-level for IDE reliability) +- `VP_HOME/bin/` directory is added to PATH (system-level for IDE reliability) - Shims (`node`, `npm`, `npx`, `corepack`) are symlinks to the `vp` binary (Unix) or trampoline `.exe` files (Windows) -- The `vp` CLI itself is also in `VITE_PLUS_HOME/bin/`, so users only need one PATH entry +- The `vp` CLI itself is also in `VP_HOME/bin/`, so users only need one PATH entry - The binary detects invocation via `argv[0]` and dispatches accordingly - Version resolution and installation leverage existing `vite_js_runtime` infrastructure @@ -124,10 +124,10 @@ vp env use --silent-if-unchanged # Suppress output if version already active **How it works:** 1. `~/.vite-plus/env` includes a `vp()` shell function that intercepts `vp env use` calls -2. The wrapper sets `VITE_PLUS_ENV_USE_EVAL_ENABLE=1` before calling `command vp env use ...` +2. The wrapper sets `VP_ENV_USE_EVAL_ENABLE=1` before calling `command vp env use ...` 3. When the env var is present (wrapper active), `vp env use` outputs shell commands to stdout for eval 4. When the env var is absent in CI, `vp env use` writes a session file (`~/.vite-plus/.session-node-version`) instead -5. The shim dispatch checks `VITE_PLUS_NODE_VERSION` env var first, then the session file, in the resolution chain +5. The shim dispatch checks `VP_NODE_VERSION` env var first, then the session file, in the resolution chain On Windows interactive shells, `vp env use` requires the PowerShell setup script (`~/.vite-plus/env.ps1`, written by `vp env setup`) to be dot-sourced in the current shell so the selected version stays session-scoped: @@ -144,7 +144,7 @@ Invoke-Item $PROFILE **Automatic session file (for CI):** -When `vp env use` detects a CI environment and the shell eval wrapper is not active (i.e., `VITE_PLUS_ENV_USE_EVAL_ENABLE` is not set), it automatically writes the resolved version to `~/.vite-plus/.session-node-version`. Shims read this file directly from disk, so CI jobs can keep using `vp env use` without shell setup. The env var still takes priority when set, so the shell wrapper experience is unchanged. +When `vp env use` detects a CI environment and the shell eval wrapper is not active (i.e., `VP_ENV_USE_EVAL_ENABLE` is not set), it automatically writes the resolved version to `~/.vite-plus/.session-node-version`. Shims read this file directly from disk, so CI jobs can keep using `vp env use` without shell setup. The env var still takes priority when set, so the shell wrapper experience is unchanged. ```bash # GitHub Actions example (no shell wrapper, session file written automatically) @@ -155,12 +155,12 @@ When `vp env use` detects a CI environment and the shell eval wrapper is not act **Shell-specific output:** -| Shell | Set | Unset | -| ---------------- | ----------------------------------------- | -------------------------------------------- | -| POSIX (bash/zsh) | `export VITE_PLUS_NODE_VERSION=20.18.1` | `unset VITE_PLUS_NODE_VERSION` | -| Fish | `set -gx VITE_PLUS_NODE_VERSION 20.18.1` | `set -e VITE_PLUS_NODE_VERSION` | -| PowerShell | `$env:VITE_PLUS_NODE_VERSION = "20.18.1"` | `Remove-Item Env:VITE_PLUS_NODE_VERSION ...` | -| cmd.exe | `set VITE_PLUS_NODE_VERSION=20.18.1` | `set VITE_PLUS_NODE_VERSION=` | +| Shell | Set | Unset | +| ---------------- | ---------------------------------- | ------------------------------------- | +| POSIX (bash/zsh) | `export VP_NODE_VERSION=20.18.1` | `unset VP_NODE_VERSION` | +| Fish | `set -gx VP_NODE_VERSION 20.18.1` | `set -e VP_NODE_VERSION` | +| PowerShell | `$env:VP_NODE_VERSION = "20.18.1"` | `Remove-Item Env:VP_NODE_VERSION ...` | +| cmd.exe | `set VP_NODE_VERSION=20.18.1` | `set VP_NODE_VERSION=` | **Shell function wrappers** are included in env files created by `vp env setup`: @@ -287,7 +287,7 @@ argv[0] = "corepack" → Shim mode: resolve version, exec corepack (managed fal │ ▼ │ │ ┌──────────────────────────────┐ ┌─────────────────────────────┐ │ │ │ Version Resolution │────▶│ Priority Order: │ │ -│ │ (walk up directory tree) │ │ 0. VITE_PLUS_NODE_VERSION │ │ +│ │ (walk up directory tree) │ │ 0. VP_NODE_VERSION │ │ │ └──────────────┬───────────────┘ │ 1. .session-node-version │ │ │ │ │ 2. .node-version │ │ │ │ │ 3. package.json#devEngines │ │ @@ -312,7 +312,7 @@ argv[0] = "corepack" → Shim mode: resolve version, exec corepack (managed fal │ DIRECTORY STRUCTURE │ ├─────────────────────────────────────────────────────────────────────────────┤ │ │ -│ ~/.vite-plus/ (VITE_PLUS_HOME) │ +│ ~/.vite-plus/ (VP_HOME) │ │ ├── bin/ │ │ │ ├── vp ────────────────────── Symlink to ../current/bin/vp │ │ │ ├── node ──────────────────────┐ │ @@ -356,10 +356,10 @@ argv[0] = "corepack" → Shim mode: resolve version, exec corepack (managed fal └─────────────────────────────────────────────────────────────────────────────┘ ``` -### VITE_PLUS_HOME Directory Layout +### VP_HOME Directory Layout ``` -VITE_PLUS_HOME/ # Default: ~/.vite-plus +VP_HOME/ # Default: ~/.vite-plus ├── bin/ │ ├── vp -> ../current/bin/vp # Symlink to current vp binary (Unix) │ ├── node -> ../current/bin/vp # Symlink to vp binary (Unix) @@ -538,7 +538,7 @@ New LTS codenames are added dynamically based on the Node.js release schedule. v When resolving which Node.js version to use, vite-plus checks the following sources in order: -0. **`VITE_PLUS_NODE_VERSION` env var** (session override, highest priority) +0. **`VP_NODE_VERSION` env var** (session override, highest priority) - Set by `vp env use` via shell wrapper eval - Overrides all file-based resolution @@ -607,7 +607,7 @@ lts/iron | actions/setup-node | ✅ | ✅ | ✅ | ✅ | | asdf | ✅ | ❌ | ❌ | ❌ | -**Note**: Node.js binaries are stored in VITE_PLUS_HOME: +**Note**: Node.js binaries are stored in VP_HOME: - Linux/macOS: `~/.vite-plus/js_runtime/node/{version}/` - Windows: `%USERPROFILE%\.vite-plus\js_runtime\node\{version}\` @@ -645,42 +645,42 @@ crates/vite_global_cli/ ### Shim Dispatch Flow -1. Check `VITE_PLUS_BYPASS` environment variable → bypass to system tool (filters all listed directories from PATH) -2. Check `VITE_PLUS_TOOL_RECURSION` → if set, use passthrough mode +1. Check `VP_BYPASS` environment variable → bypass to system tool (filters all listed directories from PATH) +2. Check `VP_TOOL_RECURSION` → if set, use passthrough mode 3. Check shim mode from config: - - If `system_first`: try system tool first, fallback to managed; appends own bin dir to `VITE_PLUS_BYPASS` before exec to prevent loops with multiple installations + - If `system_first`: try system tool first, fallback to managed; appends own bin dir to `VP_BYPASS` before exec to prevent loops with multiple installations - If `managed`: use vite-plus managed Node.js 4. Resolve version (with mtime-based caching) 5. Ensure Node.js is installed (download if needed) 6. Locate tool binary in the installed Node.js 7. Prepend real node bin dir to PATH for child processes -8. Set `VITE_PLUS_TOOL_RECURSION=1` to prevent recursion +8. Set `VP_TOOL_RECURSION=1` to prevent recursion 9. Execute the tool (Unix: `execve`, Windows: spawn) ### Shim Recursion Prevention To prevent infinite loops when shims invoke other shims, vite-plus uses environment variable markers: -**Environment Variable**: `VITE_PLUS_TOOL_RECURSION` +**Environment Variable**: `VP_TOOL_RECURSION` **Mechanism:** -1. When a shim executes the real binary, it sets `VITE_PLUS_TOOL_RECURSION=1` +1. When a shim executes the real binary, it sets `VP_TOOL_RECURSION=1` 2. Subsequent shim invocations check this variable 3. If set, shims use **passthrough mode** (skip version resolution, use current PATH) 4. `vp env exec` explicitly **removes** this variable to force re-evaluation -**Environment Variable**: `VITE_PLUS_BYPASS` (PATH-style list) +**Environment Variable**: `VP_BYPASS` (PATH-style list) **SystemFirst Loop Prevention:** When multiple vite-plus installations exist in PATH and `system_first` mode is active, each installation could find the other's shim as the "system tool", causing an infinite exec loop. To prevent this: -1. In `system_first` mode, before exec'ing the found system tool, the current installation appends its own bin directory to `VITE_PLUS_BYPASS` -2. The next installation sees `VITE_PLUS_BYPASS` is set and enters bypass mode via `find_system_tool()` -3. `find_system_tool()` filters all directories listed in `VITE_PLUS_BYPASS` (plus its own bin dir) from PATH +1. In `system_first` mode, before exec'ing the found system tool, the current installation appends its own bin directory to `VP_BYPASS` +2. The next installation sees `VP_BYPASS` is set and enters bypass mode via `find_system_tool()` +3. `find_system_tool()` filters all directories listed in `VP_BYPASS` (plus its own bin dir) from PATH 4. This ensures the search skips all known vite-plus bin directories and finds the real system binary (or errors cleanly) -5. `VITE_PLUS_BYPASS` is preserved through `vp env exec` so loop protection remains active +5. `VP_BYPASS` is preserved through `vp env exec` so loop protection remains active **Flow Diagram:** @@ -688,7 +688,7 @@ When multiple vite-plus installations exist in PATH and `system_first` mode is a User runs: node app.js │ ▼ -Shim checks VITE_PLUS_TOOL_RECURSION +Shim checks VP_TOOL_RECURSION │ ├── Not set → Resolve version, set RECURSION=1, exec real node │ @@ -698,7 +698,7 @@ Shim checks VITE_PLUS_TOOL_RECURSION **Code Example:** ```rust -const RECURSION_ENV_VAR: &str = "VITE_PLUS_TOOL_RECURSION"; +const RECURSION_ENV_VAR: &str = "VP_TOOL_RECURSION"; fn execute_shim() { if env::var(RECURSION_ENV_VAR).is_ok() { @@ -756,7 +756,7 @@ fn execute_run_command() { ### 3. Trampoline Executables for Windows -**Decision**: Use lightweight trampoline `.exe` files on Windows instead of `.cmd` wrappers. Each trampoline detects its tool name from its own filename, sets `VITE_PLUS_SHIM_TOOL`, and spawns `vp.exe`. See [RFC: Trampoline EXE for Shims](./trampoline-exe-for-shims.md). +**Decision**: Use lightweight trampoline `.exe` files on Windows instead of `.cmd` wrappers. Each trampoline detects its tool name from its own filename, sets `VP_SHIM_TOOL`, and spawns `vp.exe`. See [RFC: Trampoline EXE for Shims](./trampoline-exe-for-shims.md). **Rationale**: @@ -775,14 +775,14 @@ fn execute_run_command() { - Windows doesn't support `execve`-style process replacement - `spawn` on Windows with proper exit code propagation is standard practice -### 5. Separate VITE_PLUS_HOME from Cache +### 5. Separate VP_HOME from Cache -**Decision**: Keep VITE_PLUS_HOME (bin, config) separate from cache (Node binaries). +**Decision**: Keep VP_HOME (bin, config) separate from cache (Node binaries). **Rationale**: - Cache uses XDG/platform-standard locations (already implemented) -- VITE_PLUS_HOME needs to be user-accessible for PATH configuration +- VP_HOME needs to be user-accessible for PATH configuration - Allows clearing cache without breaking shim setup ### 6. mtime-Based Cache Invalidation @@ -813,7 +813,7 @@ v22.13.0 # Falls back to latest LTS The resolution order is: -1. `VITE_PLUS_NODE_VERSION` env var (session override) +1. `VP_NODE_VERSION` env var (session override) 2. `.session-node-version` file (session override) 3. `.node-version` in current or parent directories 4. `package.json#devEngines.runtime` in current or parent directories @@ -827,7 +827,7 @@ The resolution order is: $ node -v vp: Failed to install Node 20.18.0: Network error: connection refused vp: Check your network connection and try again -vp: Or set VITE_PLUS_BYPASS=1 to use system node +vp: Or set VP_BYPASS=1 to use system node ``` ### Tool Not Found @@ -843,7 +843,7 @@ vp: npx is available in Node 5.2.0+ ```bash $ vp env doctor Installation - ✓ VITE_PLUS_HOME ~/.vite-plus + ✓ VP_HOME ~/.vite-plus ✓ Bin directory exists ✓ Shims node, npm, npx, corepack @@ -942,7 +942,7 @@ Restart your terminal and IDE, then run 'vp env doctor' to verify. ```bash $ vp env doctor Installation - ✓ VITE_PLUS_HOME ~/.vite-plus + ✓ VP_HOME ~/.vite-plus ✓ Bin directory exists ✓ Shims node, npm, npx, corepack @@ -975,7 +975,7 @@ $ vp env doctor Configuration ✓ Node.js mode managed ✓ IDE integration env sourced in ~/.zshenv - ⚠ Session override VITE_PLUS_NODE_VERSION=20.18.0 + ⚠ Session override VP_NODE_VERSION=20.18.0 Overrides all file-based resolution. Run 'vp env use --unset' to remove. ⚠ Session override (file) .session-node-version=20.18.0 @@ -1024,7 +1024,7 @@ Configuration ```bash $ vp env doctor Installation - ✓ VITE_PLUS_HOME ~/.vite-plus + ✓ VP_HOME ~/.vite-plus ✗ Bin directory does not exist ✗ Missing shims node, npm, npx, corepack Run 'vp env setup' to create bin directory and shims. @@ -1353,7 +1353,7 @@ When using session override: $ vp env which node /Users/user/.vite-plus/js_runtime/node/18.20.0/bin/node Version: 18.20.0 - Source: VITE_PLUS_NODE_VERSION (session) + Source: VP_NODE_VERSION (session) ``` **Global packages** - shows binary path plus package metadata: @@ -1986,9 +1986,9 @@ When `--node` is **not provided** and the first command is a shim tool: - **Matching package-manager tools (npm/npx, pnpm/pnpx, yarn/yarnpkg, bun/bunx)**: If `packageManager` explicitly declares the same tool family, the shim downloads/runs that package-manager version while keeping the project-resolved Node.js runtime on PATH. Mismatched tools are not translated. - **Global packages (tsc, eslint, etc.)**: Uses the Node.js version that was used during `vp install -g` -Both use the **exact same code path** as Unix symlinks (`shim::dispatch()`), ensuring identical behavior across platforms. On Windows, trampoline `.exe` shims set `VITE_PLUS_SHIM_TOOL` to enter shim dispatch mode. +Both use the **exact same code path** as Unix symlinks (`shim::dispatch()`), ensuring identical behavior across platforms. On Windows, trampoline `.exe` shims set `VP_SHIM_TOOL` to enter shim dispatch mode. -**Important**: The `VITE_PLUS_TOOL_RECURSION` environment variable is cleared before dispatch to ensure fresh version resolution, even when invoked from within a context where the variable is already set (e.g., when pnpm runs through the vite-plus shim). +**Important**: The `VP_TOOL_RECURSION` environment variable is cleared before dispatch to ensure fresh version resolution, even when invoked from within a context where the variable is already set (e.g., when pnpm runs through the vite-plus shim). ### Explicit Version Mode Behavior @@ -1997,7 +1997,7 @@ When `--node` **is provided**: 1. **Version Resolution**: Specified versions are resolved to exact versions 2. **Auto-Install**: If the version isn't installed, it's downloaded automatically 3. **PATH Construction**: Constructs PATH with specified version's bin directory -4. **Recursion Reset**: Clears `VITE_PLUS_TOOL_RECURSION` to force context re-evaluation +4. **Recursion Reset**: Clears `VP_TOOL_RECURSION` to force context re-evaluation ### Examples @@ -2159,22 +2159,22 @@ $ vp env --current --json ## Environment Variables -| Variable | Description | Default | -| ------------------------------- | ----------------------------------------------------------------------------------------------- | -------------- | -| `VITE_PLUS_HOME` | Base directory for bin and config | `~/.vite-plus` | -| `VITE_PLUS_NODE_VERSION` | Session override for Node.js version (set by `vp env use`) | unset | -| `VITE_PLUS_LOG` | Log level: debug, info, warn, error | `warn` | -| `VITE_PLUS_DEBUG_SHIM` | Enable extra shim diagnostics | unset | -| `VITE_PLUS_BYPASS` | PATH-style list of bin dirs to skip when finding system tools; set `=1` to bypass shim entirely | unset | -| `VITE_PLUS_TOOL_RECURSION` | **Internal**: Prevents shim recursion | unset | -| `VITE_PLUS_ENV_USE_EVAL_ENABLE` | **Internal**: Set by shell wrappers to signal that `vp env use` output will be eval'd | unset | +| Variable | Description | Default | +| ------------------------ | ----------------------------------------------------------------------------------------------- | -------------- | +| `VP_HOME` | Base directory for bin and config | `~/.vite-plus` | +| `VP_NODE_VERSION` | Session override for Node.js version (set by `vp env use`) | unset | +| `VITE_LOG` | Log level: debug, info, warn, error | `warn` | +| `VP_DEBUG_SHIM` | Enable extra shim diagnostics | unset | +| `VP_BYPASS` | PATH-style list of bin dirs to skip when finding system tools; set `=1` to bypass shim entirely | unset | +| `VP_TOOL_RECURSION` | **Internal**: Prevents shim recursion | unset | +| `VP_ENV_USE_EVAL_ENABLE` | **Internal**: Set by shell wrappers to signal that `vp env use` output will be eval'd | unset | ## Unix-Specific Considerations ### Shim Structure ``` -VITE_PLUS_HOME/ +VP_HOME/ ├── bin/ │ ├── vp -> ../current/bin/vp # Symlink to actual binary │ ├── node -> ../current/bin/vp # Symlink to same binary @@ -2220,13 +2220,13 @@ ln -sf ../current/bin/vp ~/.vite-plus/bin/tsc ### Shim Structure ``` -VITE_PLUS_HOME\ +VP_HOME\ ├── bin\ │ ├── vp.exe # Trampoline forwarding to current\bin\vp.exe -│ ├── node.exe # Trampoline shim (sets VITE_PLUS_SHIM_TOOL=node) -│ ├── npm.exe # Trampoline shim (sets VITE_PLUS_SHIM_TOOL=npm) -│ ├── npx.exe # Trampoline shim (sets VITE_PLUS_SHIM_TOOL=npx) -│ ├── corepack.exe # Trampoline shim (sets VITE_PLUS_SHIM_TOOL=corepack) +│ ├── node.exe # Trampoline shim (sets VP_SHIM_TOOL=node) +│ ├── npm.exe # Trampoline shim (sets VP_SHIM_TOOL=npm) +│ ├── npx.exe # Trampoline shim (sets VP_SHIM_TOOL=npx) +│ ├── corepack.exe # Trampoline shim (sets VP_SHIM_TOOL=corepack) │ └── tsc.exe # Trampoline shim for global package └── current\ └── bin\ @@ -2236,7 +2236,7 @@ VITE_PLUS_HOME\ ### Trampoline Executables -Windows shims use lightweight trampoline `.exe` files (see [RFC: Trampoline EXE for Shims](./trampoline-exe-for-shims.md)). Each trampoline detects its tool name from its own filename, sets `VITE_PLUS_SHIM_TOOL`, and spawns `vp.exe`. This avoids the "Terminate batch job (Y/N)?" prompt from `.cmd` wrappers and works in all shells (cmd.exe, PowerShell, Git Bash) without needing separate wrapper formats. +Windows shims use lightweight trampoline `.exe` files (see [RFC: Trampoline EXE for Shims](./trampoline-exe-for-shims.md)). Each trampoline detects its tool name from its own filename, sets `VP_SHIM_TOOL`, and spawns `vp.exe`. This avoids the "Terminate batch job (Y/N)?" prompt from `.cmd` wrappers and works in all shells (cmd.exe, PowerShell, Git Bash) without needing separate wrapper formats. #### Why Not Symlinks? @@ -2251,7 +2251,7 @@ Instead, trampoline `.exe` files are used. See [RFC: Trampoline EXE for Shims](. 1. User runs `npm install` 2. Windows finds `~/.vite-plus/bin/npm.exe` in PATH -3. Trampoline sets `VITE_PLUS_SHIM_TOOL=npm` and spawns `vp.exe` +3. Trampoline sets `VP_SHIM_TOOL=npm` and spawns `vp.exe` 4. `vp env exec` command handles version resolution and execution **Benefits of this approach**: @@ -2311,7 +2311,7 @@ env-doctor/ ## Security Considerations -1. **Path Validation**: Verify executed binaries are under VITE_PLUS_HOME/cache paths +1. **Path Validation**: Verify executed binaries are under VP_HOME/cache paths 2. **No Path Traversal**: Sanitize version strings before path construction 3. **Atomic Installs**: Use temp directory + rename pattern (already implemented) 4. **Log Sanitization**: Don't log sensitive environment variables @@ -2331,7 +2331,7 @@ env-doctor/ 9. Implement `vp env pin [version]` for per-directory version pinning 10. Implement `vp env unpin` as alias for `pin --unpin` 11. Implement `vp env list` (local) and `vp env list-remote` (remote) to show versions -12. Implement recursion prevention (`VITE_PLUS_TOOL_RECURSION`) +12. Implement recursion prevention (`VP_TOOL_RECURSION`) 13. Implement `vp env exec --node ` command ### Phase 2: Full Tool Support (P1) @@ -2354,7 +2354,7 @@ env-doctor/ ### Phase 3: Polish (P2) 1. Implement `vp env --print` for session-only env -2. Add VITE_PLUS_BYPASS escape hatch +2. Add VP_BYPASS escape hatch 3. Improve error messages 4. Add IDE-specific setup guidance 5. Documentation @@ -2385,9 +2385,9 @@ This is a new feature with no impact on existing functionality. The `vp` binary The following decisions have been made: -1. **VITE_PLUS_HOME Default Location**: `~/.vite-plus` - Simple, memorable path that's easy for users to find and configure. +1. **VP_HOME Default Location**: `~/.vite-plus` - Simple, memorable path that's easy for users to find and configure. -2. **Windows Shim Strategy**: Trampoline `.exe` files that set `VITE_PLUS_SHIM_TOOL` and spawn `vp.exe` - Avoids "Terminate batch job?" prompt, works in all shells. See [RFC: Trampoline EXE for Shims](./trampoline-exe-for-shims.md). +2. **Windows Shim Strategy**: Trampoline `.exe` files that set `VP_SHIM_TOOL` and spawn `vp.exe` - Avoids "Terminate batch job?" prompt, works in all shells. See [RFC: Trampoline EXE for Shims](./trampoline-exe-for-shims.md). 3. **Corepack Handling**: Included as a default shim (revisited in [#1309](https://github.com/voidzero-dev/vite-plus/issues/1309), originally excluded). The shim prefers a vp-managed global corepack, falls back to the Node-bundled binary (Node.js ≤ 24), and auto-installs a managed copy on Node.js 25+ where corepack is no longer bundled. See [Corepack Shim](#corepack-shim). diff --git a/rfcs/exec-command.md b/rfcs/exec-command.md index 72b8dbf9af..d1c7d50f23 100644 --- a/rfcs/exec-command.md +++ b/rfcs/exec-command.md @@ -101,7 +101,7 @@ vp exec -r --parallel -- eslint . vp exec -r --resume-from @my/app -- tsc --noEmit # Run on workspace root only -vp exec -w -- node -e "console.log(process.env.VITE_PLUS_PACKAGE_NAME)" +vp exec -w -- node -e "console.log(process.env.VP_PACKAGE_NAME)" # Save execution summary vp exec -r --report-summary -- vitest run @@ -161,7 +161,7 @@ Based on pnpm exec behavior (reference: `exec/plugin-commands-script-runners/src 2. **Strip leading `--`** from the command for backward compatibility 3. **Execute command** via process spawn with `stdio: inherit` — the command resolves through the modified PATH (local bins first, then system PATH) 4. **Shell mode**: When `-c` is specified, pass `shell: true` to the child process -5. **Set `VITE_PLUS_PACKAGE_NAME`** env var with the current package name (analogous to pnpm's `PNPM_PACKAGE_NAME`) +5. **Set `VP_PACKAGE_NAME`** env var with the current package name (analogous to pnpm's `PNPM_PACKAGE_NAME`) 6. **Error if no command**: `'vp exec' requires a command to run` ## Relationship Between Commands @@ -290,7 +290,7 @@ The following existing code is reused: ### 4. Same Env Var Convention -**Decision**: Set `VITE_PLUS_PACKAGE_NAME` env var when executing in a workspace package. +**Decision**: Set `VP_PACKAGE_NAME` env var when executing in a workspace package. **Rationale**: @@ -583,7 +583,7 @@ This is a new feature with no breaking changes: | Name + path filter | `--filter 'app-*{./packages}'` | `--filter 'app-*{./packages}'` | | Parallel | `--parallel` | `--parallel` | | Report summary | `--report-summary` | `--report-summary` | -| Package name env var | `PNPM_PACKAGE_NAME` | `VITE_PLUS_PACKAGE_NAME` | +| Package name env var | `PNPM_PACKAGE_NAME` | `VP_PACKAGE_NAME` | | Strip leading `--` | Yes | Yes | ## Future Enhancements diff --git a/rfcs/global-cli-rust-binary.md b/rfcs/global-cli-rust-binary.md index 86c471a829..4decc605a8 100644 --- a/rfcs/global-cli-rust-binary.md +++ b/rfcs/global-cli-rust-binary.md @@ -717,14 +717,14 @@ For users who prefer standalone installation without npm: # https://vite.plus # # Environment variables: -# VITE_PLUS_VERSION - Version to install (default: latest) -# VITE_PLUS_INSTALL_DIR - Installation directory (default: ~/.vite-plus) +# VP_VERSION - Version to install (default: latest) +# VP_HOME - Installation directory (default: ~/.vite-plus) # NPM_CONFIG_REGISTRY - Custom npm registry URL (default: https://registry.npmjs.org) set -e -VITE_PLUS_VERSION="${VITE_PLUS_VERSION:-latest}" -INSTALL_DIR="${VITE_PLUS_INSTALL_DIR:-$HOME/.vite-plus}" +VP_VERSION="${VP_VERSION:-latest}" +INSTALL_DIR="${VP_HOME:-$HOME/.vite-plus}" NPM_REGISTRY="${NPM_CONFIG_REGISTRY:-https://registry.npmjs.org}" NPM_REGISTRY="${NPM_REGISTRY%/}" @@ -732,7 +732,7 @@ NPM_REGISTRY="${NPM_REGISTRY%/}" # (platform detection code omitted for brevity) # Set up version-specific directories -VERSION_DIR="$INSTALL_DIR/$VITE_PLUS_VERSION" +VERSION_DIR="$INSTALL_DIR/$VP_VERSION" BIN_DIR="$VERSION_DIR/bin" DIST_DIR="$VERSION_DIR/dist" CURRENT_LINK="$INSTALL_DIR/current" @@ -741,15 +741,15 @@ CURRENT_LINK="$INSTALL_DIR/current" mkdir -p "$BIN_DIR" "$DIST_DIR" # Download platform package (binary + .node files) -platform_url="${NPM_REGISTRY}/${package_name}/-/vite-plus-cli-${package_suffix}-${VITE_PLUS_VERSION}.tgz" +platform_url="${NPM_REGISTRY}/${package_name}/-/vite-plus-cli-${package_suffix}-${VP_VERSION}.tgz" # Extract to temp dir, copy binary to BIN_DIR, copy .node files to DIST_DIR # Download main package (JS scripts + package.json) -main_url="${NPM_REGISTRY}/vite-plus-cli/-/vite-plus-cli-${VITE_PLUS_VERSION}.tgz" +main_url="${NPM_REGISTRY}/vite-plus-cli/-/vite-plus-cli-${VP_VERSION}.tgz" # Extract dist/* to DIST_DIR, copy package.json to VERSION_DIR # Create/update current symlink -ln -sfn "$VITE_PLUS_VERSION" "$CURRENT_LINK" +ln -sfn "$VP_VERSION" "$CURRENT_LINK" # Cleanup old versions (keep max 3) cleanup_old_versions @@ -768,14 +768,14 @@ For Windows users, provide a PowerShell script: # https://vite.plus/ps1 # # Environment variables: -# VITE_PLUS_VERSION - Version to install (default: latest) -# VITE_PLUS_INSTALL_DIR - Installation directory (default: $env:USERPROFILE\.vite-plus) +# VP_VERSION - Version to install (default: latest) +# VP_HOME - Installation directory (default: $env:USERPROFILE\.vite-plus) # NPM_CONFIG_REGISTRY - Custom npm registry URL (default: https://registry.npmjs.org) $ErrorActionPreference = "Stop" -$ViteVersion = if ($env:VITE_PLUS_VERSION) { $env:VITE_PLUS_VERSION } else { "latest" } -$InstallDir = if ($env:VITE_PLUS_INSTALL_DIR) { $env:VITE_PLUS_INSTALL_DIR } else { "$env:USERPROFILE\.vite-plus" } +$ViteVersion = if ($env:VP_VERSION) { $env:VP_VERSION } else { "latest" } +$InstallDir = if ($env:VP_HOME) { $env:VP_HOME } else { "$env:USERPROFILE\.vite-plus" } $NpmRegistry = if ($env:NPM_CONFIG_REGISTRY) { $env:NPM_CONFIG_REGISTRY.TrimEnd('/') } else { "https://registry.npmjs.org" } # Detect architecture and get version... diff --git a/rfcs/implode-command.md b/rfcs/implode-command.md index e0ff23d224..3da3ff49c9 100644 --- a/rfcs/implode-command.md +++ b/rfcs/implode-command.md @@ -225,7 +225,7 @@ crates/vite_global_cli/ - `test_remove_vite_plus_lines_absolute_path` — handles `/home/user/.vite-plus/env` variant - `test_remove_vite_plus_lines_preserves_surrounding` — other content untouched - `test_clean_shell_profile_integration` — tempdir-based integration test -- `test_execute_not_installed` — points `VITE_PLUS_HOME` at non-existent path, verifies success +- `test_execute_not_installed` — points `VP_HOME` at non-existent path, verifies success ### CI Tests diff --git a/rfcs/js-runtime.md b/rfcs/js-runtime.md index a3f6dd0e73..056ab5555d 100644 --- a/rfcs/js-runtime.md +++ b/rfcs/js-runtime.md @@ -227,7 +227,7 @@ let runtime = download_runtime_for_project(&project_path).await?; Following the PackageManager pattern: ``` -$VITE_PLUS_HOME/js_runtime/{runtime}/{version}/ +$VP_HOME/js_runtime/{runtime}/{version}/ ``` Examples: @@ -241,7 +241,7 @@ Examples: The Node.js version index is cached locally to avoid repeated network requests: ``` -$VITE_PLUS_HOME/js_runtime/node/index_cache.json +$VP_HOME/js_runtime/node/index_cache.json ``` Cache structure: diff --git a/rfcs/merge-global-and-local-cli.md b/rfcs/merge-global-and-local-cli.md index aa0f01eb90..aacacb018f 100644 --- a/rfcs/merge-global-and-local-cli.md +++ b/rfcs/merge-global-and-local-cli.md @@ -281,5 +281,5 @@ if (command === 'create') { - `pnpm -F vite-plus snap-test-local` — Local CLI snap tests pass - `pnpm -F vite-plus snap-test-global` — Global CLI snap tests pass - `pnpm bootstrap-cli` — Full build and global install succeeds -- `VITE_PLUS_VERSION=test bash packages/cli/install.sh` — Production install from npm works +- `VP_VERSION=test bash packages/cli/install.sh` — Production install from npm works - Manual testing: `vp create`, `vp migrate`, `vp --version`, `vp build`, `vp test` all work diff --git a/rfcs/trampoline-exe-for-shims.md b/rfcs/trampoline-exe-for-shims.md index 1294a23df8..b073288456 100644 --- a/rfcs/trampoline-exe-for-shims.md +++ b/rfcs/trampoline-exe-for-shims.md @@ -75,13 +75,13 @@ On Unix, shims are symlinks to the `vp` binary. The binary detects the tool name ``` ~/.vite-plus/bin/ ├── vp.exe # Trampoline → spawns current\bin\vp.exe -├── node.exe # Trampoline → sets VITE_PLUS_SHIM_TOOL=node, spawns vp.exe -├── npm.exe # Trampoline → sets VITE_PLUS_SHIM_TOOL=npm, spawns vp.exe -├── npx.exe # Trampoline → sets VITE_PLUS_SHIM_TOOL=npx, spawns vp.exe -├── corepack.exe # Trampoline → sets VITE_PLUS_SHIM_TOOL=corepack, spawns vp.exe -├── vpx.exe # Trampoline → sets VITE_PLUS_SHIM_TOOL=vpx, spawns vp.exe -├── vpr.exe # Trampoline → sets VITE_PLUS_SHIM_TOOL=vpr, spawns vp.exe -└── tsc.exe # Trampoline → sets VITE_PLUS_SHIM_TOOL=tsc, spawns vp.exe (package shim) +├── node.exe # Trampoline → sets VP_SHIM_TOOL=node, spawns vp.exe +├── npm.exe # Trampoline → sets VP_SHIM_TOOL=npm, spawns vp.exe +├── npx.exe # Trampoline → sets VP_SHIM_TOOL=npx, spawns vp.exe +├── corepack.exe # Trampoline → sets VP_SHIM_TOOL=corepack, spawns vp.exe +├── vpx.exe # Trampoline → sets VP_SHIM_TOOL=vpx, spawns vp.exe +├── vpr.exe # Trampoline → sets VP_SHIM_TOOL=vpr, spawns vp.exe +└── tsc.exe # Trampoline → sets VP_SHIM_TOOL=tsc, spawns vp.exe (package shim) ``` Each trampoline is a copy of `vp-shim.exe` (the template binary distributed alongside `vp.exe`). @@ -124,11 +124,11 @@ fn main() { // 4. Spawn vp.exe with env vars let mut cmd = Command::new(&vp_exe); cmd.args(env::args_os().skip(1)); - cmd.env("VITE_PLUS_HOME", vp_home); + cmd.env("VP_HOME", vp_home); if tool_name != "vp" { - cmd.env("VITE_PLUS_SHIM_TOOL", tool_name); - cmd.env_remove("VITE_PLUS_TOOL_RECURSION"); + cmd.env("VP_SHIM_TOOL", tool_name); + cmd.env_remove("VP_TOOL_RECURSION"); } // 5. Propagate exit code (error message via write_all, not eprintln!) @@ -170,11 +170,11 @@ fn install_ctrl_handler() { The trampoline sets three env vars before spawning `vp.exe`: -| Variable | When | Purpose | -| -------------------------- | -------------------------- | ------------------------------------------------------------------------------ | -| `VITE_PLUS_HOME` | Always | Tells vp.exe the install directory (derived from `bin_dir.parent()`) | -| `VITE_PLUS_SHIM_TOOL` | Tool shims only (not "vp") | Tells vp.exe to enter shim dispatch mode for the named tool | -| `VITE_PLUS_TOOL_RECURSION` | Removed for tool shims | Clears the recursion marker for fresh version resolution in nested invocations | +| Variable | When | Purpose | +| ------------------- | -------------------------- | ------------------------------------------------------------------------------ | +| `VP_HOME` | Always | Tells vp.exe the install directory (derived from `bin_dir.parent()`) | +| `VP_SHIM_TOOL` | Tool shims only (not "vp") | Tells vp.exe to enter shim dispatch mode for the named tool | +| `VP_TOOL_RECURSION` | Removed for tool shims | Clears the recursion marker for fresh version resolution in nested invocations | ### Ctrl+C Handling @@ -190,11 +190,11 @@ The trampoline installs a console control handler that returns `TRUE` (1): ### Integration with Shim Detection -`detect_shim_tool()` in `shim/mod.rs` checks `VITE_PLUS_SHIM_TOOL` env var **before** `argv[0]`: +`detect_shim_tool()` in `shim/mod.rs` checks `VP_SHIM_TOOL` env var **before** `argv[0]`: ``` Trampoline (node.exe) - → sets VITE_PLUS_SHIM_TOOL=node, VITE_PLUS_HOME=..., removes VITE_PLUS_TOOL_RECURSION + → sets VP_SHIM_TOOL=node, VP_HOME=..., removes VP_TOOL_RECURSION → spawns current/bin/vp.exe with original args → detect_shim_tool() reads env var → "node" → dispatch("node", args) diff --git a/rfcs/vpx-command.md b/rfcs/vpx-command.md index 1fc645f5c9..2472a0b7b1 100644 --- a/rfcs/vpx-command.md +++ b/rfcs/vpx-command.md @@ -155,7 +155,7 @@ if tool == "vpx" { ### Windows -On Windows, `vpx.exe` is a trampoline executable (consistent with existing `node.exe`, `npm.exe`, `npx.exe` shims). It detects its tool name from its own filename (`vpx`), sets `VITE_PLUS_SHIM_TOOL=vpx`, and spawns `vp.exe`. See [RFC: Trampoline EXE for Shims](./trampoline-exe-for-shims.md). +On Windows, `vpx.exe` is a trampoline executable (consistent with existing `node.exe`, `npm.exe`, `npx.exe` shims). It detects its tool name from its own filename (`vpx`), sets `VP_SHIM_TOOL=vpx`, and spawns `vp.exe`. See [RFC: Trampoline EXE for Shims](./trampoline-exe-for-shims.md). ### Setup