Skill: jimliu/baoyu-diagram (version 1.117.3)

--- name: baoyu-diagram description: Create professional, dark-themed SVG diagrams of any type — architecture diagrams, flowcharts, sequence diagrams, structural diagrams, mind maps, timelines, illustrative/conceptual diagrams, and more. Use this skill whenever the user asks for any kind of technical or conceptual diagram, visualization of a system, process flow, data flow, component relationship, network topology, decision tree, org chart, state machine, or any visual representation of structure/logic/process. Also trigger when the user says "画个图" "画一个架构图" "diagram" "flowchart" "sequence diagram" "draw me a ..." or uploads content and asks to visualize it. Output is always a standalone .svg file. version: 1.117.3 --- # Diagram Generator Create professional SVG diagrams across multiple diagram types. All output is a single self-contained `.svg` file with embedded styles and fonts. ## Supported Diagram Types | Type | When to Use | Key Characteristics | |------|-------------|-------------------| | **Architecture** | System components & relationships | Grouped boxes, connection arrows, region boundaries | | **Flowchart** | Decision logic, process steps | Diamond decisions, rounded step boxes, directional flow | | **Sequence** | Time-ordered interactions between actors | Vertical lifelines, horizontal messages, activation bars | | **Structural** | Class diagrams, ER diagrams, org charts | Compartmented boxes, typed relationships (inheritance, composition) | | **Mind Map** | Brainstorming, topic exploration | Central node, radiating branches, organic layout | | **Timeline** | Chronological events | Horizontal/vertical axis, event markers, period spans | | **Illustrative** | Conceptual explanations, comparisons | Free-form layout, icons, annotations, visual metaphors | | **State Machine** | State transitions, lifecycle | Rounded state nodes, labeled transitions, start/end markers | | **Data Flow** | Data transformation pipelines | Process bubbles, data stores, external entities | ## Design System ### Color Palette Semantic colors for component categories: | Category | Fill (rgba) | Stroke | Use For | |----------|-------------|--------|---------| | Primary | `rgba(8, 51, 68, 0.4)` | `#22d3ee` (cyan) | Frontend, user-facing, inputs | | Secondary | `rgba(6, 78, 59, 0.4)` | `#34d399` (emerald) | Backend, services, processing | | Tertiary | `rgba(76, 29, 149, 0.4)` | `#a78bfa` (violet) | Database, storage, persistence | | Accent | `rgba(120, 53, 15, 0.3)` | `#fbbf24` (amber) | Cloud, infrastructure, regions | | Alert | `rgba(136, 19, 55, 0.4)` | `#fb7185` (rose) | Security, errors, warnings | | Connector | `rgba(251, 146, 60, 0.3)` | `#fb923c` (orange) | Buses, queues, middleware | | Neutral | `rgba(30, 41, 59, 0.5)` | `#94a3b8` (slate) | External, generic, unknown | | Highlight | `rgba(59, 130, 246, 0.3)` | `#60a5fa` (blue) | Active state, focus, current step | For flowcharts and sequence diagrams, assign colors by role (actor, decision, process) rather than by technology. ### Typography Use embedded SVG `@font-face` or system monospace fallback: ```svg <style> @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500;600;700&amp;display=swap'); text { font-family: 'JetBrains Mono', 'SF Mono', 'Cascadia Code', monospace; } </style> ``` Font sizes by role: - **Title:** 16px, weight 700 - **Component name:** 11-12px, weight 600 - **Sublabel / description:** 9px, weight 400, color `#94a3b8` - **Annotation / note:** 8px, weight 400 - **Tiny label (on arrows):** 7-8px ### Core Visual Elements **Background:** `#0f172a` (slate-900) with subtle grid: ```svg <defs> <pattern id="grid" width="40" height="40" patternUnits="userSpaceOnUse"> <path d="M 40 0 L 0 0 0 40" fill="none" stroke="#1e293b" stroke-width="0.5"/> </pattern> </defs> <rect width="100%" height="100%" fill="#0f172a"/> <rect width="100%" height="100%" fill="url(#grid)"/> ``` **Arrowhead marker (standard):** ```svg <marker id="arrow" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto"> <polygon points="0 0, 10 3.5, 0 7" fill="#64748b"/> </marker> ``` **Arrowhead marker (colored) — create per-color as needed:** ```svg <marker id="arrow-cyan" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto"> <polygon points="0 0, 10 3.5, 0 7" fill="#22d3ee"/> </marker> ``` **Open arrowhead (for async/return messages):** ```svg <marker id="arrow-open" markerWidth="10" markerHeight="7" refX="9" refY="3.5" orient="auto"> <polyline points="0 0, 10 3.5, 0 7" fill="none" stroke="#64748b" stroke-width="1.5"/> </marker> ``` ### SVG Structure & Layering Draw elements in this order to get correct z-ordering (SVG paints back-to-front): 1. Background fill + grid pattern 2. Region/group boundaries (dashed outlines) 3. Connection arrows and lines 4. Opaque masking rects (same position as component boxes, `fill="#0f172a"`) 5. Component boxes (semi-transparent fill + stroke) 6. Text labels 7. Legend (bottom-right or bottom area, outside all boundaries) 8. Title block (top-left) The opaque masking rect trick is essential — semi-transparent component fills will show arrows underneath without it: ```svg <!-- Mask layer: opaque background to hide arrows --> <rect x="100" y="100" width="160" height="60" rx="6" fill="#0f172a"/> <!-- Visual layer: styled component --> <rect x="100" y="100" width="160" height="60" rx="6" fill="rgba(8,51,68,0.4)" stroke="#22d3ee" stroke-width="1.5"/> <text x="180" y="125" fill="white" font-size="11" font-weight="600" text-anchor="middle">API Gateway</text> <text x="180" y="141" fill="#94a3b8" font-size="9" text-anchor="middle">Kong / Nginx</text> ``` ### Spacing Rules These prevent overlapping — follow them strictly: - **Component box height:** 50-70px (standard), 80-120px (large/complex) - **Minimum gap between components:** 40px vertical, 30px horizontal - **Arrow label clearance:** 10px from any box edge - **Region boundary padding:** 20px inside edges around contained components - **Legend placement:** At least 20px below the lowest diagram element - **Title block:** 20px from top-left, outside diagram content area - **viewBox:** Always extend to fit all content + 30px padding on all sides ### Component Patterns **Standard box (service/process):** ```svg <rect x="X" y="Y" width="160" height="60" rx="6" fill="#0f172a"/> <rect x="X" y="Y" width="160" height="60" rx="6" fill="FILL" stroke="STROKE" stroke-width="1.5"/> <text x="CX" y="Y+24" fill="white" font-size="11" font-weight="600" text-anchor="middle">Name</text> <text x="CX" y="Y+40" fill="#94a3b8" font-size="9" text-anchor="middle">description</text> ``` **Decision diamond (flowchart):** ```svg <g transform="translate(CX, CY)"> <polygon points="0,-35 50,0 0,35 -50,0" fill="#0f172a"/> <polygon points="0,-35 50,0 0,35 -50,0" fill="rgba(120,53,15,0.3)" stroke="#fbbf24" stroke-width="1.5"/> <text y="4" fill="white" font-size="10" font-weight="600" text-anchor="middle">Condition?</text> </g> ``` **Database cylinder:** ```svg <g transform="translate(X, Y)"> <rect x="0" y="10" width="120" height="50" rx="2" fill="#0f172a"/> <ellipse cx="60" cy="10" rx="60" ry="12" fill="#0f172a"/> <ellipse cx="60" cy="60" rx="60" ry="12" fill="#0f172a"/> <rect x="0" y="10" width="120" height="50" fill="rgba(76,29,149,0.4)"/> <ellipse cx="60" cy="10" rx="60" ry="12" fill="rgba(76,29,149,0.4)" stroke="#a78bfa" stroke-width="1.5"/> <ellipse cx="60" cy="60" rx="60" ry="12" fill="rgba(76,29,149,0.4)" stroke="#a78bfa" stroke-width="1.5"/> <line x1="0" y1="10" x2="0" y2="60" stroke="#a78bfa" stroke-width="1.5"/> <line x1="120" y1="10" x2="120" y2="60" stroke="#a78bfa" stroke-width="1.5"/> <text x="60" y="40" fill="white" font-size="11" font-weight="600" text-anchor="middle">PostgreSQL</text> </g> ``` **Region boundary:** ```svg <rect x="X" y="Y" width="W" height="H" rx="12" fill="none" stroke="#fbbf24" stroke-width="1" stroke-dasharray="8,4"/> <text x="X+12" y="Y+16" fill="#fbbf24" font-size="9" font-weight="600">AWS us-east-1</text> ``` **Security group:** ```svg <rect x="X" y="Y" width="W" height="H" rx="8" fill="none" stroke="#fb7185" stroke-width="1" stroke-dasharray="4,4"/> <text x="X+10" y="Y+14" fill="#fb7185" font-size="8" font-weight="500">VPC / Security Group</text> ``` ## Type-Specific Layout Guidance Determine this SKILL.md file's directory path as `{baseDir}`. Read the reference file for the specific diagram type before starting layout. Reference files are located at `{baseDir}/references/` and contain detailed layout algorithms and examples. ### Architecture Diagrams → Read `{baseDir}/references/architecture.md` Key points: left-to-right or top-to-bottom data flow. Group related services in region boundaries. Use buses/connectors between layers. Place databases at the bottom or right. ### Flowcharts → Read `{baseDir}/references/flowchart.md` Key points: top-to-bottom primary flow. Diamonds for decisions with Yes/No labels on exit arrows. Rounded rectangles for start/end. Use the Highlight color for the happy path. ### Sequence Diagrams → Read `{baseDir}/references/sequence.md` Key points: actors as boxes at top, vertical dashed lifelines, horizontal arrows for messages (solid=sync, dashed=return). Time flows downward. Activation bars show processing. Number messages if complex. ### Structural Diagrams → Read `{baseDir}/references/structural.md` Key points: compartmented boxes (name / attributes / methods for class diagrams). Relationship lines: solid with filled diamond=composition, solid with empty diamond=aggregation, dashed arrow=dependency, solid triangle=inheritance. ### Mind Maps Free-form radiating layout from a central concept. Use organic curves (`<path>` with cubic beziers) for branches. Vary branch colors using the palette. Larger font for central node, decreasing as you go outward. ### Timelines Horizontal or vertical axis line. Event markers as circles or diamonds on the axis. Description text offset to alternating sides to avoid overlap. Use color to categorize event types. ### State Machines Rounded-rect states with double-border for composite states. Filled circle for initial state, bullseye for final state. Curved arrows for self-transitions. Label all transitions with `event [guard] / action` format. ## Output Rules 1. Output a **single `.svg` file** — no external dependencies except the Google Fonts import 2. Set `viewBox` to fit all content with 30px padding; do NOT set fixed `width`/`height` attributes (let the SVG scale responsively) 3. Include `xmlns="http://www.w3.org/2000/svg"` on the root `<svg>` element 4. Put all `<style>`, `<defs>`, markers, and patterns at the top of the SVG 5. Use `text-anchor="middle"` for centered labels; ensure text doesn't overflow boxes 6. **Chinese text support:** When labels contain Chinese characters, use `font-family: 'JetBrains Mono', 'Noto Sans SC', 'PingFang SC', sans-serif'` and increase box widths — CJK characters are wider 7. **Save location:** If the input is a file, save to `{inputFileDir}/diagram/`. Otherwise save to `{projectDir}/diagram/{topic-slug}/`. Create the directory if it doesn't exist ## Script Determine this SKILL.md file's directory path as `{baseDir}`. Script path: `{baseDir}/scripts/main.ts`. Resolve `${BUN_X}` runtime: if `bun` installed → `bun`; if `npx` available → `npx -y bun`; else suggest installing bun. ### SVG → @2x PNG After saving the SVG, convert it to a @2x PNG: ```bash ${BUN_X} {baseDir}/scripts/main.ts <svg-path> [options] ``` Options: - `-s, --scale <n>` — Scale factor (default: 2) - `-o, --output <path>` — Custom output path (default: `<input>@2x.png`) - `--json` — JSON output ## Process 1. Identify the diagram type from the user's request 2. Read the relevant reference file if one exists for that type 3. Plan the layout: list all components, determine grouping and flow direction, calculate positions 4. Write the SVG following the layering order above 5. Verify spacing rules — no overlaps, legends outside boundaries, viewBox large enough 6. Save the SVG file 7. Run `${BUN_X} {baseDir}/scripts/main.ts <svg-path>` to generate @2x PNG 8. Present both files to the user

