Générateur de diagrammes

Transformez des descriptions en anglais ou du code mermaid en diagrammes modifiables : source mermaid, scène excalidraw, et rendus SVG/PNG. Fonctionne hors ligne.

Spar Skills Guide Bot
ProductiviteIntermédiaire
0031/08/2026
Claude Code
#diagram#mermaid#excalidraw#flowchart#visualization

Recommandé pour


name: diagram preamble-tier: 1 version: 1.0.0 description: | Turn an English description (or mermaid source) into a diagram triplet: the source, an editable .excalidraw file you can open on excalidraw.com, and rendered SVG + PNG. The SVG/PNG use clean mermaid style; the .excalidraw carries the hand-drawn aesthetic. Fully offline. Use when asked to "make a diagram", "draw the architecture", "create a flowchart", "diagram this", or "visualize this flow". (gstack) allowed-tools:

  • Bash
  • Read
  • Write
  • AskUserQuestion triggers:
  • make a diagram
  • draw a diagram
  • create a flowchart
  • diagram this
  • visualize this flow
  • architecture diagram

{{PREAMBLE}}

/diagram — English in, editable diagram out

Every run emits a triplet, never a dead pixel dump:

| Artifact | What it's for | |---|---| | <slug>.mmd | the mermaid source — the LLM-friendly interchange format | | <slug>.excalidraw | editable scene — open it at excalidraw.com, move a box, keep working | | <slug>.svg + <slug>.png | crisp vector for docs + raster for chat/issues/READMEs |

Rendering is fully offline via the diagram-render bundle in the browse daemon (lib/diagram-render/dist/diagram-render.html). No CDN, no network.

Step 1 — Author the diagram

Write mermaid for the user's request. Rules:

  • Flowcharts (graph LR/graph TD) are the sweet spot: they convert to a fully editable excalidraw scene. Prefer graph LR for pipelines/flows, graph TD for hierarchies.
  • Sequence, state, gantt, and other mermaid types render to SVG/PNG fine, but the official converter only supports flowcharts — for those types the .excalidraw artifact is skipped and you MUST tell the user: "sequence diagrams render but aren't excalidraw-editable yet (upstream converter limitation — flowcharts are)."
  • Keep node labels short; put detail in edge labels. 5-15 nodes is the readable range. If the user's ask needs more, split into multiple diagrams and say why.

Decide the output directory: ./diagrams/ when the cwd is a git repo (artifacts the user can commit), else /tmp/gstack-diagrams/. Derive <slug> from the diagram's subject (kebab-case, ≤40 chars).

Step 2 — Stage the render bundle (once per session)

The staged copy is content-addressed (same convention as make-pdf's pre-pass), so concurrent sessions and mixed gstack versions never clobber each other:

BUNDLE=""
for c in "$HOME/.claude/skills/gstack/lib/diagram-render/dist/diagram-render.html" \
         "$(git rev-parse --show-toplevel 2>/dev/null)/lib/diagram-render/dist/diagram-render.html"; do
  [ -f "$c" ] && BUNDLE="$c" && break
done
[ -z "$BUNDLE" ] && echo "BUNDLE_MISSING — run: cd ~/.claude/skills/gstack && bun run build:diagram-render" && exit 1
SHA=$(shasum -a 256 "$BUNDLE" | cut -c1-16)
STAGED="/tmp/gstack-diagram-render-$SHA.html"
[ -f "$STAGED" ] && shasum -a 256 "$STAGED" | grep -q "^$SHA" || { cp "$BUNDLE" "$STAGED.$$" && mv "$STAGED.$$" "$STAGED"; }
TAB=$($B newtab --json | sed -n 's/.*"tabId":\s*\([0-9]*\).*/\1/p')
[ -z "$TAB" ] && echo "TAB_OPEN_FAILED — daemon busy? check browse status" && exit 1
$B load-html "$STAGED" --tab-id "$TAB"
$B wait '#done' --tab-id "$TAB"
echo "RENDER_TAB_READY: tab $TAB"

Remember $TABevery $B js / $B wait / $B closetab below MUST pass --tab-id $TAB. Without it, calls hit whatever tab is active, which may be a live /qa or /scrape session sharing the daemon.

If BUNDLE_MISSING: stop and show the user the build command. Do not improvise a CDN fallback — offline is the contract.

Step 3 — Render the triplet

Write the mermaid source to <outdir>/<slug>.mmd first (Write tool). The page cannot read files itself, so ship the source in via base64 — never splice file contents into a JS template literal (backticks, ${, and backslashes in the source would be interpreted and corrupt it):

# SVG (always). atob() decodes the base64 inside the page.
$B js --tab-id "$TAB" "window.__renderMermaid('diagram-1', atob('$(base64 < <outdir>/<slug>.mmd | tr -d '\n')')).then(s => { window.__svg = s; return 'SVG OK ' + s.length })"
$B js --tab-id "$TAB" "window.__svg" --out <outdir>/<slug>.svg

# PNG at 300dpi of a 6.5in placement (1950px)
$B js --tab-id "$TAB" "window.__rasterize(window.__svg, 1950)" --out <outdir>/<slug>.png

# Editable scene (flowcharts only)
$B js --tab-id "$TAB" "window.__mermaidToExcalidraw(atob('$(base64 < <outdir>/<slug>.mmd | tr -d '\n')')).then(j => { window.__scene = j; return 'SCENE OK ' + JSON.parse(j).elements.length + ' elements' })"
$B js --tab-id "$TAB" "window.__scene" --out <outdir>/<slug>.excalidraw

Note: atob() yields Latin-1; for sources with non-ASCII labels use decodeURIComponent(escape(atob('…'))) to recover UTF-8 exactly.

If the mermaid render returns an error, show the parse error to the user, fix the mermaid, and retry — do not hand the user a broken source file. If __mermaidToExcalidraw fails on a non-flowchart type, skip the .excalidraw artifact and deliver the rest with the limitation note from Step 1.

Step 4 — Show and deliver

  1. Read the PNG with the Read tool so the user sees the diagram inline.
  2. List the triplet paths.
  3. One-line editability note: "The .excalidraw file opens at excalidraw.com (File → Open) — edit it there and I can re-render from the edited scene."
  4. If the user wants changes, edit the .mmd source and re-run Step 3 — the source is the single source of truth.

Re-rendering an EDITED .excalidraw (user round-trip): load the scene file and export without touching the mermaid — base64 transport again, since scene JSON is full of quotes and backslashes:

$B js --tab-id "$TAB" "window.__excalidrawToSvg(atob('$(base64 < <outdir>/<slug>.excalidraw | tr -d '\n')')).then(s => { window.__svg = s; return 'OK' })"
$B js --tab-id "$TAB" "window.__svg" --out <outdir>/<slug>.svg
$B js --tab-id "$TAB" "window.__rasterize(window.__svg, 1950)" --out <outdir>/<slug>.png

Rules

  • Never ship the triplet without rendering it. A .mmd file alone is not a diagram. If rendering is impossible (bundle missing, browse down), say so and stop.
  • Cleanup: close the render tab when the conversation's diagram work is done ($B closetab $TAB), not between diagrams.
  • For diagrams destined for a PDF: remind the user that make-pdf renders ```mermaid fences natively — embedding the .mmd in their markdown is better than embedding the PNG.

Completion status

  • DONE — triplet (or SVG/PNG pair + limitation note) delivered and shown.
  • BLOCKED — bundle or browse unavailable; build/setup command surfaced.
Skills similaires