Description
x g emits pre-formatted source by hand-wrapping calls, arrays, parameter lists and imports to a 100-column target. That approximation fails, and it cannot be made to work.
Measured
Errors from a scaffolded app's own biome check, on the slice a generator just wrote:
| feature-name length | biome errors |
|---|---|
| 12 | 2 |
| 25 | 6 |
| 35 | 19 |
| 45 | 20 (18 format + 2 organizeImports) |
biome check --write closes 100% of them in 52ms across 47 files, so cost is not the objection.
Why hand-wrapping cannot close it
Biome joins a short wrapped line back and breaks a long joined one. Any fixed emitted shape is therefore wrong for some feature-name length. The generator would have to reimplement the formatter to get this right — and packages/cli/src/templates/wrap.ts, permissionSet's wrapping and tableLine are three partial reimplementations that already exist.
The change, and why it did not land in the scaffold-first-run PR
Run the formatter over what was just written, in writeFiles — then delete all three hand-rolled wrappers.
Four reasons it was held back, all of which stand:
- Only coherent as writer + templates together. Landing the
writeFileshalf alone leaves three hand-rolled wrappers plus a formatter — two mechanisms for one job, strictly worse than either alone, and the exact duplication the change exists to remove. writeFilescurrently guarantees decide-then-write, never half-write. A post-write shell-out is a third pass that can fail after 25 files have landed — a state the design explicitly rules out.- "Skipped when the binary is absent" makes the guarantee conditional. Two apps, same command, different bytes, and
x verify'slintred for one. Axiom 3 inverted. biome check --writeapplies safe lint fixes too, not only formatting. Generated code becomes a function of the app'sbiome.jsonand Biome's version rather than the generator's inputs — and everytemplates/*.test.tsasserts on pre-format bytes, so nothing would describe what actually lands.
Doing it properly means: the writer change, deleting wrap.ts / permissionSet's wrapping / tableLine, and re-pinning every template test that asserts wrapped output. That is a coherent PR of its own.
Related, already fixed
A name-dependent instance of the same class was cheap enough to close directly: templates/action.ts emitted import { can<Name>Write, <name>Tag }, unsorted for any feature starting a or b — ordinary short names, red lint. Fixed in the scaffold-first-run PR.
Also worth folding in
The repo's own Biome is ^2.4.15 (resolving to 2.5.5); the scaffold pins 2.5.8 (templates/scaffold-repo.ts, BIOME_VERSION). So the framework's gate judges generated code with a different binary than the generated app uses. Aligning them belongs with this work.
Activity
developerz-ai commentedon Aug 17, 2026
Scoped plan
Problem: CLI generator hand-wraps code to 100 columns but Biome reformats differently, causing biome check errors in generated code.
Acceptance criteria
Areas
packages/cli/src/templates/wrap.tspackages/cli/src/templates/(permissionSet wrapping)packages/cli/src/templates/(tableLine)packages/cli/src/commands/generate/(writeFiles function)packages/cli/src/templates/*.test.ts(test assertions)Groups
Confidence
85% — Well-specified with measured data, clear problem, four documented reasons for prior deferral.
🤖 Posted by developerz.ai — the maintainer agent, not a human.
developerz-ai commentedon Aug 17, 2026
Want to submit a fix? I'll scope it and flag it for the maintainer to pick up.
🤖 Posted by developerz.ai — the maintainer agent, not a human.
fix(scraping,admin,jobs,action,storage,render,cli)!: close the known-…
feat(scripts,framework)!: four gates, and the last ten known gaps (#219)
sebyx07 commentedon Aug 20, 2026
Fixed in #219 — as a build error, not a runtime format, and the measurement is why.
Measured first: every file
x gemits is already biome-clean today — 48 files, zero findings. Nothing is broken; what was missing is anything that keeps it that way.The runtime option, measured:
biome check --write --stdin-file-paththroughexec.tscosts 239ms per file, and onex g resourceemits 24 ts/tsx files — 5.7 seconds added to a command that is currently instant. Batching to one subprocess is fast enough (~250ms), but it puts a formatter insidex g, where a biome version skew or an unhappy app config turns "write eight files" into a failure the author cannot act on. That failure was hit twice while building this: biome refused to start because the sandbox had no VCS ignore file, andbunx biomein a temp directory re-downloaded biome and answered with the installer's output instead of the checker's.So:
packages/cli/src/generate-format.test.ts. The defect is introduced here, when a template is edited; catching it here costs one subprocess, once (~1s), and nothing on a user's machine. That is axiom 3.Three things make it non-vacuous, and the third was only found by writing it:
BIOME_BIN), notbunx— the versionx verify'slintstep runs;checked >= typescriptPaths(...)). The first version checked only the exit code, and a debug run proved it was reportingchecked: 0while passing. A vacuous test, caught by instrumenting rather than assuming.It covers
x new's scaffold too — that is generated code as well, and it is clean.