adr-graph-easy-architect
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseADR Graph-Easy Architect
ADR Graph-Easy 架构图生成指南
Create comprehensive ASCII architecture diagrams for Architecture Decision Records (ADRs) using graph-easy. Pure text output with automatic layout - no image rendering required.
使用graph-easy为架构决策记录(ADRs)生成完整的ASCII架构图。纯文本输出,自动布局——无需图像渲染。
When to Use This Skill
何时使用本技能
- Writing new ADR that involves architectural changes
- ADR describes migration, integration, or system changes
- User asks for visual representation of a decision
- Existing ADR diagram needs review or update
- 撰写涉及架构变更的新ADR
- ADR描述迁移、集成或系统变更内容
- 用户需要决策的可视化表示
- 现有ADR图需要审核或更新
Preflight Check
预检查
Run these checks in order. Each layer depends on the previous.
按顺序运行以下检查,每一层都依赖于前一层。
Layer 1: Package Manager
第一层:包管理器
bash
/usr/bin/env bash << 'SETUP_EOF'bash
/usr/bin/env bash << 'SETUP_EOF'Detect OS and set package manager
Detect OS and set package manager
case "$(uname -s)" in
Darwin) PM="brew" ;;
Linux) PM="apt" ;;
*) echo "ERROR: Unsupported OS (require macOS or Linux)"; exit 1 ;;
esac
command -v $PM &>/dev/null || { echo "ERROR: $PM not installed"; exit 1; }
echo "✓ Package manager: $PM"
SETUP_EOF
undefinedcase "$(uname -s)" in
Darwin) PM="brew" ;;
Linux) PM="apt" ;;
*) echo "ERROR: Unsupported OS (require macOS or Linux)"; exit 1 ;;
esac
command -v $PM &>/dev/null || { echo "ERROR: $PM not installed"; exit 1; }
echo "✓ Package manager: $PM"
SETUP_EOF
undefinedLayer 2: Perl + cpanminus (mise-first approach)
第二层:Perl + cpanminus(优先使用mise)
bash
undefinedbash
undefinedPrefer mise for unified tool management
Prefer mise for unified tool management
if command -v mise &>/dev/null; then
Install Perl via mise
mise which perl &>/dev/null || mise install perl
Install cpanminus under mise perl
mise exec perl -- cpanm --version &>/dev/null 2>&1 || {
echo "Installing cpanminus under mise perl..."
mise exec perl -- curl -L https://cpanmin.us | mise exec perl -- perl - App::cpanminus
}
echo "✓ cpanminus installed (via mise perl)"
else
Fallback: Install cpanminus via system package manager
command -v cpanm &>/dev/null || {
echo "Installing cpanminus via $PM..."
case "$PM" in
brew) brew install cpanminus ;;
apt) sudo apt install -y cpanminus ;;
esac
}
echo "✓ cpanminus installed"
fi
undefinedif command -v mise &>/dev/null; then
Install Perl via mise
mise which perl &>/dev/null || mise install perl
Install cpanminus under mise perl
mise exec perl -- cpanm --version &>/dev/null 2>&1 || {
echo "Installing cpanminus under mise perl..."
mise exec perl -- curl -L https://cpanmin.us | mise exec perl -- perl - App::cpanminus
}
echo "✓ cpanminus installed (via mise perl)"
else
Fallback: Install cpanminus via system package manager
command -v cpanm &>/dev/null || {
echo "Installing cpanminus via $PM..."
case "$PM" in
brew) brew install cpanminus ;;
apt) sudo apt install -y cpanminus ;;
esac
}
echo "✓ cpanminus installed"
fi
undefinedLayer 3: Graph::Easy Perl module
第三层:Graph::Easy Perl模块
bash
undefinedbash
undefinedCheck if Graph::Easy is installed (mise-first)
Check if Graph::Easy is installed (mise-first)
if command -v mise &>/dev/null; then
mise exec perl -- perl -MGraph::Easy -e1 2>/dev/null || {
echo "Installing Graph::Easy via mise perl cpanm..."
mise exec perl -- cpanm Graph::Easy
}
echo "✓ Graph::Easy installed (via mise perl)"
else
perl -MGraph::Easy -e1 2>/dev/null || {
echo "Installing Graph::Easy via cpanm..."
cpanm Graph::Easy
}
echo "✓ Graph::Easy installed"
fi
undefinedif command -v mise &>/dev/null; then
mise exec perl -- perl -MGraph::Easy -e1 2>/dev/null || {
echo "Installing Graph::Easy via mise perl cpanm..."
mise exec perl -- cpanm Graph::Easy
}
echo "✓ Graph::Easy installed (via mise perl)"
else
perl -MGraph::Easy -e1 2>/dev/null || {
echo "Installing Graph::Easy via cpanm..."
cpanm Graph::Easy
}
echo "✓ Graph::Easy installed"
fi
undefinedLayer 4: Verify graph-easy is in PATH
第四层:验证graph-easy是否在PATH中
bash
undefinedbash
undefinedVerify graph-easy is accessible and functional
Verify graph-easy is accessible and functional
command -v graph-easy &>/dev/null || {
echo "ERROR: graph-easy not found in PATH"
exit 1
}
command -v graph-easy &>/dev/null || {
echo "ERROR: graph-easy not found in PATH"
exit 1
}
Test actual functionality (--version exits with code 2, unreliable)
Test actual functionality (--version exits with code 2, unreliable)
echo "[Test] -> [OK]" | graph-easy &>/dev/null && echo "✓ graph-easy ready"
undefinedecho "[Test] -> [OK]" | graph-easy &>/dev/null && echo "✓ graph-easy ready"
undefinedAll-in-One Preflight Script
一站式预检查脚本
bash
/usr/bin/env bash << 'PREFLIGHT_EOF'bash
/usr/bin/env bash << 'PREFLIGHT_EOF'Copy-paste this entire block to ensure graph-easy is ready (macOS + Linux)
Copy-paste this entire block to ensure graph-easy is ready (macOS + Linux)
Prefers mise for unified cross-platform tool management
Prefers mise for unified cross-platform tool management
Check for mise first (recommended)
Check for mise first (recommended)
if command -v mise &>/dev/null; then
echo "Using mise for Perl management..."
mise which perl &>/dev/null || mise install perl
mise exec perl -- cpanm --version &>/dev/null 2>&1 ||
mise exec perl -- curl -L https://cpanmin.us | mise exec perl -- perl - App::cpanminus mise exec perl -- perl -MGraph::Easy -e1 2>/dev/null || mise exec perl -- cpanm Graph::Easy else
mise exec perl -- curl -L https://cpanmin.us | mise exec perl -- perl - App::cpanminus mise exec perl -- perl -MGraph::Easy -e1 2>/dev/null || mise exec perl -- cpanm Graph::Easy else
Fallback: system package manager
echo "💡 Tip: Install mise for unified tool management: curl https://mise.run | sh"
case "$(uname -s)" in
Darwin) PM="brew" ;;
Linux) PM="apt" ;;
*) echo "ERROR: Unsupported OS"; exit 1 ;;
esac
command -v $PM &>/dev/null || { echo "ERROR: $PM not installed"; exit 1; }
command -v cpanm &>/dev/null || { [ "$PM" = "apt" ] && sudo apt install -y cpanminus || brew install cpanminus; }
perl -MGraph::Easy -e1 2>/dev/null || cpanm Graph::Easy
fi
if command -v mise &>/dev/null; then
echo "Using mise for Perl management..."
mise which perl &>/dev/null || mise install perl
mise exec perl -- cpanm --version &>/dev/null 2>&1 ||
mise exec perl -- curl -L https://cpanmin.us | mise exec perl -- perl - App::cpanminus mise exec perl -- perl -MGraph::Easy -e1 2>/dev/null || mise exec perl -- cpanm Graph::Easy else
mise exec perl -- curl -L https://cpanmin.us | mise exec perl -- perl - App::cpanminus mise exec perl -- perl -MGraph::Easy -e1 2>/dev/null || mise exec perl -- cpanm Graph::Easy else
Fallback: system package manager
echo "💡 Tip: Install mise for unified tool management: curl https://mise.run | sh"
case "$(uname -s)" in
Darwin) PM="brew" ;;
Linux) PM="apt" ;;
*) echo "ERROR: Unsupported OS"; exit 1 ;;
esac
command -v $PM &>/dev/null || { echo "ERROR: $PM not installed"; exit 1; }
command -v cpanm &>/dev/null || { [ "$PM" = "apt" ] && sudo apt install -y cpanminus || brew install cpanminus; }
perl -MGraph::Easy -e1 2>/dev/null || cpanm Graph::Easy
fi
Verify graph-easy is in PATH and functional
Verify graph-easy is in PATH and functional
command -v graph-easy &>/dev/null || {
echo "ERROR: graph-easy not in PATH after installation"
exit 1
}
command -v graph-easy &>/dev/null || {
echo "ERROR: graph-easy not in PATH after installation"
exit 1
}
Test actual functionality (--version exits with code 2, unreliable)
Test actual functionality (--version exits with code 2, unreliable)
echo "[Test] -> [OK]" | graph-easy &>/dev/null && echo "✓ graph-easy ready"
PREFLIGHT_EOF
---echo "[Test] -> [OK]" | graph-easy &>/dev/null && echo "✓ graph-easy ready"
PREFLIGHT_EOF
---Part 1: DSL Syntax
第一部分:DSL语法
Basic Elements
基础元素
undefinedundefinedNodes (square brackets)
Nodes (square brackets)
[Node Name]
[Node Name]
Edges (arrows)
Edges (arrows)
[A] -> [B]
[A] -> [B]
Labeled edges
Labeled edges
[A] -- label --> [B]
[A] -- label --> [B]
Bidirectional
Bidirectional
[A] <-> [B]
[A] <-> [B]
Chain
Chain
[A] -> [B] -> [C]
undefined[A] -> [B] -> [C]
undefinedGroups (Containers)
分组(容器)
undefinedundefinedNamed group with dashed border
Named group with dashed border
( Group Name:
[Node A]
[Node B]
)
( Group Name:
[Node A]
[Node B]
)
Nested connections
Nested connections
( Before:
[Old System]
)
( After:
[New System]
)
[Before] -> [After]
undefined( Before:
[Old System]
)
( After:
[New System]
)
[Before] -> [After]
undefinedNode Labels
节点标签
undefinedundefinedCustom label (different from ID)
Custom label (different from ID)
[db] { label: "PostgreSQL Database"; }
[db] { label: "PostgreSQL Database"; }
ASCII markers for visual distinction INSIDE boxes
ASCII markers for visual distinction INSIDE boxes
(emojis break box alignment - use ASCII markers instead)
(emojis break box alignment - use ASCII markers instead)
[deleted] { label: "[x] Old Component"; }
[added] { label: "[+] New Component"; }
[warning] { label: "[!] Deprecated"; }
[success] { label: "[OK] Passed"; }
**Character rules for nodes:**
- Graphical emojis (🚀 💡 ✅ ❌) - NEVER (double-width breaks box alignment)
- Unicode symbols (✓ ✗ ⚠ → ←) - OK (single-width, safe)
- ASCII markers ([x] [+] [!] :) ) - ALWAYS safe (monospace)
Use `graph { label: "..."; }` for graphical emojis in title/legend.
**Example: Emoji breaks alignment (DON'T DO THIS)**
[deleted] { label: "[x] Old Component"; }
[added] { label: "[+] New Component"; }
[warning] { label: "[!] Deprecated"; }
[success] { label: "[OK] Passed"; }
**节点字符规则:**
- 图形化emoji(🚀 💡 ✅ ❌)——绝对禁止(双宽度会破坏框对齐)
- Unicode符号(✓ ✗ ⚠ → ←)——允许(单宽度,安全)
- ASCII标记([x] [+] [!] :) )——始终安全(等宽)
在标题/图例中使用`graph { label: "..."; }`来添加图形化emoji。
**示例:Emoji破坏对齐(请勿这样做)**
BAD - emoji inside node
BAD - emoji inside node
[rocket] { label: "🚀 Launch"; }
Renders broken:
┌────────────┐
│ 🚀 Launch │ <-- box edge misaligned due to double-width emoji
└────────────┘
**Example: ASCII marker preserves alignment (DO THIS)**
[rocket] { label: "🚀 Launch"; }
渲染结果错乱:
┌────────────┐
│ 🚀 Launch │ <-- 由于双宽度emoji导致框边缘对齐错误
└────────────┘
**示例:ASCII标记保持对齐(推荐做法)**
GOOD - ASCII marker inside node
GOOD - ASCII marker inside node
[rocket] { label: "[>] Launch"; }
Renders correctly:
┌────────────┐
│ [>] Launch │
└────────────┘
**Example: Emoji safe in graph title (OK)**
[rocket] { label: "[>] Launch"; }
渲染结果正确:
┌────────────┐
│ [>] Launch │
└────────────┘
**示例:Emoji在图标题中安全使用(允许)**
OK - emoji in graph label (outside boxes)
OK - emoji in graph label (outside boxes)
graph { label: "🚀 Deployment Pipeline"; flow: east; }
[Build] -> [Test] -> [Deploy]
Renders correctly (emoji in title, not in boxes):
🚀 Deployment Pipeline┌───────┐ ┌──────┐ ┌────────┐
│ Build │ --> │ Test │ --> │ Deploy │
└───────┘ └──────┘ └────────┘
undefinedgraph { label: "🚀 Deployment Pipeline"; flow: east; }
[Build] -> [Test] -> [Deploy]
渲染结果正确(emoji在标题中,不在节点框内):
🚀 Deployment Pipeline┌───────┐ ┌──────┐ ┌────────┐
│ Build │ --> │ Test │ --> │ Deploy │
└───────┘ └──────┘ └────────┘
undefinedFlow Direction (MANDATORY: Always specify)
流向(必填:必须明确指定)
undefinedundefinedMANDATORY: Always specify flow direction explicitly
MANDATORY: Always specify flow direction explicitly
graph { flow: south; } # Top-to-bottom (architecture, decisions)
graph { flow: east; } # Left-to-right (pipelines, sequences)
Never rely on default flow - explicit is clearer.graph { flow: south; } # 从上到下(架构图、决策图)
graph { flow: east; } # 从左到右(流水线、序列图)
永远不要依赖默认流向——明确指定更清晰。Graph Title and Legend (Outside Boxes - Emojis Safe Here)
图标题和图例(节点框外——Emoji可安全使用)
Emojis break alignment INSIDE boxes but are SAFE in graph titles/legends.
Emoji Selection Guide - Choose emoji that matches diagram purpose:
| Diagram Type | Emoji | Example Title |
|---|---|---|
| Migration/Change | 🔄 | |
| Deployment/Release | 🚀 | |
| Data Flow | 📊 | |
| Security/Auth | 🔐 | |
| Error/Failure | ⚠️ | |
| Decision/Branch | 🔀 | |
| Architecture | 🏗️ | |
| Network/API | 🌐 | |
| Storage/Database | 💾 | |
| Monitoring/Observability | 📡 | |
| Hook/Event | 🪝 | |
| Before/After comparison | ⏮️/⏭️ | |
undefinedEmoji在节点框内会破坏对齐,但在图标题/图例中是安全的。
Emoji选择指南——选择与图用途匹配的emoji:
| 图类型 | Emoji | 示例标题 |
|---|---|---|
| 迁移/变更 | 🔄 | |
| 部署/发布 | 🚀 | |
| 数据流 | 📊 | |
| 安全/认证 | 🔐 | |
| 错误/故障 | ⚠️ | |
| 决策/分支 | 🔀 | |
| 架构 | 🏗️ | |
| 网络/API | 🌐 | |
| 存储/数据库 | 💾 | |
| 监控/可观测性 | 📡 | |
| 钩子/事件 | 🪝 | |
| 前后对比 | ⏮️/⏭️ | |
undefinedTitle with semantic emoji
带语义emoji的标题
graph { label: "🚀 Deployment Pipeline"; flow: east; }
graph { label: "🚀 Deployment Pipeline"; flow: east; }
Title with legend (multiline using \n)
带图例的标题(使用\n换行)
graph { label: "🪝 Hook Flow\n──────────\n✓ Allow ✗ Deny ⚠ Warn"; flow: south; }
**Rendered:**
Hook Flow
──────────
✓ Allow ✗ Deny ⚠ Warn
╭───────╮
│ Start │
╰───────╯
**Rule**: Emojis ONLY in `graph { label: "..."; }` - NEVER inside `[ node ]`graph { label: "🪝 Hook Flow\n──────────\n✓ Allow ✗ Deny ⚠ Warn"; flow: south; }
**渲染结果:**
Hook Flow
──────────
✓ Allow ✗ Deny ⚠ Warn
╭───────╮
│ Start │
╰───────╯
**规则**:Emoji仅可用于`graph { label: "..."; }`中——绝对不能在`[ node ]`内使用Node Styling (Best Practices)
节点样式(最佳实践)
undefinedundefinedRounded corners for start/end nodes
开始/结束节点使用圆角
[ Start ] { shape: rounded; }
[ End ] { shape: rounded; }
[ Start ] { shape: rounded; }
[ End ] { shape: rounded; }
Double border for emphasis
双边框用于强调
[ Critical Step ] { border: double; }
[ Critical Step ] { border: double; }
Bold border for important nodes
粗边框用于重要节点
[ Key Decision ] { border: bold; }
[ Key Decision ] { border: bold; }
Dotted border for optional/skippable
虚线边框用于可选/可跳过节点
[ Optional ] { border: dotted; }
[ Optional ] { border: dotted; }
Multiline labels with \n
使用\n实现多行标签
[ Hook Input\n(stdin JSON) ]
**Rendered examples:**
╭─────────╮ ┌─────────┐
│ Rounded │ │ Default │
╰─────────╯ └─────────┘
╔═════════╗ ┏━━━━━━━━━┓
║ Double ║ ┃ Bold ┃
╚═════════╝ ┗━━━━━━━━━┛
> **Note:** Dotted borders (`{ border: dotted; }`) use `⋮` characters that render inconsistently on GitHub. Use sparingly.[ Hook Input\n(stdin JSON) ]
**渲染示例:**
╭─────────╮ ┌─────────┐
│ Rounded │ │ Default │
╰─────────╯ └─────────┘
╔═════════╗ ┏━━━━━━━━━┓
║ Double ║ ┃ Bold ┃
╚═════════╝ ┗━━━━━━━━━┛
> **注意**:虚线边框(`{ border: dotted; }`)使用`⋮`字符,在GitHub上渲染效果不一致,请谨慎使用。Edge Styles
边样式
[ A ] -> [ B ] # Solid arrow (default)
[ A ] ..> [ B ] # Dotted arrow
[ A ] ==> [ B ] # Bold/double arrow
[ A ] - -> [ B ] # Dashed arrow
[ A ] -- label --> [ B ] # Labeled edge[ A ] -> [ B ] # 实线箭头(默认)
[ A ] ..> [ B ] # 虚线箭头
[ A ] ==> [ B ] # 粗/双箭头
[ A ] - -> [ B ] # 破折号箭头
[ A ] -- label --> [ B ] # 带标签的边Part 2: Common Diagram Patterns
第二部分:常见图模式
Migration (Before → After)
迁移(之前→之后)
graph { flow: south; }
[Before] -- migrate --> [After]graph { flow: south; }
[Before] -- migrate --> [After]Multi-Component System
多组件系统
graph { flow: south; }
[A] -> [B] -> [C]
[B] -> [D]graph { flow: south; }
[A] -> [B] -> [C]
[B] -> [D]Pipeline (Left-to-Right)
流水线(从左到右)
graph { flow: east; }
[Input] -> [Process] -> [Output]graph { flow: east; }
[Input] -> [Process] -> [Output]Decision with Options
带选项的决策
graph { flow: south; }
[Decision] -> [Option A]
[Decision] -> [Option B]graph { flow: south; }
[Decision] -> [Option A]
[Decision] -> [Option B]Grouped Components
分组组件
( Group:
[Component 1]
[Component 2]
)
[External] -> [Component 1]( Group:
[Component 1]
[Component 2]
)
[External] -> [Component 1]Bidirectional Flow
双向流
[Client] <-> [Server]
[Server] -> [Database][Client] <-> [Server]
[Server] -> [Database]Part 3: Rendering
第三部分:渲染
Command (MANDATORY: Always use boxart)
命令(必填:始终使用boxart)
bash
undefinedbash
undefinedMANDATORY: Always use --as=boxart for clean output
MANDATORY: Always use --as=boxart for clean output
graph-easy --as=boxart << 'EOF'
graph { flow: south; }
[A] -> [B] -> [C]
EOF
**Never use** `--as=ascii` - it produces ugly `+--+` boxes instead of clean `┌──┐` lines.graph-easy --as=boxart << 'EOF'
graph { flow: south; }
[A] -> [B] -> [C]
EOF
**绝对不要使用** `--as=ascii`——它会生成丑陋的`+--+`框,而非整洁的`┌──┐`线条。Output Modes
输出模式
| Mode | Command | Usage |
|---|---|---|
| | MANDATORY - clean Unicode lines |
| | NEVER USE - ugly output, legacy only |
| 模式 | 命令 | 用途 |
|---|---|---|
| | 必填——整洁的Unicode线条 |
| | 绝对不要使用——输出丑陋,仅为遗留模式 |
Validation Workflow
验证流程
bash
undefinedbash
undefined1. Write DSL to heredoc
1. 将DSL写入here文档
2. Render with boxart
2. 使用boxart渲染
graph-easy --as=boxart << 'EOF'
[Your] -> [Diagram] -> [Here]
EOF
graph-easy --as=boxart << 'EOF'
[Your] -> [Diagram] -> [Here]
EOF
3. Review output
3. 检查输出
4. Iterate if needed
4. 如有需要则迭代修改
5. Copy final ASCII to ADR
5. 将最终ASCII图复制到ADR中
---
---Part 4: Embedding in ADR
第四部分:嵌入到ADR中
Markdown Format (MANDATORY: Always Include Source)
Markdown格式(必填:始终包含源代码)
CRITICAL: Every rendered diagram MUST be followed by a collapsible block containing the graph-easy source code. This is non-negotiable for:
<details>- Reproducibility: Future maintainers can regenerate the diagram
- Editability: Source can be modified and re-rendered
- Auditability: Changes to diagrams are trackable in git diffs
markdown
undefined关键要求:每个渲染后的图必须紧跟一个可折叠的块,其中包含graph-easy源代码。这是不可协商的,原因如下:
<details>- 可复现性:未来维护者可以重新生成图
- 可编辑性:源代码可修改并重新渲染
- 可审计性:图的变更可在git diff中追踪
markdown
undefinedArchitecture
Architecture
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Before │ ──> │ After │ ──> │ Database │
└──────────┘ └──────────┘ └──────────┘graph { flow: east; }
[Before] -> [After] -> [Database]The block is MANDATORY - never embed a diagram without its source.
<details>┌──────────┐ ┌──────────┐ ┌──────────┐
│ Before │ ──> │ After │ ──> │ Database │
└──────────┘ └──────────┘ └──────────┘graph { flow: east; }
[Before] -> [After] -> [Database]<details>GFM Collapsible Section Syntax
GFM可折叠区域语法
GitHub Flavored Markdown supports HTML and tags for collapsible sections. Key syntax rules:
<details><summary>Structure:
html
<details>
<summary>Click to expand</summary>
<!-- BLANK LINE REQUIRED HERE -->
Content goes here (Markdown supported)
<!-- BLANK LINE REQUIRED HERE -->
</details>Critical rules:
- Blank lines required - Must have empty line after and before
<summary>for Markdown to render</details> - No indentation - and
<details>must be at column 0 (no leading spaces)<summary> - Summary is clickable label - Text in appears as the collapsed header
<summary> - Markdown inside works - Code blocks, headers, lists all render correctly inside
Optional: Default expanded:
html
<details open>
<summary>Expanded by default</summary>
Content visible on page load
</details>Common mistake (Markdown won't render):
html
<details>
<summary>Broken</summary>
No blank line - this won't render as Markdown!
</details>References:
GitHub风味Markdown支持HTML的和标签来创建可折叠区域。关键语法规则:
<details><summary>结构:
html
<details>
<summary>点击展开</summary>
<!-- 此处必须留空行 -->
内容写在这里(支持Markdown)
<!-- 此处必须留空行 -->
</details>关键规则:
- 必须留空行——后和
<summary>前必须有空行,Markdown才能正确渲染</details> - 不要缩进——和
<details>必须从第0列开始(无前置空格)<summary> - 摘要为可点击标签——中的文本作为折叠状态的标题
<summary> - 内部支持Markdown——代码块、标题、列表等在内部均可正确渲染
可选:默认展开
html
<details open>
<summary>默认展开</summary>
页面加载时内容可见
</details>常见错误(Markdown无法渲染):
html
<details>
<summary>错误示例</summary>
没有空行——这部分无法作为Markdown渲染!
</details>File Organization
文件组织
No separate asset files needed - diagram is inline in the markdown.
无需单独的资源文件——图直接内联在Markdown中。
Regeneration
重新生成
If ADR changes, regenerate by running the source through graph-easy again:
bash
undefined如果ADR发生变更,可通过将源代码再次传入graph-easy来重新生成图:
bash
undefinedExtract source from <details> block, pipe through graph-easy
从<details>块中提取源代码,通过管道传给graph-easy
graph-easy --as=boxart << 'EOF'
graph-easy --as=boxart << 'EOF'
paste source here
粘贴源代码到此处
EOF
---EOF
---Reference: Monospace-Safe Symbols
参考:等宽安全符号
Avoid emojis - they have variable width and break box alignment on GitHub.
避免使用emoji——它们宽度可变,会在GitHub上破坏框对齐。
Status Markers
状态标记
| Meaning | Marker |
|---|---|
| Added/New | |
| Removed/Deleted | |
| Changed/Updated | |
| Warning/Deprecated | |
| Deferred/Pending | |
| Current/Active | |
| Optional | |
| Locked/Fixed | |
| 含义 | 标记 |
|---|---|
| 新增/添加 | |
| 移除/删除 | |
| 修改/更新 | |
| 警告/废弃 | |
| 延迟/待处理 | |
| 当前/活跃 | |
| 可选 | |
| 锁定/固定 | |
Box Drawing (U+2500-257F)
框绘制字符(U+2500-257F)
─ │ ┌ ┐ └ ┘ ├ ┤ ┬ ┴ ┼ (light)
═ ║ ╔ ╗ ╚ ╝ ╠ ╣ ╦ ╩ ╬ (double)─ │ ┌ ┐ └ ┘ ├ ┤ ┬ ┴ ┼ (细线条)
═ ║ ╔ ╗ ╚ ╝ ╠ ╣ ╦ ╩ ╬ (双线条)Arrows & Pointers
箭头与指针
→ ← ↑ ↓ (arrows)
∨ ∧ (logic - graph-easy uses these)
< > ^ v (ASCII arrows)→ ← ↑ ↓ (箭头)
∨ ∧ (逻辑符号——graph-easy使用这些)
< > ^ v (ASCII箭头)Shapes & Bullets
形状与项目符号
• ○ ● (bullets)
□ ■ (squares)
◇ ◆ (diamonds)• ○ ● (项目符号)
□ ■ (正方形)
◇ ◆ (菱形)Math & Logic
数学与逻辑符号
× ÷ ± ≠ ≤ ≥ ∞ (math)
∧ ∨ ¬ (logic)× ÷ ± ≠ ≤ ≥ ∞ (数学符号)
∧ ∨ ¬ (逻辑符号)Reference: Common Patterns
参考:常见模式
undefinedundefinedVertical flow (architecture)
垂直流向(架构图)
graph { flow: south; }
graph { flow: south; }
Horizontal flow (pipeline)
水平流向(流水线)
graph { flow: east; }
graph { flow: east; }
Labeled edge
带标签的边
[A] -- label text --> [B]
[A] -- label text --> [B]
Group with border
带边框的分组
( Group Name:
[Node A]
[Node B]
)
( Group Name:
[Node A]
[Node B]
)
Custom node label
自定义节点标签
[id] { label: "Display Name"; }
---[id] { label: "显示名称"; }
---Graph Label (MANDATORY: EVERY diagram MUST have emoji + title)
图标签(必填:每个图必须包含emoji + 标题)
WARNING: This is the most commonly forgotten requirement. Diagrams without labels are invalid.
警告:这是最常被遗忘的要求。没有标签的图是无效的。
Correct Example
正确示例
graph { label: "🔄 Database Migration"; flow: south; }
[Old DB] -> [New DB]graph { label: "🔄 Database Migration"; flow: south; }
[Old DB] -> [New DB]Anti-Pattern (INVALID - DO NOT DO THIS)
反模式(无效——请勿这样做)
graph { flow: south; }
[Old DB] -> [New DB]Why this is wrong: Missing with emoji. The preflight validator will BLOCK any ADR containing diagrams without .
label:graph { label: "emoji ..."; }graph { flow: south; }
[Old DB] -> [New DB]错误原因:缺少带emoji的。预检查验证器会阻止任何包含无图的ADR。
label:graph { label: "emoji ..."; }Mandatory Checklist (Before Rendering)
渲染前必填检查清单
Graph-Level (MUST have)
图级别(必须具备)
- - semantic emoji + title (MOST FORGOTTEN - check first!)
graph { label: "🚀 Title"; } - or
graph { flow: south; }- explicit directiongraph { flow: east; } - Command uses - NEVER
--as=boxart--as=ascii
- ——语义emoji + 标题(最容易被遗忘——首先检查!)
graph { label: "🚀 标题"; } - 或
graph { flow: south; }——明确指定流向graph { flow: east; } - 命令使用——绝对不要使用
--as=boxart--as=ascii
Embedding (MUST have - non-negotiable)
嵌入要求(必须具备——不可协商)
- block with source - EVERY diagram MUST have collapsible source code block
<details> - Format: rendered diagram in block, followed immediately by
```with source in<details><summary>graph-easy source</summary>block``` - Never commit a diagram without its reproducible source
- 包含源代码的块——每个图必须紧跟可折叠的源代码块
<details> - 格式:渲染后的图放在块中,紧跟
```,源代码放在<details><summary>graph-easy source</summary>块中``` - 绝对不要提交没有可复现源代码的图
Node Styling (Visual hierarchy)
节点样式(视觉层次)
- Start/end nodes: - entry/exit points
{ shape: rounded; } - Critical/important nodes: or
{ border: double; }{ border: bold; } - Optional/skippable nodes:
{ border: dotted; } - Default nodes: no styling (standard border)
┌──┐ - Long labels use for multiline - max ~15 chars per line
\n
- 开始/结束节点:——入口/出口点
{ shape: rounded; } - 关键/重要节点:或
{ border: double; }{ border: bold; } - 可选/可跳过节点:
{ border: dotted; } - 默认节点:无样式(标准边框)
┌──┐ - 长标签使用换行——每行最多约15个字符
\n
Edge Styling (Semantic meaning)
边样式(语义含义)
- Main/happy path: solid arrow
-> - Conditional/alternate: dotted arrow
..> - Emphasized/critical: bold arrow
==> - Edge labels are SHORT (1-3 words): ,
-- YES -->-- error -->
- 主路径/正常流程:实线箭头
-> - 条件/备选路径:虚线箭头
..> - 重点/关键路径:粗箭头
==> - 边标签要简短(1-3个单词):,
-- YES -->-- error -->
Character Safety (Alignment)
字符安全(对齐)
- NO graphical emojis inside nodes (🚀 💡 ✅ ❌ break alignment)
- Unicode symbols OK inside nodes (✓ ✗ ⚠ are single-width)
- ASCII markers ALWAYS safe ([x] [+] [!] [OK])
- Graphical emojis ONLY in title
graph { label: "..."; }
- 节点内禁止使用图形化emoji(🚀 💡 ✅ ❌会破坏对齐)
- 节点内可使用Unicode符号(✓ ✗ ⚠为单宽度)
- ASCII标记始终安全([x] [+] [!] [OK])
- 图形化emoji仅可用于标题中
graph { label: "..."; }
Structure (Organization)
结构(组织)
- Groups used for logical clustering when 4+ related nodes
( Name: ... ) - Node IDs short, labels descriptive:
[db] { label: "PostgreSQL"; } - No more than 7-10 nodes per diagram (split if larger)
- 当有4个以上相关节点时,使用分组进行逻辑聚类
( Name: ... ) - 节点ID简短,标签描述性强:
[db] { label: "PostgreSQL"; } - 每个图节点数不超过7-10个(如果更多则拆分)
Success Criteria
成功标准
Correctness
正确性
- Parses without error - graph-easy accepts the DSL
- Renders cleanly - no misaligned boxes or broken lines
- Matches content - all key elements from description represented
- Source preserved (MANDATORY) - EVERY diagram MUST have block with graph-easy DSL source immediately after the rendered output
<details>
- 无错误解析——graph-easy可接受该DSL
- 渲染整洁——无对齐错误的框或断裂线条
- 内容匹配——描述中的所有关键元素均已呈现
- 源代码已保留(必填)——每个图必须在渲染输出后紧跟包含graph-easy DSL源代码的块
<details>
Aesthetics
美观性
- Uses boxart - clean Unicode lines , not ASCII
┌──┐+--+ - Visual hierarchy - start/end rounded, important bold/double, optional dotted
- Consistent styling - same border style = same semantic meaning throughout
- Readable labels - multiline with , no truncation
\n - Clear flow - direction matches natural reading (top-down or left-right)
- 使用boxart——整洁的Unicode线条,而非ASCII的
┌──┐+--+ - 视觉层次清晰——开始/结束节点用圆角,重要节点用粗/双边框,可选节点用虚线边框
- 样式一致——相同边框样式代表相同语义
- 标签可读——使用换行,无截断
\n - 流向清晰——流向符合自然阅读习惯(从上到下或从左到右)
Comprehensiveness
完整性
- Semantic emoji in title - emoji consciously chosen to match diagram purpose (see Emoji Selection Guide)
- Legend if needed - multiline title with for complex diagrams
\n - Edge semantics - solid=normal, dotted=conditional, bold=critical
- Logical grouping - related nodes in containers
( Group: ... )
- 标题带语义emoji——根据图的用途有意识选择emoji(参考Emoji选择指南)
- 复杂图带图例——使用实现多行标题添加图例
\n - 边语义明确——实线=正常,虚线=条件,粗线=关键
- 逻辑分组合理——相关节点放在容器中
( Group: ... )
Troubleshooting
故障排除
| Issue | Cause | Solution |
|---|---|---|
| graph-easy not installed | Run preflight check |
| Misaligned boxes | Used | Always use |
| Box border broken | Graphical emoji in node | Remove 🚀💡, use ✓✗ or [x][+] |
| Nodes overlap | Too complex | Split into multiple diagrams (max 7-10 nodes) |
| Edge labels cut off | Label too long | Shorten to 1-3 words |
| No title showing | Wrong syntax | Use |
| Weird layout | No flow direction | Add |
| Parse error | Special chars in node | Escape or simplify node names |
| 问题 | 原因 | 解决方案 |
|---|---|---|
| graph-easy未安装 | 运行预检查 |
| 框对齐错误 | 使用了 | 始终使用 |
| 框边框断裂 | 节点内使用了图形化emoji | 移除🚀💡,改用✓✗或[x][+] |
| 节点重叠 | 图过于复杂 | 拆分为多个图(每个图最多7-10个节点) |
| 边标签被截断 | 标签过长 | 缩短为1-3个单词 |
| 标题未显示 | 语法错误 | 使用 |
| 布局怪异 | 未指定流向 | 添加 |
| 解析错误 | 节点包含特殊字符 | 转义或简化节点名称 |