Create ASCII diagrams for markdown using graph-easy. TRIGGERS - ASCII diagram, graph-easy, architecture diagram, markdown diagram.
Install to Claude Code
npx -y skills add majiayu000/claude-skill-registry --skill graph-easy --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Graph Easy?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/majiayu000-graph-easy)More formats (shields.io, HTML) on the badges page.
---
name: graph-easy
description: Create ASCII diagrams for markdown using graph-easy. TRIGGERS - ASCII diagram, graph-easy, architecture diagram, markdown diagram.
---
# Graph-Easy Diagram Skill
Create ASCII architecture diagrams for any GitHub Flavored Markdown file using graph-easy. Pure text output with automatic layout - no image rendering required.
## When to Use This Skill
- Adding diagrams to README files
- Design specification documentation
- Any GFM markdown file needing architecture visualization
- Creating flowcharts, pipelines, or system diagrams
- User mentions "diagram", "ASCII diagram", "graph-easy", or "architecture chart"
**NOT for ADRs** - Use `adr-graph-easy-architect` for Architecture Decision Records (includes ADR-specific patterns like 2-diagram requirement and before/after templates).
## Preflight Check
Run these checks in order. Each layer depends on the previous.
### Layer 1: Package Manager
```bash
/usr/bin/env bash << 'SETUP_EOF'
# 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
```
### Layer 2: Perl + cpanminus (mise-first approach)
```bash
# 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
```
### Layer 3: Graph::Easy Perl module
```bash
# 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
```
### Layer 4: Verify graph-easy is in PATH
```bash
# Verify graph-easy is accessible and functional
command -v graph-easy &>/dev/null || {
echo "ERROR: graph-easy not found in PATH"
exit 1
}
# Test actual functionality (--version hangs waiting for stdin AND exits with code 2)
echo "[Test] -> [OK]" | graph-easy &>/dev/null && echo "✓ graph-easy ready"
```
### All-in-One Preflight Script
```bash
/usr/bin/env bash << 'PREFLIGHT_EOF'
# Copy-paste this entire block to ensure graph-easy is ready (macOS + Linux)
# Prefers mise for unified cross-platform tool management
# 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
# 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
command -v graph-easy &>/dev/null || {
echo "ERROR: graph-easy not in PATH after installation"
exit 1
}
# Test actual functionality (--version hangs waiting for stdin AND exits with code 2)
echo "[Test] -> [OK]" | graph-easy &>/dev/null && echo "✓ graph-easy ready"
PREFLIGHT_EOF
```
---
## Part 1: DSL Syntax
### Basic Elements
```
# Nodes (square brackets)
[Node Name]
# Edges (arrows)
[A] -> [B]
# Labeled edges
[A] -- label --> [B]
# Bidirectional
[A] <-> [B]
# Chain
[A] -> [B] -> [C]
```
### Groups (Containers)
```
# Named group with dashed border
( Group Name:
[Node A]
[Node B]
)
# Nested connections
( Frontend:
[React App]
[API Client]
)
( Backend:
[API Server]
[Database]
)
[API Client] -> [API Server]
```
### Node Labels
```
# Custom label (different from ID)
[db] { label: "PostgreSQL Database"; }
# ASCII markers for visual distinction INSIDE boxes
# (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 (rocket, bulb, checkmark) - NEVER (double-width breaks box alignment)
- Unicode symbols (check, cross, arrow) - 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)**
```
# 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)**
```
# GOOD - ASCII marker inside node
[rocket] { label: "[>] Launch"; }
```
Renders correctly:
```
+--------------+
| [>] Launch |
+--------------+
```
### Flow Direction (MANDATORY: Always specify)
```
# 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 Title and Legend (Outside Boxes - Emojis Safe Here)
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 | swap | `"Database Migration"` |
| Deployment/Release | rocket | `"Deployment Pipeline"` |
| Data Flow | chart | `"Data Ingestion Flow"` |
| Security/Auth | lock | `"Authentication Flow"` |
| Error/Failure | warn | `"Error Handling"` |
| Decision/Branch | split | `"Routing Decision"` |
| Architecture | build | `"System Architecture"` |
| Network/API | globe | `"API Integration"` |
| Storage/Database | disk | `"Storage Layer"` |
| Monitoring/Observability | signal | `"Monitoring Stack"` |
```
# Title with semantic emoji
graph { label: "Deployment Pipeline"; flow: east; }
# Title with legend (multiline using \n)
graph { label: "Hook Flow\n----------\nAllow Deny Warn"; flow: south; }
```
### Node Styling (Best Practices)
```
# Rounded corners for start/end nodes
[ Start ] { shape: rounded; }
[ End ] { shape: rounded; }
# Double border for emphasis
[ Critical Step ] { border: double; }
# Bold border for important nodes
[ Key Decision ] { border: bold; }
# Dotted border for optional/skippable
[ Optional ] { border: dotted; }
# Multiline labels with \n
[ Hook Input\n(stdin JSON) ]
```
**Rendered examples:**
```
+----------+ +---------+
| Rounded | | Default |
+----------+ +---------+
+==========+ +=========+
| Double | | Bold |
+==========+ +=========+
```
> **Note:** Dotted borders (`{ border: dotted; }`) use special characters that render inconsistently on GitHub. Use sparingly.
### 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
```
---
## Part 2: Common Diagram Patterns
### Pipeline (Left-to-Right)
```
graph { flow: east; }
[Input] -> [Process] -> [Output]
```
### Multi-Component System
```
graph { flow: south; }
[API Gateway] -> [Service A]
[API Gateway] -> [Service B]
[Service A] -> [Database]
[Service B] -> [Database]
```
### Decision with Options
```
graph { flow: south; }
[Decision] -> [Option A]
[Decision] -> [Option B]
[Decision] -> [Option C]
```
### Grouped Components
```
( Frontend:
[React App]
[Vue App]
)
( Backend:
[API Server]
[Worker]
)
[React App] -> [API Server]
[Vue App] -> [API Server]
[API Server] -> [Worker]
```
### Bidirectional Flow
```
[Client] <-> [Server]
[Server] -> [Database]
```
### Layered Architecture
```
graph { flow: south; }
( Presentation:
[UI Components]
)
( Business:
[Services]
)
( Data:
[Repository]
[Database]
)
[UI Components] -> [Services]
[Services] -> [Repository]
[Repository] -> [Database]
```
---
## Part 3: Rendering
### Command (Platform-Aware)
```bash
# For GitHub markdown (RECOMMENDED) - renders as solid lines
graph-easy --as=ascii << 'EOF'
graph { flow: south; }
[A] -> [B] -> [C]
EOF
# For terminal/local viewing - prettier Unicode lines
graph-easy --as=boxart << 'EOF'
graph { flow: south; }
[A] -> [B] -> [C]
EOF
```
### Output Modes
| Mode | Command | When to Use |
| -------- | ------------- | --------------------------------------------------------------- |
| `ascii` | `--as=ascii` | **GitHub markdown** - `+--+` renders as solid lines everywhere |
| `boxart` | `--as=boxart` | **Terminal only** - `┌──┐` looks nice locally, dotted on GitHub |
**Why ASCII for GitHub?** GitHub's markdown preview renders Unicode box-drawing characters (`┌─┐│└─┘`) as **dotted lines**, breaking the visual appearance. Pure ASCII (`+---+`, `|`) renders correctly as solid lines on all platforms.
### Validation Workflow
```bash
# 1. Write DSL to heredoc
# 2. Render with ascii (for GitHub) or boxart (for terminal)
graph-easy --as=ascii << 'EOF'
[Your] -> [Diagram] -> [Here]
EOF
# 3. Review output
# 4. Iterate if needed
# 5. Copy final output to markdown
# 6. Validate alignment (RECOMMENDED)
```
### Post-Generation Alignment Validation (Recommended)
After embedding diagram in markdown, validate alignment to catch rendering issues.
**Use the doc-tools plugin skill:**
```
Skill: doc-tools:ascii-diagram-validator
```
Or invoke directly: `Skill(doc-tools:ascii-diagram-validator)` with the target file path.
**Why validate?**
- Catches copy-paste alignment drift
- Detects font rendering issues
- Ensures vertical columns align properly
- Graph-easy output is machine-aligned, but manual edits can break it
**When to skip**: If diagram was just generated by graph-easy and not manually edited, validation is optional (output is inherently aligned).
---
## Part 4: Embedding in Markdown
### Markdown Format (MANDATORY: Always Include Source)
**CRITICAL**: Every rendered diagram MUST be followed by a collapsible `<details>` block containing the graph-easy source code. This is non-negotiable for:
- **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
## Architecture
```
+----------+ +----------+ +----------+
| Input | --> | Process | --> | Output |
+----------+ +----------+ +----------+
```
<details>
<summary>graph-easy source</summary>
```
graph { flow: east; }
[Input] -> [Process] -> [Output]
```
</details>
````
**The `<details>` block is MANDATORY** - never embed a diagram without its source.
### GFM Collapsible Section Syntax
GitHub Flavored Markdown supports HTML `<details>` and `<summary>` tags for collapsible sections. Key syntax rules:
**Structure:**
```html
<details>
<summary>Click to expand</summary>
<!-- BLANK LINE REQUIRED HERE -->
Content goes here (Markdown supported)
<!-- BLANK LINE REQUIRED HERE -->
</details>
```
**Critical rules:**
1. **Blank lines required** - Must have empty line after `<summary>` and before `</details>` for Markdown to render
2. **No indentation** - `<details>` and `<summary>` must be at column 0 (no leading spaces)
3. **Summary is clickable label** - Text in `<summary>` appears as the collapsed header
4. **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 Docs: Collapsed sections](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/organizing-information-with-collapsed-sections)
### Regeneration
If the markdown changes, regenerate by running the source through graph-easy again:
```bash
# Extract source from <details> block, pipe through graph-easy
graph-easy --as=boxart << 'EOF'
# paste source here
EOF
```
---
## Reference: Monospace-Safe Symbols
**Avoid emojis** - they have variable width and break box alignment on GitHub.
### Status Markers
| Meaning | Marker |
| ------------------ | ------ |
| Added/New | `[+]` |
| Removed/Deleted | `[x]` |
| Changed/Updated | `[*]` |
| Warning/Deprecated | `[!]` |
| Deferred/Pending | `[~]` |
| Current/Active | `[>]` |
| Optional | `[?]` |
| Locked/Fixed | `[=]` |
### Box Drawing (U+2500-257F)
```
- | + + + + + + + + + (light)
= | + + + + + + + + + (double)
```
### Arrows & Pointers
```
-> <- up down (arrows)
v ^ (logic - graph-easy uses these)
< > ^ v (ASCII arrows)
```
### Shapes & Bullets
```
* o O (bullets)
[ ] # (squares)
< > <> (diamonds)
```
---
## Graph Label (MANDATORY: EVERY diagram MUST have emoji + title)
**WARNING**: This is the most commonly forgotten requirement. Diagrams without labels are invalid.
### Correct Example
```
graph { label: "🚀 Deployment Pipeline"; flow: east; }
[Build] -> [Test] -> [Deploy]
```
### Anti-Pattern (INVALID - DO NOT DO THIS)
```
graph { flow: east; }
[Build] -> [Test] -> [Deploy]
```
**Why this is wrong**: Missing `label:` with emoji. Every diagram needs context at a glance.
---
## Mandatory Checklist (Before Rendering)
### Graph-Level (MUST have)
- [ ] **`graph { label: "🚀 Title"; }`** - semantic emoji + title (MOST FORGOTTEN - check first!)
- [ ] `graph { flow: south; }` or `graph { flow: east; }` - explicit direction
- [ ] Command uses `--as=ascii` for GitHub markdown (or `--as=boxart` for terminal only)
### Embedding (MUST have - non-negotiable)
- [ ] **`<details>` block with source** - EVERY diagram MUST have collapsible source code block
- [ ] Format: rendered diagram in code block, followed immediately by `<details><summary>graph-easy source</summary>` with source in code block
- [ ] Never commit a diagram without its reproducible source
### Post-Embedding Validation (Recommended)
- [ ] Run `ascii-diagram-validator` on the file after embedding diagram
- [ ] Especially important if diagram was manually edited after generation
- [ ] Catches alignment drift from copy-paste or font rendering issues
### Node Styling (Visual hierarchy)
- [ ] Start/end nodes: `{ shape: rounded; }` - entry/exit points
- [ ] Critical/important nodes: `{ border: double; }` or `{ border: bold; }`
- [ ] Optional/skippable nodes: `{ border: dotted; }`
- [ ] Default nodes: no styling (standard border)
- [ ] Long labels use `\n` for multiline - max ~15 chars per line
### 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 -->`
### Character Safety (Alignment)
- [ ] NO graphical emojis inside nodes (break alignment)
- [ ] Unicode symbols OK inside nodes (single-width)
- [ ] ASCII markers ALWAYS safe ([x] [+] [!] [OK])
- [ ] Graphical emojis ONLY in `graph { label: "..."; }` title
### Structure (Organization)
- [ ] Groups `( Name: ... )` used for logical clustering when 4+ related nodes
- [ ] Node IDs short, labels descriptive: `[db] { label: "PostgreSQL"; }`
- [ ] No more than 7-10 nodes per diagram (split if larger)
## Success Criteria
### Correctness
1. **Parses without error** - graph-easy accepts the DSL
2. **Renders cleanly** - no misaligned boxes or broken lines
3. **Matches content** - all key elements from description represented
4. **Source preserved (MANDATORY)** - EVERY diagram MUST have `<details>` block with graph-easy DSL source immediately after the rendered output
### Aesthetics
1. **Platform-appropriate output** - `--as=ascii` for GitHub (solid lines), `--as=boxart` for terminal only
2. **Readable labels** - multiline with `\n`, no truncation
3. **Clear flow** - direction matches natural reading (top-down or left-right)
4. **Consistent styling** - same border style = same semantic meaning throughout
### Comprehensiveness
1. **Edge semantics** - solid=normal, dotted=conditional, bold=critical
2. **Logical grouping** - related nodes in `( Group: ... )` containers
## Troubleshooting
| Issue | Cause | Solution |
| ------------------- | ------------------------ | --------------------------------------------- |
| `command not found` | graph-easy not installed | Run preflight check |
| Dotted lines on GH | Used `--as=boxart` | Use `--as=ascii` for GitHub markdown |
| Box border broken | Graphical emoji in node | Remove emojis, use ASCII markers [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 `graph { label: "Title"; flow: south; }` |
| Weird layout | No flow direction | Add `graph { flow: south; }` or `flow: east` |
| Parse error | Special chars in node | Escape or simplify node names |
## Resources
- [Graph::Easy on CPAN](https://metacpan.org/dist/Graph-Easy)
- [Graph::Easy Manual](http://bloodgate.com/perl/graph/manual/)
- [Graph::Easy GitHub](https://github.com/ironcamel/Graph-Easy)
Scanned 2/12/2026
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!