fix(cli): report unexported generated classes before deploy - #345
Conversation
A declared container, workflow or agent whose generated class the worker entry never re-exports is invisible to every check a project runs: `tsc` is clean, codegen is clean, the tests pass. Wrangler only rejects the unexported `class_name` when it provisions the binding, so the first signal is deploy day — and a Worker can ship with three workflows and nothing to run them. The dev server already raises it in the error overlay and `build` / `deploy` / `prepare` warn. But a project that drives its own dev server and deploys through its own IaC runs none of those, and `lunora codegen` — the one command it does run — stayed silent. Two gaps closed: - `doctor` checked containers ONLY, while inference computes the same status for workflows and agents. A project could pass `doctor` with an unexported workflow. It now reports all three from `collectExportGaps`, so a fourth kind cannot be added to inference and silently skipped. - `lunora codegen` now warns for each gap. A warning, not a non-zero exit: codegen runs on every save, and failing between declaring a workflow and wiring the entry would fail the edit that is halfway through fixing it. `doctor`/`prepare`/`deploy` still fail on it. `collectExportGaps` is exported from `@lunora/config/cloudflare` so both callers get the gaps without the `wrangler.jsonc` rewrite that is the rest of `reconcileWranglerBindings`. The warning lives in the command wrapper rather than `runCodegenCommand`, which stays sync — it is a published entry point for exactly the IaC callers this helps. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
✅ Deploy Preview for lunorash ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
Thank you for confirming the Contributor License Agreement! 🙏 |
|
Warning Review limit reached
Next review available in: 25 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
WalkthroughThe Cloudflare configuration now exposes export-gap collection. The codegen command warns about missing worker exports after generation. The doctor command validates containers, workflows, and agents. ChangesExport Gap Detection
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant Codegen
participant BindingInference
participant ExportGapCollector
participant Logger
User->>Codegen: Run codegen
Codegen->>BindingInference: Infer bindings
BindingInference-->>Codegen: Return inferred bindings
Codegen->>ExportGapCollector: Collect export gaps
ExportGapCollector-->>Codegen: Return missing exports
Codegen->>Logger: Report remediation warnings
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Thank you for following the naming conventions! 🙏 |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/cli/src/commands/codegen/handler.ts`:
- Around line 207-210: Gate the warnAboutExportGaps call in runCodegenCommand on
an explicit signal that code generation completed, so validation failures for
invalid --format or unresolved --target return without scanning or warning. Set
and check that signal around the generation path while preserving the existing
loggerForFormat behavior, and add tests covering both early-failure cases.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 4728a989-bca1-460b-864b-c991b0742b47
⛔ Files ignored due to path filters (3)
api-snapshots/config.api.mdis excluded by none and included by nonepackages/cli/__tests__/commands/codegen.test.tsis excluded by!**/__tests__/**,!**/*.test.tsand included bypackages/**packages/cli/__tests__/commands/doctor.test.tsis excluded by!**/__tests__/**,!**/*.test.tsand included bypackages/**
📒 Files selected for processing (4)
packages/cli/src/commands/codegen/handler.tspackages/cli/src/commands/doctor/handler.tspackages/config/src/cloudflare/index.tspackages/config/src/cloudflare/reconcile-bindings.ts
Merging this PR will degrade performance by 0.84%
Warning Please fix the performance issues or acknowledge them on CodSpeed. Performance Changes
Tip Investigate this regression by commenting Comparing Footnotes
|
Review catch. `runCodegenCommand` returns before generation for an invalid `--format` and for an unresolved `--target`, but `execute` scanned for export gaps unconditionally afterwards. The result was export-gap warnings stacked on top of the real validation error, describing a codegen that never happened — and naming whatever classes a previous run had left on disk. Gated on `outputDirectory`, which both early returns leave empty and a real emit always fills. Deliberately not `result.error`: that is also set for a platform diagnostic raised AFTER a successful emit, where the warning still applies. Both cases covered, and demonstrated to fail without the gate — the warning currently prints right beside `codegen: unknown --format "nope"`. cli 1078/1078. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019WfuWNN3cWJE6beZjng347
`eslint --fix` rewrote three concise arrow bodies into block bodies on a single line after Prettier had already run, which Prettier then wants expanded — so the file landed formatted by neither. Prettier owns formatting here, so it runs last. The repo convention is Prettier then ESLint; the missing half is re-running Prettier when an ESLint autofix touches layout. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
What
A declared container, workflow or agent whose generated class the worker entry never re-exports is invisible to every check a project runs:
tscis clean, codegen is clean, the tests pass. Wrangler only rejects the unexportedclass_namewhen it provisions the binding, so the first signal is deploy day — and a Worker can ship with three workflows and nothing to run them.Why it wasn't already covered
It partly was. The dev server raises it in the Vite error overlay, and
build/deploy/prepareall warn — that machinery is not new.It never reaches a project that drives its own dev server and deploys through its own IaC, because that project runs none of those commands. The two it does run were the two that stayed silent:
build/deploy/preparedoctorlunora codegendoctoris the sharper of the two: inference already computed the identicalexportedstatus for workflows and agents, and the check simply ignored two of the three kinds. A project could passdoctorwith an unexported workflow.How
collectExportGapsalready existed and already covered all three kinds — it was just private toreconcile-bindings. It is now exported from@lunora/config/cloudflare, so both callers get the gaps without thewrangler.jsoncrewrite that is the rest ofreconcileWranglerBindings. Deriving the gaps again at each call site is precisely how one kind ended up silently uncovered, so this routes both through the same function.Two deliberate calls:
codegenwarns, it does not fail. Codegen runs on every save. Failing between declaring a workflow and wiring the entry would fail the edit that is halfway through fixing it.doctor,prepareanddeploystill fail on it — that is where failing is useful.runCodegenCommandstays sync. Inference is async, but that function is a published entry point for exactly the IaC callers this change helps (seeconcepts/monorepos-and-iac). Theawaitlives in the command wrapper instead of breaking its signature.Tests
Four new cases, each mutation-checked — I reverted the fix and confirmed the test fails, then restored:
doctorfails on an unexported workflow / passes on an exported one. Excluding workflows from the gap set again →× fails when a declared workflow is not exported by the worker entry.lunora codegenwarns on a gap / stays quiet when the entry re-exports the module. Removing the call →× warns when a declared workflow is not exported by the worker entry.Verification
Full-repo
lint:typesexit 0 ·api:check(snapshot updated for the one new export) ·lint:package-jsonclean ·eslint --max-warnings=0on every changed file · tests: cli 1076, config 579, vite 189.🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes