Skip to content

fix(web): render Mermaid diagrams as images - #13970

Closed
asonawalla wants to merge 1 commit into
pingdotgg:mainfrom
asonawalla:t3code/render-mermaid-diagrams
Closed

asonawalla wants to merge 1 commit into
pingdotgg:mainfrom
asonawalla:t3code/render-mermaid-diagrams

Conversation

@asonawalla

@asonawalla asonawalla commented Sep 27, 2026 •

Copy link
Copy Markdown

What Changed

Mermaid fences now render as SVG images in the shared web/desktop Markdown renderer. Diagrams use the existing image viewer for zooming and keep their source available for copying. Invalid or incomplete diagrams retain the code fallback.

Why

The renderer previously sent every fenced block through syntax highlighting, so Mermaid diagrams appeared as text. Mermaid now loads only when needed, renders completed fences, and caches images by source and theme.

Native mobile is unchanged.

UI Changes

Before After
Mermaid displayed as source Mermaid rendered inline as an image

Expanded diagram

Before recording:

before.mp4

After recording:

after.mp4

The after recording covers the image viewer, source controls, a sequence diagram in light mode, and malformed-diagram fallback.

Validation

  • 54 focused tests passed across ChatMarkdown.test.tsx and lib/mermaid.test.ts.
  • Web typecheck passed; targeted lint reports only existing warnings; formatting passed.
  • Verified in an isolated T3 client, including keyboard preview and focus restoration.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Implemented with GPT-6-Astra via the Codex harness in T3 Code.

Summary by CodeRabbit

  • New Features
    • Mermaid diagrams in chat messages now render as themed images once their code fences are complete. Expandable details let you view the original diagram source.
    • While a diagram is streaming or rendering, or if rendering fails, its code remains visible and readable.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Sep 27, 2026
@macroscopeapp

macroscopeapp Bot commented Sep 27, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR changes the default presentation of existing Mermaid code blocks into rendered, zoomable SVG diagrams and adds a substantial client-side Mermaid rendering dependency and pipeline. Because the behavior is automatic across existing Markdown content rather than opt-in, the production and product-default impact merits human review.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Sep 27, 2026

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: pingdotgg/t3code/.coderabbit.yaml

Review profile: CHILL

Plan: Advanced

Run ID: 9674fd54-a33c-4b2d-8661-7f0acdd5d5b5

📥 Commits

Reviewing files that changed from the base of the PR and between de251fc and a4f1f23.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (5)
  • apps/web/package.json
  • apps/web/src/components/ChatMarkdown.test.tsx
  • apps/web/src/components/ChatMarkdown.tsx
  • apps/web/src/lib/mermaid.test.ts
  • apps/web/src/lib/mermaid.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

The web Markdown renderer now displays completed Mermaid fences as themed SVG images. The new renderer serializes Mermaid calls, caches generated images, and cleans up temporary containers. Source code remains available while rendering, after failures, and in expandable image details.

Changes

Mermaid image rendering

Layer / File(s) Summary
SVG rendering and caching
apps/web/package.json, apps/web/src/lib/mermaid.ts, apps/web/src/lib/mermaid.test.ts
Adds Mermaid as a dependency and introduces renderMermaidImage, which serializes renders, caches SVG data URLs, applies theme and security settings, and removes temporary containers. Tests cover caching, SVG output, and queue recovery after errors.
Markdown fence rendering
apps/web/src/components/ChatMarkdown.tsx, apps/web/src/components/ChatMarkdown.test.tsx
Routes completed Mermaid fences to the image renderer. Displays successful images with expandable source and retains the code block while rendering or after failure. Tests cover streaming fences, stale results, and failed renders.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant ChatMarkdown
  participant renderMermaidImage
  participant Mermaid
  ChatMarkdown->>renderMermaidImage: request image for completed fence
  renderMermaidImage->>Mermaid: render diagram
  Mermaid-->>renderMermaidImage: return SVG
  renderMermaidImage-->>ChatMarkdown: return SVG data URL
  ChatMarkdown-->>ChatMarkdown: display image and expandable source
Loading

Possibly related PRs

  • pingdotgg/t3code#9621: Implements Mermaid fence detection and rendering in the same Markdown chat renderer.

Suggested reviewers: juliusmarminge

Merge Risk: ⚪ Minimal · up to a4f1f

Mermaid diagrams retain their source fallback and can be zoomed. No material issue remains to resolve before merging.

Security Architecture Review

Security architecture risk: 🟡 Moderate · up to a4f1f

Diagrams use a safer image display path, but many distinct diagrams can still queue rendering work after they are no longer needed. That could slow or stall diagram rendering in the current client session. No code-execution or data-exposure path was established.

Retained concerns

  • Medium · security · inferred: Distinct completed fences, including ones replaced or unmounted before rendering, remain in the shared serial queue. A large set of supplied diagrams can delay later renders and consume client resources; the image-cache limit does not bound queued work.
Security review details

Security Blast Radius

  • inferred — Content rendered in a web or desktop client can initiate work in that client's shared diagram queue. The observed effect is client-session availability, not a demonstrated cross-tenant or privileged-service action.

Security Findings and Attack Paths

  • inferred — A source able to place many distinct completed Mermaid fences in viewed Markdown can cause automatic, serialized rendering. Replaced or unmounted blocks stop receiving results but do not withdraw their queued requests.

Trust Boundaries and Controls

  • observed — Untrusted fence text reaches Mermaid rendering rather than the raw-HTML sanitizer. Strict mode and disabled HTML labels are configured; output is encoded and displayed with an image element, not inserted as inline SVG.

Resilience and Maintainability Implications

  • observed — The cache has entry and estimated-memory limits, failed renders do not poison later queue entries, and settled renders remove temporary DOM. Pending queue length and abandoned rendering work have no corresponding bound in this module.

Hardening Proposals

  • proposed — Bound or coalesce pending renders and withdraw obsolete requests where possible; retain the source fallback if rendering exceeds a per-client work budget.
  • proposed — Validate the generated SVG's permitted references and attributes before exposing it through image actions, and verify the applicable browser and desktop content policies. This is defense in depth, not an established SVG exploit.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 4 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description check ✅ Passed The description includes What Changed, Why, UI Changes with before-and-after visuals, and a completed Checklist. It also documents validation results and scope.
Title check ✅ Passed The title clearly and concisely identifies the primary change: rendering Mermaid diagrams as images in the web application.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 4 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

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

@divy-piyushm

Copy link
Copy Markdown

This is a great feature, hope it gets merged soon

lukemaj added a commit to toolboxmd/chromeria that referenced this pull request Oct 1, 2026
Upstream: pingdotgg/t3code#13970 by @asonawalla, plus fork-map registration and a khroma@2.1.0 MIT license override.

Co-authored-by: Azim Sonawalla <azim.sonawalla@gmail.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

Copy link
Copy Markdown
Member

Note

This comment is posted by Julius' dot

Closing under the prior-approval rule. Automatic Mermaid rendering adds a new Markdown capability. Maintainers declined this direction in #6191, and this PR has no later approval of its direction and scope. The supplied visual evidence and focused checks do not replace that approval. Please obtain explicit maintainer approval before requesting reconsideration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XL 500-999 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants