A monorepo task runner (like Nx/Turbo) with intelligent caching and dependency resolution, distributed as the vp run command in Vite+.
crates/vite_task— Task execution engine with caching and session managementcrates/vite_task_bin— Internal dev CLI binary (vt) and task synthesizercrates/vite_task_graph— Task dependency graph construction and config loadingcrates/vite_task_plan— Execution planning (resolves env vars, working dirs, commands)crates/vite_workspace— Workspace detection and package dependency graphcrates/fspy*— File system access tracing (9 crates: supervisor, preload libs, platform backends)crates/pty_terminal*— Cross-platform headless terminal emulator (3 crates)crates/vite_path— Type-safe absolute/relative path systemcrates/vite_str— Stack-allocated compact string typecrates/vite_glob— Glob pattern matchingcrates/vite_shell— Shell command parsingcrates/vite_select— Interactive fuzzy selection UIcrates/vite_tui— Terminal UI components (WIP, unfinished)crates/vite_graph_ser— Graph serialization utilitiescrates/subprocess_test— Subprocess testing frameworkpackages/tools— Node.js test utilities (print, json-edit, check-tty, etc.)docs/— Documentation (inputs configuration guide)
just init # Install build tools and dependencies
just ready # Full quality check (fmt, check, test, lint, doc)
just fmt # Format code (cargo fmt, cargo shear, vp fmt)
just check # Check compilation with all features
just test # Run all tests
just lint # Clippy linting
just lint-linux # Cross-clippy for Linux (requires cargo-zigbuild)
just lint-windows # Cross-clippy for Windows (requires cargo-xwin)
just doc # Documentation generationIf gt (Graphite CLI) is available in PATH, use it instead of gh to create pull requests.
PR titles must use Conventional Commits format: type(scope): summary (scope is optional), e.g. feat(cache): add LRU eviction, fix: handle symlink loops, test(e2e): add ctrl-c propagation test.
Commit messages for AI-assisted changes must always include a Co-authored-by: trailer that discloses the AI model and version used, e.g. Co-authored-by: GPT-5 Codex <codex@openai.com>.
PR descriptions must include a Motivation section. If the motivation is not clear from the request or surrounding context, ask the user before creating the PR. Do not add Validation, Test plan, or similar testing/verification sections.
cargo test # All tests
cargo test -p vite_task_bin --test e2e_snapshots # E2E snapshot tests
cargo test -p vite_task_plan --test plan_snapshots # Plan snapshot tests
cargo test --test e2e_snapshots -- stdin # Filter by test name
UPDATE_SNAPSHOTS=1 cargo test # Update snapshotsDefault cargo test runs only the tests that need nothing beyond the Rust toolchain. Tests that require Node.js or pnpm install are marked #[ignore] and can be exercised with cargo test -- --include-ignored (or --ignored to run only them) after running pnpm install at the workspace root (which, via pnpm workspaces, also installs packages/tools). You don't need pnpm install in test fixture directories.
The test suite has no known pre-existing failures or flaky tests. If a test fails during your changes, treat it as a real regression caused by your work. Fix the root cause properly — do not skip, ignore, or work around failing tests.
- Plan:
crates/vite_task_plan/tests/plan_snapshots/fixtures/— quicker, sufficient for testing task graph, resolved configs, program paths, cwd, and env vars - E2E:
crates/vite_task_bin/tests/e2e_snapshots/fixtures/— needed for testing execution, caching, output styling
CRITICAL: This project must work on both Unix (macOS/Linux) and Windows. Skipping tests on either platform is UNACCEPTABLE, except on musl targets when an essential dependency or required platform capability is unavailable. Document the unavailable requirement and keep the skip scoped to musl.
- Use
#[cfg(unix)]and#[cfg(windows)]for platform-specific code within tests - Both platforms must execute the test and verify the feature works correctly
- Use cross-platform libraries for common operations (e.g.,
terminal_sizefor terminal dimensions)
CLI (vite_task_bin) → Task Graph (vite_task_graph) → Plan (vite_task_plan) → Execution (vite_task)
↑ ↓
vite_workspace fspy (file tracing)
- Explicit: Defined via
dependsOninvite-task.json(skip with--ignore-depends-on) - Topological: Based on package.json dependencies
- With
-r/--recursive: runs task across all packages in dependency order - With
-t/--transitive: runs task in current package and its dependencies
- With
Tasks are defined in vite-task.json:
{
"cache": true | false | { "scripts": bool, "tasks": bool },
"tasks": {
"test": {
"command": "vitest run",
"cwd": "relative/path",
"dependsOn": ["build", "package#task"],
"cache": true,
"env": ["NODE_ENV"],
"untrackedEnv": ["CI"],
"input": ["src/**", "!dist/**", { "auto": true }, { "pattern": "tsconfig.json", "base": "workspace" }]
}
}
}This repo uses internal names that differ from the public-facing product. In code comments, docs, and user-facing strings, use the public names:
| Internal (this repo) | Public (Vite+) |
|---|---|
vt |
vp |
vite-task.json |
vite.config.* |
vite-task.json and vt are fine in implementation code, test fixtures, and CLAUDE.md itself — just not in doc comments or user-facing messages.
Enforced by .clippy.toml:
| Instead of | Use |
|---|---|
HashMap/HashSet |
FxHashMap/FxHashSet from rustc-hash |
std::path::Path/PathBuf |
vite_path::AbsolutePath/RelativePath |
std::format! |
vite_str::format! |
String (for small strings) |
vite_str::Str |
std::env::current_dir |
vite_path::current_dir |
.to_lowercase()/.to_uppercase() |
cow_utils methods |
- Use
AbsolutePathfor internal data flow; only convert toRelativePathwhen saving to cache - Use methods like
strip_prefix/joinfromvite_pathinstead of converting to std paths - Only convert to std paths when interfacing with std library functions
- Add necessary methods in
vite_pathinstead of falling back to std path types
All code must work on both Unix and Windows without platform skipping. The only exception is for tests on musl targets when an essential dependency or required platform capability is unavailable; document the reason and scope the skip to musl.
- Use
#[cfg(unix)]/#[cfg(windows)]for platform-specific implementations - Platform differences should be handled gracefully, not skipped
- After major changes to
fspy*or platform-specific crates, runjust lint-linuxandjust lint-windows
When a change is user-facing (new feature, changed behavior, bug fix, removal, or perf improvement), run /update-changelog to add an entry to CHANGELOG.md. Do not add entries for internal refactors, CI, dep bumps, test fixes, or docs changes.
- Task Format:
package#task(e.g.,app#build,@test/utils#lint) - Config File:
vite-task.jsonin each package - Rust Edition: 2024, MSRV 1.88.0