fix(templates): scaffold the Markdown renderer into saas-starter too - #3362
Conversation
#3358 wired the chat starters by scanning `app/*.tsx` for `<Chat>`. `saas-starter` renders it from `app/dashboard/page.tsx`, one level down, so it was missed and still shows raw Markdown source. Scaffold the renderer there, install it around `<Chat>`, declare the pinned parser, and add the consumer tsc options the relative `.tsx` import needs, matching the other chat starters. The test now discovers chat starters instead of listing them, so a starter that starts rendering `<Chat>` cannot silently miss a renderer again. It also asserts every file that renders `<Chat>` installs one, which is what actually failed here, and pins the discovered set so adding or removing a chat starter is a deliberate edit. Verified by removing the provider: the test names the offending file. `does not make baseline framework extensions starter-specific` asserted that saas-starter had no template config at all. Its subject is baseline framework extensions, which the CLI resolves, not project dependencies, so it now asserts exactly that.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Warning Review limit reached
Next review available in: 5 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. 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: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
Comment |
There was a problem hiding this comment.
Pull request overview
This PR updates the saas-starter CLI template so any rendered <Chat> UI installs a Markdown renderer (matching the other chat starters), and strengthens template tests so missing renderer wiring is caught even when <Chat> is nested below app/.
Changes:
- Scaffold
app/markdown-renderer.tsxintosaas-starterand wrapapp/dashboard/page.tsx’s<Chat>withMarkdownRendererProvider. - Add
saas-startertotemplateConfigssoreact-markdown@9.0.3andremark-gfm@4.0.1are installed for that starter. - Update the templates test suite to discover “chat starters” by scanning for
<Chat...>and assert that every file rendering<Chat>installs a renderer.
Verification
- Not run in this review environment.
- PR description reports:
deno fmt --check,deno lint,deno check,generate:manifests:check, andcli/templatessuite passing locally.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| cli/templates/manifest.json | Adds the renderer file and provider wiring to the embedded saas-starter template output, plus consumer TS config options. |
| cli/templates/index.ts | Adds saas-starter npm deps so the scaffolded renderer has its pinned parser packages available. |
| cli/templates/index.test.ts | Discovers templates rendering <Chat> and asserts renderer installation across all <Chat>-rendering files. |
| cli/templates/files/saas-starter/tsconfig.json | Enables allowImportingTsExtensions + noEmit for consumer tsc compatibility with explicit .tsx imports. |
| cli/templates/files/saas-starter/app/markdown-renderer.tsx | Adds the saas-starter Markdown renderer implementation using react-markdown + remark-gfm. |
| cli/templates/files/saas-starter/app/dashboard/page.tsx | Wraps <Chat> with MarkdownRendererProvider and imports the new renderer. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Checking for the identifier passed on a file that imported the provider and never used it. The guard now looks for the JSX usage and requires it to open before <Chat>, which a bare import cannot satisfy. Verified by deleting just the JSX from the dashboard page: the test fails and names the file.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.
Suppressed comments (2)
cli/templates/index.test.ts:923
- If
getTemplate(name)unexpectedly returnsnullhere,files ?? []makes the test silently pass for that template. Add anassertExists(files)so a missing/failed template load fails the test and the renderer guard is still enforced.
const files = await getTemplate(name);
for (const file of files ?? []) {
cli/templates/index.test.ts:903
- Within this test, the explanatory comment below refers specifically to
app/page.tsximporting./markdown-renderer.tsx. That is no longer true for all discovered chat starters (for example,saas-starterimports../markdown-renderer.tsxfromapp/dashboard/page.tsx). Rewording the comment to describe the general TS5097 constraint will keep it accurate as templates evolve.
it("allows the relative .tsx import during consumer tsc", async () => {
for (const name of await chatTemplates()) {
const files = await getTemplate(name);
const tsconfig = files?.find((file) => file.path === "tsconfig.json");
assertExists(tsconfig, `${name} should declare consumer TypeScript options`);
#3358 wired the chat starters by scanning
app/*.tsxfor<Chat>.saas-starterrenders it fromapp/dashboard/page.tsx, one level down, so it was missed and still shows raw Markdown source. My scan was the bug, not the template.The fix
Same shape as the other chat starters: scaffold
app/markdown-renderer.tsx, install it around<Chat>, declare the pinned parser (react-markdown@9.0.3,remark-gfm@4.0.1), and add theallowImportingTsExtensions/noEmitoptions the relative.tsximport needs for consumertsc.Making it not recur
The test listed chat starters by hand, which is exactly how this was missed. It now discovers them:
<Chat>, and pins the discovered set, so adding or removing a chat starter is a deliberate edit rather than a silent drift.<Chat>installs a renderer. That is what actually failed here; a per-template check would still have passed onceapp/markdown-renderer.tsxexisted.Matching on
<Chatalone also matches<ChatThemeScopeand<ChatSidebar(both indocs-agent/app/layout.tsx), neither of which renders Markdown, so the match is/<Chat[\s/>]/.Verified the guard bites: removing the provider from the dashboard page fails with
One existing test adjusted
does not make baseline framework extensions starter-specificassertedtemplateConfigs["saas-starter"] === undefined, which is broader than its subject. The guard is about baseline framework extensions, which the CLI resolves; a starter declaring its own npm dependencies is normal and is what every other chat starter does. It now assertsfirstPartyExtensionsis undefined, which is the actual invariant.Also checked and deliberately not changed:
docs-agent/app/uploads/page.tsxrendersAttachmentsPanel, not<Chat>, so it has no Markdown surface.Green locally:
deno fmt --check,deno lint,deno check,generate:manifests:check, and thecli/templatessuite (54 steps).