Skill Decision Flowchart Generator
Reads a SKILL.md, extracts structured data nodes.json, and deterministically generates a flowchart HTML via a script.
Division of Labor
| Phase | Who Does It | Why |
|---|---|---|
| SKILL.md → nodes.json | AI | SKILL.md is natural language; semantics are unstable. AI understands context. |
| nodes.json → HTML | Script | Coordinate computation must be deterministic, reproducible, and pixel-aligned. |
AI only outputs structured data, never coordinates or SVG; the script only does geometry, never guesses semantics.
Execution Steps
1. Read SKILL.md
Read the user-specified SKILL.md. If not found, prompt the user for a path.
2. AI Extracts nodes.json
Output JSON following the schema below. Every outgoing edge must explicitly include a side field — this is the AI's semantic judgment, the script will not guess.
Top-Level Structure
{
"title": "Skill Name",
"subtitle": "Optional description",
"nodes": [ ... ],
"edges": [ ... ],
"loops": [ ... ],
"legend": [ ... ]
}
nodes: Required, array of nodesedges: Required, array of directed edgesloops: Optional, dashed loop edges (see below)legend: Usually leave as[]to use default legend
Node type
| type | Meaning | Shape |
|---|---|---|
entry | Flow start | Rounded rectangle |
decision | Decision point (yes/no, has/has not) | Diamond |
process | Processing step | Rounded rectangle |
output | Report/file output | Rounded rectangle |
terminal | Termination/error exit | Rounded rectangle |
Node role (color scheme)
| role | Meaning | fill / stroke |
|---|---|---|
ai | AI reasoning / LLM call | #E6F1FB / #185FA5 |
output | Report / file output | #EEEDFE / #534AB7 |
decision | Decision point | #FAEEDA / #854F0B |
script | Script execution | #E1F5EE / #0F6E56 |
terminal | Termination / error | #FCEBEB / #A32D2D |
A node must have exactly one role. If a step involves multiple different types of work (corresponding to different roles), it must be split into multiple nodes in sequence. For example, "Script fetches baseline + AI supplements analysis" cannot be combined into a single role=ai node; it must be split into a role=script node and a role=ai node.
Edge side (Critical!)
| side | Meaning | Layout Behavior |
|---|---|---|
bottom | Main flow downward | target is one level below from, cx inherits from |
left | Decision left branch / fork left | decision → same level horizontal connection; normal → next level orthogonal polyline |
right | Decision right branch / fork right | Same as above, opposite direction |
Semantic judgment of side is done by the AI:
- Decision diamond (type=decision) with
left/right→ same level as decision, horizontal line - Normal rectangle (type=process/output) with
left/right→ next level, orthogonal polyline (vertical → horizontal → vertical, no diagonals)
Loops (optional, dashed lines)
Used when the flow involves "returning to a previous step," for example:
- Re-review after fixing (
apply_fix → entry) - Retry (
retry → checkpoint) - Loop until condition met (
recheck → validate)
{ "from": "apply_fix", "to": "entry", "label": "Re-review after fix", "path": "left_edge" }
Field descriptions:
from: Loop start node id (usually the last step)to: Loop end node id (usually the flow start or some checkpoint)label: Loop label, displayed next to the dashed linepath: Fixed to"left_edge"(routes along the left edge of the diagram)
Note:
- Do not duplicate edges between the loop start and end in the
edgesarray, otherwise they will be rendered twice - Nodes referenced in
loopsfrom/to do not participate in depth calculation
Legend
Usually leave as [], the script will use a default 5-color legend. For custom legends:
[
{ "label": "AI Execution", "fill": "#E6F1FB", "stroke": "#185FA5" },
{ "label": "Output/Report", "fill": "#EEEDFE", "stroke": "#534AB7" },
{ "label": "Decision Point", "fill": "#FAEEDA", "stroke": "#854F0B" },
{ "label": "Script", "fill": "#E1F5EE", "stroke": "#0F6E56" },
{ "label": "Termination", "fill": "#FCEBEB", "stroke": "#A32D2D" }
]
3. Run Script to Generate HTML
python3 <skill_dir>/scripts/flowchart.py <nodes.json> --out docs/decision-flowchart.html
The script will:
- Validate: id uniqueness, side/type/role validity, from/to reference validity
- Automatically compute levels (decision side-branch same level / normal fork next level / join point = max(incoming edges) + 1)
- Automatically compute x (determined by side) and y (by level + node height)
- Render connections (horizontal side-branch / orthogonal polyline / vertical main flow / three-segment join / dashed loop)
- Auto viewBox + bottom legend
- Output a self-contained HTML
nodes.json Examples
docs/halucatch-v2-nodes.json— Full example (with loop, three-way branch, join point)docs/halucatch-nodes.json— Basic exampledocs/security-review-nodes.json— Multiple decision points exampledocs/self-nodes.json— Minimal example (9 nodes)
Self-Check List
- Entry node type=entry is at the top
- Every edge has a side field (bottom/left/right)
- Decision diamond side=left/right uses side-branch (same level horizontal)
- Normal rectangle side=left/right uses fork (next level orthogonal polyline)
- One node, one role; mixed steps are split
- Join point (multiple incoming edges to same node) requires no special handling; script auto-detects
- Loops use the loops field, not repeated in edges
- All node ids are referenced in edges (no orphan nodes)
- Legend left as
[]
Frequently Asked Questions
Q: Nodes overlap. What should I do?
Check if the side field is missing. Decision branches must have a side (left/right/bottom); otherwise, both target nodes will inherit the same position.
Q: The dashed loop line is not drawn?
Loops are declared in the loops array (not edges), and the from/to nodes must not be repeated in edges. The path field must be "left_edge".
Q: The script reports a JSON format error? JSON does not support comments or single quotes. Common issues: missing commas, trailing commas (at end of array), single quotes.
For more questions, see docs/FAQ.md.