Skip to content

fix(cli): make local Bingo generators work in vp create#1777

Draft
fengmk2 wants to merge 18 commits into
mainfrom
fix/create-picker-local-generators
Draft

fix(cli): make local Bingo generators work in vp create#1777
fengmk2 wants to merge 18 commits into
mainfrom
fix/create-picker-local-generators

Conversation

@fengmk2
Copy link
Copy Markdown
Member

@fengmk2 fengmk2 commented Jun 7, 2026

Problem

Local generator packages (scaffolded by vp create vite:generator) were broken in two ways:

  1. The interactive vp create picker never offered them. Workspace detection already flags template packages (bingo-template keyword or a bingo dependency), but the picker only listed built-in templates.
  2. Running one always crashed with ERR_MODULE_NOT_FOUND. The template's bin imported '../src/template.js', but vp create runs the template directly with node bin/index.ts, where Node type stripping does not remap .js specifiers to .ts files.

Changes

  • Picker: getInitialTemplateOptions now appends local template packages (monorepo only). Selection flows into the existing local-package path in discoverTemplate, so no execution changes were needed.

    › Vite+ Application: Create vite applications
      Vite+ Library: Create vite libraries
      million-finding: Generate new components for our monorepo
    
  • Template: import '../src/template.ts' directly, update bingo to 0.9.3, align the catalog zod with bingo (which requires zod 3), and bump engines to >=22.18.0 (first Node version that runs .ts unflagged). bingo/zod move from the root package.json to vite-plus devDependencies.

  • Tests: unit tests for the picker and the template bin (both failed before the fixes), plus a new create-generator-monorepo snap test covering scaffold and execution end to end.

  • Docs: Code Generators section in the create guide, and local validation testing notes in CONTRIBUTING.md.

Verified in a real monorepo: the generator appears in the picker and vp create million-finding -- --name demo-pkg --directory demo-pkg generates the package correctly.


Note

Medium Risk
Touches template discovery, monorepo placement, and dependency versions for vp create, but behavior is heavily covered by new unit and snap tests rather than security-critical paths.

Overview
Fixes local Bingo generator workflows in monorepos: interactive vp create now lists workspace packages marked with bingo-template / vite-plus-template, and running them uses clearer local bin resolution (including multi-bin packages), Bingo execution with auto --skip-requests, and output placement next to the generator under tools/ instead of defaulting to apps/. Packages that only depend on bingo still run as generators by name but no longer appear in the picker; marker-keyword template packages without a bin entry error instead of falling through to npm create-*.

The vite:generator scaffold is updated for direct node bin/index.ts execution (.ts imports, bingo 0.9.3, zod v3 aligned with bingo, Node >=22.18.0); bingo/zod move from the repo root into vite-plus devDependencies. Coverage adds unit tests, a create-generator-monorepo snap test, spinner-frame normalization for stable snaps, and docs (Code Generators guide + CONTRIBUTING local validation via pnpm link).

Reviewed by Cursor Bugbot for commit aa6b1be. Configure here.

@fengmk2 fengmk2 self-assigned this Jun 7, 2026
@netlify
Copy link
Copy Markdown

netlify Bot commented Jun 7, 2026

Deploy Preview for viteplus-preview canceled.

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

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 7, 2026

✅ Staging deployment successful!

Preview: https://viteplus-staging.void.app/
Commit: 6196e82

@fengmk2 fengmk2 changed the title fix(cli): offer local generator packages in the create template picker fix(cli): make local Bingo generators discoverable and runnable in vp create Jun 7, 2026
@fengmk2 fengmk2 changed the title fix(cli): make local Bingo generators discoverable and runnable in vp create fix(cli): make local Bingo generators work in vp create Jun 7, 2026
@fengmk2 fengmk2 added test: e2e Auto run e2e tests test: install-e2e run vite install e2e test test: create-e2e Run `vp create` e2e tests labels Jun 7, 2026
@fengmk2
Copy link
Copy Markdown
Member Author

fengmk2 commented Jun 7, 2026

@cursor review

@fengmk2
Copy link
Copy Markdown
Member Author

fengmk2 commented Jun 7, 2026

@codex review

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 676352f. Configure here.

Copy link
Copy Markdown

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

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: 676352fd0e

ℹ️ 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/create/initial-template-options.ts
Comment thread packages/cli/templates/generator/bin/index.ts
fengmk2 added 12 commits June 8, 2026 13:39
Workspace packages scaffolded by `vp create vite:generator` carry the
`bingo-template` keyword and are flagged as template packages during
workspace detection, but the interactive `vp create` picker only listed
built-in templates, so local generators were never offered.

`getInitialTemplateOptions` now accepts the workspace packages and
appends an option per template package (after the built-ins, monorepo
only), with the package name as value and its description as hint.
Selecting one flows into the existing `discoverTemplate` local-package
path, which already runs bingo templates via their bin entry with
`--skip-requests`.
Add a Code Generators section to the create guide covering how to
scaffold a generator with `vp create vite:generator`, run it from the
interactive picker or by package name, and customize the template.
…project

Explain how the global vp resolves the project-local vite-plus first,
how to link a checkout into a test project with pnpm link, and when
pnpm bootstrap-cli is needed for Rust global CLI changes.
The generator template scaffolded by `vp create vite:generator` crashed
with ERR_MODULE_NOT_FOUND whenever the generator was run: its bin
imported '../src/template.js' (a tsc-style specifier), but vp create
executes the template directly with `node bin/index.ts`, where Node
type stripping does not remap .js specifiers to .ts files.

- import '../src/template.ts' directly and cast for runTemplateCLI,
  whose parameter type is wider than createTemplate's return under TS 6