path: references/architecture.md
content: # Architecture Diagram Layout

## Flow Direction

Choose one primary direction:
- **Left-to-Right (LTR):** Best for data pipelines, request flows. Users/clients on left, data stores on right.
- **Top-to-Bottom (TTB):** Best for layered architectures. Clients at top, infrastructure at bottom.

## Layout Algorithm

1. **Identify layers:** Group components by role (clients, gateways, services, data, infrastructure)
2. **Assign columns (LTR) or rows (TTB):** One layer per column/row
3. **Within each layer:** Stack components vertically (LTR) or horizontally (TTB), 40px gap minimum
4. **Region boundaries:** Draw around groups that share infrastructure (e.g., "AWS us-east-1", "Kubernetes Cluster")
5. **Connectors:** Route arrows between layers. For buses/queues between layers, place a thin connector bar in the gap.

## Typical Layer Structure (LTR)

```
Col 1 (x=40)     Col 2 (x=250)     Col 3 (x=460)     Col 4 (x=670)
┌──────────┐     ┌──────────┐      ┌──────────┐      ┌──────────┐
│  Client   │────▶│ Gateway  │─────▶│ Services │─────▶│ Database │
│  Layer    │     │  Layer   │      │  Layer   │      │  Layer   │
└──────────┘     └──────────┘      └──────────┘      └──────────┘
```

