Skip to content
Merged
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
15 changes: 3 additions & 12 deletions .claude/skills/bump-vite-task/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,13 @@ vite-task changes often affect CLI output, which means snapshot tests need updat
- **Cache behavior messages**: e.g., new summary lines about cache status
- **Task output formatting**: e.g., step numbering, separator lines

**PTY snapshot suite (`crates/vite_cli_snapshots`)**, the primary suite:
**PTY snapshot suite (`crates/vite_cli_snapshots`):**

- A bump can break it two ways: runner compilation (it consumes vite-task's `pty_terminal_test`, `pty_terminal_test_client`, and `snapshot_test` crates directly, so their API changes surface here; fix in the runner) and recorded CLI output.
- Unlike the legacy trees, output changes are handled locally with real assertions: `UPDATE_SNAPSHOTS=1 just snapshot-test`, then review the `.md` diffs like code. Without a built `packages/cli/dist`, run the global flavor only: `VP_SNAP_SKIP_FLAVORS=local UPDATE_SNAPSHOTS=1 just snapshot-test`.
- Update output locally with real assertions: `UPDATE_SNAPSHOTS=1 just snapshot-test`, then review the `.md` diffs like code. Without a built `packages/cli/dist`, run the global flavor only: `VP_SNAP_SKIP_FLAVORS=local UPDATE_SNAPSHOTS=1 just snapshot-test`.
- Windows runs in the `CLI snapshot test (Windows)` CI job via a cross-compiled nextest archive; snapshots are OS-shared, so a Windows-only diff there means a redaction gap, not a re-record.
- Reference: `crates/vite_cli_snapshots/tests/cli_snapshots/README.md`.

**Legacy snap trees** (`packages/cli/snap-tests/*/snap.txt`, `packages/cli/snap-tests-global/*/snap.txt`, being migrated; do not add cases):

1. Push your changes and let CI run the snap tests.
2. CI will show the diff in the E2E test logs if snap tests fail.
3. Extract the diff from CI logs and apply it locally.
4. Check all three platforms (Linux, Mac, Windows) since they may have slightly different snap test coverage.
5. Watch for trailing newline issues - ensure snap files end consistently.

### 7. Review changelog and update docs

- Fetch the vite-task `CHANGELOG.md` diff between old and new commits to see what changed:
Expand Down Expand Up @@ -98,13 +90,12 @@ After creating the PR, automatically watch CI without asking the user first. Ens
- **Lint**: Clippy and format checks
- **Test** (Linux, Mac, Windows): Rust unit tests
- **CLI snapshot test** (Linux, Mac, Windows): the PTY snapshot suite - most likely to fail on a vite-task bump (runner compiles against vite-task crates AND asserts CLI output)
- **CLI E2E test** (Linux, Mac, Windows): legacy snap tests during the migration
- **Run task**: Task runner integration tests
- **Cargo Deny**: License/advisory checks (may have pre-existing failures unrelated to bump)

The only **required** status check for merging is `done`, which aggregates the other checks (excluding Cargo Deny).

## Notes

- Building the full CLI locally (`pnpm bootstrap-cli`) requires the rolldown Node.js package to be built first, which is complex. Prefer relying on CI for snap test generation.
- Building the full CLI locally (`pnpm bootstrap-cli`) requires the rolldown Node.js package to be built first, which is complex. Prefer the global-only snapshot command above or CI when no local CLI build is available.
- `Cargo.lock` is automatically updated by cargo when you change the revision in `Cargo.toml`.
3 changes: 1 addition & 2 deletions .claude/skills/release-manager/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,7 @@ Do not assume the merge brought in only the fix PR: `main` may have accumulated

Known release-branch-only failure modes:

- **Binding version drift**: `CLI E2E test` fails its no-unexpected-changes guard with a diff flipping version strings in `binding/index.cjs`. Fix: step 2.
- **Unpublished-version installs**: the release branch carries version `X.Y.Z` before it exists on npm. Snap fixtures that run a real package-manager install (`vp create` / `vp migrate` followed by install) fail with `ERR_PNPM_NO_MATCHING_VERSION` or bun/yarn `failed to resolve` for `vite-plus@X.Y.Z` / `@voidzero-dev/vite-plus-core@X.Y.Z`. Fix: pin `"VP_VERSION": "<published version>"` in the fixture's `steps.json` env (see #2017); the snapshot normalizer rewrites versions to `<semver>`, so output does not change. Any new install-performing fixture must ship with this pin or it will break the next release.
- **Binding version drift**: CI's no-unexpected-changes guard reports a diff flipping version strings in `binding/index.cjs`. Fix: step 2.
- **Registry flakes**: registry-bound fixtures can time out (about 50s) and look like regressions. Rerun before diagnosing, and never commit a `[timeout]` snapshot.

## 6. Merge
Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/sync-tsdown-cli/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@ Compare the upstream `tsdown` CLI options with `vp pack` (defined in `packages/c
- `-c, --config` is intentionally commented out (vp pack uses vite.config.ts)
- `--env-prefix` has a different default (`['VITE_PACK_', 'TSDOWN_']`)
6. Verify with `pnpm --filter vite-plus build-ts` and `vp pack -h`
7. If new parameters were added, add a corresponding snap test under `packages/cli/snap-tests/` to verify the new option works correctly
7. If new parameters were added, add a corresponding PTY snapshot case under `crates/vite_cli_snapshots/tests/cli_snapshots/fixtures/` to verify the new option works correctly
4 changes: 2 additions & 2 deletions .claude/skills/verify-interactive-cli/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
name: verify-interactive-cli
description: Drive and capture vp's interactive (clack) prompts in a tmux session to verify interactive UX and catch spinner-over-prompt bugs that snap tests (which run non-interactively) miss. Use when asked to test/verify/capture an interactive vp command's prompts (vp migrate, vp create, ...), reproduce a prompt-rendering bug, or show the real interactive CLI output for a PR.
description: Drive and capture vp's interactive (clack) prompts in a tmux session to manually verify interactive UX and catch spinner-over-prompt bugs. Use when asked to test/verify/capture an interactive vp command's prompts (vp migrate, vp create, ...), reproduce a prompt-rendering bug, or show the real interactive CLI output for a PR.
allowed-tools: Bash, Read
---

# Verify vp's interactive CLI prompts

Snap tests run `vp` non-interactively, so interactive clack prompts (hooks / agent / editor confirms, the Node-version upgrade confirm) and TTY-only rendering bugs are never exercised. This skill drives the real prompts in a TTY (via tmux), captures clean output, and can catch a spinner animating underneath an active prompt (a real, recurring UX bug class, e.g. the "Preparing migration" and "Checking Node.js version support" spinners).
The PTY snapshot suite covers scripted prompt flows. This skill complements it by driving an installed CLI in tmux, capturing clean output, and checking a prompt over several seconds for a spinner animating underneath it (a real, recurring UX bug class, e.g. the "Preparing migration" and "Checking Node.js version support" spinners).

## Prerequisites

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash
# Drive and capture an interactive `vp` (clack) prompt flow inside tmux, to verify
# interactive UX that snap tests (which run non-interactively) never cover.
# Drive and capture an interactive `vp` (clack) prompt flow inside tmux for
# manual verification against an installed CLI.
#
# Usage:
# interactive-cli-tmux-driver.sh <project-dir> "<command>" [STOP_AT_REGEX]
Expand Down
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,3 @@ rolldown-vite
vite
/crates/vite_global_cli/vp
.void/

# Generated by `tool migrate-snap-tests`; batch PRs summarize it in the description instead
crates/vite_cli_snapshots/tests/cli_snapshots/MIGRATION-REPORT.md
1 change: 0 additions & 1 deletion .typos.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ PnP = "PnP"

[files]
extend-exclude = [
"**/snap-tests/**/snap.txt",
"crates/fspy_detours_sys/detours",
"crates/fspy_detours_sys/src/generated_bindings.rs",
"packages/cli/src/oxfmt-config.ts",
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@
"typescript.reportStyleChecksAsWarnings": false,
"typescript.updateImportsOnFileMove.enabled": "always",
"typescript.experimental.useTsgo": true,
"vitest.configSearchPatternExclude": "{**/node_modules/**,**/vendor/**,**/.*/**,**/*.d.ts,{**/packages/cli/snap-tests*/**,**/crates/vite_cli_snapshots/tests/cli_snapshots/**}}"
"vitest.configSearchPatternExclude": "{**/node_modules/**,**/vendor/**,**/.*/**,**/*.d.ts,**/crates/vite_cli_snapshots/tests/cli_snapshots/**}"
}
31 changes: 8 additions & 23 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,15 @@ High-signal repo map:

```
vite-plus/
├── packages/cli/ # Published vite-plus package, JS CLI, docs, templates, legacy snap tests, NAPI binding
├── packages/cli/ # Published vite-plus package, JS CLI, docs, templates, NAPI binding
│ ├── src/bin.ts # JS entrypoint and local CLI dispatch
│ ├── src/resolve-test.ts # Resolves upstream Vitest for `vp test`
│ ├── src/utils/agent.ts # Generated agent-file marker/update logic
│ ├── binding/ # Rust NAPI binding used by the local CLI
│ ├── snap-tests/ # Legacy local CLI output snapshots
│ └── snap-tests-global/ # Legacy global CLI output snapshots
│ └── binding/ # Rust NAPI binding used by the local CLI
├── packages/core/ # @voidzero-dev/vite-plus-core bundled Vite/Rolldown/tsdown/VitePress surfaces
├── packages/prompts/ # Prompt UI/helpers package, including snapshot milestones
├── packages/tools/ # Repo tooling, local npm registry, legacy snap migrator
├── crates/vite_cli_snapshots/ # PTY snapshot test runner + vpt helper (new CLI tests)
├── packages/tools/ # Repo tooling and local npm registry
├── crates/vite_cli_snapshots/ # PTY snapshot test runner + vpt helper (CLI tests)
├── crates/vite_command/ # Shared command execution helpers
├── crates/vite_error/ # Shared error types
├── crates/vite_global_cli/ # Standalone global vp binary and top-level command routing
Expand Down Expand Up @@ -62,9 +60,9 @@ vite-plus/
- **Bundled toolchain surfaces**: start with `packages/core/BUNDLING.md` and `packages/cli/BUNDLING.md`.
- **Generated project agent guidance**: `packages/cli/AGENTS.md` and `packages/cli/src/utils/agent.ts`; do not edit these when the task is only to improve root repo guidance.
- **Product/repo docs**: root contributor docs live at the repo root and the VitePress site under `docs/` (`docs/guide/`, `docs/config/`); generated agent guidance is separate.
- **CLI output behavior**: inspect the relevant code plus `crates/vite_cli_snapshots/tests/cli_snapshots/` (PTY snapshot suite; write new cases here). Legacy `packages/cli/snap-tests/` and `packages/cli/snap-tests-global/` are migration-only.
- **CLI output behavior**: inspect the relevant code plus `crates/vite_cli_snapshots/tests/cli_snapshots/` (PTY snapshot suite; write new cases here).
- **Interactive CLI testing (prompts, pickers, keystrokes)**: `crates/vite_cli_snapshots/tests/cli_snapshots/README.md` and `rfcs/interactive-snapshot-tests.md`.
- **Install-testing against the local build**: `packages/tools/src/local-npm-registry.ts` serves the packed checkout behind a real registry interface; used by install snap fixtures (`localVitePlusPackages`), ecosystem e2e (`ecosystem-ci/patch-project.ts`), and local `vp migrate`/`vp create` iteration (see `CONTRIBUTING.md`).
- **Install-testing against the local build**: `packages/tools/src/local-npm-registry.ts` serves the packed checkout behind a real registry interface; used by PTY snapshot fixtures, ecosystem e2e (`ecosystem-ci/patch-project.ts`), and local `vp migrate`/`vp create` iteration (see `CONTRIBUTING.md`).

## Command and Config Model

Expand Down Expand Up @@ -142,18 +140,6 @@ UPDATE_SNAPSHOTS=1 just snapshot-test <name-filter> # record/accept snapshots

Snapshot mismatches fail the run with a unified diff and write `<case>.md.new`; recorded `.md` snapshots are reviewed like code and committed with the fixture. Steps are argv arrays (no shell); use `vpt` subcommands instead of coreutils so cases stay platform-identical. Cases declare `vp = "local" | "global" | ["local", "global"]`; local-flavor cases require a fresh `packages/cli/dist`.

### Snap tests (legacy, being migrated)

The old trees `packages/cli/snap-tests/` and `packages/cli/snap-tests-global/` still run in CI during the migration but must not receive new cases; convert them with `node packages/tools/src/bin.js migrate-snap-tests ...` instead (see the runner README).

```bash
pnpm -F vite-plus snap-test
pnpm -F vite-plus snap-test-local <name-filter>
pnpm -F vite-plus snap-test-global <name-filter>
```

Legacy snap tests regenerate `snap.txt` and can exit successfully even when output changed. Always inspect `git diff` afterward. Ensure fixture inputs are committed or created by the test setup, not accidentally supplied by ignored local files.

## Code Conventions

### Rust
Expand All @@ -178,22 +164,21 @@ Reference these files instead of duplicating rules here:

## Testing Strategy

Use the validation matrix above as the source of truth. For behavior-bearing changes, find the nearest existing tests before editing and add or update coverage in the same area. For CLI output changes, pair focused tests with snap-test diff review. For documentation-only changes, verify referenced paths, commands, and links instead of running unrelated suites.
Use the validation matrix above as the source of truth. For behavior-bearing changes, find the nearest existing tests before editing and add or update coverage in the same area. For CLI output changes, pair focused tests with PTY snapshot diff review. For documentation-only changes, verify referenced paths, commands, and links instead of running unrelated suites.

## Common Pitfalls

- **Treating Vite+ as only Vite Task**: Vite Task is integrated, but this repo spans CLI, runtime, package management, bundled packages, create/migrate, docs, and upstream integration.
- **Looking for local `packages/test` or `crates/vite_task`**: neither is tracked here. Check `packages/cli/BUNDLING.md` for test shims and `Cargo.toml` for Vite Task git dependency wiring.
- **Confusing built-ins with scripts**: `vp test` and `vp run test` can do different things.
- **Trusting snap-test exit status alone**: always inspect snapshot diffs.

## Debugging

- Use `vp --version` to see bundled tool versions before researching tool behavior.
- Use `vp help` and `vp <command> --help` to inspect command surfaces.
- For command routing bugs, compare the global path (`crates/vite_global_cli/`) with the local/NAPI path (`packages/cli/src/bin.ts`, `packages/cli/binding/`).
- For config-loading bugs, compare the static extractor (`crates/vite_static_config/`) with the JS resolver fallback (`packages/cli/src/resolve-vite-config.ts`).
- For package-manager behavior, inspect `crates/vite_pm_cli/`, `crates/vite_install/`, and related snap tests.
- For package-manager behavior, inspect `crates/vite_pm_cli/`, `crates/vite_install/`, and related PTY snapshot cases.
- For `vp check`, lint, format, or type-check behavior, validate end-to-end because bundled-tool routing can hide silent config drift.

## AI Assistant Tips
Expand Down
23 changes: 2 additions & 21 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ vp upgrade --force

## Validate the local build against a real project

Unit and snap tests don't cover everything. Interactive flows in particular (prompts, pickers, scaffolding) are easiest to validate by running your work-in-progress CLI inside a real Vite+ project.
Automated tests don't cover everything. Complex flows such as prompts, pickers, and scaffolding are also worth validating by running your work-in-progress CLI inside a real Vite+ project.

First, understand how `vp` picks which `vite-plus` to run: for JS-backed commands (such as `vp create`), the global `vp` binary resolves `vite-plus` from the project's `node_modules` first and only falls back to the global installation in `~/.vite-plus`. If your test project has `vite-plus` installed from npm, `pnpm bootstrap-cli` alone will not make it run your local code.

Expand Down Expand Up @@ -118,7 +118,7 @@ pnpm local-registry --pack --serve
Notes:

- The served versions carry an old publish time, so `minimumReleaseAge` gates never quarantine them, and wrapped runs get throwaway Yarn Berry / bun caches (both cache registry state in ways that would otherwise leak stale local builds between runs).
- The same server backs the install snap fixtures (`localVitePlusPackages` in `steps.json`) and ecosystem e2e (`ecosystem-ci/patch-project.ts`), so a flow that works here works there too.
- The same server backs PTY snapshot cases with `local-registry = true` and ecosystem e2e (`ecosystem-ci/patch-project.ts`), so a flow that works here works there too.
- `pnpm local-registry:ps` lists any registry processes still running (e.g. a `--serve` you forgot, or a wrapper that was killed mid-run); `pnpm local-registry:kill` stops them all and removes their leftover temp caches.

### Global CLI (Rust) changes
Expand Down Expand Up @@ -155,25 +155,6 @@ UPDATE_SNAPSHOTS=1 just snapshot-test create

The full case/step/interaction reference (including the `vpt` helper tool and milestone conventions for interactive tests) lives in `crates/vite_cli_snapshots/tests/cli_snapshots/README.md`; the design rationale is in `rfcs/interactive-snapshot-tests.md`.

## Running Snap Tests (legacy)

The legacy snap trees in `packages/cli/snap-tests/` (local CLI) and `packages/cli/snap-tests-global/` (global CLI) still run in CI while they are migrated to the PTY runner (`tool migrate-snap-tests`). Do not add new cases to them.

```bash
# Run all snap tests (local + global)
pnpm -F vite-plus snap-test

# Run only local CLI snap tests
pnpm -F vite-plus snap-test-local
pnpm -F vite-plus snap-test-local <name-filter>

# Run only global CLI snap tests
pnpm -F vite-plus snap-test-global
pnpm -F vite-plus snap-test-global <name-filter>
```

Legacy snap tests auto-generate `snap.txt` files. Check `git diff` to verify output changes are correct.

## Verified Commits

All commits in PR branches should be GitHub-verified so reviewers can confirm commit authenticity.
Expand Down
2 changes: 1 addition & 1 deletion crates/vite_cli_snapshots/src/bin/vpt/chmod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/// chmod `<octal-mode>|+x` `<path>`
///
/// Sets POSIX permission bits; `+x` adds the execute bits to the current
/// mode (the common legacy-fixture form, `chmod +x hook.mjs`). Windows
/// mode (for example, `chmod +x hook.mjs`). Windows
/// treats it as a validated no-op: the mode and target are still checked,
/// so a typo or a failed earlier setup step fails on every platform.
pub fn run(args: &[String]) -> Result<(), Box<dyn std::error::Error>> {
Expand Down
2 changes: 1 addition & 1 deletion crates/vite_cli_snapshots/src/bin/vpt/json_edit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
///
/// Sets a (possibly nested) key in a JSON file. `value` is parsed as JSON;
/// if that fails it is treated as a plain string. Intermediate objects are
/// created as needed. Replaces the old snap-test `json-edit` helper.
/// created as needed.
pub fn run(args: &[String]) -> Result<(), Box<dyn std::error::Error>> {
let [file, dot_path, raw_value] = args else {
return Err("Usage: vpt json-edit <file> <dot-path> <value>".into());
Expand Down
4 changes: 2 additions & 2 deletions crates/vite_cli_snapshots/src/bin/vpt/list_dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ pub fn run(args: &[String]) -> Result<(), Box<dyn std::error::Error>> {
}
let dir = dir.ok_or("Usage: vpt list-dir <dir> [--ext <suffix>] [--recursive] [--all]")?;

// Like `ls <file>`, a file target prints its own name; legacy fixtures
// use that form as an existence assertion.
// Like `ls <file>`, a file target prints its own name so it can serve as
// an existence assertion.
let path = std::path::Path::new(dir);
if path.is_file() {
println!("{dir}");
Expand Down
Loading
Loading