# AI Agent Guidelines for Vite-Plus

This document helps AI coding assistants work on the **vite-plus repository**. It is repo-specific: `CLAUDE.md` points here for compatibility, while `packages/cli/AGENTS.md` is the generated guidance shipped to projects that use Vite+.

Use this file to orient quickly, choose the right code area, and pick validation that matches the change. Prefer canonical source files and docs over duplicating details here.

## Project Overview

Vite+ is **the unified toolchain for the web** behind the `vp` CLI. It combines Vite, Rolldown, Vitest, tsdown, Oxlint, Oxfmt, Vite Task, runtime management, package-manager workflows, project creation/migration, and monorepo task caching.

### Key Technologies

- **TypeScript / Node ESM**: CLI entrypoints, create/migrate/config/staged commands, docs tooling, and package exports.
- **Rust 2024**: global `vp` binary, local CLI binding, package-manager/runtime helpers, config extraction, shared utilities.
- **NAPI**: bridges the TypeScript CLI package to Rust command implementations under `packages/cli/binding/`.
- **pnpm workspaces**: local packages under `packages/*`.
- **Vite+ config**: `vite.config.ts` configures lint, format, test, and run tasks for this repo.

## Architecture

High-signal repo map:

```
vite-plus/
├── 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
├── packages/core/             # @voidzero-dev/vite-plus-core bundled Vite/Rolldown/tsdown surfaces
├── packages/prompts/          # Prompt UI/helpers package, including snapshot milestones
├── packages/tools/            # Repo tooling and local npm registry
├── crates/vp_cli_snapshots/ # PTY snapshot test runner + vpt helper (CLI tests)
├── crates/vp_command/       # Shared command execution helpers
├── crates/vp_error/         # Shared error types
├── crates/vp_global_cli/    # Standalone global vp binary and top-level command routing
├── crates/vp_installer/     # Installer binary support
├── crates/vp_js_runtime/    # Managed Node.js runtime support
├── crates/vp_migration/     # Rust migration helpers
├── crates/vp_pm_cli/        # Package-manager detection, download, command resolution, and dispatch
├── crates/vp_setup/         # Setup helpers
├── crates/vp_shared/        # Shared Rust env config, tracing, output, utilities
├── crates/vp_static_config/ # Static extraction of vite.config.* data
└── crates/vp_trampoline/    # Windows shim trampoline
```

`packages/test` is no longer tracked. The public test API is `vite-plus/test*`, generated by `packages/cli/build.ts` as shims over upstream `vitest` and `@vitest/browser*` exports.

## Where to Start

- **JS-backed CLI behavior**: start at `packages/cli/src/bin.ts` and nearby `packages/cli/src/**` files.
- **Local CLI / NAPI-backed behavior**: start at `packages/cli/binding/src/lib.rs` and `packages/cli/binding/src/cli/mod.rs`.
- **Global `vp` routing, aliases, and runtime bootstrap**: start at `crates/vp_global_cli/src/main.rs` and `crates/vp_global_cli/src/cli.rs`.
- **Package-manager behavior**: start at `crates/vp_pm_cli/`.
- **Managed Node runtime / shims**: start at `crates/vp_js_runtime/`.
- **Static `vite.config.ts` extraction**: start at `crates/vp_static_config/README.md` and `packages/cli/src/resolve-vite-config.ts`.
- **Migration behavior**: `docs/guide/migrate-rules.md`.
- **Migrator code (`vp migrate`)**: category modules under `packages/cli/src/migration/migrator/` behind the `migrator.ts` barrel; follow `migrator/README.md` when changing migrator code.
- **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/vp_cli_snapshots/tests/cli_snapshots/` (PTY snapshot suite; write new cases here).
- **Interactive CLI testing (prompts, pickers, keystrokes)**: `crates/vp_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 PTY snapshot fixtures, ecosystem e2e (`ecosystem-ci/patch-project.ts`), and local `vp migrate`/`vp create` iteration (see `CONTRIBUTING.md`).

## Command and Config Model

`vp` has built-in toolchain commands and a separate task runner:

```bash
vp dev       # Vite dev server
vp build     # Vite + Rolldown build
vp test      # Bundled upstream Vitest
vp lint      # Oxlint
vp fmt       # Oxfmt
vp check     # Format/lint/type-check workflow
vp pack      # Library/app packaging

vp run build # Run a package.json script or configured run task
vpr build    # Shorthand for vp run build
```

Important distinctions:

- `vp test` is a built-in command that executes upstream Vitest. `vp run test` runs a `package.json` script or `vite.config.ts` run task named `test`.
- User-facing test imports should stay on `vite-plus/test*`; do not recreate `@voidzero-dev/vite-plus-test`.
- Existing `package.json` scripts are first-class `vp run <script>` targets and are not cached by default.
- Define `run.tasks` in `vite.config.ts` when a task needs explicit command config, default caching, dependencies, input tracking, or environment tracking.
- A task name can come from `package.json` or `vite.config.ts`, but not both.
- Do not introduce `vite-task.json`; current Vite+ task configuration lives under `run` in `vite.config.ts`.
- Do not run `cargo test -p vt` in this repo; Vite Task crates are git dependencies, not local workspace members.

Reference: `docs/guide/run.md` and `docs/config/run.md`.

## Development Workflow

### Initial setup

```bash
just init
```

### Build and install from source

```bash
just build          # Release build for Vite+
pnpm bootstrap-cli  # Build packages, compile vp/NAPI, and install the global CLI
vp --version
```

Use `pnpm bootstrap-cli` when you need to validate the installed global CLI at `~/.vite-plus`.

### Routine validation

Choose checks by change type:

| Change type                   | Useful validation                                                                           |
| ----------------------------- | ------------------------------------------------------------------------------------------- |
| Docs-only / agent-guide edits | Check referenced paths and commands; run `git diff --check -- <files>`                      |
| TypeScript or JS CLI behavior | `vp check`, `pnpm test:unit`, plus focused package tests when available                     |
| Rust CLI/crate behavior       | `just check`, `just test`, `just lint`                                                      |
| CLI output or command UX      | `just snapshot-test <filter>` (PTY runner); `UPDATE_SNAPSHOTS=1` to accept reviewed changes |
| Global CLI behavior           | `pnpm bootstrap-cli`, `vp --version`, or `just snapshot-test-global <filter>`               |
| Release/build behavior        | `just build`                                                                                |
| Pre-merge/full validation     | `pnpm bootstrap-cli && pnpm test && git status`                                             |

Use `vp check --fix` only when you intentionally want formatting or lint fixes applied.

### CLI snapshot tests (PTY runner)

**New CLI tests go here**, including all interactive-flow coverage. Fixtures live in `crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/`; each declares cases in `snapshots.toml` with a `vp = "local" | "global" | [both]` flavor. Read `crates/vp_cli_snapshots/tests/cli_snapshots/README.md` before writing a case (case/step/interaction schema, `vpt` helpers, milestone conventions); design rationale is in `rfcs/interactive-snapshot-tests.md`.

```bash
just snapshot-test                    # build vp, run everything
just snapshot-test <name-filter>
just snapshot-test-global <name-filter>  # skip local flavor when no JS build is available
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`.

### Submitting changes

Prioritize stacked pull requests: split multi-part work into a stack of small PRs so reviewers can approve and merge each layer on its own. Create stacks with the `gh-stack` CLI extension or on github.com. Stacks require all branches to be in this repository (GitHub does not support cross-fork stacks), so from a fork submit standalone PRs instead. See the "Submitting Pull Requests" section in `CONTRIBUTING.md`.

## Code Conventions

### Rust

Reference these files instead of duplicating rules here:

- `.clippy.toml` — custom lint restrictions and disallowed Rust APIs/macros.
- `crates/vp_shared/src/output.rs` — shared user-facing output helpers.
- `crates/vp_shared/src/env_config.rs` — test-scoped environment configuration helpers.
- `crates/vp_command/src/lib.rs` and `crates/vp_global_cli/src/cli.rs` — examples of `vt_path` usage in local Rust code.

Prefer shared output helpers for user-facing messages and match nearby command style. New Rust code should satisfy the custom clippy restrictions.

### TypeScript

Reference these files instead of duplicating rules here:

- `packages/cli/src/utils/terminal.ts` — shared user-facing terminal output helpers.
- `tsconfig.json` — TypeScript compiler settings.
- `vite.config.ts` — repository lint, format, test, and task configuration.
- `packages/cli/src/utils/agent.ts` and `packages/cli/AGENTS.md` — generated/migrated project agent guidance.

## 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 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/vt`**: 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.

## 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/vp_global_cli/`) with the local/NAPI path (`packages/cli/src/bin.ts`, `packages/cli/binding/`).
- For config-loading bugs, compare the static extractor (`crates/vp_static_config/`) with the JS resolver fallback (`packages/cli/src/resolve-vite-config.ts`).
- For package-manager behavior, inspect `crates/vp_pm_cli/` 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

- Identify the ownership layer before editing: JS CLI, Rust global CLI, NAPI/local CLI, package manager, runtime, config, docs, or bundled packages.
- Prefer source references over copied explanations when adding guidance; this file should help agents navigate, not replace the docs.
- Keep diffs scoped to the requested area and leave unrelated tracked or untracked files alone.

## References

- Product overview: `README.md`
- Contributor workflow: `CONTRIBUTING.md`
- Root scripts: `package.json`
- Repo config: `vite.config.ts`
- Vite+ guide: `docs/guide/index.md`
- Run guide: `docs/guide/run.md`
- Run config: `docs/config/run.md`
- CLI package architecture: `packages/cli/BUNDLING.md`
- Core package architecture: `packages/core/BUNDLING.md`
- CLI snapshot runner: `crates/vp_cli_snapshots/tests/cli_snapshots/README.md`
- Generated agent guidance: `packages/cli/AGENTS.md`, `packages/cli/src/utils/agent.ts`
