Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
"css-module-lexer",
"html5gum",
"prettyplease",
"proc-macro2",

Check warning on line 11 in Cargo.toml

View workflow job for this annotation

GitHub Actions / Lint

shear/redundant_ignore

redundant ignore `proc-macro2` (remove from ignored list)
"quote",

Check warning on line 12 in Cargo.toml

View workflow job for this annotation

GitHub Actions / Lint

shear/redundant_ignore

redundant ignore `quote` (remove from ignored list)
"string_cache",
"syn",

Check warning on line 14 in Cargo.toml

View workflow job for this annotation

GitHub Actions / Lint

shear/redundant_ignore

redundant ignore `syn` (remove from ignored list)
]

[workspace.package]
Expand Down Expand Up @@ -298,6 +298,7 @@
vite_setup = { path = "crates/vite_setup" }
vite_shared = { path = "crates/vite_shared" }
vite_static_config = { path = "crates/vite_static_config" }
vite_toolchain = { path = "crates/vite_toolchain" }
vite_path = { git = "https://github.com/voidzero-dev/vite-task.git", rev = "5c1d02c750ac21c6f4cf0528062590a145e87fd1" }
vite_powershell = { git = "https://github.com/voidzero-dev/vite-task.git", rev = "5c1d02c750ac21c6f4cf0528062590a145e87fd1" }
vite_select = { git = "https://github.com/voidzero-dev/vite-task.git", rev = "5c1d02c750ac21c6f4cf0528062590a145e87fd1" }
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Vite+ is the unified entry point for local web development. It combines [Vite](h
- **`vp build`:** Build applications for production with Vite + Rolldown
- **`vp run`:** Run `package.json` scripts and monorepo tasks with caching and dependency-aware scheduling
- **`vp pack`:** Build libraries for npm publishing or standalone app binaries
- **`vp toolchain`:** Inspect the exact Vite+, Vite, Rolldown, Oxc, and other tool versions in use
- **`vp create` / `vp migrate`:** Scaffold new projects and migrate existing ones

All of this is configured from your project root and works across Vite's framework ecosystem.
Expand Down Expand Up @@ -145,6 +146,7 @@ Vite+ automatically wraps your package manager (pnpm, npm, Yarn, or Bun) based o

#### Maintain

- **toolchain** - Show Vite+ tool versions and their relationships
- **upgrade** - Update `vp` itself to the latest version
- **implode** - Remove `vp` and all related data

Expand Down Expand Up @@ -195,7 +197,7 @@ If you are manually migrating a project to Vite+, install these dev dependencies
npm install -D vite-plus @voidzero-dev/vite-plus-core@latest
```

You need to add overrides to your package manager so that other packages resolve the Vite+ versions: alias `vite` to `@voidzero-dev/vite-plus-core`, and pin `vitest` to the version Vite+ bundles (run `vp --version`) so the whole project shares a single Vitest copy with `vp test`. Without the `vitest` pin, a dependency or workspace package can pull a different Vitest than the bundled runner, splitting Vitest's internals (mocks, `expect`, runner state):
You need to add overrides to your package manager so that other packages resolve the Vite+ versions: alias `vite` to `@voidzero-dev/vite-plus-core`, and pin `vitest` to the version reported by `vp toolchain vitest` so the whole project shares a single Vitest copy with `vp test`. Without the `vitest` pin, a dependency or workspace package can pull a different Vitest than the bundled runner, splitting Vitest's internals (mocks, `expect`, runner state):

```json
"overrides": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ Manage Dependencies:
rebuild Rebuild native modules
pm Forward a command to the package manager

Inspect:
toolchain Show versions and relationships in the active Vite+ toolchain

Maintain:
upgrade Update vp itself to the latest version
implode Remove vp and all related data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Core Commands:
cache Manage the task cache
config Configure hooks and agent integration
staged Run linters on staged files
toolchain Show versions and relationships in the Vite+ toolchain

Package Manager Commands:
install Install all dependencies, or add packages if package names are provided
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ Core Commands:
cache Manage the task cache
config Configure hooks and agent integration
staged Run linters on staged files
toolchain Show versions and relationships in the Vite+ toolchain

Package Manager Commands:
install Install all dependencies, or add packages if package names are provided
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "command-toolchain",
"version": "1.0.0",
"private": true,
"packageManager": "pnpm@11.0.6"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
[[case]]
name = "toolchain_full_local"
vp = "local"
comment = "The local CLI reads the manifest shipped in its vite-plus package."
steps = [["vp", "toolchain"]]

[[case]]
name = "toolchain_full_global"
vp = "global"
comment = "The global flag reads the manifest paired with the global binary."
steps = [["vp", "toolchain", "--global"]]

[[case]]
name = "toolchain_filters"
vp = "local"
steps = [
{ argv = ["vp", "toolchain", "vite"], comment = "a tool filter keeps its ownership and engine chain" },
{ argv = ["vp", "toolchain", "vite", "vitest"], comment = "multiple filters return a stable union" },
{ argv = ["vp", "toolchain", "vite-plus-core", "tsgolint", "vite-task"], comment = "stable IDs and declared aliases resolve" },
]

[[case]]
name = "toolchain_json"
vp = "global"
steps = [
{ argv = ["vp", "toolchain", "vite", "--json", "--global"], tty = false, comment = "JSON contains one node per ID and no human header" },
]

[[case]]
name = "toolchain_unknown"
vp = "local"
steps = [
{ argv = ["vp", "toolchain", "rollup"], comment = "human output points back to the package graph", continue-on-failure = true },
{ argv = ["vp", "toolchain", "rollup", "--json"], tty = false, comment = "JSON mode omits the human hint", continue-on-failure = true },
]

[[case]]
name = "toolchain_global_from_local_cli"
vp = "local"
steps = [
{ argv = ["vp", "toolchain", "--global"], comment = "the local package leaves global selection to the global vp binary", continue-on-failure = true },
]

[[case]]
name = "toolchain_old_local_routing"
vp = "global"
steps = [
{ argv = ["vpt", "mkdir", "-p", "node_modules/vite-plus/dist"], snapshot = false },
{ argv = ["vpt", "write-file", "node_modules/vite-plus/package.json", "{\"name\":\"vite-plus\",\"version\":\"0.1.0\"}\n"], snapshot = false },
{ argv = ["vpt", "write-file", "node_modules/vite-plus/dist/bin.js", "console.error(\"error: Command 'toolchain' not found\");\nprocess.exitCode = 2;\n"], snapshot = false },
{ argv = ["vp", "toolchain"], timeout = 120000, comment = "the global binary delegates and lets an old local CLI reject the command", continue-on-failure = true },
{ argv = ["vp", "toolchain", "--global"], comment = "--global skips the old local package" },
]

[[case]]
name = "toolchain_why_hint"
vp = ["local", "global"]
steps = [
{ argv = ["vp", "why", "vite"], timeout = 120000, comment = "a successful human package query points to toolchain inspection" },
{ argv = ["vp", "why", "vite", "--json"], tty = false, timeout = 120000, comment = "machine-readable package-manager output has no hint" },
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# toolchain_filters

## `vp toolchain vite`

a tool filter keeps its ownership and engine chain

```
Vite+ toolchain (local)

vite-plus@0.2.7
`-- depends on @voidzero-dev/vite-plus-core@<version>
`-- bundles vite@8.2.0
`-- uses rolldown@1.2.2
|-- compiles oxc@0.142.0
`-- compiles oxc-resolver@11.24.2
```

## `vp toolchain vite vitest`

multiple filters return a stable union

```
Vite+ toolchain (local)

vite-plus@0.2.7
|-- depends on @voidzero-dev/vite-plus-core@<version>
| `-- bundles vite@8.2.0
| `-- uses rolldown@1.2.2
| |-- compiles oxc@0.142.0
| `-- compiles oxc-resolver@11.24.2
`-- depends on vitest@4.1.10
```

## `vp toolchain vite-plus-core tsgolint vite-task`

stable IDs and declared aliases resolve

```
Vite+ toolchain (local)

vite-plus@0.2.7
|-- depends on @voidzero-dev/vite-plus-core@<version>
|-- depends on oxlint-tsgolint@7.0.2001
`-- compiles vite-task@0.0.0 (5c1d02c750ac21c6f4cf0528062590a145e87fd1)
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# toolchain_full_global

The global flag reads the manifest paired with the global binary.

## `vp toolchain --global`

```
Vite+ toolchain (global)

vite-plus@0.2.7
|-- depends on @voidzero-dev/vite-plus-core@<version>
| |-- bundles vite@8.2.0
| | `-- uses rolldown@1.2.2
| | |-- compiles oxc@0.142.0
| | `-- compiles oxc-resolver@11.24.2
| |-- bundles rolldown@1.2.2
| | |-- compiles oxc@0.142.0
| | `-- compiles oxc-resolver@11.24.2
| `-- bundles tsdown@0.22.14
|-- depends on vitest@4.1.10
|-- depends on oxlint@1.76.0
|-- depends on oxlint-tsgolint@7.0.2001
|-- depends on oxfmt@0.61.0
`-- compiles vite-task@0.0.0 (5c1d02c750ac21c6f4cf0528062590a145e87fd1)
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# toolchain_full_local

The local CLI reads the manifest shipped in its vite-plus package.

## `vp toolchain`

```
Vite+ toolchain (local)

vite-plus@0.2.7
|-- depends on @voidzero-dev/vite-plus-core@<version>
| |-- bundles vite@8.2.0
| | `-- uses rolldown@1.2.2
| | |-- compiles oxc@0.142.0
| | `-- compiles oxc-resolver@11.24.2
| |-- bundles rolldown@1.2.2
| | |-- compiles oxc@0.142.0
| | `-- compiles oxc-resolver@11.24.2
| `-- bundles tsdown@0.22.14
|-- depends on vitest@4.1.10
|-- depends on oxlint@1.76.0
|-- depends on oxlint-tsgolint@7.0.2001
|-- depends on oxfmt@0.61.0
`-- compiles vite-task@0.0.0 (5c1d02c750ac21c6f4cf0528062590a145e87fd1)
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# toolchain_global_from_local_cli

## `vp toolchain --global`

the local package leaves global selection to the global vp binary

**Exit code:** 1

```
error: `--global` is only supported by the globally installed `vp` CLI
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# toolchain_json

## `vp toolchain vite --json --global`

JSON contains one node per ID and no human header

```
{
"schemaVersion": 1,
"source": {
"scope": "global",
"path": "<home>/.vite-plus/current/node_modules/vite-plus",
"vitePlusVersion": "0.2.7"
},
"nodes": [
{
"id": "vite-plus",
"name": "vite-plus",
"version": "0.2.7",
"kind": "package",
"delivery": [
"dependency"
],
"aliases": []
},
{
"id": "vite-plus-core",
"name": "@voidzero-dev/vite-plus-core",
"version": "0.2.7",
"kind": "package",
"delivery": [
"dependency"
],
"aliases": [
"vite-plus-core"
]
},
{
"id": "vite",
"name": "vite",
"version": "8.2.0",
"kind": "tool",
"delivery": [
"bundled"
],
"aliases": []
},
{
"id": "rolldown",
"name": "rolldown",
"version": "1.2.2",
"kind": "tool",
"delivery": [
"bundled",
"compiled"
],
"aliases": []
},
{
"id": "oxc",
"name": "oxc",
"version": "0.142.0",
"kind": "engine",
"delivery": [
"compiled"
],
"aliases": []
},
{
"id": "oxc-resolver",
"name": "oxc-resolver",
"version": "11.24.2",
"kind": "engine",
"delivery": [
"compiled"
],
"aliases": []
}
],
"edges": [
{
"from": "vite-plus",
"to": "vite-plus-core",
"relationship": "depends-on"
},
{
"from": "vite-plus-core",
"to": "vite",
"relationship": "bundles"
},
{
"from": "vite",
"to": "rolldown",
"relationship": "uses"
},
{
"from": "rolldown",
"to": "oxc",
"relationship": "compiles"
},
{
"from": "rolldown",
"to": "oxc-resolver",
"relationship": "compiles"
}
]
}
```
Loading
Loading