Skip to content

feat(cli): note when a built-in shares a name with a package.json script - #2259

Merged
wan9chi merged 2 commits into
mainfrom
opencode/witty-eagle
Jul 30, 2026
Merged

feat(cli): note when a built-in shares a name with a package.json script#2259
wan9chi merged 2 commits into
mainfrom
opencode/witty-eagle

Conversation

@wan9chi

@wan9chi wan9chi commented Jul 26, 2026

Copy link
Copy Markdown
Member

Motivation

Built-in commands cannot be overridden, so vp dev runs the Vite+ dev server
even in a project whose dev script does something else entirely (a framework
wrapper, extra flags, a custom runner). Users regularly reach for the built-in
when they meant the script — see #2243.

Stacked on #2265 (notes go to stderr) and #2262 (the raw subcommand reaches
this CLI).

What this does

When the user writes vp <name> and <name> is both a built-in and a
package.json script:

note: You are running `vp dev` as a Vite+ built-in command. If you meant to run the dev npm script, use `vpr dev` instead.

The trigger is the name as written. It comes from VP_RAW_SUBCOMMAND when the
global CLI provides it, since that is the only accurate source once a command
has been resolved to its canonical name — vp format names the format
script, not fmt. Otherwise it comes from the command line, where a rewrite is
rejected: vp help fmt runs as fmt --help, and writing help is not writing
the built-in.

