TermAl

Feature Brief: Source Renderers

Status

Phases 1-5 shipped plus an Inline-zones enhancement that merges the read-only “Inline” preview into the editable Code mode: when a file has renderable regions, MonacoCodeEditor hosts view zones that render each diagram inline after its last source line, alongside the editable source. Markdown source Preview/Split also reuse the rendered Markdown editing surface from Git diff, so rendered preview edits write back to the same source buffer. Phase 6 (additional renderers beyond Mermaid/math) planned.

This document defines a shared renderer model for source-backed previews. It extends the Markdown document work into a more general capability: render recognized diagrams, equations, and other safe visual blocks from the same source buffer used by Monaco editing, Git diff edit mode, and rendered Markdown views.

Related: Code Navigation MCP can use source-renderer metadata when building compact context packs for renderable files.

Phase 1 shipped

Phase 2 shipped

Phase 3 shipped

Phase 4 shipped

Phase 5 shipped

Inline zones shipped (post-Phase-5 enhancement)

Diagrams now render in-place WITHIN the editable Code view, not just in a separate Preview/Split pane. The earlier read-only “Inline” mode was dropped — feedback was that mode toggles were friction (“separate modes are not that useful”).

Fit-to-frame Mermaid previews shipped

Source-preview surfaces enable fillMermaidAvailableSpace so rendered Markdown can use the full preview column and Mermaid diagrams can fit the available width. Default conversation/history Markdown keeps the older scrollable Mermaid frame: wide diagrams preserve their intrinsic iframe width when the column has room, and shrink with the iframe when max-width: 100% constrains it so the aspect-ratio height does not clip the bottom of the SVG. Source previews instead pass fitToFrame: true into the Mermaid iframe srcdoc and frame-style helper.

Fit mode changes two things deliberately:

This mode is preview-wide rather than Mermaid-only: enabling it also applies markdown-copy-shell-fill-mermaid, widening the Markdown copy shell around the diagram so the iframe can actually consume the preview pane width.

Problem

TermAl already uses Monaco as the source editor. That is the right editing surface, but many source files contain content that is easier to understand as rendered output:

The current Markdown document spec covers Markdown files and Markdown Git diffs, but it does not define a reusable model for renderers that work across:

Goals

Non-goals

Product Model

There are two separate surfaces:

  1. Source editing surface: Monaco owns the source text, undo stack, selection, save behavior, stale-file checks, and conflict handling.
  2. Rendered preview surface: TermAl renders safe generated output from the current source text or selected Git side.

The rendered preview is always derived from source. It is not the source of truth.

Renderer Targets

Markdown Files

Markdown files continue to use the MarkdownDocumentView path.

Supported renderable blocks:

```mermaid
sequenceDiagram
  Alice->>Bob: Hello
```
Inline math: $E = mc^2$

Block math:

$$
\int_0^1 x^2 dx = \frac{1}{3}
$$

Optional fenced math syntax:

```math
E = mc^2
```

Rust Source Files

Rust support should start with doc comments because they already use Markdown semantics.

Supported forms:

/// Architecture sketch:
///
/// ```mermaid
/// sequenceDiagram
///   UI->>Backend: POST /api/git/diff
///   Backend-->>UI: documentContent
/// ```
pub fn example() {}
//! Module invariant:
//!
//! ```math
//! revision_{n+1} = revision_n + 1
//! ```

Rules:

Dedicated Diagram Or Equation Files

Dedicated file types can render the whole file:

Extension Initial Renderer
.mmd, .mermaid Mermaid
.tex, .latex Math preview, only when the file is a single equation or explicitly marked as previewable

Dedicated support should be opt-in and conservative. For example, a full LaTeX document is not the same as a single KaTeX equation.

Source Panel Behavior

For files with renderable content, the source panel can expose:

Rules:

Diff Panel Behavior

Diff views must preserve the selected Git section semantics:

Section Rendered Source
unstaged working tree after side
staged index after side
untracked in unstaged working tree file
added in staged index file

Rules:

Rendered Markdown Diff Editing

Rendered Markdown diff editing is special because it can edit Markdown sections directly through contentEditable.

Renderer rules:

Renderer Registry

Create a narrow renderer registry instead of scattering special cases through panels.

type SourceRenderContext = {
  path: string | null;
  language: string | null;
  content: string;
  mode: "source" | "diff" | "diff-edit" | "markdown-diff";
};

type SourceRenderableRegion = {
  id: string;
  renderer: "markdown" | "mermaid" | "math";
  sourceStartLine: number;
  sourceEndLine: number;
  sourceText: string;
  displayText: string;
  editable: boolean;
};

Responsibilities:

Initial Renderer Families

Mermaid

Use the existing Mermaid renderer path.

Rules:

Math

Use KaTeX first unless a future use case requires MathJax.

Recommended dependencies:

Rules:

Safety

Testing

Automated tests:

Manual checks:

Delivery Plan

Phase 1: Math in Shared Markdown Renderer

Phase 2: Renderer Registry

Phase 3: Source Panel Integration

Phase 4: Diff Panel Integration

Phase 5: Rust Doc Comments

Phase 6: Additional Renderers

Consider additional renderers only after Mermaid and math are stable: