Declare every runtime-shimmed package for types in plugin scaffolds - #2227
Open
SawyerHood wants to merge 1 commit into
Open
Declare every runtime-shimmed package for types in plugin scaffolds#2227SawyerHood wants to merge 1 commit into
SawyerHood wants to merge 1 commit into
Conversation
`bb plugin build` swaps sonner, vaul, @pierre/diffs, the portal radix
families and the host-resident clsx/tailwind-merge/cva for runtime shims,
but a plugin's tsc resolves those imports through node_modules, and the
scaffold only declared the four packages its starter components happened
to import. The documented `import { toast } from "sonner"` therefore
failed to typecheck in a fresh `bb plugin new --app` (#2072).
- Move the shim table into packages/plugin-build/src/runtime-shims.mjs,
plain ESM read by the builder, the export-manifest generator and the
plugin-scaffold generator, so the three hand-copied lists cannot drift.
- Scaffold every shimmed npm package as a type-only devDependency at the
host's version (PLUGIN_SHIMMED_TYPE_DEPENDENCIES, mirrored from
apps/app/package.json).
- `bb plugin types` repins those devDependencies alongside the SDK pin
(adding missing ones for app plugins, moving any out of dependencies)
and `--check` reports the drift.
- Document the rule in the plugin-authoring skill, the plugin guide, the
bb-cli skill and the scaffold README; guard it with a CLI test
(scaffold devDependencies ⊇ shim list) and a templates test that runs
the scaffold's tsc over every shimmed specifier.
Co-Authored-By: Claude <noreply@anthropic.com>
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.
What was wrong
bb plugin buildresolves sonner, vaul,@pierre/diffs, the ten portal radix families and the host-residentclsx/tailwind-merge/class-variance-authoritythrough an esbuild shim plus a generated export manifest, so the bundle never reads them fromnode_modules. A plugin'stschas no such shim: it resolves those imports through ordinary node resolution, and nothing supplied declarations for them. The scaffold only declared the four shimmed packages its starter components happened to import (@radix-ui/react-dialog,clsx,tailwind-merge,class-variance-authority), so the documentedimport { toast } from "sonner"— and 12 other shimmed specifiers — failed withTS2307: Cannot find module 'sonner'in a freshbb plugin new --app, even thoughbb plugin buildsucceeded. The shim list was also hand-copied in three places (the builder, the export-manifest generator, and the scaffold generator), and the scaffold's copy had already drifted (@pierre/diffsmissing). Issue #2072; investigation report: https://get-bb.github.io/reports/issues/2072.html.What changed
packages/plugin-build/src/runtime-shims.mjs(+.d.mts): the single shim table. Plain ESM so the two generator scripts that run under barenodebefore any TypeScript is compiled can read it by file path (@bb/templatescannot depend on@bb/plugin-buildwithout a workspace cycle). ExportsRUNTIME_SLOT_BY_SPECIFIER,RUNTIME_SHIM_NPM_SPECIFIERS(what the export manifest introspects) andSHIMMED_TYPE_PACKAGES(the npm packages a plugin must declare for types: every shimmed package except React, whose types are@types/react*).build-plugin-app.ts,generate-runtime-export-manifest.mjsandgenerate-plugin-scaffold.mjsall read it; the hand-copiedRUNTIME_MODULE_IDSandSHIMMED_SPECIFIERSlists are gone.turbo.jsonadds the file to both generate tasks'inputs.packages/templates/scripts/generate-plugin-scaffold.mjs: the generated module now emitsPLUGIN_SHIMMED_TYPE_DEPENDENCIES(renamed fromPLUGIN_STARTER_TYPE_DEPENDENCIES) covering every shimmed package, versions mirrored fromapps/app/package.jsonvia the existingversionedDeps().scaffoldPluginwrites all of them into an app scaffold'sdevDependencies.bb plugin types(setPluginSdkPininpackages/templates/src/plugin-scaffold.ts): alongside the SDK pin it brings the shimmed packages' type-only devDependencies to the host's versions — repinning a drifted range, moving a copy out ofdependencies, and (forbb.appplugins) adding any that are missing.--checkreports each one and exits 1.bb plugin migrateis unchanged (its plan stays the SDK layout switch). The CLI prints one line per repinned package.bb-plugin-authoringskill (manifest rules,bb plugin types, the "import freely" list), thebb-cliskill, the in-CLI plugin guide (packages/templates/src/templates/bb-guide-plugins.md: command reference and the shim paragraph) and the scaffold README now say shimmed packages need adevDependenciesentry for types at the host's version and never belong independencies.No wire changes;
HOST_DAEMON_PROTOCOL_VERSIONuntouched. No new plugin API members.How you verified
packages/templates/test/plugin-scaffold-shim-types.test.ts: scaffolds an app plugin, links exactly the packages itspackage.jsondeclares intonode_modules(no network), addsimport { toast } from "sonner"toapp.tsxplus a file importing every shimmed specifier (including@pierre/diffs/react), and runs the scaffold's owntsc. Against the previous generator it fails withCannot find module 'sonner'/'@pierre/diffs/react'/ ...; it passes with this change.apps/cli/src/__tests__/plugin-scaffold-dependencies.test.ts: the app scaffold'sdevDependencies⊇SHIMMED_TYPE_PACKAGES, and none of them is independencies— derived from the build's own table, so adding a slot without declaring its types fails the test.setPluginSdkPincases inpackages/templates/test/plugin-migrate-layout.test.ts: an app plugin with a driftedsonnerrange,vaulindependenciesand the rest missing ends up with every shimmed package indevDependenciesat the host's version and is idempotent afterwards; a headless plugin only has the shimmed packages it already declares repinned.pnpm exec turbo run test --filter=@bb/plugin-build --filter=@bb/templates --filter=@bb/cli(all green),apps/serverplugin-install.test.ts(uses the scaffold; green), andpnpm exec turbo run build typecheckfor the whole repo (88/88).BB_CLI_REEXEC=1so the installedbbdoes not take over, isolatedBB_DATA_DIR):bb plugin new toasty --app→package.jsonlists all 16 shimmed packages indevDependencies; addingimport { toast } from "sonner"; toast.success("hi")toapp.tsx→npx tsc --noEmitexit 0;bb plugin types --checkexit 0; afternpm pkg set devDependencies.sonner="^0.1.0",--checkprintsSet "sonner" to ^1.7.4 in devDependencies — the version this bb shims at runtimeand exits 1;bb plugin typesprintssonner: ^0.1.0 → ^1.7.4 in devDependencies.;bb plugin buildstill succeeds.Fixes #2072