Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
c240ee1
feat(cli): global -C flag and workspace-root target elicitation for a…
fengmk2 Jul 3, 2026
acc492f
refactor(cli): dedupe interactivity gate and vite config probing, nor…
fengmk2 Jul 3, 2026
21e4577
refactor: memoized terminal checks behind a clippy rule, document -C …
fengmk2 Jul 3, 2026
509ae9c
rfc: global -C flag for working-directory switching
fengmk2 Jul 3, 2026
d361078
fix(snap): sort vite_shared exports, show raw error output in root fi…
fengmk2 Jul 3, 2026
b099a8f
docs(monorepo): document the workspace-root app-command experience
fengmk2 Jul 3, 2026
1aa74b9
test(snap): add -C to the vp --help snapshot
fengmk2 Jul 4, 2026
1945e8b
test(snap): reset dist between pack forms to avoid platform-dependent…
fengmk2 Jul 4, 2026
bab43e1
test(snapshot): PTY coverage for app-root resolution
fengmk2 Jul 5, 2026
29a3a53
feat(cli): interactive package picker for bare app commands at the wo…
fengmk2 Jul 5, 2026
8f17190
test(snapshot): migrate cwd-flag and app-root snap tests to the PTY h…
fengmk2 Jul 5, 2026
8c8a69b
fix(cli): document -C in the local CLI help
fengmk2 Jul 5, 2026
feeab0f
fix(cli): pack runnable ranking requires a pack block or the tsdown d…
fengmk2 Jul 5, 2026
413f0b8
rfc: cite upstream defaults behind the runnable heuristic
fengmk2 Jul 5, 2026
260f1b0
test(snapshot): vp pack auto-select via tsdown default entry
fengmk2 Jul 5, 2026
40776f0
test(snapshot): single-package repos bypass elicitation
fengmk2 Jul 5, 2026
b525d26
refactor(cli): apply cleanup review to app-target elicitation
fengmk2 Jul 5, 2026
2057bf3
test(snapshot): re-record for byte-size redaction
fengmk2 Jul 5, 2026
0a02a62
fix(cli): address Codex review round 1
fengmk2 Jul 5, 2026
0174d57
fix(cli): address Codex review round 2
fengmk2 Jul 5, 2026
495d3de
fix(cli): address Codex review round 3
fengmk2 Jul 5, 2026
e8f345f
fix(cli): address Codex review round 4
fengmk2 Jul 5, 2026
9c907d2
fix(cli): address Codex review round 5
fengmk2 Jul 5, 2026
d274176
fix(cli): address Codex review round 6
fengmk2 Jul 5, 2026
092f445
test(snapshot): pin the member defaultPackage regression on a real wo…
fengmk2 Jul 5, 2026
50504bc
fix(cli): address Codex review round 7
fengmk2 Jul 5, 2026
82ba730
fix(cli): restore parse_leading_chdir test import lost in a restack
fengmk2 Jul 5, 2026
da50c1e
fix(cli): address Codex review round 9
fengmk2 Jul 5, 2026
1bd520f
fix(cli): treat pack --root as an explicit target
fengmk2 Jul 6, 2026
2192209
fix(cli): gate picker milestones behind VP_EMIT_MILESTONES
fengmk2 Jul 6, 2026
c128244
fix(cli): make chdir the single -C validation point in bin.ts
fengmk2 Jul 6, 2026
f232b80
refactor(cli): apply cleanup review across the -C and elicitation code
fengmk2 Jul 6, 2026
30bc3f6
fix(cli): keep normalize_args doc off apply_chdir
fengmk2 Jul 6, 2026
2517bb8
fix(cli): a runnable workspace root runs in place, TTY or not
fengmk2 Jul 6, 2026
9a798e9
test(snapshot): pin the non-TTY runnable-root rule on tsdown output only
fengmk2 Jul 6, 2026
210a24c
test(snapshot): re-record runnable-root headers for the comment change
fengmk2 Jul 6, 2026
bda10f9
build: bump vite-task pin to the #510 head (ca55bb232aa8) after v0.2.…
fengmk2 Jul 7, 2026
d4007d5
perf(cli): reuse the workspace root across target resolution
fengmk2 Jul 8, 2026
ce07ac8
ci: bound the PTY snapshot step with a 10-min timeout
fengmk2 Jul 8, 2026
ed0e9be
test(snapshot): cover vpr -C and the dev/build positional (Vite root)
fengmk2 Jul 9, 2026
1b8fb6f
fix(cli): honor TS-wrapped defaultPackage and config-only root builds
fengmk2 Jul 9, 2026
40c59ca
fix(cli): refine defaultPackage/root-build/config-flag handling per r…
fengmk2 Jul 9, 2026
d879829
test(snapshots): PTY-render the two build cases for Windows stability
fengmk2 Jul 9, 2026
7ec2626
fix(cli): address Codex review round 6
fengmk2 Jul 9, 2026
87780db
style: rustfmt the round-6 defaultPackage extractor tests
fengmk2 Jul 9, 2026
b8a74cf
test(snapshots): remove the temporary PTY step trace
fengmk2 Jul 9, 2026
560eed5
fix(cli): hand-emit picker milestones after the vite-task cb580c2 rebase
fengmk2 Jul 10, 2026
c8dabbd
fix(cli): deliver PWD to -C children on the non-JS spawn paths
fengmk2 Jul 10, 2026
b1e4300
chore(snapshots): drop a stray .md.new runner artifact
fengmk2 Jul 10, 2026
0eba149
test(snapshots): skip the PWD env-exec case on Windows
fengmk2 Jul 10, 2026
1394e3e
refactor(cli): apply simplify-review cleanups across the -C code
fengmk2 Jul 10, 2026
6bacff0
refactor(cli): use cfg! branches for the unix-only PWD sync
fengmk2 Jul 10, 2026
b6da3c6
docs: tighten the -C RFC and monorepo guide prose
fengmk2 Jul 10, 2026
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
1 change: 1 addition & 0 deletions .clippy.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ disallowed-methods = [
{ path = "str::replace", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_replace` instead." },
{ path = "str::replacen", reason = "To avoid memory allocation, use `cow_utils::CowUtils::cow_replacen` instead." },
{ path = "std::env::current_dir", reason = "To get an `AbsolutePathBuf`, Use `vite_path::current_dir` instead." },
{ path = "std::io::IsTerminal::is_terminal", reason = "Use `vite_powershell::is_stdin_terminal` for stdin, or `vite_shared::is_stdout_terminal` / `vite_shared::is_stderr_terminal`, which memoize the lookup." },
Comment thread
fengmk2 marked this conversation as resolved.
Comment thread
fengmk2 marked this conversation as resolved.
]

disallowed-types = [
Expand Down
4 changes: 4 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 @@ -307,6 +307,7 @@ vite_shared = { path = "crates/vite_shared" }
vite_static_config = { path = "crates/vite_static_config" }
vite_path = { git = "https://github.com/voidzero-dev/vite-task.git", rev = "cb580c214bb2314fc1f633a3812782c9b3a1d956" }
vite_powershell = { git = "https://github.com/voidzero-dev/vite-task.git", rev = "cb580c214bb2314fc1f633a3812782c9b3a1d956" }
vite_select = { git = "https://github.com/voidzero-dev/vite-task.git", rev = "cb580c214bb2314fc1f633a3812782c9b3a1d956" }
vite_str = { git = "https://github.com/voidzero-dev/vite-task.git", rev = "cb580c214bb2314fc1f633a3812782c9b3a1d956" }
vite_task = { git = "https://github.com/voidzero-dev/vite-task.git", rev = "cb580c214bb2314fc1f633a3812782c9b3a1d956" }
vite_workspace = { git = "https://github.com/voidzero-dev/vite-task.git", rev = "cb580c214bb2314fc1f633a3812782c9b3a1d956" }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<!doctype html>
<html>
<body>
<h1>web</h1>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "name": "web", "private": true }
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "name": "app-root-auto-select", "private": true, "workspaces": ["apps/*", "packages/*"] }
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "name": "ui", "private": true, "type": "module", "main": "src/index.ts" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function hello(name: string): string {
return `hello ${name}`;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[[case]]
name = "auto_select"
vp = ["local", "global"]
comment = """
With exactly one likely-runnable package, a bare app command in an interactive
terminal auto-selects it, prints the Selected/Tip teaching lines, and runs
there (rfcs/cwd-flag.md). This TTY-only branch was untestable in the legacy
snap runner.
"""
steps = [["vp", "build"]]
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# auto_select

With exactly one likely-runnable package, a bare app command in an interactive
terminal auto-selects it, prints the Selected/Tip teaching lines, and runs
there (rfcs/cwd-flag.md). This TTY-only branch was untestable in the legacy
snap runner.

## `vp build`

```
VITE+ - The Unified Toolchain for the Web

Selected package: web (apps/web)
Tip: run this directly with `vp -C apps/web build`
vite <version> building client environment for production...
✓ 2 modules transformed.
computing gzip size...
dist/index.html <size> kB │ gzip: <size> kB

✓ built in <duration>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# auto_select

With exactly one likely-runnable package, a bare app command in an interactive
terminal auto-selects it, prints the Selected/Tip teaching lines, and runs
there (rfcs/cwd-flag.md). This TTY-only branch was untestable in the legacy
snap runner.

## `vp build`

```
Selected package: web (apps/web)
Tip: run this directly with `vp -C apps/web build`
vite <version> building client environment for production...
✓ 2 modules transformed.
computing gzip size...
dist/index.html <size> kB │ gzip: <size> kB

✓ built in <duration>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<!doctype html>
<html>
<body>
<h1>frontend</h1>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "name": "frontend", "private": true }
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "name": "dc-wrapper-config", "private": true }
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { defineConfig, type UserConfig } from 'vite-plus';

export default defineConfig({
defaultPackage: './frontend',
} satisfies UserConfig);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "name": "missing-default", "private": true }
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
defaultPackage: './packages/nope',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "name": "app-root-default-package", "private": true }
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "name": "ui", "private": true, "type": "module", "main": "src/index.ts" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function hello(name: string): string {
return `hello ${name}`;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
[[case]]
name = "default_package"
vp = ["local", "global"]
comment = """
defaultPackage in the root config acts as an implicit -C for bare app
commands, including at a root that is not a JS workspace; vp prints a note
line and runs in the configured directory (rfcs/cwd-flag.md).
"""
steps = [
["vp", "pack"],
{ argv = ["vpt", "list-dir", "packages/ui/dist"], comment = "output lands in the configured package" },
]

[[case]]
name = "default_package_missing"
vp = ["local", "global"]
comment = "defaultPackage pointing at a missing directory errors before any workspace lookup."
steps = [{ argv = ["vp", "build"], cwd = "missing" }]

[[case]]
name = "unanalyzable_config_ignored"
vp = ["local", "global"]
comment = """
Regression guard for spread/unanalyzable configs: a config that only parses
as an open map might hide defaultPackage behind the spread, but that must
not fail the command. Bare vp build falls through and runs in place.
"""
# PTY-rendered (not tty = false): non-TTY steps record raw bytes, and the
# raw Windows byte stream of a vite build differs invisibly from macOS; the
# grid rendering normalizes that and is what the assertion needs anyway.
steps = [{ argv = ["vp", "build"], cwd = "spread" }]

[[case]]
name = "default_package_ts_wrapper"
vp = ["local", "global"]
comment = """
Regression: defaultPackage declared through a TypeScript wrapper
(`satisfies UserConfig`, `as const`) is still a static string literal and
must be honored. vp builds ./frontend, not the wrapper root.
"""
steps = [{ argv = ["vp", "build"], cwd = "ts_wrapper" }]

[[case]]
name = "default_package_value_wrapper"
vp = ["local", "global"]
comment = """
Regression: the TypeScript wrapper is on the defaultPackage VALUE
(`'./frontend' as const`), not the config object. Static extraction must
unwrap it too, so vp builds ./frontend rather than erroring that
defaultPackage is not a static string literal.
"""
steps = [{ argv = ["vp", "build"], cwd = "value_wrapper" }]

[[case]]
name = "default_package_define_config_wrapper"
vp = ["local", "global"]
comment = """
defaultPackage inside `defineConfig({ ... } satisfies UserConfig)` is also
honored: the wrapper on the defineConfig argument is unwrapped too.
"""
steps = [{ argv = ["vp", "build"], cwd = "dc_wrapper" }]
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# default_package

defaultPackage in the root config acts as an implicit -C for bare app
commands, including at a root that is not a JS workspace; vp prints a note
line and runs in the configured directory (rfcs/cwd-flag.md).

## `vp pack`

```
VITE+ - The Unified Toolchain for the Web
note: vp pack: using ./packages/ui (defaultPackage)
ℹ entry: src/index.ts
ℹ Build start
ℹ dist/index.mjs <size> kB │ gzip: <size> kB
ℹ 1 files, total: <size> kB
✔ Build complete in <duration>
```

## `vpt list-dir packages/ui/dist`

output lands in the configured package

```
index.mjs
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# default_package

defaultPackage in the root config acts as an implicit -C for bare app
commands, including at a root that is not a JS workspace; vp prints a note
line and runs in the configured directory (rfcs/cwd-flag.md).

## `vp pack`

```
note: vp pack: using ./packages/ui (defaultPackage)
ℹ entry: src/index.ts
ℹ Build start
ℹ dist/index.mjs <size> kB │ gzip: <size> kB
ℹ 1 files, total: <size> kB
✔ Build complete in <duration>
```

## `vpt list-dir packages/ui/dist`

output lands in the configured package

```
index.mjs
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# default_package_define_config_wrapper

defaultPackage inside `defineConfig({ ... } satisfies UserConfig)` is also
honored: the wrapper on the defineConfig argument is unwrapped too.

## `cd dc_wrapper && vp build`

```
VITE+ - The Unified Toolchain for the Web

note: vp build: using ./frontend (defaultPackage)
vite <version> building client environment for production...
✓ 2 modules transformed.
computing gzip size...
dist/index.html <size> kB │ gzip: <size> kB

✓ built in <duration>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# default_package_define_config_wrapper

defaultPackage inside `defineConfig({ ... } satisfies UserConfig)` is also
honored: the wrapper on the defineConfig argument is unwrapped too.

## `cd dc_wrapper && vp build`

```
note: vp build: using ./frontend (defaultPackage)
vite <version> building client environment for production...
✓ 2 modules transformed.
computing gzip size...
dist/index.html <size> kB │ gzip: <size> kB

✓ built in <duration>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# default_package_missing

defaultPackage pointing at a missing directory errors before any workspace lookup.

## `cd missing && vp build`

**Exit code:** 1

```
VITE+ - The Unified Toolchain for the Web

error: defaultPackage points to a missing directory: ./packages/nope
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# default_package_missing

defaultPackage pointing at a missing directory errors before any workspace lookup.

## `cd missing && vp build`

**Exit code:** 1

```
error: defaultPackage points to a missing directory: ./packages/nope
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# default_package_ts_wrapper

Regression: defaultPackage declared through a TypeScript wrapper
(`satisfies UserConfig`, `as const`) is still a static string literal and
must be honored. vp builds ./frontend, not the wrapper root.

## `cd ts_wrapper && vp build`

```
VITE+ - The Unified Toolchain for the Web

note: vp build: using ./frontend (defaultPackage)
vite <version> building client environment for production...
✓ 2 modules transformed.
computing gzip size...
dist/index.html <size> kB │ gzip: <size> kB

✓ built in <duration>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# default_package_ts_wrapper

Regression: defaultPackage declared through a TypeScript wrapper
(`satisfies UserConfig`, `as const`) is still a static string literal and
must be honored. vp builds ./frontend, not the wrapper root.

## `cd ts_wrapper && vp build`

```
note: vp build: using ./frontend (defaultPackage)
vite <version> building client environment for production...
✓ 2 modules transformed.
computing gzip size...
dist/index.html <size> kB │ gzip: <size> kB

✓ built in <duration>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# default_package_value_wrapper

Regression: the TypeScript wrapper is on the defaultPackage VALUE
(`'./frontend' as const`), not the config object. Static extraction must
unwrap it too, so vp builds ./frontend rather than erroring that
defaultPackage is not a static string literal.

## `cd value_wrapper && vp build`

```
VITE+ - The Unified Toolchain for the Web

note: vp build: using ./frontend (defaultPackage)
vite <version> building client environment for production...
✓ 2 modules transformed.
computing gzip size...
dist/index.html <size> kB │ gzip: <size> kB

✓ built in <duration>
```
Loading
Loading