Skip to content

docs(rfc): Vite+ Project Detection for Editor Extensions#1614

Draft
fengmk2 wants to merge 4 commits into
mainfrom
vp-detect
Draft

docs(rfc): Vite+ Project Detection for Editor Extensions#1614
fengmk2 wants to merge 4 commits into
mainfrom
vp-detect

Conversation

@fengmk2
Copy link
Copy Markdown
Member

@fengmk2 fengmk2 commented May 18, 2026

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 which vp executable to spawn for --lsp. This is the prerequisite identified in #1557 for removing the per-package bin/oxlint / bin/oxfmt wrappers.

Core rule

A workspace is Vite+ iff some walked-up package.json directly declares vite-plus in dependencies or devDependencies (bounded by the workspace root). The runnable vp binary is resolved separately, also bounded by the workspace root, and validated against a real vite-plus package (name === "vite-plus").

Detector returns a tri-state:

  • null — not Vite+; editor uses plain oxlint/oxfmt.
  • { root, vpPath } — Vite+ and runnable; editor launches vp 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 bare vp.

A transitively hoisted node_modules/vite-plus/, a global vp, a vp on \$PATH, and a configured oxc.<tool>.binPath all return null by construction.

Distribution

  • oxc-vscode and coc-oxc consume a shared bundled-devDependency npm package (proposed @voidzero-dev/detect-vite-plus) at packages/detect-vite-plus/.
  • oxc-zed (Rust/WASM) and oxc-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:

  • Final package name.
  • Caching policy in editor consumers.
  • "Declared but not installed" UX (silent fallback vs. install hint).
  • Workspace-root marker parity gap with vite-task (recognized as a known follow-up; deliberately not blocked on).

Refs #1557

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
@fengmk2 fengmk2 self-assigned this May 18, 2026
@netlify
Copy link
Copy Markdown

netlify Bot commented May 18, 2026

Deploy Preview for viteplus-preview canceled.

Name Link
🔨 Latest commit 8a66ee0
🔍 Latest deploy log https://app.netlify.com/projects/viteplus-preview/deploys/6a0a8d2e4ab3c8000875dc6d

fengmk2 added 3 commits May 18, 2026 11:02
… 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant