Draw a mermaid diagram from a natural-language intent and return a syntax-validated mermaid source, verifying it with mermaid.parse() against a vendored, version-pinned mermaid.js driven by playwright-cli. Designed to be called from other skills (e.g. plan-to-issue, create-pr) through a subagent whose only return value is the validated mermaid on success or a failure reason on failure. Use whenever a mermaid diagram must be produced with a guarantee that it parses without syntax errors. Triggers include "mermaidで図を描いて構文チェックまでして", "draw a mermaid diagram and make sure it has no syntax errors", "syntax-checked mermaid".
Resources
1Install
npx skillscat add handlename/agent-skills/draw-mermaid Install via the SkillsCat registry.
Draw Mermaid
Overview
Take a natural-language intent for a diagram, author it as mermaid, and return a mermaid source that is guaranteed to pass mermaid.parse() with no syntax errors. Authoring and syntax repair both happen inside this skill; the caller only supplies the intent and receives a validated diagram.
The syntax check is not a heuristic: the mermaid is parsed by a real, version-pinned mermaid.js (11.16.0) vendored into this skill (vendor/mermaid.min.js), loaded in a real browser via playwright-cli, and run through mermaid.parse(). Validation is fully offline and deterministic — no CDN, no external service, no mmdc, no package.json.
This skill does NOT decide what the diagram means (the caller passes the intent), does NOT render an image (that is mermaid-to-svg) or upload anything (that is github-attachment-upload), and does NOT embed the result anywhere.
When to Use
- Another skill (e.g.
plan-to-issue,create-pr) needs to author a mermaid diagram and wants a guarantee that the mermaid parses before it is shown, embedded, or handed tomermaid-to-svg. - An agent is about to write mermaid and wants it verified against a real parser rather than trusting the model's output.
Do Not Use When
- The caller already has a mermaid source they only want imaged — that is
mermaid-to-svg(thengithub-attachment-uploadto publish it). - No mermaid is needed at all (plain prose is enough).
- The environment has neither
npx/node(for playwright-cli) norpython3/npx(for the local static server) — see the failure contract below.
Contract (input / output)
Input (provided by the caller, e.g. in the subagent prompt):
intent: a natural-language description of what the diagram should convey (the components/relationships/flow/states to show). Required.diagram_type(optional): a hint such asflowchart,sequenceDiagram,stateDiagram-v2,erDiagram. If omitted, pick the type that best conveys the intent.
Output (when run as a subagent, the final message MUST be exactly this — no prose around it):
- Success: the validated mermaid source only — the raw mermaid text, with no
```mermaidfence and no surrounding commentary. - Failure:
FAILED: <one-line reason and, if applicable, a remediation hint>.
Never return an unvalidated diagram as if it were validated; if it does not parse after the repair budget is exhausted, return FAILED: with the last parse error.
Process
Author the mermaid — from
intent, write a high-level mermaid diagram. Pick the diagram type (flowchart,sequenceDiagram,stateDiagram-v2,erDiagram, …) that best conveys the structure; honordiagram_typeif given. Keep it for human comprehension, not implementation detail.Resolve the validator directory — this skill ships a validator at
vendor/validate.html+vendor/mermaid.min.js. Let<vendor-dir>be the absolute path to this skill'svendor/directory (thevendor/folder sitting next to thisSKILL.md).Start a local static server for the validator — playwright-cli blocks the
file:protocol, so the validator is served over127.0.0.1(local only, no external network). Preferpython3; fall back tonpx http-serverifpython3is absent.cd "<vendor-dir>" # -u is required: without unbuffered output the "Serving HTTP on ... port N" banner # is not flushed to the log file, so the ephemeral port cannot be read back. python3 -u -m http.server 0 --bind 127.0.0.1 > /tmp/draw-mermaid-server.log 2>&1 & SRV_PID=$! sleep 1 PORT=$(grep -oE 'port [0-9]+' /tmp/draw-mermaid-server.log | head -1 | grep -oE '[0-9]+') # Fallback if python3 is unavailable: # npx -y http-server "<vendor-dir>" -a 127.0.0.1 -p 8791 > /tmp/draw-mermaid-server.log 2>&1 & # PORT=8791If no server can be started (no
python3andnpxcannot fetchhttp-server):FAILED: could not start a local static server for the mermaid validator (<error>).Open the validator in playwright-cli — run every playwright-cli command as
npx -y @playwright/cli <command>(the same convention asgithub-attachment-upload;-yskips the install prompt that would otherwise hang an agent; do NOT usenpx playwright-cli, which is a different package). Use a dedicated session so it does not collide with other browsers.npx -y @playwright/cli -s=draw-mermaid open "http://127.0.0.1:$PORT/validate.html"If npx cannot fetch
@playwright/cli(offline, registry error): stop the server and returnFAILED: could not run @playwright/cli via npx (<error>).Validate
mermaid.parse()— pass the mermaid to the page as base64 (this avoids every CLI quoting/newline problem and preserves UTF-8 labels). The page'swindow.__validateMermaid(b64)returns{ok: true}or{ok: false, error: "<parse error with line and position>"}.B64=$(printf '%s' "$MERMAID_SOURCE" | base64) npx -y @playwright/cli -s=draw-mermaid eval "async () => await window.__validateMermaid('$B64')"Repair loop (budget: 3 revisions) — if the result is
ok: false, read theerror(it names the line and what the parser expected), fix the mermaid, and re-run step 5. Repeat untilok: trueor 3 revisions have failed. On exhaustion, returnFAILED: mermaid did not parse after 3 revisions — <last parse error>.Tear down — always close the browser and stop the server, even on failure:
npx -y @playwright/cli -s=draw-mermaid close kill "$SRV_PID" 2>/dev/nullReturn — output the validated mermaid source as the entire final message (raw mermaid, no fence), or
FAILED: <reason>.
Notes for Callers
- Invoke through a subagent and treat its final message as the return value: a validated mermaid source, or
FAILED: .... - The returned mermaid is the canonical structure record — preserve it (e.g. in a collapsed
<details>block) and pass it tomermaid-to-svgwhen an image is wanted.draw-mermaidproduces the diagram;mermaid-to-svghand-draws it as an SVG file;github-attachment-uploadpublishes that file. They compose:draw-mermaid→ validated mermaid →mermaid-to-svg→ SVG path →github-attachment-upload→ attachment URL. - Validation is pinned to mermaid 11.16.0. A diagram that parses here is guaranteed against that grammar; features newer than 11.16.0 are not recognized.
- To bump the vendored mermaid version, replace
vendor/mermaid.min.jswith a newer pinned build and update the version noted here and in the frontmatter.
Final Checklist
- Input
intentwas present; a diagram type was chosen (ordiagram_typehonored). - The mermaid was validated by
mermaid.parse()on the vendored, version-pinned mermaid.js served over127.0.0.1(neverfile:; never a CDN). - On a parse error, the mermaid was revised and re-validated, within the 3-revision budget.
- The local server was stopped and the browser closed, on both success and failure.
- Returned exactly the validated mermaid source (success) or
FAILED: <reason>(failure) — nothing else, no```mermaidfence.