The only suppression is VP_RUN, set by the task runner
(voidzero-dev/vite-task#570), since the user is then already on the vpr path.
There is no TTY check: the note goes to stderr, so an agent capturing piped
output still sees it while parsed stdout — oxlint -f json, vitest --reporter=json, oxfmt --stdin-filepath — stays intact.

Script lookup walks up to the nearest package.json, the package vp run
itself resolves a task from, so the note also applies from a subdirectory and
deliberately stops there rather than climbing to a package vpr could not
reach.

Only the built-ins are covered. run/cache are the script path itself,
install and friends legitimately trigger a project's install lifecycle
scripts through the package manager, and exec names a binary rather than a
task.

vp_build_cache and vp_build_cache_monorepo are re-recorded: both define
"build": "vp build" and run vp build directly, so they now show the note.

Refs #2243

@netlify

netlify Bot commented Jul 26, 2026

Copy link
Copy Markdown

Deploy Preview for viteplus-preview canceled.

Name Link
🔨 Latest commit 144213a
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/6a661710074b920008887d1d

@wan9chi
wan9chi force-pushed the opencode/witty-eagle branch from 4bc275b to 65090f1 Compare July 26, 2026 14:09
@wan9chi wan9chi changed the title feat(cli): note when a built-in shadows a package.json script feat(cli): note when a built-in shares a name with a package.json script Jul 26, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4bc275b399

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/cli/binding/src/cli/script_shadow.rs Outdated
Comment thread packages/cli/binding/src/cli/script_shadow.rs Outdated
@wan9chi
wan9chi marked this pull request as draft July 26, 2026 14:12
@github-actions

github-actions Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Native binary sizes (6d4c28c)

Final release artifacts built by the canonical build-upstream and build-windows-cli actions.

Artifact Format Base PR Change
vp (Linux x64) Binary 10.31 MiB 10.31 MiB 0 B (0.00%)
vp (Linux x64) gzip -9 4.42 MiB 4.42 MiB -56 B (-0.00%)
NAPI (Linux x64) Binary 33.07 MiB 33.08 MiB +12.00 KiB (+0.04%)
NAPI (Linux x64) gzip -9 12.72 MiB 12.72 MiB +262 B (+0.00%)
vp (macOS ARM64) Binary 7.64 MiB 7.64 MiB 0 B (0.00%)
vp (macOS ARM64) gzip -9 3.84 MiB 3.84 MiB +244 B (+0.01%)
NAPI (macOS ARM64) Binary 40.50 MiB 40.50 MiB 0 B (0.00%)
NAPI (macOS ARM64) gzip -9 16.97 MiB 16.97 MiB +1.11 KiB (+0.01%)
vp (Windows x64) Binary 8.35 MiB 8.35 MiB 0 B (0.00%)
vp (Windows x64) gzip -9 3.64 MiB 3.63 MiB -1.18 KiB (-0.03%)
NAPI (Windows x64) Binary 27.51 MiB 27.51 MiB +7.00 KiB (+0.02%)
NAPI (Windows x64) gzip -9 10.70 MiB 10.70 MiB +1.49 KiB (+0.01%)
Trampoline (Windows x64) Binary 203.00 KiB 203.00 KiB 0 B (0.00%)
Trampoline (Windows x64) gzip -9 97.91 KiB 97.91 KiB -1 B (-0.00%)
Installer (Windows x64) Binary 4.44 MiB 4.44 MiB 0 B (0.00%)
Installer (Windows x64) gzip -9 2.08 MiB 2.08 MiB -204 B (-0.01%)

@wan9chi
wan9chi changed the base branch from main to graphite-base/2259 July 27, 2026 03:55
@wan9chi
wan9chi force-pushed the opencode/witty-eagle branch from 144213a to b9ca7ab Compare July 27, 2026 03:55
@wan9chi
wan9chi changed the base branch from graphite-base/2259 to feat/global-forward-subcommand July 27, 2026 03:55
@wan9chi
wan9chi marked this pull request as ready for review July 27, 2026 03:55

wan9chi commented Jul 27, 2026

Copy link
Copy Markdown
Member Author

How to use the Graphite Merge Queue

Add the label auto-merge to this PR to add it to the merge queue.

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@wan9chi
wan9chi force-pushed the opencode/witty-eagle branch 2 times, most recently from cebd5be to 9cb494b Compare July 27, 2026 05:31
@wan9chi
wan9chi force-pushed the feat/global-forward-subcommand branch from 42a80af to de5c091 Compare July 27, 2026 10:40
@wan9chi
wan9chi force-pushed the opencode/witty-eagle branch from 9cb494b to c0e1bba Compare July 27, 2026 10:40
@wan9chi
wan9chi force-pushed the feat/global-forward-subcommand branch from de5c091 to dd3ac6c Compare July 27, 2026 11:35
@wan9chi
wan9chi force-pushed the opencode/witty-eagle branch from c0e1bba to d2278b2 Compare July 27, 2026 11:35
@wan9chi
wan9chi force-pushed the feat/global-forward-subcommand branch from dd3ac6c to 2c4e38a Compare July 27, 2026 11:55
@wan9chi
wan9chi force-pushed the opencode/witty-eagle branch 2 times, most recently from 2666b38 to 92e4e48 Compare July 27, 2026 12:03
@wan9chi
wan9chi force-pushed the feat/global-forward-subcommand branch from 2c4e38a to 4aa3c6c Compare July 27, 2026 12:03
@wan9chi
wan9chi force-pushed the opencode/witty-eagle branch from 92e4e48 to dcea48e Compare July 27, 2026 12:10
@wan9chi
wan9chi force-pushed the feat/global-forward-subcommand branch from 4aa3c6c to 311383d Compare July 27, 2026 12:10
@wan9chi
wan9chi force-pushed the opencode/witty-eagle branch from dcea48e to 496c873 Compare July 27, 2026 12:35
@wan9chi
wan9chi force-pushed the feat/global-forward-subcommand branch from 311383d to 363be77 Compare July 27, 2026 12:35
@fengmk2 fengmk2 self-assigned this Jul 30, 2026
@fengmk2 fengmk2 added the test: e2e Auto run e2e tests label Jul 30, 2026
@fengmk2 fengmk2 added the test: create-e2e Run `vp create` e2e tests label Jul 30, 2026
@wan9chi
wan9chi force-pushed the opencode/witty-eagle branch from 496c873 to 7b18e90 Compare July 30, 2026 10:31
@wan9chi
wan9chi force-pushed the feat/global-forward-subcommand branch from 363be77 to 672e256 Compare July 30, 2026 10:31
@wan9chi
wan9chi force-pushed the opencode/witty-eagle branch 4 times, most recently from 9698ba8 to aeced44 Compare July 30, 2026 11:49
@wan9chi
wan9chi force-pushed the feat/global-forward-subcommand branch from 672e256 to 2b7dd18 Compare July 30, 2026 11:49
@graphite-app

graphite-app Bot commented Jul 30, 2026

Copy link
Copy Markdown

Merge activity

wan9chi added 2 commits July 30, 2026 12:45
## Motivation

The local CLI runs a command under its canonical name, so it sees `fmt` whether
the user wrote `vp fmt` or `vp format`. The spelling is gone by the time it
arrives, and nothing downstream can recover it from argv.

#2259, above this in the stack, needs it: a note that says "use `vpr fmt`" when
the user wrote `vp format` is pointing at the wrong script.

## What this does

The subcommand is read from argv before `normalize_args` can rewrite it, and
travels to the local CLI as `VP_RAW_SUBCOMMAND`.

It is passed *alongside* the command rather than in place of it: the command
name stays canonical, because that string becomes the local CLI's `argv[0]` and
has to name the command this process resolved. `vp help fmt` is the case where
the two differ — the user wrote `help`, but the local CLI must still run
`fmt --help`, since being handed `help --help` would print vp's top-level help
instead of the formatter's.

Nothing reads `VP_RAW_SUBCOMMAND` in this PR.

`vite_plugins_skip_on_format` now runs both flavors, so the global one covers
forwarding the alias.
…ipt (#2259)

## Motivation

Built-in commands cannot be overridden, so `vp dev` runs the Vite+ dev server
even in a project whose `dev` script does something else entirely (a framework
wrapper, extra flags, a custom runner). Users regularly reach for the built-in
when they meant the script — see #2243.

Stacked on #2265 (notes go to stderr) and #2262 (the raw subcommand reaches
this CLI).

## What this does

When the user writes `vp <name>` and `<name>` is both a built-in and a
`package.json` script:

```
note: You are running `vp dev` as a Vite+ built-in command. If you meant to run the dev npm script, use `vpr dev` instead.
```

The trigger is the name as written. It comes from `VP_RAW_SUBCOMMAND` when the
global CLI provides it, since that is the only accurate source once a command
has been resolved to its canonical name — `vp format` names the `format`
script, not `fmt`. Otherwise it comes from the command line, where a rewrite is
rejected: `vp help fmt` runs as `fmt --help`, and writing `help` is not writing
the built-in.

The only suppression is `VP_RUN`, set by the task runner
(voidzero-dev/vite-task#570), since the user is then already on the `vpr` path.
There is no TTY check: the note goes to stderr, so an agent capturing piped
output still sees it while parsed stdout — `oxlint -f json`, `vitest
--reporter=json`, `oxfmt --stdin-filepath` — stays intact.

Script lookup walks up to the nearest `package.json`, the package `vp run`
itself resolves a task from, so the note also applies from a subdirectory and
deliberately stops there rather than climbing to a package `vpr` could not
reach.

Only the built-ins are covered. `run`/`cache` are the script path itself,
`install` and friends legitimately trigger a project's `install` lifecycle
scripts through the package manager, and `exec` names a binary rather than a
task.

`vp_build_cache` and `vp_build_cache_monorepo` are re-recorded: both define
`"build": "vp build"` and run `vp build` directly, so they now show the note.

Refs #2243
graphite-app Bot pushed a commit that referenced this pull request Jul 30, 2026
## Motivation

- #2259, at the top of this stack, adds a note that has to reach an AI agent capturing piped output while leaving machine-readable stdout alone (`oxlint -f json`, `vitest --reporter=json` and `oxfmt --stdin-filepath` all put
their payload on stdout). Gating that note on a TTY would hide it from some ai agents; printing it to stdout would corrupt those payloads. Moving `note` to stderr resolves both.

- This is also what `rfcs/cli-output-polish.md` specified for `note` in both Rust
and TypeScript — the implementation incorrectly used `println!`.

## CI stability

The delegation test now pins its temporary project to Node.js 22.13.1. The unofficial musl index can advertise a newer LTS before the matching archive exists, which made this otherwise unrelated test fail with `HashNotFound`. Runtime behavior is unchanged.
@graphite-app
graphite-app Bot force-pushed the feat/global-forward-subcommand branch from 2b7dd18 to 41cc9dd Compare July 30, 2026 12:46
@graphite-app
graphite-app Bot force-pushed the opencode/witty-eagle branch from aeced44 to 6d4c28c Compare July 30, 2026 12:46
wan9chi added a commit that referenced this pull request Jul 30, 2026
## Motivation

The local CLI runs a command under its canonical name, so it sees `fmt`
whether
the user wrote `vp fmt` or `vp format`. The spelling is gone by the time
it
arrives, and nothing downstream can recover it from argv.

#2259, above this in the stack, needs it: a note that says "use `vpr
fmt`" when
the user wrote `vp format` is pointing at the wrong script.

## What this does

The subcommand is read from argv before `normalize_args` can rewrite it,
and
travels to the local CLI as `VP_RAW_SUBCOMMAND`.

It is passed *alongside* the command rather than in place of it: the
command
name stays canonical, because that string becomes the local CLI's
`argv[0]` and
has to name the command this process resolved. `vp help fmt` is the case
where
the two differ — the user wrote `help`, but the local CLI must still run
`fmt --help`, since being handed `help --help` would print vp's
top-level help
instead of the formatter's.

Nothing reads `VP_RAW_SUBCOMMAND` in this PR.

`vite_plugins_skip_on_format` now runs both flavors, so the global one
covers
forwarding the alias.
Base automatically changed from feat/global-forward-subcommand to main July 30, 2026 13:19
@wan9chi
wan9chi merged commit fb1c82b into main Jul 30, 2026
99 checks passed
@wan9chi
wan9chi deleted the opencode/witty-eagle branch July 30, 2026 13:20
wan9chi added a commit that referenced this pull request Jul 31, 2026
Release vite-plus v0.2.7: Clearer commands and smoother setup.

This release makes built-in and package-script collisions easier to
navigate, adds concurrency control to `vp pack`, and smooths migrations
and package-manager setup.

### Highlights

- Guide users to `vpr <name>` when a built-in shares a name with a
`package.json` script, preserve the exact command alias they typed, and
avoid duplicate notes from task-spawned tools
([#2262](#2262),
[#2259](#2259),
[vite-task#570](voidzero-dev/vite-task#570)), by
@wan9chi
- Add `--concurrency` to `vp pack` to limit parallel Rolldown builds,
and update tsdown `0.22.13` -> `0.22.14` and Vite DevTools `0.4.2` ->
`0.4.5` ([#2233](#2233)),
by @voidzero-guard[bot]
- Add read-only Svelte rune globals to migrated Oxlint overrides,
preventing false `no-undef` errors
([#2192](#2192)), by
@naokihaba
- Install package managers from npm tarballs with nonstandard top-level
directories, fixing Yarn 1.22.19 installation
([#2264](#2264)), by
@TheAlexLichter

### Fixes & Enhancements

- Preserve machine-readable command output by sending informational CLI
notes to stderr
([#2265](#2265)), by
@wan9chi
- Prevent the Oxc language server from crashing when contributors open
the Vite+ workspace in VS Code
([#2245](#2245)), by
@jong-kyung

### Docs

- Document the full procedure for removing Vite+ commit hooks
([#2218](#2218)), by
@TheAlexLichter
- Document per-process and per-machine ways to disable Vite+ commit
hooks without uninstalling them
([#2230](#2230)), by
@TheAlexLichter
- Clarify when to use built-in `vp` commands versus package scripts
through `vp run` or `vpr`, including migration and agent guidance
([#2255](#2255)), by
@wan9chi
- Document GitLab CI/CD setup with the reusable `setup-vp` template
([#2258](#2258)), by
@naokihaba

### Chore

- Run Semgrep security scans on pull requests and pushes to `main`
([#2223](#2223)), by
@Boshen
- Re-enable Vitest browser-mode CLI snapshot coverage on every supported
platform ([#2275](#2275)),
by @wan9chi
- Stabilize Windows CLI snapshot tests for interrupted installs and
browser port fallback
([#2282](#2282)), by
@wan9chi
- Replace deprecated shared JavaScript and TypeScript VS Code settings
with their current `js/ts.*` names
([#2246](#2246)), by
@jong-kyung

### Bundled Versions

| Tool | Version | Source |
| --------------- | ---------- |
-----------------------------------------------------------------------
|
| vite | `8.1.5` |
[`5e7fe12`](vitejs/vite@5e7fe12)
|
| rolldown | `1.2.0` |
[`03e1e34`](rolldown/rolldown@03e1e34)
|
| tsdown | `0.22.14` | [npm](https://npmx.dev/package/tsdown/v/0.22.14)
|
| vitest | `4.1.10` | [npm](https://npmx.dev/package/vitest/v/4.1.10) |
| oxlint | `1.75.0` | [npm](https://npmx.dev/package/oxlint/v/1.75.0) |
| oxlint-tsgolint | `7.0.2001` |
[npm](https://npmx.dev/package/oxlint-tsgolint/v/7.0.2001) |
| oxfmt | `0.60.0` | [npm](https://npmx.dev/package/oxfmt/v/0.60.0) |

### Upgrade

```bash
vp upgrade
```

**Full Changelog**:
v0.2.6...v0.2.7

---

Merging this PR will trigger the release workflow.

---------

Co-authored-by: voidzero-guard[bot] <278573678+voidzero-guard[bot]@users.noreply.github.com>
Co-authored-by: wan9chi <dk4rest@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

test: create-e2e Run `vp create` e2e tests test: e2e Auto run e2e tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants