Skip to content

refactor: replace @voidzero-dev/vite-plus-test with upstream vitest#1588

Open
Brooooooklyn wants to merge 136 commits into
mainfrom
refactor/replace-vite-plus-test-with-vitest
Open

refactor: replace @voidzero-dev/vite-plus-test with upstream vitest#1588
Brooooooklyn wants to merge 136 commits into
mainfrom
refactor/replace-vite-plus-test-with-vitest

Conversation

@Brooooooklyn

@Brooooooklyn Brooooooklyn commented May 15, 2026

Copy link
Copy Markdown
Member

Summary

Deletes the bundled @voidzero-dev/vite-plus-test wrapper and consumes upstream vitest@4.1.5 (plus @vitest/browser*) directly. The vite redirection role that drove the wrapper is now handled cleanly by package-manager overrides (vite@voidzero-dev/vite-plus-core), so the bundle was dead weight that lagged upstream releases.

Public API contract preserved:

  • vite-plus/test* IS the public test API — existing user code (import { vi } from 'vite-plus/test', etc.) is NEVER rewritten.
  • New vite-plus users don't install vitest or @vitest/* separately; they come in transitively as direct deps of vite-plus.
  • vp migrate on an upstream-vitest project still forward-migrates vitest, vitest/*, @vitest/browser*, declare-module specifiers, and /// <reference types> directives to the vite-plus/test* surface (one-time transition).

Notable changes:

  • packages/cli/build.ts: syncTestPackageExports auto-generates ./test/* shims from upstream vitest's exports map, plus ./test/<provider> and ./test/browser/providers/<short> shims projected from each @vitest/browser-* package's exports.
  • packages/cli/package.json: adds @vitest/browser, @vitest/browser-playwright, @vitest/browser-preview, @vitest/browser-webdriverio as direct catalog deps pinned to 4.1.5.
  • crates/vite_global_cli/src/commands/version.rs: vitest ToolSpec points at the vitest package directly.
  • packages/cli/src/resolve-test.ts: resolves vitest/package.json and reads bin.vitest so vp test invokes upstream vitest.
  • packages/cli/src/utils/constants.ts: drops vitest from VITE_PLUS_OVERRIDE_PACKAGES; only vite remains a managed key.
  • packages/cli/src/migration/migrator.ts:
    • Adds an isVitestAdjacent flag that flips needVitePlus = true for projects with packages like vitest-browser-svelte even when there's no vite/oxlint/tsdown to migrate.
    • Adds pruneLegacyWrapperAliases / pruneYamlMapLegacyWrapperAliases sweeps that rewrite stale vitest: npm:@voidzero-dev/vite-plus-test@* aliases to ^4.1.5 (so existing catalog: refs keep resolving) and drop other stale wrapper-targeted keys.
  • packages/cli/src/migration/bin.ts: adds a handleInstallResult helper so failed reinstalls warn the user, append to report.warnings, and flip process.exitCode instead of being silently reported as success.

User-visible behavior changes

vp test -h and live test runs now show vitest's native banner (vitest/<semver>, RUN v<semver> <cwd>) instead of the wrapper-rebranded output (vp test/<semver>, RUN <cwd>). This is the tradeoff for delegating directly to upstream vitest without a wrapper layer.

Test plan

  • cargo test -p vite_migration --lib: 167 tests pass
  • pnpm exec vitest run (packages/cli): 374 tests pass
  • pnpm bootstrap-cli succeeds
  • pnpm -F vite-plus snap-test-global + snap-test-local: all fixtures regenerated; diffs only reflect expected behavior (forward import rewrites, @vitest/browser* removed from user devDeps, playwright/webdriverio preserved as peers, stale vite-plus-test catalog aliases normalized to ^4.1.5).
  • Manual end-to-end: vp test on a fixture using import { vi } from 'vite-plus/test'; vi.mock(...). See "Follow-up" below.
  • Manual end-to-end: vp migrate on a fresh upstream-vitest project.
  • pnpm install clean: zero @voidzero-dev/vite-plus-test references in the lockfile, browser-provider packages installed transitively via vite-plus.

Follow-up

🤖 Generated with Claude Code


Note

Medium Risk
Touches release pipelines, dependency bump automation, and CI install overrides where mistakes could break daily bumps or matrix smoke tests; changes are mostly operational and documented, not core runtime auth or data paths.

Overview
This PR finishes the upstream vitest migration in automation, docs, and small runtime helpers that still assumed the removed @voidzero-dev/vite-plus-test wrapper.

Release & publishing: prepare_release, release, and publish-to-pkg.pr.new no longer bump, publish, or mention @voidzero-dev/vite-plus-test. Release notes and Discord copy list only @voidzero-dev/vite-plus-core and vite-plus.

Daily dependency bumps (upgrade-deps.ts): Catalog updates now match a plain exact vitest: entry and keep all listed @vitest/* keys on the same version. The script no longer edits and instead syncs VITEST_VERSION in constants.ts and rewrites vitest-family pins in test-vp-create.yml (replacing the old packages/test/package.json updater).

CI packaging (e2e-test, test-vp-create): Stops packing packages/test, forces core/cli to 0.0.0 so artifact names stay *-0.0.0.tgz, and adds repack-vite-tgz to produce vite-7.99.0.tgz for Bun (vitest’s peer vite check). Create smoke tests pin vitest/@vitest/* via VP_OVERRIDE_PACKAGES and pick the masquerade tgz only for Bun.

User-facing & tooling: README manual migration tells users to pin vitest to the bundled semver (e.g. 4.1.9) instead of the test wrapper npm alias. vp --version reports vitest from the vitest package. Migration file walking now includes .cjs/.cts for reverse-migration of require('vite-plus/test/...'). Typos config whitelists PnP for Yarn docs/comments.

Reviewed by Cursor Bugbot for commit d21d56d. Bugbot is set up for automated code reviews on this repo. Configure here.

@netlify

netlify Bot commented May 15, 2026

Copy link
Copy Markdown

Deploy Preview for viteplus-preview canceled.

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

Comment thread packages/cli/src/migration/migrator.ts Outdated

@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: 365a61de42

ℹ️ 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/src/resolve-test.ts Outdated
Brooooooklyn added a commit that referenced this pull request May 15, 2026
…mat/typo

PR #1588 CI failures:
- Force-override mode (VP_FORCE_MIGRATE=1, set by test-vp-create.yml and
  ecosystem-ci) now re-pins any pre-existing vite-plus range to the local
  tgz path in monorepo workspace packages. Without this, pnpm reads the
  published vite-plus@0.1.21 metadata to resolve transitive deps including
  @voidzero-dev/vite-plus-test@0.1.21, which shadowed upstream vitest@4.1.5
  at runtime and broke vp create monorepo tests.
- typos CI: rename yarn-PnP to yarn Plug'n'Play (Pn→On false positive).
- vp check: format packages/cli/build.ts shim-generation block.
- Rename __dirname in install-failure-guard.spec.ts to satisfy
  eslint(no-underscore-dangle).

@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: 4fafa67971

ℹ️ 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/build.ts
Comment thread .github/scripts/upgrade-deps.ts
Comment thread packages/cli/src/migration/bin.ts Outdated

@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: ec69abaadb

ℹ️ 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/package.json
Comment thread packages/cli/src/migration/migrator.ts Outdated

@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: 381b6e2c20

ℹ️ 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/src/migration/migrator.ts Outdated
Comment thread packages/cli/build.ts
Brooooooklyn added a commit that referenced this pull request May 15, 2026
…mat/typo

PR #1588 CI failures:
- Force-override mode (VP_FORCE_MIGRATE=1, set by test-vp-create.yml and
  ecosystem-ci) now re-pins any pre-existing vite-plus range to the local
  tgz path in monorepo workspace packages. Without this, pnpm reads the
  published vite-plus@0.1.21 metadata to resolve transitive deps including
  @voidzero-dev/vite-plus-test@0.1.21, which shadowed upstream vitest@4.1.5
  at runtime and broke vp create monorepo tests.
- typos CI: rename yarn-PnP to yarn Plug'n'Play (Pn→On false positive).
- vp check: format packages/cli/build.ts shim-generation block.
- Rename __dirname in install-failure-guard.spec.ts to satisfy
  eslint(no-underscore-dangle).
@Brooooooklyn Brooooooklyn force-pushed the refactor/replace-vite-plus-test-with-vitest branch from 5c48da8 to 39efcbf Compare May 15, 2026 13:15
Comment thread packages/cli/src/migration/bin.ts

@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: 39efcbf239

ℹ️ 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 crates/vite_migration/src/import_rewriter.rs

@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: 2fceee5296

ℹ️ 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/src/resolve-test.ts Outdated

@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: b888329d76

ℹ️ 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/src/migration/migrator.ts
@Brooooooklyn

Copy link
Copy Markdown
Member Author

Upstream blockers (still needed after the fixes in this PR)

  • @vitest/mocker: the static hoister hardcodes hoistedModule = "vitest" so vi.mock() calls authored as import { vi } from 'vite-plus/test' are silently not hoisted — we ship a defineConfig-injected pre-stage Vite plugin (commit d69fe03) that rewrites 'vite-plus/test''vitest' at transform time as a workaround, but the long-term fix is exposing hoistedModule as a configurable option upstream.
  • rolldown/oxc parser: rejects the legal TypeScript syntax import type Default, { Named } from 'mod', breaking vp build against .d.ts files such as postcss@8.5.8's that use this form.

Comment thread .github/workflows/test-vp-create.yml Outdated
Comment thread ecosystem-ci/patch-project.ts Outdated
@Brooooooklyn

Copy link
Copy Markdown
Member Author

Upstream blockers (updated)

After the latest fixes (21937c5b1), the remaining upstream items are:

  • @vitest/mocker: hardcodes hoistedModule = "vitest" in its static hoister, so any redistributor that surfaces vi under a different specifier breaks vi.mock() silently — we now rewrite 'vite-plus/test''vitest' in the Rust migrator (commit 21937c5) plus keep a runtime Vite plugin (d69fe03) as a safety net, but the long-term fix is exposing hoistedModule as a configurable option upstream so vite-plus/test could also be recognized natively.
  • rolldown/oxc parser: rejects the legal TypeScript syntax import type Default, { Named } from 'mod', breaking vp build against .d.ts files such as postcss@8.5.8's that use this form (only vp-config E2E remains failing on this).

@Brooooooklyn

Copy link
Copy Markdown
Member Author

Final status (after b6b5b8b)

The aggressive Rust source-rewrite in 21937c5 (which made 'vitest' canonical) was reverted because it broke vp create templates that use from "vitest" and rely on the forward rewrite to resolve to vite-plus/test. The reverse-direction migration was over-reach and the cure was worse than the disease for the affected projects (vinext's 4 vi.mock files).

Confirmed upstream blockers:

  • @vitest/mocker: hardcodes hoistedModule = "vitest" in its static hoister, so any redistributor surfacing vi under a different specifier breaks vi.mock() silently — affects ~4 files in vinext that import vi from vite-plus/test (the runtime plugin in d69fe03 handles non-mocker vi usage but cannot intercept the static hoister which runs in vitest's own plugin pipeline). The long-term fix is exposing hoistedModule as a configurable option upstream.
  • rolldown/oxc parser: rejects the legal TypeScript syntax import type Default, { Named } from 'mod', breaking vp build against .d.ts files such as postcss@8.5.8's that use this form (only vp-config E2E remains failing on this).

@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: b6b5b8b0bf

ℹ️ 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/src/index.ts
Comment thread .github/scripts/upgrade-deps.ts
Comment thread crates/vite_migration/src/import_rewriter.rs

@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: 60b7d0f0ac

ℹ️ 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/src/index.ts
Comment thread packages/cli/src/utils/constants.ts Outdated
@Brooooooklyn

Copy link
Copy Markdown
Member Author

Final status — branch HEAD 3ffb7cd

E2E now at expected steady state. The two remaining upstream items:

  • @vitest/mocker hardcodes hoistedModule = "vitest" so the static mock hoister doesn't recognize vi imported via redistributor specifiers — needs upstream PR exposing hoistedModule as a configurable option. (Workaround in this PR: defineConfig injects a pre-stage Vite plugin that rewrites 'vite-plus/test''vitest', propagated into test.projects entries.)
  • rolldown/oxc parser rejects valid TypeScript import type Default, { Named } from 'mod' syntax — breaks vp build against postcss@8.5.8's .d.ts declarations (only vp-config E2E still fails on this).

Everything else (npmx.dev, vinext, vue-mini, frm-stack, varlet, vitepress, reactive-resume, rollipop, dify, etc.) is now green.

Brooooooklyn added a commit that referenced this pull request May 16, 2026
…mat/typo

PR #1588 CI failures:
- Force-override mode (VP_FORCE_MIGRATE=1, set by test-vp-create.yml and
  ecosystem-ci) now re-pins any pre-existing vite-plus range to the local
  tgz path in monorepo workspace packages. Without this, pnpm reads the
  published vite-plus@0.1.21 metadata to resolve transitive deps including
  @voidzero-dev/vite-plus-test@0.1.21, which shadowed upstream vitest@4.1.5
  at runtime and broke vp create monorepo tests.
- typos CI: rename yarn-PnP to yarn Plug'n'Play (Pn→On false positive).
- vp check: format packages/cli/build.ts shim-generation block.
- Rename __dirname in install-failure-guard.spec.ts to satisfy
  eslint(no-underscore-dangle).
@Brooooooklyn Brooooooklyn force-pushed the refactor/replace-vite-plus-test-with-vitest branch from 3ffb7cd to a0d248e Compare May 16, 2026 09:20

@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: a0d248e65e

ℹ️ 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/src/define-config.ts Outdated
Comment thread packages/cli/src/migration/migrator.ts

@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: 1a5b2697e5

ℹ️ 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/src/define-config.ts
Comment thread .github/workflows/test-vp-create.yml Outdated
Brooooooklyn and others added 4 commits June 15, 2026 17:34
…dated install

Rebasing onto main's #1821 (deferred `needsInstall` flag + a single
consolidated install block) replaced this branch's inline ESLint/Prettier
early-return install — which passed `--no-frozen-lockfile` (pnpm/yarn) or
`--force` (npm/bun) per commit 1321e34 — with main's
`forceInstall ? ['--force'] : undefined`. `forceInstall` is only true for
npm/bun bootstrap changes, so a pnpm/yarn migration that only rewrites
package.json got no args and would fail a frozen-lockfile reinstall under CI
(ERR_PNPM_LOCKFILE_CONFIG_MISMATCH).

Compute the install args from the package manager in the consolidated block,
mirroring executeMigrationPlan, so every install reached after a
package.json-modifying migration step re-resolves the now-stale lockfile.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rride set

Rebasing onto main pulled in five ensureVitePlusBootstrap tests that assert the
old `npm:@voidzero-dev/vite-plus-test@latest` wrapper override and a two-entry
peer-rule set. This branch replaces that wrapper with a direct `vitest: 4.1.9`
pin plus the individual `@vitest/*` family pins, so update the assertions to the
refactored output: preserved existing wrapper aliases, completed @vitest/*
family overrides, and the full allowAny / allowedVersions sets.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The rebase auto-merge left the lockfile with stale `@voidzero-dev/vite-plus-test`
wrapper links and vitest 4.1.7 pins. Regenerate against the rebased catalog
(vitest 4.1.9) and the refactored package.json files (wrapper removed); the
result matches the pre-rebase branch's lockfile state.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…est override set

These create snaps were added by main's #1828 and asserted the old
`npm:@voidzero-dev/vite-plus-test@latest` wrapper. Regenerate for this branch's
direct `vitest: 4.1.9` pin plus the `@vitest/*` family overrides and the direct
`vite` core rewrite. pnpm/yarn now surface the browser-provider build scripts
(edgedriver/geckodriver) that live in the direct vitest 4.1.9 dependency tree
but were bundled away by the curated wrapper; bun's trustedDependencies flow is
unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@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: 28fe475180

ℹ️ 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/src/migration/migrator.ts
Comment thread docs/guide/migrate.md Outdated
…verride set

already-vite-plus: legacy wrapper-override projects are no longer a no-op;
`vp migrate` now completes the missing @vitest/* family pins (wrapper kept).
partially-installed: catalog/overrides/peerDependencyRules gain the family.
Update the already-vite-plus first-command comment to match the new behavior.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@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: ade4885bbb

ℹ️ 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/src/utils/constants.ts
Comment thread packages/cli/src/index.ts Outdated
Brooooooklyn and others added 2 commits June 15, 2026 18:25
…t lockfile

Two rebase regressions that turned PR CI red on this branch's HEAD:

* migrator.ts: `ensureVitePlusBootstrap` called `rewritePnpmWorkspaceYaml`
  with a single argument. main's PR #1821 added this call site with the
  pre-widening 1-arg signature; this branch had already grown the function
  to 3-4 params (pnpm major + build-allowance), so the rebased call no
  longer type-checked (TS2554), failing `pnpm tsgo` / `vp check` and thus
  the CLI E2E jobs on linux/mac/windows. Pass an undefined pnpm major so
  build-script allowance stays skipped on this bootstrap path, matching the
  behavior it had before the signature grew.

* pnpm-lock.yaml: the lockfile was regenerated for the vitest 4.1.9 pin but
  never deduped, leaving the vendored `vite` importer's `vitest` at 4.1.8.
  `pnpm dedupe --check` (Lint job) flagged the skew. Ran `pnpm dedupe`;
  only the vitest family + coverage transitive deps move.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The rebase pulled main's PR #1821 `needsInstall` consolidation into the
early-return path (`main`, hasVitePlusDependency branch). main's version
handled a failed install with an inline `cancelAndExit` (hard abort) and
credited `installSummary.durationMs` unconditionally — dropping this
branch's `handleInstallResult` wiring there. The full migration path kept
the helper, so only the early-return path regressed, which the
install-failure-guard.spec guard test caught (it was masked behind the
TS2554 compile error until that was fixed).

Route the early-return install back through `handleInstallResult`: a failed
install now warns, appends to report.warnings, and flips process.exitCode
(matching the full path) instead of being credited as a successful
migration. The success path is unchanged — the helper returns durationMs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@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: 7ed01a584b

ℹ️ 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/package.json Outdated
Yarn 4 hardened mode (auto-enabled for public-PR installs) quarantines
packages younger than `npmMinimalAgeGate`, so a freshly published vitest
pin makes `yarn install` fail for projects Vite+ creates/migrates — the
four `vp create … (yarn)` CI jobs hit this on the same-day 4.1.9 release.

Add `npmPreapprovedPackages: [vitest, '@vitest/*']` to the generated
`.yarnrc.yml` (rewriteYarnrcYml, shared by create + migrate) so the
Vite+-managed vitest family is exempt from the age gate regardless of
release age. The `@vitest/*` glob also covers the optional
`@vitest/browser-*` peers that are not in the override set. Guarded by
`!doc.has(...)` so it never clobbers a user's existing list.

Regenerates the migration-monorepo-yarn4 global snap (only fixture that
captures `.yarnrc.yml`).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

@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: e50937c06f

ℹ️ 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/src/migration/migrator.ts Outdated
Brooooooklyn and others added 3 commits June 16, 2026 00:16
…/wrapper migration

Addresses the PR review threads and the rollipop/vinext ecosystem-CI failures.

- define-config: gate `vite-plus:vitest-resolver` to @vitest/browser's browser
  Vite server only. The signal is read per-server, per-call from
  `this.environment.getTopLevelConfig().plugins` (a `vitest:browser*` plugin) —
  no shared/closure state — so node-mode resolution stays externalized to the
  bundled runner. Fixes the Yarn dual-copy crash (TypeError reading 'config',
  rollipop) without regressing browser-mode pinning, incl. the `--browser` CLI
  flag and node-mode jsdom/happy-dom.
- define-config / index: wrap `defineProject` so migrated project configs get
  the resolver + auto-inline plugins instead of the raw vitest/config helper.
- migration: treat `@vitest/browser-playwright` as an opt-in provider (kept and
  pinned for projects that use it, optional peer) instead of a forced top-level
  dep; pin direct `vitest` for existing-vite-plus browser projects; reject stale
  `npm:@voidzero-dev/vite-plus-test` wrapper overrides; recurse alias pruning
  into nested overrides.
- docs/migrate: node-mode needs a single vite-plus install; browser providers
  (Playwright/WebdriverIO) are opt-in and added by migration when used.
- ecosystem-ci: raise vinext integration testTimeout 30s→60s (borderline flake).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…layouts

The browser-server gate added to `vite-plus:vitest-resolver` was justified
only by the rollipop ecosystem-CI crash. A local reproduction proved that
crash is a Yarn hoisting problem, not a resolver problem: rollipop's root
`.yarnrc.yml` sets `nmHoistingLimits: workspaces`, so every workspace that
gains a direct `vite-plus` dep gets its OWN physical `vitest`/`@vitest/runner`
copy and the runner splits across two instances (`TypeError: Cannot read
properties of undefined (reading 'config')`). A hard `return null` in the
resolver still crashed identically. The unconditional resolver passed every
browser AND node ecosystem project on the base run, so revert the gate and fix
the actual layouts instead.

- define-config: drop the `hasBrowserServerPlugin` gate and restore the
  unconditional resolver (identical to the PR base). The `defineProject`
  wrapper that injects the resolver / auto-inline plugins is kept.
- migration: when a Yarn `node-modules` repo isolates workspace hoisting via an
  effective `nmHoistingLimits: workspaces`, set `installConfig.hoistingLimits:
  "none"` on each workspace the migration adds `vite-plus` to, so the bundled
  `vitest` family dedupes to the single root copy. The effective limit is resolved
  across the `.yarnrc.yml` chain at and above the workspace root (Yarn merges the
  ancestor chain; the closest file that sets the key wins — both verified with Yarn
  4.17), so a limit inherited from a parent rc is honoured and a root rc value
  overrides an ancestor. The `.yarnrc.yml` files are left intact and an explicit
  per-workspace `installConfig.hoistingLimits` is preserved, never clobbered.
  Layouts a per-workspace opt-out cannot dedupe — root `dependencies` (verified with
  Yarn 4.17: `none` opt-out still leaves two copies), or any workspace that pins its
  own isolating `workspaces`/`dependencies` limit — are left un-rewritten and instead
  get a migration warning naming the workspace, so the migration never reports
  success while `vp test` is still split.
- migration: for npm projects that use an opt-in browser provider
  (Playwright/WebdriverIO), inject a direct `vite` devDep (the override target)
  so npm hoists one top-level `node_modules/vite` the provider's nested
  `@vitest/mocker` can resolve (else `ERR_MODULE_NOT_FOUND: vite` at browser
  config load). npm-only; pnpm/Yarn expose the override via symlink/PnP.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@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: 34290ff45a

ℹ️ 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/src/migration/migrator.ts Outdated
Brooooooklyn and others added 2 commits June 16, 2026 04:33
…and gate on node-modules

Harden the Yarn workspace-hoisting auto-fix so it reacts to the EFFECTIVE
`nmHoistingLimits`/`nodeLinker` Yarn would apply, not just the value literally
present in the workspace-root `.yarnrc.yml`. All rules verified against Yarn
4.17 `yarn config get`.

- Resolve each key across Yarn's precedence: the `YARN_*` env var, then the
  `.yarnrc.yml` chain from the workspace root up to the filesystem root (closest
  dir wins), then the home `~/.yarnrc.yml`, then Yarn's default. The home rc
  matters for repos OUTSIDE $HOME (devcontainers/Codespaces mount the repo under
  /workspaces while $HOME is /home/<user>); for in-$HOME repos the ancestor walk
  already passes through $HOME.
- Gate the whole auto-fix/warn on the effective `nodeLinker` being
  `node-modules`. `nmHoistingLimits` only splits physical copies under that
  linker; under Plug'n'Play (Yarn's default when `nodeLinker` is unset)
  resolution is virtual, so writing `installConfig.hoistingLimits: none` there
  would be a spurious mutation that weakens isolation if the repo later switches
  linkers. rollipop sets `nodeLinker: node-modules`, so its auto-fix is
  unaffected.

Scope boundaries (documented in-code), both with a conservative no-op failure
mode — never a spurious mutation, no worse than having no hoisting handling:

- rc values are read VERBATIM; Yarn's `${VAR}`/`${VAR:-default}` interpolation is
  not evaluated. An interpolated `nmHoistingLimits`/`nodeLinker` simply won't match
  the literal comparison, so the fix does nothing for it.
- `YARN_RC_FILENAME` is not honoured. The migrator only ever WRITES `.yarnrc.yml`
  (`rewriteYarnrcYml`/catalog writers, pre-existing), so reading a renamed rc would
  be partial and inconsistent; full support is a separate, larger change.

Tests: cover env precedence (both directions), PnP skip, ancestor-rc inheritance,
home-rc-outside-$HOME, and the closest-rc-wins override. The hoisting describe
clears `HOME`/`YARN_NODE_LINKER`/`YARN_NM_HOISTING_LIMITS` in setup so an ambient
env can't override fixture `.yarnrc.yml` values (hermetic regardless of the runner
environment).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ses USERPROFILE)

The new "home ~/.yarnrc.yml for a repo OUTSIDE $HOME" test only set `process.env.HOME`,
which redirects `os.homedir()` on POSIX but NOT on Windows (Node reads `USERPROFILE`
there). On windows-latest the home-rc read fell through to the real profile, the
node-modules gate did not fire, and the test failed. Set both `HOME` and `USERPROFILE`
in the hoisting describe's env isolation and in that test so `os.homedir()` is
redirected on every platform. Production code is unaffected — it already uses
`os.homedir()`, which is correct (and matches Yarn) on Windows.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@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: 3920c8030f

ℹ️ 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/src/migration/migrator.ts Outdated
The pnpm v10 `allowBuilds` writers only ADDED an edgedriver/geckodriver key when
ABSENT, so a re-migration never updated a stale entry a prior run wrote. Two
inline-review findings fall out of that, fixed in BOTH sinks (package.json `pnpm`
field and pnpm-workspace.yaml) with one three-way rule per driver:

- WebdriverIO present (`shouldAllow`): write `true` unconditionally, overwriting a
  stale `false` from an earlier WebdriverIO-less migration. Otherwise a re-run after
  adding WebdriverIO keeps the driver postinstall blocked and browser tests break.
- driver is a DIRECT dependency (user's own Selenium setup): leave the key ABSENT so
  pnpm honours the user's approval/prompt — remove only a stale `false`, and PRESERVE
  an existing `true` (the user's recorded postinstall approval, which deleting would
  silently revoke).
- otherwise: write `false` only when absent — default-deny the untrusted postinstall
  without clobbering an entry the user (or a prior run) set on purpose.

The YAML sink reads effective values via `allowBuilds.toJS(doc)` so anchor/alias
denials (`&a false` / `*a`) resolve the same as plain scalars, matching the
package.json sink. `<<` merge keys are not resolved (no tooling emits them); such a
denial is conservatively left in place rather than wrongly removed.

Tests: re-migration flip false->true (YAML + package.json), stale-denial removal for
a newly-direct driver, true-approval preservation (both sinks), and alias-backed
false removal. The existing idempotent second-run test still passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@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: 711dcd9d5d

ℹ️ 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/build.ts
…ge at runtime

Trim VITE_PLUS_OVERRIDE_PACKAGES to { vite, vitest }. vitest@4.1.9 declares
the 7 in-tree @vitest/* siblings (expect/runner/snapshot/spy/utils/mocker/
pretty-format) as exact 4.1.9 deps, so a single `vitest` override already
cascades one consistent version to the whole tree — overriding each indirect
dep is redundant. Coverage providers (@vitest/coverage-v8 / -istanbul) are
user-owned peer deps: vite-plus no longer adds, pins, or overrides them.

Instead inject a `vite-plus:coverage-version-guard` Vitest plugin that, via
the configureVitest hook, fail-fasts when an installed coverage provider's
version skews from the bundled vitest. Vitest itself only warns on a skew and
then runs mixed versions, silently producing unreliable coverage. Provider
resolution mirrors Vitest's own anchors (project root, then bundled vitest),
the guard runs once per shared runner instance (coverage is global), and also
wraps enableCoverage() for the late programmatic-enable path.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@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: 2bdd4d986d

ℹ️ 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/src/utils/constants.ts
Comment thread packages/cli/src/migration/migrator.ts Outdated
…n the rig

The ecosystem rig force-installs the locally built vitest (4.1.9), but many
ecosystem projects pin an older `@vitest/coverage-*` in their lockfile (e.g.
vue-mini → @vitest/coverage-istanbul@4.1.2). With coverage no longer in the
shipped override map, the forced runner skewed from the project's pinned
provider and the new runtime guard aborted `vp test --coverage` — an incoherent
runner+provider combo no real install would have.

Pin the coverage providers in the rig's VP_OVERRIDE_PACKAGES so the E2E coverage
step runs against a consistent runner+provider pair, exactly as a user who
followed the guard's advice would. The shipped default (constants.ts) stays
{ vite, vitest } — coverage remains user-owned in the product.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@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: 23c264af39

ℹ️ 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/build.ts
Comment thread README.md Outdated
Brooooooklyn and others added 3 commits June 16, 2026 15:19
…ates

Vite+ pins `vitest` to an exact, sometimes freshly published version and its
in-tree @vitest/* siblings install transitively at that version. A project with
a "minimum release age" gate (pnpm `minimumReleaseAge` / Yarn hardened mode's
`npmMinimalAgeGate`) would quarantine the just-published pin and break
`vp install`.

- pnpm `rewritePnpmWorkspaceYaml`: add the vitest family to
  `minimumReleaseAgeExclude` (only when the gate is already present, alongside
  the existing vite-plus/@voidzero-dev/ox* entries; merge+dedup).
- Yarn `rewriteYarnrcYml`: MERGE the family into `npmPreapprovedPackages`
  instead of skipping when the key already exists — a repo that preapproves its
  own private packages previously lost the vitest preapproval entirely.

Factor the exempt patterns into VITEST_AGE_GATE_EXEMPT_PACKAGES. The `@vitest/*`
glob also covers the optional `@vitest/browser-*` peers and lets the coverage
provider version the guard asks for through the gate; it pins/manages nothing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The automatic migration manages `vitest` in VITE_PLUS_OVERRIDE_PACKAGES, but the
manual-migration examples only overrode `vite`. Without pinning `vitest`, a
dependency or workspace package can resolve a different Vitest than the bundled
runner `vp test` uses, splitting Vitest's internals (mocks/expect/runner state).
Add the `vitest` override to the npm/bun, pnpm, and yarn examples and explain
why, referencing `vp --version` for the bundled version.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The build copies the root README into the published package; regenerate it so
the manual-migration `vitest` override addition is reflected and the
"no unexpected file changes after build" CI check passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@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: d21d56de88

ℹ️ 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/build.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants