
Diagram Generator
- 161 installs
- 18.1k repo stars
- Updated August 4, 2026
- zhaoxuya520/reverse-skill
Turn architecture, flows, and sequences into editable Mermaid, Graphviz, PlantUML, or SVG diagram source—and optionally render them locally—for specs and READMEs.
About
Diagram Generator is an agent skill that helps solo builders and small teams produce maintainable diagram source in Mermaid, Graphviz, PlantUML, and SVG, with optional rendering via local tools. It is aimed at anyone documenting software architecture, user flows, or integration sequences in repos, RFCs, or onboarding docs—without relying on one-off screenshots from a whiteboard tool. The skill emphasizes compact, copy-paste patterns for common diagram types so agents adapt proven syntax rather than hallucinating invalid graph languages. That matters when diagrams live next to code and must diff cleanly in git. Use it during build when writing READMEs and ADRs, during validate when sketching scope and prototypes, or during operate when updating runbooks. Intermediate complexity: you need basic familiarity with at least one diagram dialect, but the patterns lower the bar for consistent output.
- Supports Mermaid, Graphviz DOT, PlantUML, and SVG as editable diagram formats
- Ships compact pattern templates for flowcharts, swimlane flows, architecture, and sequence diagrams
- Encourages adapting patterns instead of inventing fragile diagram syntax
- Optional local rendering workflow alongside source generation
- Covers decision nodes, subgraphs, async edges, and participant-style sequence flows
Diagram Generator by the numbers
- 161 all-time installs (skills.sh)
- +29 installs in the week ending Jul 28, 2026 (Skillselion tracking)
- Ranked #555 of 1,879 Documentation skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/zhaoxuya520/reverse-skill --skill diagram-generatorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 161 |
|---|---|
| repo stars | ★ 18.1k |
| Last updated | August 4, 2026 |
| Repository | zhaoxuya520/reverse-skill ↗ |
What it does
Turn architecture, flows, and sequences into editable Mermaid, Graphviz, PlantUML, or SVG diagram source—and optionally render them locally—for specs and READMEs.
Files
Diagram Generator
Purpose
Create clear, editable diagrams from messy or structured inputs. Prefer text-based diagram source first so the result can be reviewed, versioned, and refined. Render to files only when the user asks for an image/PDF or when a downloadable artifact would materially help.
Default workflow
1. Identify the user's intent, audience, and source material. 2. Choose the diagram family and language using the decision table below. 3. Normalize entities, relationships, labels, states, branches, and time/order information before writing diagram code. 4. Generate concise, readable diagram source. 5. Validate the syntax mentally and, when creating files, run scripts/render_diagram.py. 6. Return the diagram source plus a short note about assumptions. When files are generated, include links to the output files.
Do not over-ask for clarification. If the request is underspecified, make reasonable assumptions and label them briefly.
Diagram language decision table
Use Mermaid unless another language is clearly better.
| User wants | Prefer | Why |
|---|---|---|
| process flow, decision tree, simple swimlane | Mermaid flowchart | readable and easy to paste into Markdown |
| sequence of system/user interactions | Mermaid sequenceDiagram or PlantUML sequence | Mermaid for docs; PlantUML for UML formality |
| lifecycle, state machine, transitions | Mermaid stateDiagram-v2 or PlantUML state | compact transition syntax |
| database schema, entities, relationships | Mermaid erDiagram | portable ER notation |
| class/interface/object model | Mermaid classDiagram or PlantUML class | Mermaid for docs; PlantUML for detailed UML |
| project schedule | Mermaid gantt | concise timeline syntax |
| hierarchy, ideas, notes | Mermaid mindmap | good default for idea maps |
| customer/product journey | Mermaid journey | built-in journey notation |
| git history | Mermaid gitGraph | built-in git notation |
| dependency graph, package graph, large network | Graphviz DOT | better layout engines for dense graphs |
| architecture with layers, clusters, boundaries | Mermaid flowchart with subgraphs, Graphviz clusters, or PlantUML C4-style | choose based on requested fidelity |
| weighted flow/sankey-like relationship | Mermaid sankey-beta when supported, otherwise SVG or Graphviz | Mermaid support may vary by renderer |
| custom visual where source languages fit poorly | SVG | precise control over layout and styling |
Output policy
- Always provide editable source unless the user explicitly asks only for an image.
- Default to a single best diagram. Offer alternatives only when genuinely useful.
- Prefer stable, simple syntax over fancy features that may not render in older Mermaid/PlantUML versions.
- Use short labels. Split long text into notes outside the diagram when needed.
- Avoid ambiguous node IDs. Use ASCII IDs and human-readable labels.
- Preserve user terminology, but standardize capitalization within a diagram.
- For technical diagrams, include boundaries such as client, service, database, queue, external API, and operator/user when they are implied.
- For business-process diagrams, distinguish happy path, decision points, failures, retries, and manual steps when present.
- For diagrams created from uncertain text, include an
Assumptionssection after the code.
Mermaid generation rules
Consult references/diagram-patterns.md for compact templates.
General Mermaid rules:
- Start with the correct diagram directive, for example
flowchart TD,sequenceDiagram,erDiagram,gantt,mindmap, orjourney. - For flowcharts, use
flowchart TDunless the user asks for left-to-right; useflowchart LRfor architecture and pipelines. - Use subgraphs for swimlanes or architecture layers. Name subgraphs with readable labels.
- Keep node IDs stable and ASCII-only, for example
ingest_service[Ingest Service]. - Quote labels that contain punctuation likely to confuse the parser.
- Use decision diamonds for branching:
decision{Condition?}. - Use consistent edge labels:
-- yes -->,-- no -->,-. async .->, or== critical ==>only when meaningful. - In sequence diagrams, declare participants before messages. Use
actorfor humans andparticipantfor systems. - Use
alt/else/end,opt/end,loop/end, andpar/and/endblocks for conditional, optional, repeated, and parallel flows.
Graphviz DOT generation rules
Use Graphviz for large, dense, or layout-sensitive relationship diagrams.
- Prefer
digraph Gfor directed relationships andgraph Gfor undirected networks. - Set layout-friendly graph attributes at the top:
rankdir=LR,nodesep,ranksep, andsplines=truewhen helpful. - Use
subgraph cluster_namefor boundaries and subsystems. - Use plain labels and restrained styling.
- Use edge labels only when they add meaning.
- For many nodes, group by domain with clusters and avoid crossing-heavy all-to-all edges.
PlantUML generation rules
Use PlantUML when the user asks for UML or needs formal UML notation.
- Wrap diagrams with
@startumland@enduml. - Use
actor,participant,database,queue,collections, orcomponentstereotypes when useful. - Use
package,rectangle, ornodefor architecture boundaries. - For class diagrams, include only important fields/methods unless the user asks for exhaustive detail.
- For activity diagrams, use clear start/end markers and explicit branch labels.
SVG generation rules
Use SVG only when text diagram languages cannot express the requested visual reliably.
- Keep SVG simple, accessible, and editable.
- Include
<title>and meaningful text labels. - Prefer rectangles, lines, arrows, and groups over complex paths.
- Do not embed external fonts or remote images.
Rendering files
When the user asks for PNG/SVG/PDF, create a source file and run:
python "<SKILL_ROOT>/diagram-generator/scripts/render_diagram.py" input.mmd --format svg --out output.svg
python "<SKILL_ROOT>/diagram-generator/scripts/render_diagram.py" input.dot --format png --out output.png
python "<SKILL_ROOT>/diagram-generator/scripts/render_diagram.py" input.puml --format svg --out output.svg<SKILL_ROOT>是本包skills/目录的实际路径,AI 应自动检测。
The renderer is intentionally dependency-tolerant. It tries common local tools and reports actionable installation hints if a renderer is unavailable. Do not claim an image was rendered unless the script completed successfully and the output file exists.
Validation checklist
Before finalizing:
- The diagram type matches the user's task.
- The source is syntactically plausible for the chosen language.
- Labels are short enough to fit.
- Edges and message order reflect the input accurately.
- Assumptions are called out when the input was incomplete.
- For generated files, the output exists and opens or has nonzero size.
Common response template
Use this structure for most diagram answers:
下面是可编辑的 [language] 版本:
[source]
Assumptions:
- [only if needed]
Rendered file: [link] [only if generated]For English user requests, respond in English. For Chinese user requests, respond in Chinese unless they ask otherwise.
---
按需自举(On-Demand Bootstrap)
自动化能力边界
| 工具 | 可自动安装 | 安装方式 | 说明 |
|---|---|---|---|
| Mermaid CLI (mmdc) | ✓ | npm install -g @mermaid-js/mermaid-cli | 渲染 Mermaid 为 PNG/SVG |
| Graphviz (dot) | ✗ | 手动安装 | https://graphviz.org/download/ |
| PlantUML | ✗ | 需要 Java + plantuml.jar | https://plantuml.com/download |
| Python (render script) | ✓ | 已在 bootstrap 中 | scripts/render_diagram.py 依赖 |
说明
本 skill 主要输出文本格式的图表源码(Mermaid/DOT/PlantUML),不一定需要本地渲染工具。只有当用户明确要求生成 PNG/SVG/PDF 文件时才需要对应的渲染器。
如果渲染器不可用,scripts/render_diagram.py 会输出安装提示而不是报错。
---
路由上下文
上游入口: skills/SKILL.md(总控)、routing.md 触发条件: 用户说"画图"、"流程图"、"架构图"、"攻击路径图"、"时序图"、"Mermaid"、"Graphviz"、"PlantUML" 下游出口:
- 生成的图表可嵌入
docs-generator/的报告中 - 攻击路径图可配合
pentest-tools/的渗透报告
同级关联模块: docs-generator/(报告中嵌入图表)
interface:
display_name: "Diagram Generator"
short_description: "Generate and render Mermaid, Graphviz, PlantUML, and SVG diagrams."
Diagram Generator Skill
This skill helps AI assistants create editable diagrams in Mermaid, Graphviz DOT, PlantUML, and SVG, and optionally render them with local tools.
Diagram Patterns
Use these compact patterns when generating diagram source. Prefer adapting the pattern instead of inventing complex syntax.
Mermaid flowchart
flowchart TD
start([Start]) --> receive[Receive request]
receive --> valid{Valid?}
valid -- yes --> process[Process request]
valid -- no --> fix[Ask for missing info]
process --> finish([Finish])Mermaid swimlane-style flowchart
flowchart LR
subgraph customer[Customer]
c1[Submit order]
end
subgraph app[Application]
a1[Validate order]
a2[Create invoice]
end
subgraph ops[Operations]
o1[Review exception]
end
c1 --> a1
a1 -- valid --> a2
a1 -- invalid --> o1Mermaid architecture
flowchart LR
user[User] --> web[Web App]
web --> api[API Service]
api --> db[(Database)]
api -. async .-> queue[[Queue]]
queue --> worker[Worker]
worker --> object_store[(Object Store)]Mermaid sequence diagram
sequenceDiagram
actor User
participant Web
participant API
database DB
User->>Web: Submit request
Web->>API: POST /request
API->>DB: Save record
DB-->>API: OK
API-->>Web: 201 Created
Web-->>User: Show confirmationMermaid ER diagram
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ ORDER_ITEM : contains
PRODUCT ||--o{ ORDER_ITEM : appears_in
CUSTOMER {
string id PK
string email
}
ORDER {
string id PK
string customer_id FK
datetime created_at
}Mermaid state diagram
stateDiagram-v2
[*] --> Draft
Draft --> Submitted: submit
Submitted --> Approved: approve
Submitted --> Rejected: reject
Approved --> [*]
Rejected --> Draft: reviseMermaid class diagram
classDiagram
class User {
+string id
+string email
+login()
}
class Order {
+string id
+decimal total
+submit()
}
User "1" --> "0..*" Order : placesMermaid gantt
gantt
title Delivery Plan
dateFormat YYYY-MM-DD
section Discovery
Requirements :a1, 2026-01-01, 5d
Design :after a1, 4d
section Build
Implementation :2026-01-10, 10d
QA :2026-01-22, 5dMermaid mindmap
mindmap
root((Product Launch))
Research
Customer interviews
Market scan
Build
Prototype
QA
Go-to-market
Pricing
CampaignMermaid user journey
journey
title Trial Signup Journey
section Discover
Visit landing page: 4: User
Compare pricing: 3: User
section Activate
Create account: 5: User
Invite teammate: 4: UserGraphviz dependency graph
digraph G {
rankdir=LR;
node [shape=box, style=rounded];
app -> api;
api -> auth;
api -> db;
worker -> queue;
worker -> db;
}Graphviz clustered architecture
digraph G {
rankdir=LR;
compound=true;
node [shape=box, style=rounded];
subgraph cluster_client {
label="Client";
web;
mobile;
}
subgraph cluster_platform {
label="Platform";
api;
worker;
queue [shape=cylinder];
db [shape=cylinder];
}
web -> api;
mobile -> api;
api -> db;
api -> queue;
queue -> worker;
worker -> db;
}PlantUML sequence
@startuml
actor User
participant Web
participant API
database DB
User -> Web: Submit request
Web -> API: POST /request
API -> DB: Save record
DB --> API: OK
API --> Web: 201 Created
Web --> User: Confirmation
@endumlPlantUML component architecture
@startuml
actor User
rectangle "Client" {
[Web App]
}
rectangle "Backend" {
[API Service]
queue "Queue"
[Worker]
database "Database"
}
User --> [Web App]
[Web App] --> [API Service]
[API Service] --> Database
[API Service] --> Queue
Queue --> [Worker]
[Worker] --> Database
@endumlSVG fallback
<svg xmlns="http://www.w3.org/2000/svg" width="900" height="360" viewBox="0 0 900 360" role="img">
<title>Simple process diagram</title>
<defs>
<marker id="arrow" markerWidth="10" markerHeight="10" refX="8" refY="3" orient="auto">
<path d="M0,0 L0,6 L9,3 z" />
</marker>
</defs>
<rect x="40" y="120" width="160" height="70" rx="10" fill="white" stroke="black" />
<text x="120" y="160" text-anchor="middle">Start</text>
<line x1="200" y1="155" x2="320" y2="155" stroke="black" marker-end="url(#arrow)" />
<rect x="320" y="120" width="180" height="70" rx="10" fill="white" stroke="black" />
<text x="410" y="160" text-anchor="middle">Process</text>
</svg>#!/usr/bin/env python3
"""Create sample diagram sources for smoke testing the diagram-generator skill."""
from pathlib import Path
SAMPLES = {
"sample_flow.mmd": """flowchart TD\n start([Start]) --> validate{Valid?}\n validate -- yes --> done([Done])\n validate -- no --> fix[Fix input]\n fix --> validate\n""",
"sample_graph.dot": """digraph G {\n rankdir=LR;\n node [shape=box, style=rounded];\n app -> api;\n api -> db;\n}\n""",
"sample_sequence.puml": """@startuml\nactor User\nparticipant API\nUser -> API: Request\nAPI --> User: Response\n@enduml\n""",
"sample.svg": """<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"200\" height=\"80\" role=\"img\"><title>Sample</title><rect x=\"10\" y=\"10\" width=\"180\" height=\"60\" fill=\"white\" stroke=\"black\"/><text x=\"100\" y=\"45\" text-anchor=\"middle\">Sample</text></svg>\n""",
}
def main() -> int:
out_dir = Path.cwd() / "samples"
out_dir.mkdir(exist_ok=True)
for name, content in SAMPLES.items():
path = out_dir / name
path.write_text(content, encoding="utf-8")
print(path)
return 0
if __name__ == "__main__":
raise SystemExit(main())
#!/usr/bin/env python3
"""Render Mermaid, Graphviz DOT, PlantUML, or SVG diagram source to an output file.
The script is intentionally dependency-tolerant. It uses common command-line
renderers when available and prints actionable hints otherwise.
"""
from __future__ import annotations
import argparse
import os
import shutil
import subprocess
import sys
import tempfile
from pathlib import Path
MERMAID_EXTS = {".mmd", ".mermaid"}
GRAPHVIZ_EXTS = {".dot", ".gv"}
PLANTUML_EXTS = {".puml", ".plantuml"}
SVG_EXTS = {".svg"}
def run(cmd: list[str], cwd: Path | None = None) -> None:
print("$ " + " ".join(cmd))
completed = subprocess.run(cmd, cwd=str(cwd) if cwd else None, text=True, capture_output=True)
if completed.stdout:
print(completed.stdout, end="")
if completed.stderr:
print(completed.stderr, end="", file=sys.stderr)
if completed.returncode != 0:
raise RuntimeError(f"command failed with exit code {completed.returncode}")
def infer_kind(path: Path) -> str:
ext = path.suffix.lower()
if ext in MERMAID_EXTS:
return "mermaid"
if ext in GRAPHVIZ_EXTS:
return "graphviz"
if ext in PLANTUML_EXTS:
return "plantuml"
if ext in SVG_EXTS:
return "svg"
text = path.read_text(encoding="utf-8", errors="replace").lstrip()
if text.startswith("@startuml"):
return "plantuml"
if text.startswith("digraph") or text.startswith("graph"):
return "graphviz"
if text.startswith("<svg"):
return "svg"
return "mermaid"
def render_mermaid(src: Path, out: Path, fmt: str) -> None:
mmdc = shutil.which("mmdc")
if not mmdc:
raise RuntimeError(
"Mermaid rendering requires the Mermaid CLI executable `mmdc`. "
"Install it with `npm install -g @mermaid-js/mermaid-cli`, or return the Mermaid source only."
)
run([mmdc, "-i", str(src), "-o", str(out)])
def render_graphviz(src: Path, out: Path, fmt: str) -> None:
dot = shutil.which("dot")
if not dot:
raise RuntimeError(
"Graphviz rendering requires the `dot` executable. Install Graphviz, or return the DOT source only."
)
run([dot, f"-T{fmt}", str(src), "-o", str(out)])
def render_plantuml(src: Path, out: Path, fmt: str) -> None:
plantuml = shutil.which("plantuml")
java = shutil.which("java")
if plantuml:
with tempfile.TemporaryDirectory() as tmp:
tmp_path = Path(tmp)
temp_src = tmp_path / src.name
temp_src.write_text(src.read_text(encoding="utf-8"), encoding="utf-8")
run([plantuml, f"-t{fmt}", str(temp_src)], cwd=tmp_path)
produced = temp_src.with_suffix("." + fmt)
if not produced.exists():
candidates = list(tmp_path.glob(f"*.{fmt}"))
if not candidates:
raise RuntimeError("PlantUML completed but no output file was found")
produced = candidates[0]
shutil.copyfile(produced, out)
return
jar = os.environ.get("PLANTUML_JAR")
if java and jar and Path(jar).exists():
with tempfile.TemporaryDirectory() as tmp:
tmp_path = Path(tmp)
temp_src = tmp_path / src.name
temp_src.write_text(src.read_text(encoding="utf-8"), encoding="utf-8")
run([java, "-jar", jar, f"-t{fmt}", str(temp_src)], cwd=tmp_path)
produced = temp_src.with_suffix("." + fmt)
if not produced.exists():
candidates = list(tmp_path.glob(f"*.{fmt}"))
if not candidates:
raise RuntimeError("PlantUML completed but no output file was found")
produced = candidates[0]
shutil.copyfile(produced, out)
return
raise RuntimeError(
"PlantUML rendering requires `plantuml` on PATH, or Java plus PLANTUML_JAR pointing to plantuml.jar. "
"Return the PlantUML source only if no renderer is available."
)
def render_svg_source(src: Path, out: Path, fmt: str) -> None:
if fmt == "svg":
shutil.copyfile(src, out)
return
rsvg = shutil.which("rsvg-convert")
if rsvg:
run([rsvg, "-f", fmt, "-o", str(out), str(src)])
return
inkscape = shutil.which("inkscape")
if inkscape:
run([inkscape, str(src), f"--export-type={fmt}", f"--export-filename={out}"])
return
raise RuntimeError(
"SVG conversion requires `rsvg-convert` or `inkscape`. The SVG source itself is usable as an image."
)
def main() -> int:
parser = argparse.ArgumentParser(description="Render text diagram source to SVG, PNG, or PDF.")
parser.add_argument("input", type=Path, help="Input .mmd, .dot/.gv, .puml, or .svg file")
parser.add_argument("--format", choices=["svg", "png", "pdf"], default="svg", help="Output format")
parser.add_argument("--out", type=Path, help="Output path. Defaults to input name with the selected extension")
parser.add_argument("--kind", choices=["auto", "mermaid", "graphviz", "plantuml", "svg"], default="auto")
args = parser.parse_args()
src = args.input.resolve()
if not src.exists():
print(f"input file not found: {src}", file=sys.stderr)
return 2
out = (args.out or src.with_suffix("." + args.format)).resolve()
out.parent.mkdir(parents=True, exist_ok=True)
kind = infer_kind(src) if args.kind == "auto" else args.kind
try:
if kind == "mermaid":
render_mermaid(src, out, args.format)
elif kind == "graphviz":
render_graphviz(src, out, args.format)
elif kind == "plantuml":
render_plantuml(src, out, args.format)
elif kind == "svg":
render_svg_source(src, out, args.format)
else:
raise RuntimeError(f"unknown diagram kind: {kind}")
except Exception as exc:
print(f"render failed: {exc}", file=sys.stderr)
return 1
if not out.exists() or out.stat().st_size == 0:
print(f"render failed: output missing or empty: {out}", file=sys.stderr)
return 1
print(f"rendered {kind} diagram to {out}")
return 0
if __name__ == "__main__":
raise SystemExit(main())