Column spacing: 200-220px between column starts. Adjust if components are wider.

## Typical Layer Structure (TTB)

```
Row 1 (y=60):   [ Browser ]  [ Mobile App ]  [ API Client ]
Row 2 (y=160):  [         Load Balancer / API Gateway       ]
Row 3 (y=280):  [ Auth Svc ]  [ User Svc ]  [ Order Svc ]
Row 4 (y=400):  [  Redis  ]   [ PostgreSQL ]  [ S3 Bucket ]
```

Row spacing: 120-140px between row starts.

## Connection Routing

- Prefer straight horizontal or vertical lines
- For connections that would cross components, use two-segment (L-shaped) paths:
  ```svg
  <path d="M x1,y1 L midX,y1 L midX,y2" fill="none" stroke="#64748b" marker-end="url(#arrow)"/>
  ```
- For busy diagrams, use `stroke-opacity="0.6"` on less important connections
- Label important connections with a text element near the midpoint

## Message Bus / Event Bus Pattern

When services communicate through a shared bus, draw it as a horizontal bar between the service layer:

```
Services:  [ Svc A ]    [ Svc B ]    [ Svc C ]
              │              │            │
Bus:     ════╪══════════════╪════════════╪═══════
              │              │            │
Data:    [ DB A ]        [ DB B ]     [ Cache ]
```

