Skip to content

fix(templates): scaffold the Markdown renderer into saas-starter too - #3362

Merged
kojiwakayama merged 2 commits into
mainfrom
fix/saas-starter-markdown-renderer
Aug 4, 2026
Merged

fix(templates): scaffold the Markdown renderer into saas-starter too#3362
kojiwakayama merged 2 commits into
mainfrom
fix/saas-starter-markdown-renderer

Conversation

@kojiwakayama

Copy link
Copy Markdown
Contributor

#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. 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 the allowImportingTsExtensions / noEmit options the relative .tsx import needs for consumer tsc.

Making it not recur

The test listed chat starters by hand, which is exactly how this was missed. It now discovers them:

  • Finds every starter whose files render <Chat>, and pins the discovered set, so adding or removing a chat starter is a deliberate edit rather than a silent drift.
  • Asserts every file that renders <Chat> installs a renderer. That is what actually failed here; a per-template check would still have passed once app/markdown-renderer.tsx existed.

Matching on <Chat alone also matches <ChatThemeScope and <ChatSidebar (both in docs-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

saas-starter/app/dashboard/page.tsx renders <Chat> without installing a renderer

One existing test adjusted

does not make baseline framework extensions starter-specific asserted templateConfigs["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 asserts firstPartyExtensions is undefined, which is the actual invariant.

Also checked and deliberately not changed: docs-agent/app/uploads/page.tsx renders AttachmentsPanel, not <Chat>, so it has no Markdown surface.

Green locally: deno fmt --check, deno lint, deno check, generate:manifests:check, and the cli/templates suite (54 steps).

#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.
Copilot AI review requested due to automatic review settings August 4, 2026 16:37
@kojiwakayama
kojiwakayama requested a review from kwakayama as a code owner August 4, 2026 16:37
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@coderabbitai

coderabbitai Bot commented Aug 4, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@kojiwakayama, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 5 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

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 configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d352a053-44ba-4bc0-b540-c3cfddf13116

📥 Commits

Reviewing files that changed from the base of the PR and between b76ea50 and 266798e.

📒 Files selected for processing (6)
  • cli/templates/files/saas-starter/app/dashboard/page.tsx
  • cli/templates/files/saas-starter/app/markdown-renderer.tsx
  • cli/templates/files/saas-starter/tsconfig.json
  • cli/templates/index.test.ts
  • cli/templates/index.ts
  • cli/templates/manifest.json

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.tsx into saas-starter and wrap app/dashboard/page.tsx’s <Chat> with MarkdownRendererProvider.
  • Add saas-starter to templateConfigs so react-markdown@9.0.3 and remark-gfm@4.0.1 are 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, and cli/templates suite 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.

Comment thread cli/templates/index.test.ts
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.
Copilot AI review requested due to automatic review settings August 4, 2026 16:46

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 returns null here, files ?? [] makes the test silently pass for that template. Add an assertExists(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.tsx importing ./markdown-renderer.tsx. That is no longer true for all discovered chat starters (for example, saas-starter imports ../markdown-renderer.tsx from app/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`);

@kojiwakayama
kojiwakayama added this pull request to the merge queue Aug 4, 2026
Merged via the queue into main with commit b89e01a Aug 4, 2026
32 checks passed
@kojiwakayama
kojiwakayama deleted the fix/saas-starter-markdown-renderer branch August 4, 2026 17:06
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.

2 participants