plan-diagram
Turn any plan / flow / decision order / architecture into an HTML diagram in a dark, hand-drawn
(excalidraw) house style. The style is fixed; the content and language are not — this skill
graphs arbitrary logic and writes the prose in whatever language the source plan uses (English,
Chinese, Russian, … — RTL scripts are fully supported). The two templates in references/ define the visual language:
references/flow-template.html — vertical FLOW (single decision path)
references/board-template.html — pan/zoom BOARD (parallel coexisting systems)
Workflow
- Understand the content and note the language. Read the plan the user gives (a
.md, a
description, or existing docs). Write the diagram in the same language as the plan (or the
language the user asks for). Set {{LANG}}/{{DIR}} accordingly (rtl for right-to-left scripts,
ltr otherwise). Ask one question only if the layout choice is genuinely ambiguous.
- Choose the layout (this is the most important decision — see "Layout choice" below).
- Load the design language:
references/design-system.md — that is the class vocabulary the
body is written in. For ready-made block examples, read the content zone (between
<!-- CONTENT:START --> and <!-- CONTENT:END -->) of the matching template:
- FLOW →
references/flow-template.html
- BOARD →
references/board-template.html
- Write a content MD, not the full HTML. The CSS / pan-zoom JS shell is invariant — never
retype it; the builder copies it from the template. Write
<name>.md next to the planned
output path, containing:
- frontmatter:
layout: flow|board, lang, dir, title, plus subtitle (FLOW) or
hint, zoom_in, zoom_out, fit, parallel (BOARD) — every chrome string in the
plan's language; for FLOW forks also yes_label / no_label;
- body: the plan's logic in the content DSL (see below) — semantic lines, so the MD
doubles as a machine-readable plan spec another AI can work from. Raw HTML blocks are
the escape hatch for shapes the DSL doesn't cover (all BOARD bodies, for now). Keep
every concrete decision (durations, limits, security rules, config requirements, API
addresses) — condense wording, never drop facts. Dense prose →
note lines; reachable
results → yes: results / res:.
- Build:
python3 <skill-base-dir>/scripts/build.py <name>.md <output>.html
Output path: docs/html/<name>.html if the project has a docs/ folder (kebab-case, matching
the plan's topic); otherwise any sensible docs location or the path the user asks for. The
builder injects the body into the template shell and auto-runs the validator.
- Fix anything the validator flags (unbalanced braces/divs, leftover
{{...}} placeholders,
missing entry point) by editing the MD and re-running the build — keep the MD as the editable
source of truth.
Content DSL
The MD body is a sequence of blank-line-separated blocks. A block whose first character is
< is raw HTML and passes through untouched; anything else is a DSL directive. Lines starting
with # are comments and don't ship. Write all text in the plan's language.
step: ① Title | detail # + optional `api: GET /path` line in the same block
arrow: ↓ | optional label
q: ② | condition text # decision diamond; `code` allowed inside
yes: ▶ Result title | detail # `yes:` + `no:` in ONE block render a fork
no: ↓ label # or an empty `no:` with an indented `dlg …` line under it
divider: section label
dlg red: 🔐 CAP | Title | text | [Main] [Sub] | after-text # red|violet|green, default gold
note warn: Label | text # warn|key|good, or plain `note:`
res: ▶ Title | detail
Inline formatting in any text: **bold** → <b>, `code` → <code>; & < > are
auto-escaped. A note label ending in its own colon (e.g. Chinese :) is kept verbatim.
See examples/jwt-auth-flow.en.md for a complete FLOW written in the DSL. BOARD bodies are
raw-HTML blocks for now (their 2-D column structure isn't covered by the DSL) — see
examples/session-vs-jwt.en.md and the board template's content zone for the block shapes.
Layout choice — the core decision
Explicit request wins. If the user names a layout ("board", "graph", "flow", or the equivalent in the plan's language),
use that layout — even if the auto-rule below would pick the other one. Only when nothing is specified,
decide by content shape:
Ask: is the content one path, or a map of coexisting things?
| Content shape |
Layout |
Template |
| A single ordered decision path: ①→②→③, "check this first, then that", branch/stop |
FLOW (vertical) |
flow-template.html |
| Several systems that exist at the same time (A / B / A+), a 2-D relationship, "these run in parallel" |
BOARD (pan/zoom canvas) |
board-template.html |
- If it reads top-to-bottom as "do X, if Y then Z" → FLOW. Example: an access-check order
(check A first, then B, branch or stop) or a step-by-step solution to a puzzle.
- If it's "system A does this, system B does that, both coexist, here's how they relate" → BOARD.
Example: a login architecture where several auth methods live together at the same time.
- When unsure, prefer FLOW — it reads more easily. Only reach for BOARD when the content genuinely is a
2-D map that a vertical list would distort.
Hard rules
- Write in the plan's language, set direction to match. Fill
{{LANG}}/{{DIR}} from that
language; use dir="rtl" for right-to-left scripts, dir="ltr" otherwise. Latin/code
tokens always read LTR. Don't force any one language or script — the style is fixed, the words are not.
- Fill every
{{PLACEHOLDER}}, including chrome. Chrome strings live in the MD frontmatter;
the validator fails on any leftover {{...}}, which is what stops an untranslated
toolbar/label from shipping.
- Keep the design language exact. Same CSS variables, same
.sketch/.q/.branch/.res/.dlg/
.note/.divider classes, same color meanings (see references/design-system.md). Do not invent a
new visual style.
- Every diagram has a visible entry point. FLOW: the
h1 + first .step. BOARD: the .readpath
🧭 read-order badge at the top, and start() fits the whole board on load (no pan/zoom skill needed
to grasp the structure).
- BOARD connector arrows are drawn by the shell JS from content hooks. Keep
.mode.a /
.mode.b in the overview, exactly three .gtitles inside .cols, and (optionally) the
bm1 / bm2 / bmt ids for the branch-merge arrows — remove the hooks and the arrows
silently disappear.
- Preserve real decisions. Notes carry facts (durations, limits, security exclusions, config
requirements, etc.). Condense wording, never delete a fact.
- Color = logic, not decoration. Blue = decision node / path A; violet = path B / alternate;
green = reached/completed result; red = "no" branch / expired; gold = notes & API addresses.
- Self-contained HTML. Inline
<style> and <script>, single Google-fonts link for Vazirmatn.
No build step, no framework.
Validation
The builder runs the validator automatically. To re-check an existing file by hand:
python3 <skill-base-dir>/scripts/validate.py <output>.html
(<skill-base-dir> = this skill's base directory, shown when the skill is invoked.)
It checks: balanced {} / () / [], balanced <div>/</div>, no leftover {{...}} placeholders,
and (for BOARD) the presence of the .readpath entry badge and a full-view start(). A clean run
prints OK. The checks are language-agnostic — a diagram may be in any language.
1---2name: plan-diagram3description: Generate a visual plan diagram in a dark, hand-drawn (excalidraw) house style. Graphs any logic (not tied to a specific project); prose is written in whatever language the plan is in — English, Chinese, Russian, etc., with full RTL (right-to-left) support. Use when the user asks to turn a plan, flow, decision order, architecture, or multi-system design into an HTML diagram ("plan diagram", "flow chart", "diagram", "流程图", "示意图", or the equivalent in any language). Picks between a vertical FLOW layout (single decision path) and a pan/zoom BOARD layout (multiple parallel coexisting systems), fills the chosen template, writes the HTML into the project, and validates structure.4---56# plan-diagram78Turn any plan / flow / decision order / architecture into an HTML diagram in a dark, hand-drawn9(excalidraw) house style. The **style** is fixed; the **content and language are not** — this skill10graphs arbitrary logic and writes the prose in whatever language the source plan uses (English,11Chinese, Russian, … — RTL scripts are fully supported). The two templates in `references/` define the visual language:12- `references/flow-template.html` — vertical **FLOW** (single decision path)13- `references/board-template.html` — pan/zoom **BOARD** (parallel coexisting systems)1415## Workflow16171. **Understand the content and note the language.** Read the plan the user gives (a `.md`, a18 description, or existing docs). Write the diagram in the **same language as the plan** (or the19 language the user asks for). Set `{{LANG}}`/`{{DIR}}` accordingly (`rtl` for right-to-left scripts,20 `ltr` otherwise). Ask one question only if the layout choice is genuinely ambiguous.212. **Choose the layout** (this is the most important decision — see "Layout choice" below).223. **Load the design language:** `references/design-system.md` — that is the class vocabulary the23 body is written in. For ready-made block examples, read the content zone (between24 `<!-- CONTENT:START -->` and `<!-- CONTENT:END -->`) of the matching template:25 - FLOW → `references/flow-template.html`26 - BOARD → `references/board-template.html`274. **Write a content MD, not the full HTML.** The CSS / pan-zoom JS shell is invariant — never28 retype it; the builder copies it from the template. Write `<name>.md` next to the planned29 output path, containing:30 - frontmatter: `layout: flow|board`, `lang`, `dir`, `title`, plus `subtitle` (FLOW) or31 `hint`, `zoom_in`, `zoom_out`, `fit`, `parallel` (BOARD) — every chrome string in the32 plan's language; for FLOW forks also `yes_label` / `no_label`;33 - body: the plan's logic in the **content DSL** (see below) — semantic lines, so the MD34 doubles as a machine-readable plan spec another AI can work from. Raw HTML blocks are35 the escape hatch for shapes the DSL doesn't cover (all BOARD bodies, for now). Keep36 every concrete decision (durations, limits, security rules, config requirements, API37 addresses) — condense wording, never drop facts. Dense prose → `note` lines; reachable38 results → `yes:` results / `res:`.395. **Build:** `python3 <skill-base-dir>/scripts/build.py <name>.md <output>.html`40 Output path: `docs/html/<name>.html` if the project has a `docs/` folder (kebab-case, matching41 the plan's topic); otherwise any sensible docs location or the path the user asks for. The42 builder injects the body into the template shell and auto-runs the validator.436. **Fix anything the validator flags** (unbalanced braces/divs, leftover `{{...}}` placeholders,44 missing entry point) by editing the MD and re-running the build — keep the MD as the editable45 source of truth.4647## Content DSL4849The MD body is a sequence of **blank-line-separated blocks**. A block whose first character is50`<` is raw HTML and passes through untouched; anything else is a DSL directive. Lines starting51with `#` are comments and don't ship. Write all text in the plan's language.5253```54step: ① Title | detail # + optional `api: GET /path` line in the same block55arrow: ↓ | optional label56q: ② | condition text # decision diamond; `code` allowed inside57yes: ▶ Result title | detail # `yes:` + `no:` in ONE block render a fork58no: ↓ label # or an empty `no:` with an indented `dlg …` line under it59divider: section label60dlg red: 🔐 CAP | Title | text | [Main] [Sub] | after-text # red|violet|green, default gold61note warn: Label | text # warn|key|good, or plain `note:`62res: ▶ Title | detail63```6465Inline formatting in any text: `**bold**` → `<b>`, `` `code` `` → `<code>`; `& < >` are66auto-escaped. A `note` label ending in its own colon (e.g. Chinese `:`) is kept verbatim.67See `examples/jwt-auth-flow.en.md` for a complete FLOW written in the DSL. BOARD bodies are68raw-HTML blocks for now (their 2-D column structure isn't covered by the DSL) — see69`examples/session-vs-jwt.en.md` and the board template's content zone for the block shapes.7071## Layout choice — the core decision7273**Explicit request wins.** If the user names a layout ("board", "graph", "flow", or the equivalent in the plan's language),74use that layout — even if the auto-rule below would pick the other one. Only when nothing is specified,75decide by content shape:7677Ask: **is the content one path, or a map of coexisting things?**7879| Content shape | Layout | Template |80|---|---|---|81| A single ordered decision path: ①→②→③, "check this first, then that", branch/stop | **FLOW** (vertical) | `flow-template.html` |82| Several systems that exist **at the same time** (A / B / A+), a 2-D relationship, "these run in parallel" | **BOARD** (pan/zoom canvas) | `board-template.html` |8384- If it reads top-to-bottom as "do X, if Y then Z" → FLOW. Example: an access-check order85 (check A first, then B, branch or stop) or a step-by-step solution to a puzzle.86- If it's "system A does this, system B does that, both coexist, here's how they relate" → BOARD.87 Example: a login architecture where several auth methods live together at the same time.88- When unsure, prefer FLOW — it reads more easily. Only reach for BOARD when the content genuinely is a89 2-D map that a vertical list would distort.9091## Hard rules9293- **Write in the plan's language, set direction to match.** Fill `{{LANG}}`/`{{DIR}}` from that94 language; use `dir="rtl"` for right-to-left scripts, `dir="ltr"` otherwise. Latin/code95 tokens always read LTR. Don't force any one language or script — the style is fixed, the words are not.96- **Fill every `{{PLACEHOLDER}}`, including chrome.** Chrome strings live in the MD frontmatter;97 the validator fails on any leftover `{{...}}`, which is what stops an untranslated98 toolbar/label from shipping.99- **Keep the design language exact.** Same CSS variables, same `.sketch`/`.q`/`.branch`/`.res`/`.dlg`/100 `.note`/`.divider` classes, same color meanings (see `references/design-system.md`). Do not invent a101 new visual style.102- **Every diagram has a visible entry point.** FLOW: the `h1` + first `.step`. BOARD: the `.readpath`103 🧭 read-order badge at the top, and `start()` fits the whole board on load (no pan/zoom skill needed104 to grasp the structure).105- **BOARD connector arrows are drawn by the shell JS from content hooks.** Keep `.mode.a` /106 `.mode.b` in the overview, exactly three `.gtitle`s inside `.cols`, and (optionally) the107 `bm1` / `bm2` / `bmt` ids for the branch-merge arrows — remove the hooks and the arrows108 silently disappear.109- **Preserve real decisions.** Notes carry facts (durations, limits, security exclusions, config110 requirements, etc.). Condense wording, never delete a fact.111- **Color = logic, not decoration.** Blue = decision node / path A; violet = path B / alternate;112 green = reached/completed result; red = "no" branch / expired; gold = notes & API addresses.113- **Self-contained HTML.** Inline `<style>` and `<script>`, single Google-fonts link for Vazirmatn.114 No build step, no framework.115116## Validation117118The builder runs the validator automatically. To re-check an existing file by hand:119120```bash121python3 <skill-base-dir>/scripts/validate.py <output>.html122```123124(`<skill-base-dir>` = this skill's base directory, shown when the skill is invoked.)125126It checks: balanced `{}` / `()` / `[]`, balanced `<div>`/`</div>`, no leftover `{{...}}` placeholders,127and (for BOARD) the presence of the `.readpath` entry badge and a full-view `start()`. A clean run128prints `OK`. The checks are language-agnostic — a diagram may be in any language.