Use the Connector color (orange) for the bus bar.

## Multi-Region / Multi-Cloud

Nest region boundaries:
- Outer boundary: Cloud provider (AWS, GCP)
- Inner boundary: Region or VPC
- Innermost: Availability zones or subnets

Use different dash patterns to distinguish nesting levels:
- Outer: `stroke-dasharray="12,4"`
- Middle: `stroke-dasharray="8,4"`
- Inner: `stroke-dasharray="4,4"`


path: references/flowchart.md
content: # Flowchart Layout

## Shape Vocabulary

| Shape | Meaning | SVG Element |
|-------|---------|-------------|
| Rounded rect (large radius) | Start / End | `<rect rx="25">` |
| Rectangle | Process / Action | `<rect rx="6">` |
| Diamond | Decision | `<polygon>` rotated 45° |
| Parallelogram | Input / Output | `<polygon>` with skew |
| Cylinder | Data store | Ellipse + rect combo |

## Flow Direction

Primary flow: **top to bottom**. Branch flows go left/right from decisions.

## Layout Algorithm

1. **Identify the main path** (happy path / most common flow) — this runs straight down the center
2. **Branch from decisions:** "Yes" continues down center, "No" branches right (or left if space is tight)
3. **Merge paths:** Route branches back to the main path using L-shaped connectors
4. **Loop-backs:** Route upward on the far left/right side of the diagram with curved paths

## Spacing

- Step-to-step vertical gap: 60-80px (enough for arrow + optional label)
- Decision diamond height: 70px (point to point)
- Decision diamond width: 100px (point to point)
- Branch horizontal offset: 200px from center
- Merge connector clearance: 20px from any box

## Decision Labels

Place "Yes" / "No" (or "True" / "False", "是" / "否") labels directly on the exit arrows, 10px from the diamond edge:

```svg
<!-- Decision diamond at center (400, 200) -->
<!-- Yes: downward -->
<line x1="400" y1="235" x2="400" y2="300" stroke="#64748b" marker-end="url(#arrow)"/>
<text x="412" y="260" fill="#34d399" font-size="8">Yes</text>

<!-- No: rightward -->
<line x1="450" y1="200" x2="550" y2="200" stroke="#64748b" marker-end="url(#arrow)"/>
<text x="480" y="193" fill="#fb7185" font-size="8">No</text>
```

## Coloring Strategy

- **Start/End nodes:** Highlight color (blue)
- **Process steps:** Primary (cyan) or Secondary (emerald)
- **Decision diamonds:** Accent (amber) — they draw the eye naturally
- **Error/exception paths:** Alert (rose) dashed arrows
- **Happy path arrows:** Slightly brighter than branch arrows (`stroke-opacity` difference)

## Complex Flowcharts

For flowcharts with 10+ steps:
- Group related steps into swim lanes (vertical columns with header bars)
- Add a "phase" row header at the top of each swim lane
- Use the region boundary pattern from Architecture for swim lanes


path: references/sequence.md
content: # Sequence Diagram Layout

## Core Elements

| Element | Visual | Description |
|---------|--------|-------------|
| Actor/Participant | Box at top + dashed vertical lifeline | Each entity in the interaction |
| Sync message | Solid arrow → | Request or call |
| Async message | Open arrowhead → | Fire-and-forget |
| Return message | Dashed arrow ← | Response |
| Activation bar | Narrow filled rect on lifeline | Entity is processing |
| Self-message | Arrow looping back to same lifeline | Internal processing |
| Note | Rounded rect with folded corner | Annotation |
| Alt/Opt frame | Dashed boundary with label tab | Conditional block |
| Loop frame | Dashed boundary with "loop" tab | Repetition |

## Layout Algorithm

1. **Place actors** horizontally across the top, evenly spaced (150-200px apart)
2. **Draw lifelines** as vertical dashed lines from each actor box downward
3. **Place messages** as horizontal arrows between lifelines, top to bottom in time order
4. **Vertical spacing** between messages: 40-50px
5. **Activation bars:** 10px wide, centered on lifeline, spanning from incoming to outgoing message

## Actor Box

```svg
<!-- Actor box -->
<rect x="X" y="20" width="130" height="45" rx="6" fill="#0f172a"/>
<rect x="X" y="20" width="130" height="45" rx="6" fill="rgba(8,51,68,0.4)" stroke="#22d3ee" stroke-width="1.5"/>
<text x="CX" y="47" fill="white" font-size="11" font-weight="600" text-anchor="middle">Actor Name</text>

<!-- Lifeline -->
<line x1="CX" y1="65" x2="CX" y2="BOTTOM" stroke="#334155" stroke-width="1" stroke-dasharray="6,4"/>
```

## Message Arrows

```svg
<!-- Sync message (solid arrow) -->
<line x1="FROM_CX" y1="Y" x2="TO_CX" y2="Y" stroke="#94a3b8" stroke-width="1.5" marker-end="url(#arrow)"/>
<text x="MID_X" y="Y-8" fill="#e2e8f0" font-size="9" text-anchor="middle">methodCall()</text>

<!-- Return message (dashed arrow, reversed direction) -->
<line x1="TO_CX" y1="Y" x2="FROM_CX" y2="Y" stroke="#64748b" stroke-width="1" stroke-dasharray="6,3" marker-end="url(#arrow)"/>
<text x="MID_X" y="Y-8" fill="#94a3b8" font-size="8" text-anchor="middle" font-style="italic">response</text>

<!-- Self-message (loop arrow) -->
<path d="M CX,Y L CX+40,Y L CX+40,Y+25 L CX,Y+25" fill="none" stroke="#94a3b8" stroke-width="1.5" marker-end="url(#arrow)"/>
<text x="CX+45" y="Y+15" fill="#e2e8f0" font-size="8">process()</text>
```

## Activation Bar

```svg
<rect x="CX-5" y="START_Y" width="10" height="H" rx="2" fill="rgba(8,51,68,0.6)" stroke="#22d3ee" stroke-width="1"/>
```

## Conditional / Loop Frames

```svg
<!-- Frame boundary -->
<rect x="X" y="Y" width="W" height="H" rx="4" fill="none" stroke="#64748b" stroke-width="1" stroke-dasharray="4,3"/>
<!-- Frame label tab -->
<rect x="X" y="Y" width="50" height="18" rx="4" fill="rgba(30,41,59,0.8)" stroke="#64748b" stroke-width="1"/>
<text x="X+25" y="Y+13" fill="#94a3b8" font-size="8" font-weight="600" text-anchor="middle">alt</text>
<!-- Condition text -->
<text x="X+60" y="Y+13" fill="#94a3b8" font-size="8" font-style="italic">[condition]</text>
<!-- Divider line for else -->
<line x1="X" y1="MID_Y" x2="X+W" y2="MID_Y" stroke="#64748b" stroke-width="1" stroke-dasharray="4,3"/>
<text x="X+10" y="MID_Y+13" fill="#94a3b8" font-size="8" font-style="italic">[else]</text>
```

## Numbering

For complex sequences (8+ messages), number each message:

```svg
<circle cx="FROM_CX-15" cy="Y" r="8" fill="rgba(59,130,246,0.3)" stroke="#60a5fa" stroke-width="1"/>
<text x="FROM_CX-15" y="Y+3" fill="#60a5fa" font-size="7" font-weight="600" text-anchor="middle">1</text>
```

## Color Assignment

Assign each actor a distinct color from the palette. Use that color for:
- Actor box stroke
- Activation bar on that lifeline
- Outgoing arrows from that actor (optional, for visual clarity in complex diagrams)


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal:  | SkillSpector: suspicious (HIGH)