CoolFace
Datasetpublic

basant307/AI_Governance_Project

sourceHugging Faceapache-2.0updated 2mo agoView on Hugging Face
0likes45downloads
markdown-syntax-extension.md237 linesDownload Raw Back to design
1# Markdown Syntax Extension Design2 3## Context4 5This document keeps the implementation references for the integrated Markdown6syntax extension PR. It is based on the TUI optimization research from7`origin/docs/tui-optimization-design`, especially:8 9- `docs/design/tui-optimization/00-overview.md`10- `docs/design/tui-optimization/03-rendering-extensibility.md`11- `docs/design/tui-optimization/04-gemini-cli-research.md`12- `docs/design/tui-optimization/05-claude-code-research.md`13- `docs/design/tui-optimization/06-implementation-rollout-checklist.md`14- `docs/design/tui-optimization/08-execution-plan-and-test-matrix.md`15 16The referenced research recommends a long-term Markdown architecture built17around an AST parser, block/token caching, stable-prefix streaming, bounded18detail panels, and terminal capability detection. This first implementation19keeps the runtime footprint small and makes the new behavior visible20immediately.21 22## Integrated PR Scope23 24This PR treats Markdown syntax expansion as one coherent renderer improvement,25not separate feature PRs.26 27Included in the first implementation:28 29- Mermaid code blocks render visually in the TUI.30- Mermaid diagrams render through PNG terminal images when image rendering is31  explicitly enabled, `mmdc` is available, and the terminal supports an image32  path.33- `flowchart` / `graph` Mermaid diagrams fall back to box-and-arrow previews.34- `sequenceDiagram` Mermaid diagrams fall back to participant-arrow previews.35- Basic `classDiagram`, `stateDiagram`, `erDiagram`, `gantt`, `pie`,36  `journey`, `mindmap`, `gitGraph`, and `requirementDiagram` blocks fall back37  to bounded text previews.38- Mermaid types without a text preview fall back to their original fenced39  source so the user can still read and copy the diagram definition.40- Task list items render checked/unchecked markers.41- Blockquotes render with a visible quote bar.42- Inline `$...$` math and block `$$...$$` math render with common Unicode43  substitutions.44- Existing Markdown tables continue to use `TableRenderer`.45- Existing non-Mermaid fenced code blocks continue to use `CodeColorizer`.46- Rendered visual blocks keep source reachable through `/copy mermaid N`,47  `/copy latex N`, `/copy latex inline N`, and raw mode.48- `ui.renderMode` controls whether sessions start in rendered or raw/source49  mode, while `Alt/Option+M` toggles the active session view.50 51## Mermaid Rendering Strategy52 53### First version: capability-gated image rendering plus text fallback54 55The implementation now treats Mermaid's own layout as the preferred path. When56the local environment supports it, the TUI renders Mermaid blocks through this57pipeline:58 59```text60Mermaid source61  -> mmdc / Mermaid CLI62  -> PNG63  -> Kitty or iTerm2 terminal image protocol64```65 66If the terminal does not support inline images but `chafa` is installed, the67same PNG is rendered as ANSI block graphics. If neither image protocol nor68`chafa` is available, the renderer falls back to the synchronous terminal text69preview described below.70 71The image render is not attempted while a response is still streaming. During72streaming, Mermaid blocks show a bounded pending preview. Once the response is73finalized, the image path is attempted only when explicitly enabled. This keeps74slow `mmdc` startup, especially the opt-in `npx` path, out of the default75interactive render path.76 77PNG generation is cached independently from terminal placement. Repeated78renders of the same Mermaid source, including terminal resize updates, reuse79the generated PNG and only recompute the Kitty/iTerm2 placement dimensions.80 81The image path is intentionally opt-in and capability-gated instead of always82bundling or invoking Puppeteer/Chromium from the hot CLI path. A user can enable83the image path with `QWEN_CODE_MERMAID_IMAGE_RENDERING=1`, then provide84`@mermaid-js/mermaid-cli` by installing `mmdc` on `PATH` or by setting85`QWEN_CODE_MERMAID_MMD_CLI` to the binary path. For ad-hoc local verification,86`QWEN_CODE_MERMAID_ALLOW_NPX=1` allows the renderer to invoke87`npx -y @mermaid-js/mermaid-cli@11.12.0`; this is intentionally opt-in because88the first run may install Puppeteer/Chromium and block rendering. Repo-local89`node_modules/.bin` renderers are not auto-discovered unless90`QWEN_CODE_MERMAID_ALLOW_LOCAL_RENDERERS=1` is set. Terminal protocol selection91can be forced with `QWEN_CODE_MERMAID_IMAGE_PROTOCOL=kitty|iterm2|off`.92 93For Kitty-compatible terminals such as Ghostty, the renderer uses Kitty94Unicode placeholders instead of writing the image payload as Ink text. The PNG95is transmitted through raw stdout in quiet mode (`q=2`) with a virtual96placement (`U=1`), and the React tree renders the normal placeholder character97grid (`U+10EEEE`) with explicit row and column diacritics for each cell. This98keeps Ink responsible for layout and resize while preventing APC payload bytes99from being wrapped into visible base64 text.100 101### Fallback: resizable wireframe preview102 103The fallback avoids async work because Ink's `<Static>` path is append-only: a104finalized message cannot reliably wait for a background render job and then105update in place without forcing a full static refresh. The fallback must106therefore produce terminal output during the normal React render pass.107 108For `flowchart` / `graph` diagrams, the fallback builds a lightweight graph109model instead of printing one edge at a time:110 111- Nodes are normalized by Mermaid id, label, and basic shape.112- Node labels support Mermaid-style `\n` / `<br>` line breaks.113- Top-down diagrams are ranked into horizontal layers.114- Left-to-right diagrams are ranked into vertical columns when they fit.115- Multiple outgoing edges from the same node are drawn as one fork with116  bracketed edge labels such as `[Yes]`, `[No]`, `[是]`, and `[否]`.117- Back edges and cycles are summarized in a `Cycles:` section with explicit118  `↩ to <node>` markers. This avoids unstable long cross-diagram routes in119  terminal fonts while keeping the loop semantics visible.120- The graph is recomputed from `contentWidth`, so resize changes node width,121  spacing, and connector paths.122- Large previews are bounded before graph layout so very large Mermaid blocks123  do not allocate an unbounded terminal canvas during render.124 125Example:126 127```mermaid128flowchart LR129  A[Client] --> B[API]130```131 132renders as a terminal visual preview rather than Mermaid source.133 134Other common Mermaid diagram families use bounded text summaries rather than a135full layout engine: class relationships/members, state transitions, ER136entities/relationships, Gantt tasks, pie slices, journey steps, mindmap trees,137git graph entries, and requirement trees. If a diagram type is unknown or not138previewable, the renderer shows the original fenced Mermaid source rather than139a placeholder so the content remains readable and selectable/copyable in the140terminal. Rendered Mermaid headings also show the Mermaid-specific copy command,141for example `/copy mermaid 2`, so users can recover the original diagram source142without switching the whole view to raw mode.143 144The fallback is still not a complete Mermaid engine. It is a fast,145dependency-light preview layer for common LLM-generated diagrams when146high-fidelity rendering is not available.147 148### Future providers149 150The provider boundary is intentionally open for additional native image151providers:152 153- `mmdc` / `@mermaid-js/mermaid-cli` for SVG/PNG output.154- `terminal-image` for Kitty/iTerm2 plus ANSI fallback.155- `chafa` when present for Sixel/Kitty/iTerm2/Unicode mosaics.156 157This path should remain optional, cached, and capability-gated, with cache keys158based on source hash, terminal width, renderer provider, and terminal protocol.159It should not block startup or add bundled Mermaid/Puppeteer work to the hot TUI160path by default.161 162## AST Renderer Compatibility163 164The first version extends the existing parser to minimize blast radius. The165feature boundaries are still compatible with a future `marked` token pipeline:166 167- `code(lang=mermaid)` -> `MermaidDiagram`168- `code(lang=*)` -> existing `CodeColorizer`169- `table` -> existing `TableRenderer`170- `blockquote` -> quote block renderer171- `list(task=true)` -> task list renderer172- `paragraph/text` -> inline renderer with math/link/style support173 174The implementation does not cache React nodes. A future AST renderer should175cache tokens/blocks, then render from current width/theme/settings props.176 177## Safety And Performance178 179- Mermaid source is treated as untrusted input.180- The first renderer does not execute Mermaid JavaScript.181- Native image rendering must be opt-in or capability-gated.182- Future browser-based rendering must use timeouts and size limits.183- Rendering should degrade to terminal text instead of throwing.184- Large blocks should respect available height and width.185 186## Validation187 188Targeted unit verification:189 190```bash191cd packages/cli192npx vitest run \193  src/config/settingsSchema.test.ts \194  src/ui/AppContainer.test.tsx \195  src/ui/utils/MarkdownDisplay.test.tsx \196  src/ui/utils/mermaidImageRenderer.test.ts \197  src/ui/commands/copyCommand.test.ts \198  src/ui/components/BaseTextInput.test.tsx \199  src/ui/keyMatchers.test.ts \200  src/ui/contexts/KeypressContext.test.tsx201```202 203Broader verification before PR submission:204 205```bash206npm run build --workspace=packages/cli207npm run typecheck --workspace=packages/cli208npm run lint --workspace=packages/cli209git diff --check210```211 212Terminal-capture integration scenario:213 214```bash215npm run build && npm run bundle216cd integration-tests/terminal-capture217npm run capture:markdown-rendering218```219 220This scenario captures a Markdown-heavy model response, toggles raw/source mode221with `Alt/Option+M`, and verifies the visible source copy flows with222`/copy mermaid 1` and `/copy latex 1`.223 224Manual scenarios:225 226- Assistant response with a Mermaid `flowchart LR` block.227- Assistant response with a Mermaid `sequenceDiagram` block.228- Markdown table plus Mermaid in the same answer.229- Fenced JavaScript code block still showing code formatting.230- Narrow terminal width.231- Constrained tool/detail surface.232- `ui.renderMode: "raw"` starts a session in source-oriented mode.233- `Alt/Option+M` toggles the same response between rendered and raw/source234  mode.235- Mermaid and LaTeX visual blocks expose copy hints that map to the actual236  `/copy mermaid N` and `/copy latex N` source order.237 
basant307/AI_Governance_Project · CoolFace