- update bingo to 0.9.3 (latest) in the catalog and the template
- align the catalog zod with bingo, which depends on zod 3 and
  introspects schemas via zod 3 internals; the generator template is
  the only zod consumer in the repo
- move bingo/zod to vite-plus devDependencies: they are the generator
  template's dependencies and snap tests resolve modules from the CLI
  package's node_modules
- bump the template engines to >=22.18.0, the first Node version that
  runs .ts files without the --experimental-strip-types flag
- add a unit test that runs the template bin directly with node
The only generator snap test covered the error path outside a monorepo.
The new create-generator-monorepo case scaffolds a generator inside a
monorepo with vite:generator, locks the template package.json contract
into the snapshot, runs the generator through `vp create my-generator`
(the path that crashed before the template fix), and verifies the
generated files.
pnpm 11 records the link as a vite-plus link: override in
pnpm-workspace.yaml (or pnpm.overrides in package.json), so it
survives later installs instead of being restored by them.
The bingo-template keyword / bingo dependency check was duplicated
between discoverWorkspacePackages and discoverTemplate. Both now use a
single isBingoTemplate helper so the detection criteria live in one
place. Also drop the unreachable '' fallback for the picker hint, the
package path is always set.
Spinner frames such as '◒  Preparing local Git repository...' appear in
snap output intermittently depending on timing, while the final
'◇'/'◆' state line is stable. Normalize them away in
replaceUnstableOutput and regenerate the create-generator-monorepo
snapshot without the transient frame.
The case scaffolds a generator and prints its package.json, which now
carries bingo ^0.9.3 and engines >=22.18.0.
A workspace package carrying the vite-plus-template keyword but no bin
field was offered by the create picker, then discoverTemplate silently
fell through to expandCreateShorthand and would install and run the
unrelated npm package create-<name>. The fallthrough predates the
picker, but the picker made it reachable interactively.

- extract isTemplatePackage() so the picker and discovery share the
  template classification
- discoverTemplate now throws a clear error for a template package
  without a bin entry instead of falling through to npm
- use || for the picker hint so an empty description falls back to the
  package path
- strip clack spinner frames at end-of-output without a trailing
  newline
- document why the catalog pins zod to v3 (bingo introspects schemas
  via zod 3 internals)
Running a local generator in a monorepo with multiple parent dirs (e.g.
apps/* and tools/*) placed the generated package under apps/ because
inferParentDir only recognized the literal vite:generator builtin and
fell back to the default app rule for a local generator's package name.

inferParentDir now resolves a local template package to its own parent
directory, so a generator under tools/ scaffolds its output into tools/
rather than apps/. The create-generator-monorepo snap fixture gains an
apps/* parent so it actually exercises the multi-parent case the
tools-only fixture missed.

Closes review comment on #1777.
@fengmk2 fengmk2 force-pushed the fix/create-picker-local-generators branch from 676352f to 0080cda Compare June 8, 2026 05:46
fengmk2 added 2 commits June 8, 2026 15:42
Extract findLocalPackage so discoverTemplate and inferParentDir resolve
a template specifier to a workspace package the same way. Also tighten
the inferParentDir test to exercise the isTemplatePackage guard with a
non-template package instead of re-checking the default rule.
…nd harden multi-bin resolution

Two robustness fixes for local template packages now that they are
directly selectable from the create picker:

- isTemplatePackage (picker visibility) now requires the vite-plus-template
  or bingo-template keyword. A plain `bingo` dependency no longer surfaces a
  normal workspace package as a template; it remains an execution hint in
  isBingoTemplate (controls --skip-requests), separating 'is this offered'
  from 'how is it run'.
- discoverTemplate resolves a package's bin via resolveLocalBinPath: a single
  bin (string or one-entry object) is used directly, a multi-bin package
  prefers the entry named after the package (scoped or unscoped), and an
  ambiguous multi-bin package with no matching entry throws a clear error
  instead of silently picking the first key.
@fengmk2

This comment was marked as resolved.

@fengmk2

This comment was marked as resolved.

cursor[bot]

This comment was marked as resolved.

chatgpt-codex-connector[bot]

This comment was marked as resolved.

fengmk2 added 3 commits June 8, 2026 21:12
…ep ones

inferParentDir only co-located output for keyword-marked packages, but
discoverTemplate runs a workspace package as a Bingo template when it
only has a bingo dependency. Such a package, invoked by name, scaffolded
under the default apps parent instead of next to the generator. Place
output next to any matched local package so placement matches execution.
@socket-security
Copy link
Copy Markdown

socket-security Bot commented Jun 8, 2026

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updatednpm/​bingo@​0.7.0 ⏵ 0.9.385 +110084 +192 +6100

View full report

@fengmk2
Copy link
Copy Markdown
Member Author

fengmk2 commented Jun 8, 2026

@cursor review

@fengmk2
Copy link
Copy Markdown
Member Author

fengmk2 commented Jun 8, 2026

@codex review

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit aa6b1be. Configure here.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

ℹ️ 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".

fengmk2 added a commit that referenced this pull request Jun 8, 2026
`sync-remote` rewrote pnpm-workspace.yaml by parsing it to a plain object and
re-stringifying, which dropped every comment. PR #1777 adds a comment to the
catalog (the zod-v3 pin rationale), so the next sync would silently delete it.

Add `mergeWorkspaceYaml`, a comment-preserving parse+merge+serialize seam:
parse the main workspace as a yaml Document (which retains comments), merge the
upstream rolldown/vite workspaces via the unchanged mergePnpmWorkspaces, then
reconcile the merged data back into the document so surviving keys keep their
comments. syncRemote now uses this instead of parse/stringify.
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 test: install-e2e run vite install e2e test

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant