Uh oh!
There was an error while loading. Please reload this page.
fix(cli): make the objectui init scaffold register components and load their styles (#4061, #4062) - #4067
Merged
Conversation
…oad their styles (#4061, #4062) The generated `src/App.tsx` imported only `SchemaRenderer` from `@object-ui/react`, which does not depend on `@object-ui/components` — and registration is a side effect of importing that package. Every node of all three templates took `SchemaRenderer`'s miss path and rendered "Unknown component type". The manifest already declared the package: declared and never imported. The generated `src/index.css` was a bare `@import 'tailwindcss';`, so the theme utilities the templates lean on had no tokens behind them; the `@theme` block that declares those tokens is not published, making the prebuilt `@object-ui/components/style.css` the only source (#3884). Both were invisible because this generator's SOURCES had never been judged against its manifest — #3892 anchored its ranges, but `app-generator.test.ts`'s two import/declaration gates ran only over the two temp-app generators. `buildInitFiles` exposes the scaffold as a file map (the shape `buildAppFiles` already had) and both gates now cover it, each with a self-test that plants the defect back. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017Qqyix2QcnpUC9XeYVDzx3
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
yinlianghui
marked this pull request as ready for review
August 10, 2026 03:30
Uh oh!
There was an error while loading. Please reload this page.
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 freeto 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.
Fixes#4061
Fixes#4062
A sweep pair: both cards are one generated file each in
packages/cli/src/commands/init.ts, and both are the same defect shape in opposite directions — the scaffold declared@object-ui/componentsand never imported it, and never loaded the stylesheet that package publishes. Both premises were re-verified against post-#4063origin/main(0a09793f2) before implementing; both still held, at the exact lines the issues cite.Per-item checklist
src/App.tsximport { SchemaRenderer } from '@object-ui/react';was the only@object-ui/*importimport '@object-ui/components';(and a two-line comment saying why it is not removable)src/index.css@import 'tailwindcss';— the whole file@import '@object-ui/components/style.css';on the next lineinit.tsstructureinit()wrote 11 files inline withfs, so no gate could judge thembuildInitFiles(name, template)returns the file map;init()writes that map and nothing elseapp-generator.test.tsgenerated init scaffold sourcesblockcli-bin.test.tstailwind.config.jsgit diff --statis 1:1 with that list — 4 files, nothing outside the declared surface.doctor.ts(in-flight #3891) is untouched, and so areapp-generator.tsandscaffold-dependencies.ts.Why item 3 was necessary
Both cards ask for
app-generator.test.ts's two gates to be ported onto the init generator. Those gates take a file map as input;init()had no map — it calledwriteFileSynceleven times.buildInitFilesis the same splitbuildInitPackageJsonalready received in #3892, and the same shapeapp-generator.tshas exported asbuildAppFilesall along. It is additive: nothing outside this file reads it except the tests.The refactor is behaviour-preserving, and that is measured rather than argued. I scaffolded all three templates with the real bin built from
origin/main, then again from this branch, and diffed the two trees:The entire diff is the two lines in the table above, repeated once per template. Every other byte of all 33 generated files —
app.json,README.md,.gitignore,package.json,vite.config.ts,postcss.config.js,index.html,src/main.tsx,tsconfig.json— is identical, including the per-fileCreated ...console lines and their order.Why components only, and no plugins
#4061 left this cell open. Measured rather than assumed: the distinct node types across all three templates are exactly
button,card,div,input,text,textarea, and every one of them is registered by@object-ui/componentsitself (checked against that package'sComponentRegistry.registercalls — 112 types). No template names a plugin type. The temp-app generator imports nine packages because it renders arbitrary user schemas; adding nine dependencies to a minimal scaffold that uses none of them is the declared-but-unused direction #3755 removed. A test pins the six-type set, so a future template that adds a plugin type fails here instead of silently rendering an error box.Why the components stylesheet only, and not fields
#4062 left this cell open too.
@object-ui/componentsdeclares"./style.css": "./dist/index.css"withdistinfiles— a real published export.@object-ui/fieldsis deliberately not imported: it is not a dependency of this scaffold, and per the published-tarball measurement on #4059@object-ui/fields@17.3.0ships zero CSS, so copying quick-start's second line would point an import at an empty file from a package the manifest does not declare.The gate is written as a rule, not a string pin: of the scaffold's runtime
@object-ui/*dependencies, exactly those whosepackage.jsondeclares a./style.cssexport must be imported by the generated CSS. That is discriminating in both directions here —componentsexports one,reactexports none.Quote style: the scaffold's existing line is single-quoted (
@import 'tailwindcss';) and an existing test pins that spelling, so the new line is single-quoted to match. CSS treats both identically; the issue title's double quotes carry no semantics.Flagged for the maintainer, deliberately unchanged
#4062's second open cell is out of scope here and nothing about it was touched: the scaffold's Tailwind 4 pipeline is
@tailwindcss/postcss+autoprefixerinpostcss.config.js, whilecontent/docs/guide/quick-start.mdteaches@tailwindcss/vite. Both are valid Tailwind 4 setups and this fix is correct under either, but a new user reads the two pages as one story. Left for a ruling rather than guessed at.Second observation, same character: the temp-app generator solves the styling problem a different way — it inlines the theme tokens into the CSS it generates (
APP_THEME_TOKENS) instead of importing the published sheet. That is coherent for a temp app resolved against the workspace, and the import is the right answer for a scaffold that installs published packages, but the two generators now diverge on styling strategy by design rather than by accident. Noted, not changed.Verification
Local, from the repo root:
pnpm exec vitest run packages/cli/ --maxWorkers=2— 76 passed (76), 3 files. 12 of those cases are new.pnpm --filter @object-ui/cli type-check— clean.pnpm --filter @object-ui/cli lint— 0 errors. The 19 warnings are pre-existing and none is ininit.ts; the two incli-bin.test.ts(execFileSync,rmSyncunused) predate this branch.Reverse verification — direction predicted before running, then run: with both lines deleted from
init.tsand the bundle rebuilt, 6 tests go red, and the split is itself informative.Red, as predicted:
declares no versioned runtime dependency the generated sources never import— the ported gate, naming the packageimports the package registration is a side effect ofimports the published stylesheet of every declared dependency that ships onekeeps the Tailwind entry first, so the library sheet cannot precede itwrites a src/App.tsx that fills the component registry(real bin)writes a src/index.css that loads the library stylesheet(real bin)Green, also as predicted, and worth stating because it is the asymmetry the two gates have by construction: the other gate,
declares every package the generated sources import, stays green — removing an import cannot create an undeclared one, so only the reverse-direction gate can catch this defect class. That is precisely why #4061 survived #3892, which extended the anchor table but not these gates. The two self-tests (reports @object-ui/components as unused when the registration import is removed,is missing that stylesheet when the pre-fix CSS is restored) also stay green by design — they plant the pre-fix text back themselves, so they are gates on the rule rather than on the fix.What was NOT verified, stated plainly: no
npm installof the published packages was run. CI does not install a scaffolded project against the registry, and neither did I. The evidence for #4062 is therefore structural and documentary — the export exists inpackages/components/package.json, and #3884's matrix measured the prebuilt sheet as a strict superset (1410 rules vs the 1331 anode_modulesscan reaches) of what a consumer can otherwise obtain. The claim that the missing import costs a specific rule count in a real install remains unmeasured, as #4062 itself notes.Generated by Claude Code