Conversation
Defines a portable rule the four oxc editor extensions
(oxc-vscode, oxc-zed, oxc-intellij-plugin, coc-oxc) use to decide
whether to launch `vp lint --lsp` / `vp fmt --lsp` instead of plain
oxlint / oxfmt, and to resolve which executable to spawn.
Core algorithm (two phases, both bounded by the workspace root):
1. Phase 1 — find the package.json that DIRECTLY declares vite-plus
in dependencies or devDependencies. A transitively hoisted
`node_modules/vite-plus/` does not count.
2. Phase 2 — walk up from the declaring ancestor looking for a real
`node_modules/vite-plus/bin/vp` with a sibling `package.json` that
parses and has `name === "vite-plus"`.
Result is a tri-state: `null` (not Vite+), `{ root, vpPath }`
(Vite+ and runnable), or `{ root }` (declared but not yet installed —
editors fall back to plain oxlint/oxfmt and never launch a bare vp).
Distribution: for the Node-capable extensions (oxc-vscode, coc-oxc)
the detector ships as a shared bundled-devDependency package
(@voidzero-dev/detect-vite-plus, name TBD) at
`packages/detect-vite-plus/`. oxc-zed (Rust) and
oxc-intellij-plugin (Kotlin) port the same algorithm against the
shared conformance fixtures.
The RFC also documents:
- The four extensions' existing bin-resolution chains with code
excerpts and file:line citations.
- A Mermaid flowchart of the two-phase algorithm for cross-language
porters.
- The workspace-root marker set (`pnpm-workspace.yaml`,
`package.json#workspaces`, `lerna.json`) and a known parity gap
with vite-task that this RFC does not block on.
- Per-extension migration plans and a conformance fixture table that
pins down behaviour across every implementation.
Refs #1557
✅ Deploy Preview for viteplus-preview canceled.
|
… isn't .vp-root was a fabricated example. Replace with .vite-hooks, which is the real vite-plus hooks directory (packages/cli/src/config/hooks.ts:67) and a more useful illustration of "incidental vite-plus artifact that must not stop the walk-up." Refs #1557
The detector now reads node_modules/vite-plus/package.json#version alongside name validation and returns it in DetectResult as vpVersion. Editors compare against MIN_VP_VERSION_FOR_LSP (a constant exported by the shared detector package, filled in when #1557's wrapper removal lands) to choose between launching `vp lint --lsp` and falling through to the legacy bin/oxlint wrapper chain shipped by older vite-plus versions. Three benefits: - Smooth rollout: workspaces pinned to older vite-plus keep working via the existing wrapper, no breakage on upgrade of the editor extension alone. - Upgrade hint: editors can surface "upgrade vite-plus to enable native LSP" when the installed version is too old. - Forward compatibility: future LSP-only features can raise the threshold by bumping the detector package, not by changing every consumer. Changes: - DetectResult gains optional vpVersion (set whenever vpPath is set). - resolveVpAt() rejects installs whose package.json has no string version, treating them as orphan. - Public API adds MIN_VP_VERSION_FOR_LSP constant and supportsLsp() helper for both consumers to use. - Per-extension migration plan gains a fourth branch for the "installed but version too old" case. - New conformance fixtures: installed-but-version-too-old, installed-no-version-field. - New open question: the concrete value of MIN_VP_VERSION_FOR_LSP (TBD until #1557 ships).
826 lines → 302 lines. Reviewer flagged repetition and pushed back on the version-gating mechanism. Changes: - Drop MIN_VP_VERSION_FOR_LSP / supportsLsp / vpVersion entirely. Editors just attempt `vp lint --lsp`; if it fails on an old vp, the editor surfaces an upgrade hint at that point. - Change "declared but not installed" UX: surface an install hint instead of silently falling back to plain oxlint. The reviewer is right that plain oxlint without VP_VERSION isn't Vite+-aware anyway, so silent fallback misleads more than it helps. - Heavy trim of repetition: drop "Insight", drop the long bin-resolution code excerpts (kept brief file:line refs), fold "Why this rule" into the rule section, collapse the Decisions section, drop "Downstream coordination" (overlapped with the migration plan), drop the "Verification plan" subheading. - Move "publish as a shared npm package?" from a locked Decision to an Open Question — the reviewer asked us to make the call; making it visibly open instead of locked invites the reviewer to weigh in. - Shrink the conformance fixture table: drop entries that document non-features (global-vp-on-path, user-binpath-override) now that the rule plainly says we don't check $PATH or user settings, and drop the version-related fixtures.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Draft RFC defining how the four oxc editor extensions —
oxc-vscode,oxc-zed,oxc-intellij-plugin,coc-oxc— determine whether a workspace is a Vite+ project and whichvpexecutable to spawn for--lsp. This is the prerequisite identified in #1557 for removing the per-packagebin/oxlint/bin/oxfmtwrappers.Core rule
A workspace is Vite+ iff some walked-up
package.jsondirectly declaresvite-plusindependenciesordevDependencies(bounded by the workspace root). The runnablevpbinary is resolved separately, also bounded by the workspace root, and validated against a realvite-pluspackage (name === "vite-plus").Detector returns a tri-state:
null— not Vite+; editor uses plain oxlint/oxfmt.{ root, vpPath }— Vite+ and runnable; editor launchesvp lint --lsp/vp fmt --lsp.{ root }— declared but not yet installed (fresh clone, Berry PnP, broken install); editor falls back to plain oxlint/oxfmt and never spawns a barevp.A transitively hoisted
node_modules/vite-plus/, a globalvp, avpon\$PATH, and a configuredoxc.<tool>.binPathall returnnullby construction.Distribution
oxc-vscodeandcoc-oxcconsume a shared bundled-devDependency npm package (proposed@voidzero-dev/detect-vite-plus) atpackages/detect-vite-plus/.oxc-zed(Rust/WASM) andoxc-intellij-plugin(Kotlin) port the same algorithm against the shared conformance fixtures inside this RFC.Status
Draft for discussion. Open points called out in the RFC:
vite-task(recognized as a known follow-up; deliberately not blocked on).Refs #1557