Use only when diagrams will display in Pi's terminal.
Browser Mermaid and exported HTML have different rendering contracts.
Authority
Routine validation uses the helper; reread renderer source/docs only after upgrades or unexpected results.
Resolve installed Pi from PI_CONTEXT_PACKAGE_JSON_PATH; do not assume global npm paths.
Pi's transformer lives beside that manifest at dist/modes/interactive/components/mermaid.js in the inspected installation.
Resolve grok-mermaid from that manifest with Node createRequire; inspect its installed README for supported syntax.
Installed Pi docs are under PI_CONTEXT_DOCS_PATH; settings.md documents markdown.mermaid.
Paths and behavior can change with Pi upgrades; inspect again if validation disagrees with display.
Rendering contract
Pi uses grok-mermaid Unicode terminal art, not browser Mermaid/SVG.
Supported families: flowchart, state, class, ER, sequence.
Timeline, Gantt, and other browser diagram types are not supported by the inspected renderer.
Browser styling, HTML labels, and theme directives are not a portable terminal contract; use plain labels and Pi's theme.
Use a top-level fenced block tagged mermaid, outside lists and blockquotes.
Null render or width exceeding available message width → Pi silently retains source.
Nonempty renderer warnings → final response retains source and adds a warning.
Streaming may show partial art that falls back to source once finalized.
markdown.mermaid: off disables rendering, final waits for completion, streaming renders during generation.
Thinking content is not transformed.
The renderer README calls warnings advisory, but Pi rejects them in final messages.
Validate against Pi's final-message behavior, not merely whether partial art exists.
Layout
One claim, few nodes, short labels.
Try TD first for narrow screens, then measure; parallel vertical branches can be wider than LR.
Sequence participants also consume horizontal space.
Shorten labels or split diagrams rather than hoping Pi shrinks them; renderer computes its own width.
Terminal columns are not message columns: account for Pi padding and surrounding UI.
A tool subprocess's stdout.columns, COLUMNS, or absent TTY does not establish the live Pi viewport.
If viewport is unknown, use an explicit conservative budget (for example 40 columns), state that assumption, and report required width rather than guaranteed fit.
Passing validation does not prove semantic correctness; inspect the preview for missing edges, flattened structure, and misleading layout.
Validate without source files
Validate through stdin; never create temporary files solely for diagram validation.
Pass exact raw diagram contents, without Markdown fences, to validate-pi.mjs.
Resolve that script relative to this skill and use its absolute path when cwd differs.
No input-file option is provided.
The helper is cross-platform Node .mjs; only stdin plumbing depends on the caller's shell.
Programmatic callers can use spawnSync(process.execPath, [scriptPath, "--width", "40"], { input: source, encoding: "utf8", shell: false }) without shell quoting or temporary files.
--width is mandatory and means available message columns, not terminal columns.
Output JSON contains ok, requiredColumns, availableColumns, and, for rendered art, overflow, warnings, and preview lines.
Exit 0: fits the supplied budget with no warnings.
Exit 1: null render, warnings, or overflow; revise diagram.
Exit 2: invalid invocation or unavailable/broken Pi renderer; report blocker.
Missing PI_CONTEXT_PACKAGE_JSON_PATH or installed renderer → stop; never install a substitute or change dependencies.
Renderer resolves through createRequire(pathToFileURL(packagePath)), then imports a file URL; no hardcoded Unix paths or npm dependency declarations.
The skill's package.json is test metadata only; npm test uses Node's built-in test runner, without installation.
Renderer integration tests require Pi context; without it they explicitly skip, not claim renderer verification.
Verified examples
Human checked these in Pi after validator measurements; only A and B rendered.
Tests preserve the same inputs in validate-pi.test.mjs.
A: vertical Agent → Review flowchart, 10 columns, no warnings.
B: You/Agent sequence with Task/Patch messages, 18 columns, no warnings.
C: five long labels in a horizontal chain, 137 columns; too wide for the observed viewport.
D: Gantt source returned null; unsupported family.
E: flowchart TD followed by A[Start --> B drew partial art but warned about a missing closing bracket; rejected on final display.
Widths describe the inspected renderer version, not stable API guarantees.
Revalidate exact source after edits or renderer upgrades.
# Pi terminal Mermaid
Use only when diagrams will display in Pi's terminal.
Browser Mermaid and exported HTML have different rendering contracts.
## Authority
Routine validation uses the helper; reread renderer source/docs only after upgrades or unexpected results.
- Resolve installed Pi from `PI_CONTEXT_PACKAGE_JSON_PATH`; do not assume global npm paths.
- Pi's transformer lives beside that manifest at `dist/modes/interactive/components/mermaid.js` in the inspected installation.
- Resolve `grok-mermaid` from that manifest with Node `createRequire`; inspect its installed README for supported syntax.
- Installed Pi docs are under `PI_CONTEXT_DOCS_PATH`; `settings.md` documents `markdown.mermaid`.
- Paths and behavior can change with Pi upgrades; inspect again if validation disagrees with display.
## Rendering contract
- Pi uses `grok-mermaid` Unicode terminal art, not browser Mermaid/SVG.
- Supported families: flowchart, state, class, ER, sequence.
- Timeline, Gantt, and other browser diagram types are not supported by the inspected renderer.
- Browser styling, HTML labels, and theme directives are not a portable terminal contract; use plain labels and Pi's theme.
- Use a top-level fenced block tagged `mermaid`, outside lists and blockquotes.
- Null render or width exceeding available message width → Pi silently retains source.
- Nonempty renderer warnings → final response retains source and adds a warning.
- Streaming may show partial art that falls back to source once finalized.
- `markdown.mermaid`: `off` disables rendering, `final` waits for completion, `streaming` renders during generation.
- Thinking content is not transformed.
The renderer README calls warnings advisory, but Pi rejects them in final messages.
Validate against Pi's final-message behavior, not merely whether partial art exists.
## Layout
- One claim, few nodes, short labels.
- Try `TD` first for narrow screens, then measure; parallel vertical branches can be wider than `LR`.
- Sequence participants also consume horizontal space.
- Shorten labels or split diagrams rather than hoping Pi shrinks them; renderer computes its own width.
- Terminal columns are not message columns: account for Pi padding and surrounding UI.
- A tool subprocess's `stdout.columns`, `COLUMNS`, or absent TTY does not establish the live Pi viewport.
- If viewport is unknown, use an explicit conservative budget (for example 40 columns), state that assumption, and report required width rather than guaranteed fit.
- Passing validation does not prove semantic correctness; inspect the preview for missing edges, flattened structure, and misleading layout.
## Validate without source files
Validate through stdin; never create temporary files solely for diagram validation.
Pass exact raw diagram contents, without Markdown fences, to [validate-pi.mjs](../scripts/validate-pi.mjs).
Resolve that script relative to this skill and use its absolute path when cwd differs.
No input-file option is provided.
Example from the skill directory, using Nushell:
```nu
'flowchart TD; A["Agent"] --> B["Review"]' | ^node scripts/validate-pi.mjs --width 40
```
The helper is cross-platform Node `.mjs`; only stdin plumbing depends on the caller's shell.
Programmatic callers can use `spawnSync(process.execPath, [scriptPath, "--width", "40"], { input: source, encoding: "utf8", shell: false })` without shell quoting or temporary files.
- `--width` is mandatory and means available message columns, not terminal columns.
- Output JSON contains `ok`, `requiredColumns`, `availableColumns`, and, for rendered art, `overflow`, `warnings`, and preview `lines`.
- Exit `0`: fits the supplied budget with no warnings.
- Exit `1`: null render, warnings, or overflow; revise diagram.
- Exit `2`: invalid invocation or unavailable/broken Pi renderer; report blocker.
- Missing `PI_CONTEXT_PACKAGE_JSON_PATH` or installed renderer → stop; never install a substitute or change dependencies.
- Renderer resolves through `createRequire(pathToFileURL(packagePath))`, then imports a file URL; no hardcoded Unix paths or npm dependency declarations.
- The skill's `package.json` is test metadata only; `npm test` uses Node's built-in test runner, without installation.
- Renderer integration tests require Pi context; without it they explicitly skip, not claim renderer verification.
## Verified examples
Human checked these in Pi after validator measurements; only A and B rendered.
Tests preserve the same inputs in [validate-pi.test.mjs](../scripts/validate-pi.test.mjs).
- A: vertical Agent → Review flowchart, 10 columns, no warnings.
- B: You/Agent sequence with Task/Patch messages, 18 columns, no warnings.
- C: five long labels in a horizontal chain, 137 columns; too wide for the observed viewport.
- D: Gantt source returned null; unsupported family.
- E: `flowchart TD` followed by `A[Start --> B` drew partial art but warned about a missing closing bracket; rejected on final display.
Widths describe the inspected renderer version, not stable API guarantees.
Revalidate exact source after edits or renderer upgrades.