Skip to content

fix(cli): report compile diagnostics in the check report - #3104

Open
miguel-heygen wants to merge 2 commits into
mainfrom
fix/surface-compile-diagnostics
Open

fix(cli): report compile diagnostics in the check report#3104
miguel-heygen wants to merge 2 commits into
mainfrom
fix/surface-compile-diagnostics

Conversation

@miguel-heygen

Copy link
Copy Markdown
Collaborator

What

bundleToSingleHtml takes an optional diagnostics sink. hyperframes check passes one and renders a Compile section, in the human report and in --json.

Why

The bundler emits three warnings as bare console.warn calls:

code what it reports
color_grading_lut_not_inlined a LUT that could not be inlined, so the bundle is not self-contained
static_guard_contract a StaticGuard contract breach on the compiled entry
sub_composition_skipped a sub-composition that could not be resolved and was dropped

None of them reached the structured report. A --json consumer could not see them at all, and a terminal reader had to catch them scrolling past above the report they were reading. All three describe something wrong with the artifact you are about to ship.

How

The sink follows the onMissingComposition hook inlineSubCompositions already uses, so this is an existing pattern rather than a new one. Records carry code, severity, message and an optional source, and become CheckFindings through findingAtRoot -- the same helper motion_spec_invalid and check_runtime_failure already use.

source rather than a line number: none of the three sites carries a source position, and synthesising one would be a fabrication. All three do know a path, so that is what they report.

Three deliberate limits:

  • Nothing changes for existing callers. The sink is optional; without one these still console.warn with byte-identical text. A test pins both the identical warn calls and a byte-identical bundle string between the sink and no-sink runs.
  • Compile counts stay out of the aggregate totals, so --strict fails nothing it passes today. This changes what you can see, not what passes.
  • The section carries reached, because an empty findings list is otherwise ambiguous. runCheckPipeline short-circuits before bundling whenever lint has errors, so "clean" and "never ran" must not print the same thing. It prints not reached (fix lint errors first) instead. It is also false when the browser check throws after bundling, which would otherwise report reached: true with zero findings.

Own section rather than folded into runtime: different phase, and folding would have moved runtime.warningCount for existing --json consumers. compile is a purely additive key.

Test plan

  • Unit tests added/updated
  • Manual testing performed
  • Documentation updated (if applicable)

Core 99 files / 1697 tests, CLI 175 files / 2490 tests, bun run lint exit 0, bun run build (cross-package typecheck) exit 0.

Verified on a lint-clean probe rather than by reading the code. The LUT warning appears in the Compile section and in the --json envelope. Removing data-width from the same probe makes lint fail, and the section then correctly reads not reached.

Tests were mutation-tested rather than trusted green. Five mutants: sink ignored, source dropped, double-reporting to both sink and console, reached defaulting true, and compile warnings folded into the aggregate. All five were killed.

Every bundleToSingleHtml call site was enumerated. runBrowserCheck and bundleWithLocalizedFonts collect; captureFindingCrops deliberately does not, since it re-bundles the same project and would duplicate. Snapshot, studio server, validate, layout, compare, grade-compare, motionShot and the studio vite adapter all keep the console.warn default with no signature change. Producer has no production use of this function.

Not covered

static_guard_contract fires only when lint has errors, so it is structurally unreachable through check -- the lint short-circuit always beats it. It reaches the sink for studio, preview and render callers. Left as is; making it reachable means restructuring the short-circuit, which is a behaviour change with its own blast radius.

sub_composition_skipped is arguably an error rather than a warning for a render, since you ship a bundle silently missing a scene. Severity is deliberately unchanged here -- this PR is about visibility, not about changing what passes.

No telemetry field for the compile section. trackCheckReport takes a flat props object and never the CheckReport type, so the shape change cannot break it.

Producer and studio suites were not run; the cross-package bun run build typechecks them. The studio dev server and vite preview were not exercised live.

The bundler emits three warnings -- an un-inlinable color-grading LUT, a
StaticGuard contract breach, and a skipped sub-composition -- as bare
console.warn calls. They never reached the structured check report, so
--json consumers could not see them at all and a terminal reader had to
catch them scrolling past above the report they were reading.

bundleToSingleHtml now takes an optional diagnostics sink, following the
onMissingComposition hook inlineSubCompositions already uses. Without a
sink the calls console.warn exactly as before, with byte-identical text
and a byte-identical bundle; a test pins both. check passes one and
renders a Compile section carrying the same CheckFinding shape lint and
runtime already use.

Two deliberate limits. Compile counts stay out of the aggregate totals,
so --strict fails nothing it passes today: this changes what you can see,
not what passes. And the section carries a reached flag, because an empty
findings list is otherwise ambiguous -- runCheckPipeline short-circuits
before bundling whenever lint has errors, and clean and never-ran must
not print the same. It reports not reached (fix lint errors first)
instead, and is also false when the browser check throws after bundling.

Verified on a lint-clean probe: the LUT warning appears in the Compile
section and in the --json envelope. Removing data-width from the same
probe makes lint fail and the section correctly reads not reached.

Left as follow-ups: sub_composition_skipped is arguably an error for a
render, since you ship a bundle silently missing a scene; and
static_guard_contract fires only when lint has errors, so it is
structurally unreachable through check and surfaces for studio, preview
and render callers only.
…quires

CheckReport gained a required compile section in this branch, and the test helper that builds a report was never updated, so packages/cli stopped typechecking. reached: true with no findings is the clean-project shape; reached: false means bundling never ran, which no test here is about.
@miguel-heygen
miguel-heygen force-pushed the fix/surface-compile-diagnostics branch from 9232b44 to 8e2fe43 Compare August 9, 2026 20:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant