Fireworks Tech Graph
Generate production-quality SVG technical diagrams exported as PNG via cairosvg (recommended), rsvg-convert, or puppeteer.
Install Source
Install this skill from GitHub:
npx skills add yizhiyanhua-ai/fireworks-tech-graph
Public package page:
https://www.npmjs.com/package/@yizhiyanhua-ai/fireworks-tech-graph
Do not pass @yizhiyanhua-ai/fireworks-tech-graph directly to skills add, because the CLI expects a GitHub or local repository source.
Update command:
npx skills add yizhiyanhua-ai/fireworks-tech-graph --force -g -y
Helper Scripts (Recommended)
Four helper scripts in scripts/ directory provide stable SVG generation and validation:
1. generate-diagram.sh - Validate SVG + export PNG
./scripts/generate-diagram.sh -t architecture -s 1 -o ./output/arch.svg
- Validates an existing SVG file
- Exports PNG after validation
- Example:
./scripts/generate-diagram.sh -t architecture -s 1 -o ./output/arch.svg
2. generate-from-template.py - Create starter SVG from template
python3 ./scripts/generate-from-template.py architecture ./output/arch.svg '{"title":"My Diagram","nodes":[],"arrows":[]}'
- Loads a built-in SVG template
- Renders nodes, arrows, and legend entries from JSON input
- Escapes text content to keep output XML-valid
3. validate-svg.sh - Validate SVG syntax
./scripts/validate-svg.sh <svg-file>
- Checks XML syntax
- Verifies tag balance
- Validates marker references
- Checks attribute completeness
- Validates path data
4. test-all-styles.sh - Batch test all styles
./scripts/test-all-styles.sh
- Tests multiple diagram sizes
- Validates all generated SVGs
- Generates test report
When to use scripts:
- Use scripts when generating complex SVGs to avoid syntax errors
- Scripts provide automatic validation and error reporting
- Recommended for production diagrams
When to generate SVG directly:
- Simple diagrams with few elements
- Quick prototypes
- When you need full control over SVG structure
Workflow (Always Follow This Order)
- Classify the diagram type (see Diagram Types below)
- Extract structure — identify layers, nodes, edges, flows, and semantic groups from user description
- Plan layout — apply the layout rules for the diagram type
- Load style reference — always load
references/style-1-flat-icon.md unless user specifies another; load the matching references/style-N.md for exact color tokens and SVG patterns
- Map nodes to shapes — use Shape Vocabulary below
- Check icon needs — load
references/icons.md for known products
- Write SVG with adaptive strategy (see SVG Generation Strategy below)
- Validate: Run
python3 -c "import xml.etree.ElementTree as ET; ET.parse('file.svg')" to check XML syntax
- Export PNG: Use
cairosvg (recommended). See SVG → PNG Conversion section below for full method comparison
- Report the generated file paths
- (Optional) Visual self-review — if your runtime can read images, load the exported PNG back and inspect it. Syntactic validity does not guarantee visual correctness: arrows may cross through component interiors, labels may collide with lifelines or other labels, boxes may overlap, alt-frame text may sit on top of a message, or a legend may cover content. If you see any of these, revise the SVG and re-export; repeat until the rendered image is clean. Common fixes:
- Route arrows through gaps between boxes, not through box interiors
- Add background rects behind arrow labels (opacity 0.95, matching canvas color)
- Widen inter-row/inter-column gutters so same-layer arrows have clear corridors
- Collapse repeated cross-layer arrows into a single "delegates down" rail outside the content area
- Move legend/notes out of any region where arrows or labels land
- Increase viewBox height/width rather than packing elements tighter
- If a filtered element (drop-shadow, blur) is missing one side of its border, move it ≥30px away from that viewBox edge, or remove the filter and rely on color/contrast for visual separation
Skip this step silently if image reading is unavailable — do not guess.
Diagram Types & Layout Rules
Architecture Diagram
Nodes = services/components. Group into horizontal layers (top→bottom or left→right).
- Typical layers: Client → Gateway/LB → Services → Data/Storage
- Use
<rect> dashed containers to group related services in the same layer
- Arrow direction follows data/request flow
- ViewBox:
0 0 960 600 standard, 0 0 960 800 for tall stacks
Data Flow Diagram
Emphasizes what data moves where. Focus on data transformation.
- Label every arrow with the data type (e.g., "embeddings", "query", "context")
- Use wider arrows (
stroke-width: 2.5) for primary data paths
- Dashed arrows for control/trigger flows
- Color arrows by data category (not just Agent/RAG — use semantics)
Flowchart / Process Flow
Sequential decision/process steps.
- Top-to-bottom preferred; left-to-right for wide flows
- Diamond shapes for decisions, rounded rects for processes, parallelograms for I/O
- Keep node labels short (≤3 words); put detail in sub-labels
- Align nodes on a grid: x positions snap to 120px intervals, y to 80px
Agent Architecture Diagram
Shows how an AI agent reasons, uses tools, and manages memory.
Key conceptual layers to always consider:
- Input layer: User, query, trigger
- Agent core: LLM, reasoning loop, planner
- Memory layer: Short-term (context window), Long-term (vector/graph DB), Episodic
- Tool layer: Tool calls, APIs, search, code execution
- Output layer: Response, action, side-effects
Use cyclic arrows (loop arcs) to show iterative reasoning. Separate memory types visually.
Memory Architecture Diagram (Mem0, MemGPT-style)
Specialized agent diagram focused on memory operations.
- Show memory write path and read path separately (different arrow colors)
- Memory tiers: Working Memory → Short-term → Long-term → External Store
- Label memory operations:
store(), retrieve(), forget(), consolidate()
- Use stacked rects or layered cylinders for storage tiers
Sequence Diagram
Time-ordered message exchanges between participants.
- Participants as vertical lifelines (top labels + vertical dashed lines)
- Messages as horizontal arrows between lifelines, top-to-bottom time order
- Activation boxes (thin filled rects on lifeline) show active processing
- Group with
<rect> loop/alt frames with label in top-left corner
- ViewBox height = 80 + (num_messages × 50)
Comparison / Feature Matrix
Side-by-side comparison of approaches, systems, or components.
- Column headers = systems, row headers = attributes
- Row height: 40px; column width: min 120px; header row height: 50px
- Checked cell: tinted background (e.g.
#dcfce7) + ✓ checkmark; unsupported: #f9fafb fill
- Alternating row fills (
#f9fafb / #ffffff) for readability
- Max readable columns: 5; beyond that, split into two diagrams
Timeline / Gantt
Horizontal time axis showing durations, phases, and milestones.
- X-axis = time (weeks/months/quarters); Y-axis = items/tasks/phases
- Bars: rounded rects, colored by category, labeled inside or beside
- Milestone markers: diamond or filled circle at specific x position with label above
- ViewBox:
0 0 960 400 typical; wider for many time periods: 0 0 1200 400
Mind Map / Concept Map
Radial layout from central concept.
- Central node at
cx=480, cy=280
- First-level branches: evenly distributed around center (360/N degrees)
- Second-level branches: branch off first-level at 30-45° offset
- Use curved
<path> with cubic bezier for branches, not straight lines
Class Diagram (UML)
Static structure showing classes, attributes, methods, and relationships.
- Class box: 3-compartment rect (name / attributes / methods), min width 160px
- Top compartment: class name, bold, centered (abstract = italic)
- Middle: attributes with visibility (
+ public, - private, # protected)
- Bottom: method signatures, same visibility notation
- Relationships:
- Inheritance (extends): solid line + hollow triangle arrowhead, child → parent
- Implementation (interface): dashed line + hollow triangle, class → interface
- Association: solid line + open arrowhead, label with multiplicity (1, 0.., 1..)
- Aggregation: solid line + hollow diamond on container side
- Composition: solid line + filled diamond on container side
- Dependency: dashed line + open arrowhead
- Interface:
<<interface>> stereotype above name, or circle/lollipop notation
- Enum: compartment rect with
<<enumeration>> stereotype, values in bottom
- Layout: parent classes top, children below; interfaces to the left/right of implementors
- ViewBox:
0 0 960 600 standard; 0 0 960 800 for deep hierarchies
Use Case Diagram (UML)
System functionality from user perspective.
- Actor: stick figure (circle head + body line) placed outside system boundary
- Label below figure, 13-14px
- Primary actors on left, secondary/supporting on right
- Use case: ellipse with label centered inside, min 140×60px
- Keep names verb phrases: "Create Order", "Process Payment"
- System boundary: large rect with dashed border + system name in top-left
- Relationships:
- Include: dashed arrow
<<include>> from base to included use case
- Extend: dashed arrow
<<extend>> from extension to base use case
- Generalization: solid line + hollow triangle (specialized → general)
- Layout: system boundary centered, actors outside, use cases inside
- ViewBox:
0 0 960 600 standard
State Machine Diagram (UML)
Lifecycle states and transitions of an entity.
- State: rounded rect with state name, min 120×50px
- Internal activities: small text
entry/ action, exit/ action, do/ activity
- Initial state: filled black circle (r=8), one outgoing arrow
- Final state: filled circle (r=8) inside hollow circle (r=12)
- Choice: small hollow diamond, guard labels on outgoing arrows
[condition]
- Transition: arrow with optional label
event [guard] / action
- Guard conditions in square brackets
- Actions after
/
- Composite/nested state: larger rect containing sub-states, with name tab
- Fork/join: thick horizontal or vertical black bar (synchronization)
- Layout: initial state top-left, final state bottom-right, flow top-to-bottom
- ViewBox:
0 0 960 600 standard
ER Diagram (Entity-Relationship)
Database schema and data relationships.
- Entity: rect with entity name in header (bold), attributes below
- Primary key attribute: underlined
- Foreign key: italic or marked with (FK)
- Min width: 160px; attribute font-size: 12px
- Relationship: diamond shape on connecting line
- Label inside diamond: "has", "belongs to", "enrolls in"
- Cardinality labels near entity:
1, N, 0..1, 0..*, 1..*
- Weak entity: double-bordered rect with double diamond relationship
- Associative entity: diamond + rect hybrid (rect with diamond inside)
- Line style: solid for identifying relationships, dashed for non-identifying
- Layout: entities in 2-3 rows, relationships between related entities
- ViewBox:
0 0 960 600 standard; wider 0 0 1200 600 for many entities
Network Topology
Physical or logical network infrastructure.
- Devices: icon-like rects or rounded rects
- Router: circle with cross arrows
- Switch: rect with arrow grid
- Server: stacked rect (rack icon)
- Firewall: brick-pattern rect or shield shape
- Load Balancer: horizontal split rect with arrows
- Cloud: cloud path (overlapping arcs)
- Connections: lines between device centers
- Ethernet/wired: solid line, label bandwidth
- Wireless: dashed line with WiFi symbol
- VPN: dashed line with lock icon
- Subnets/Zones: dashed rect containers with zone label (DMZ, Internal, External)
- Labels: device hostname + IP below, 12-13px
- Layout: tiered top-to-bottom (Internet → Edge → Core → Access → Endpoints)
- ViewBox:
0 0 960 600 standard
UML Coverage Map
Full mapping of UML 14 diagram types to supported diagram types:
| UML Diagram |
Supported As |
Notes |
| Class |
Class Diagram |
Full UML notation |
| Component |
Architecture Diagram |
Use colored fills per component type |
| Deployment |
Architecture Diagram |
Add node/instance labels |
| Package |
Architecture Diagram |
Use dashed grouping containers |
| Composite Structure |
Architecture Diagram |
Nested rects within components |
| Object |
Class Diagram |
Instance boxes with underlined name |
| Use Case |
Use Case Diagram |
Full actor/ellipse/relationship |
| Activity |
Flowchart / Process Flow |
Add fork/join bars |
| State Machine |
State Machine Diagram |
Full UML notation |
| Sequence |
Sequence Diagram |
Add alt/opt/loop frames |
| Communication |
— |
Approximate with Sequence (swap axes) |
| Timing |
Timeline |
Adapt time axis |
| Interaction Overview |
Flowchart |
Combine activity + sequence fragments |
| ER Diagram |
ER Diagram |
Chen/Crow's foot notation |
Shape Vocabulary
Map semantic concepts to consistent shapes across all diagram types:
| Concept |
Shape |
Notes |
| User / Human |
Circle + body path |
Stick figure or avatar |
| LLM / Model |
Rounded rect with brain/spark icon or gradient fill |
Use accent color |
| Agent / Orchestrator |
Hexagon or rounded rect with double border |
Signals "active controller" |
| Memory (short-term) |
Rounded rect, dashed border |
Ephemeral = dashed |
| Memory (long-term) |
Cylinder (database shape) |
Persistent = solid cylinder |
| Vector Store |
Cylinder with grid lines inside |
Add 3 horizontal lines |
| Graph DB |
Circle cluster (3 overlapping circles) |
|
| Tool / Function |
Gear-like rect or rect with wrench icon |
|
| API / Gateway |
Hexagon (single border) |
|
| Queue / Stream |
Horizontal tube (pipe shape) |
|
| File / Document |
Folded-corner rect |
|
| Browser / UI |
Rect with 3-dot titlebar |
|
| Decision |
Diamond |
Flowcharts only |
| Process / Step |
Rounded rect |
Standard box |
| External Service |
Rect with cloud icon or dashed border |
|
| Data / Artifact |
Parallelogram |
I/O in flowcharts |
Arrow Semantics
Always assign arrow meaning, not just color:
| Flow Type |
Color |
Stroke |
Dash |
Meaning |
| Primary data flow |
blue #2563eb |
2px solid |
none |
Main request/response path |
| Control / trigger |
orange #ea580c |
1.5px solid |
none |
One system triggering another |
| Memory read |
green #059669 |
1.5px solid |
none |
Retrieval from store |
| Memory write |
green #059669 |
1.5px |
5,3 |
Write/store operation |
| Async / event |
gray #6b7280 |
1.5px |
4,2 |
Non-blocking, event-driven |
| Embedding / transform |
purple #7c3aed |
1px solid |
none |
Data transformation |
| Feedback / loop |
purple #7c3aed |
1.5px curved |
none |
Iterative reasoning loop |
Always include a legend when 2+ arrow types are used.
Layout Rules & Validation
Spacing:
- Same-layer nodes: 80px horizontal, 120px vertical between layers
- Canvas margins: 40px minimum, 60px between node edges
- Snap to 8px grid: horizontal 120px intervals, vertical 120px intervals
Arrow Labels (CRITICAL):
- MUST have background rect:
<rect fill="canvas_bg" opacity="0.95"/> with 4px horizontal, 2px vertical padding
- Place mid-arrow, ≤3 words, stagger by 15-20px when multiple arrows converge
- Maintain 10px safety distance from nodes
Arrow Routing:
- Prefer orthogonal (L-shaped) paths to minimize crossings
- Anchor arrows on component edges, not geometric centers
- Route around dense node clusters, use different y-offsets for parallel arrows
- Jump-over arcs (5px radius) for unavoidable crossings
Post-Generation Arrow Optimization:
When a user asks to "优化箭头" / "fix arrow routing" / "optimize the diagram" on an already-generated diagram, preserve all nodes, containers, styles, and layout — only modify the arrows entries in the JSON data, then re-render with generate-from-template.py.
Available arrow override fields (in recommended order of use):
| Field |
Type |
When to Use |
source_port / target_port |
"left" / "right" / "top" / "bottom" |
Arrow exits/enters from the wrong edge |
corridor_x |
[x, ...] |
Hint vertical segments toward this x lane (soft preference) |
corridor_y |
[y, ...] |
Hint horizontal segments toward this y lane (soft preference) |
route_points |
[[x1,y1], [x2,y2], ...] |
Force exact waypoints (bypasses auto-routing); keep segments orthogonal |
routing_padding |
number (default: 24) |
(Advanced) Adjust obstacle clearance for this arrow |
port_clearance |
number |
(Advanced) Adjust first-segment offset from node edge |
Optimization steps:
- Read the existing SVG — identify which arrows overlap, cross nodes, or look misaligned
- Find those arrows in the JSON data by
source / target pair
- Add
source_port / target_port if the exit/entry direction is wrong; add corridor_x / corridor_y to space parallel arrows apart; use route_points only when hints alone cannot resolve the path
- Re-run
generate-from-template.py with the updated JSON and validate with validate-svg.sh
Example — spacing two overlapping arrows into separate corridors:
{ "source": "nodeA", "target": "nodeB", "corridor_y": [280] }
{ "source": "nodeC", "target": "nodeD", "corridor_y": [320] }
Line Overlap Prevention (CRITICAL - most common bug on Codex):
When two arrows must cross each other, ALWAYS use jump-over arcs to prevent visual overlap:
- Crossing horizontal arrows: add a small semicircle arc (radius 5px, stroke same color as arrow, fill none) that "jumps over" the other line
- SVG pattern for jump-over: use a white/matching-background arc on the lower layer, then draw the upper arc on top
- Multiple crossings: stagger arc radii (5px, 7px, 9px) so arcs don't overlap each other
- Never let two arrows' straight-line segments cross without a jump-over arc
Validation Checklist (run before finalizing):
- Arrow-Component Collision: Arrows MUST NOT pass through component interiors (route around with orthogonal paths)
- Text Overflow: All text MUST fit with 8px padding (estimate:
text.length × 7px ≤ shape_width - 16px)
- Arrow-Text Alignment: Arrow endpoints MUST connect to shape edges (not floating); all arrow labels MUST have background rects
- Container Discipline: Prefer arrows entering and leaving section containers through open gaps between components, not through inner component bodies
- Filter Boundary Safety: For every element with
filter="url(...)", verify (element_x + element_width + filter_extension) ≤ viewBox_width AND element_x ≥ filter_extension. The default filter region extends 10-20% beyond bbox; staying near viewBox edges causes Chrome/cairosvg to clip the element's edge-side stroke (one side of the border vanishes while other sides render correctly)
SVG Technical Rules
- ViewBox:
0 0 960 600 default; 0 0 960 800 tall; 0 0 1200 600 wide
- Fonts: embed via
<style>font-family: ...</style> — no external @import (cairosvg / rsvg-convert cannot fetch external URLs)
<defs>: arrow markers, gradients, filters, clip paths
- Text: minimum 12px, prefer 13-14px labels, 11px sub-labels, 16-18px titles
- All arrows:
<marker> with markerEnd, sized markerWidth="10" markerHeight="7"
- Drop shadows:
<feDropShadow> in <filter>, apply sparingly (key nodes only)
- Curved paths: use
M x1,y1 C cx1,cy1 cx2,cy2 x2,y2 cubic bezier for loops/feedback arrows
- Clip content: use
<clipPath> if text might overflow a node box
SVG Generation & Error Prevention
MANDATORY: Python List Method (ALWAYS use this):
python3 << 'EOF'
lines = []
lines.append('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 960 700">')
lines.append(' <defs>')
# ... each line separately
lines.append('</svg>')
with open('/path/to/output.svg', 'w') as f:
f.write('\n'.join(lines))
print("SVG generated successfully")
EOF
Why mandatory: Prevents character truncation, typos, and syntax errors. Each line is independent and easy to verify.
Pre-Tool-Call Checklist (CRITICAL - use EVERY time):
- ✅ Can I write out the COMPLETE command/content right now?
- ✅ Do I have ALL required parameters ready?
- ✅ Have I checked for syntax errors in my prepared content?
If ANY answer is NO: STOP. Do NOT call the tool. Prepare the content first.
Error Recovery Protocol:
- First error: Analyze root cause, apply targeted fix
- Second error: Switch method entirely (Python list → chunked generation)
- Third error: STOP and report to user - do NOT loop endlessly
- Never: Retry the same failing command or call tools with empty parameters
Validation (run after generation):
python3 -c "import xml.etree.ElementTree as ET; ET.parse('file.svg')" && echo "✓ Valid XML"
# Or use cairosvg as a render-time check:
python3 -c "import cairosvg; cairosvg.svg2png(url='file.svg', write_to='/tmp/test.png')" && echo "✓ Renders" && rm /tmp/test.png
If using generate-from-template.py:
- Prefer
source / target node ids in arrow JSON so the generator can snap to node edges
- Keep
x1,y1,x2,y2 as hints or fallback coordinates, not the main routing primitive
- Let the generator choose orthogonal routes; avoid hardcoding center-to-center straight lines unless the path is guaranteed clear
Common Syntax Errors to Avoid:
- ❌
yt-anchor → ✅ y="60" text-anchor="middle"
- ❌
x="390 (missing y) → ✅ x="390" y="250"
- ❌
fill=#fff → ✅ fill="#ffffff"
- ❌
marker-end= → ✅ marker-end="url(#arrow)"
- ❌
L 29450 → ✅ L 290,220
- ❌ Missing
</svg> at end
- ❌ Element with
filter near viewBox edge — filter region extends 20% (default) or more beyond bbox; if that region exceeds viewBox, Chrome/cairosvg clip the filter rendering AND can drop the element's own stroke on that side. Keep filtered elements at least max(20% of element size, shadow blur radius × 3) away from viewBox edges, or omit the filter.
Output
- Default:
./[derived-name].svg and ./[derived-name].png in current directory
- Custom: user specifies path with
--output /path/ or 输出到 /path/
- PNG export: see SVG → PNG Conversion below
SVG → PNG Conversion
Method Comparison
| Tool |
Install |
Render Quality |
Notes |
rsvg-convert |
System (often preinstalled) |
⚠️ Fair |
Drops some CSS styles and <foreignObject> elements — missing borders/text on complex SVGs |
cairosvg (recommended) |
pip install cairosvg |
✅ Good |
Solid CSS support; clearly better than rsvg-convert |
puppeteer (headless Chrome) |
npm install puppeteer |
✅✅ Best |
Real browser engine; 100% fidelity but heavy (Node + Chromium) |
Recommended: cairosvg (Python one-liner)
# Single file (2x resolution for retina/docs)
python3 -c "import cairosvg; cairosvg.svg2png(url='input.svg', write_to='output.png', scale=2)"
# Batch convert all SVGs in a directory
python3 -c "
import cairosvg, os, glob
d = 'docs/00-core'
for svg in sorted(glob.glob(os.path.join(d, '*.svg'))):
png = svg.replace('.svg', '.png')
cairosvg.svg2png(url=svg, write_to=png, scale=2)
print(f'Done: {os.path.basename(svg)} -> {os.path.basename(png)}')
"
scale=2 produces 2x resolution PNG, ideal for high-DPI screens and embedded docs.
Fallback: rsvg-convert (simple but may drop styles)
# Single file
rsvg-convert -w 1920 file.svg -o file.png
# Batch (not recommended — complex SVGs may lose elements)
for f in docs/00-core/*.svg; do rsvg-convert -o "${f%.svg}.png" "$f"; done
# 2x resolution
for f in docs/00-core/*.svg; do rsvg-convert -z 2 -o "${f%.svg}.png" "$f"; done
Highest Fidelity: puppeteer (headless Chrome)
npm install puppeteer # auto-downloads Chromium
node svg2png.js [directory]
const puppeteer = require('puppeteer');
const fs = require('fs');
const path = require('path');
(async () => {
const dir = process.argv[2] || '.';
const svgFiles = fs.readdirSync(dir).filter(f => f.endsWith('.svg'));
const browser = await puppeteer.launch({
headless: 'new',
args: ['--no-sandbox', '--disable-setuid-sandbox']
});
for (const file of svgFiles) {
const svgPath = path.resolve(dir, file);
const pngPath = svgPath.replace(/\.svg$/, '.png');
const svgContent = fs.readFileSync(svgPath, 'utf-8');
const wMatch = svgContent.match(/width="(\d+)/);
const hMatch = svgContent.match(/height="(\d+)/);
const vbMatch = svgContent.match(/viewBox="[^"]*\s(\d+)\s(\d+)"/);
let width = wMatch ? parseInt(wMatch[1]) : (vbMatch ? parseInt(vbMatch[1]) : 1200);
let height = hMatch ? parseInt(hMatch[1]) : (vbMatch ? parseInt(vbMatch[2]) : 800);
const scale = 2;
const page = await browser.newPage();
await page.setViewport({ width, height, deviceScaleFactor: scale });
const html = `<!DOCTYPE html>
<html><head><style>
body { margin: 0; padding: 0; background: transparent; }
img { display: block; }
</style></head>
<body>
<img src="data:image/svg+xml;base64,${Buffer.from(svgContent).toString('base64')}" width="${width}" height="${height}" />
</body></html>`;
await page.setContent(html, { waitUntil: 'networkidle0' });
await page.screenshot({ path: pngPath, type: 'png', omitBackground: true });
await page.close();
console.log(`Done: ${file} -> ${path.basename(pngPath)} (${width}x${height} @${scale}x)`);
}
await browser.close();
})();
Gotchas (lessons learned)
rsvg-convert renders SVGs containing <foreignObject>, CSS filter, or complex <style> blocks incompletely — missing borders / missing text are the typical symptoms
cairosvg (built on Cairo) has much better CSS support than rsvg and is sufficient for most cases
- If the SVG was generated by a browser (D3.js, Mermaid, etc.), only headless Chrome (puppeteer) renders it 100% faithfully
- Chrome headless CLI
--window-size=W,H is not the drawable area — even in --headless=new mode, browser chrome (scrollbars, internal UI surfaces) consumes ~15-20% of both width and height, so the actual SVG viewport is only ~0.84×W by ~0.84×H. Symptom: SVG content past x ≈ 0.84 × W or y ≈ 0.84 × H is cut off and renders as a solid white band, even though the SVG file itself is correct. Typical failure modes: a Legend in the top-right corner loses its right border; a bottom-row container loses its bottom dashed line. Fix: pass window dimensions ≥ SVG width × 1.2 AND SVG height × 1.2, then crop the raw screenshot back to (SVG_width × scale, SVG_height × scale) with PIL or ImageMagick. Example: for a 1280×580 SVG at 3× DPR, use --window-size=1600,800 then crop the output to 3840×1740. The Puppeteer / page.setViewport() path does NOT have this issue — it sets a precise viewport regardless of window UI.
Picking a Method
- Default →
cairosvg (pip install once, one-line conversion, good fidelity)
- No Python available →
rsvg-convert (acceptable for simple flat-color diagrams)
- Browser-generated SVG or pixel-perfect required →
puppeteer
Styles
| # |
Name |
Background |
Best For |
| 1 |
Flat Icon (default) |
White |
Blogs, docs, presentations |
| 2 |
Dark Terminal |
#0f0f1a |
GitHub, dev articles |
| 3 |
Blueprint |
#0a1628 |
Architecture docs |
| 4 |
Notion Clean |
White, minimal |
Notionnce |
| 5 |
Glassmorphism |
Dark gradient |
Product sites, keynotes |
| 6 |
Claude Official |
Warm cream #f8f6f3 |
Anthropic-style diagrams |
| 7 |
OpenAI Official |
Pure white #ffffff |
OpenAI-style diagrams |
Load references/style-N.md for exact color tokens and SVG patterns.
Style Selection
Default: Style 1 (Flat Icon) for most diagrams. Load references/style-diagram-matrix.md for detailed style-to-diagram-type recommendations.
These patterns appear frequently — internalize them:
RAG Pipeline: Query → Embed → VectorSearch → Retrieve → Augment → LLM → Response
Agentic RAG: adds Agent loop with Tool use between Query and LLM
Agentic Search: Query → Planner → [Search Tool / Calculator / Code] → Synthesizer → Response
Mem0 / Memory Layer: Input → Memory Manager → [Write: VectorDB + GraphDB] / [Read: Retrieve+Rank] → Context
Agent Memory Types: Sensory (raw input) → Working (context window) → Episodic (past interactions) → Semantic (facts) → Procedural (skills)
Multi-Agent: Orchestrator → [SubAgent A / SubAgent B / SubAgent C] → Aggregator → Output
Tool Call Flow: LLM → Tool Selector → Tool Execution → Result Parser → LLM (loop)
1---2name: fireworks-tech-graph3description: Use when the user wants to create any technical diagram - architecture, data flow, flowchart, sequence, agent/memory, or concept map - and export as SVG+PNG. Trigger on: "画图" "帮我画" "生成图" "做个图" "架构图" "流程图" "可视化一下" "出图" "generate diagram" "draw diagram" "visualize" or any system/flow description the user wants illustrated.4---56# Fireworks Tech Graph78Generate production-quality SVG technical diagrams exported as PNG via `cairosvg` (recommended), `rsvg-convert`, or `puppeteer`.910## Install Source1112Install this skill from GitHub:1314```bash15npx skills add yizhiyanhua-ai/fireworks-tech-graph16```1718Public package page:1920```text21https://www.npmjs.com/package/@yizhiyanhua-ai/fireworks-tech-graph22```2324Do not pass `@yizhiyanhua-ai/fireworks-tech-graph` directly to `skills add`, because the CLI expects a GitHub or local repository source.2526Update command:2728```bash29npx skills add yizhiyanhua-ai/fireworks-tech-graph --force -g -y30```3132## Helper Scripts (Recommended)3334Four helper scripts in `scripts/` directory provide stable SVG generation and validation:3536### 1. `generate-diagram.sh` - Validate SVG + export PNG37```bash38./scripts/generate-diagram.sh -t architecture -s 1 -o ./output/arch.svg39```40- Validates an existing SVG file41- Exports PNG after validation42- Example: `./scripts/generate-diagram.sh -t architecture -s 1 -o ./output/arch.svg`4344### 2. `generate-from-template.py` - Create starter SVG from template45```bash46python3 ./scripts/generate-from-template.py architecture ./output/arch.svg '{"title":"My Diagram","nodes":[],"arrows":[]}'47```48- Loads a built-in SVG template49- Renders nodes, arrows, and legend entries from JSON input50- Escapes text content to keep output XML-valid5152### 3. `validate-svg.sh` - Validate SVG syntax53```bash54./scripts/validate-svg.sh <svg-file>55```56- Checks XML syntax57- Verifies tag balance58- Validates marker references59- Checks attribute completeness60- Validates path data6162### 4. `test-all-styles.sh` - Batch test all styles63```bash64./scripts/test-all-styles.sh65```66- Tests multiple diagram sizes67- Validates all generated SVGs68- Generates test report6970**When to use scripts:**71- Use scripts when generating complex SVGs to avoid syntax errors72- Scripts provide automatic validation and error reporting73- Recommended for production diagrams7475**When to generate SVG directly:**76- Simple diagrams with few elements77- Quick prototypes78- When you need full control over SVG structure7980## Workflow (Always Follow This Order)81821. **Classify** the diagram type (see Diagram Types below)832. **Extract structure** — identify layers, nodes, edges, flows, and semantic groups from user description843. **Plan layout** — apply the layout rules for the diagram type854. **Load style reference** — always load `references/style-1-flat-icon.md` unless user specifies another; load the matching `references/style-N.md` for exact color tokens and SVG patterns865. **Map nodes to shapes** — use Shape Vocabulary below876. **Check icon needs** — load `references/icons.md` for known products887. **Write SVG** with adaptive strategy (see SVG Generation Strategy below)898. **Validate**: Run `python3 -c "import xml.etree.ElementTree as ET; ET.parse('file.svg')"` to check XML syntax909. **Export PNG**: Use `cairosvg` (recommended). See **SVG → PNG Conversion** section below for full method comparison9110. **Report** the generated file paths9211. **(Optional) Visual self-review** — if your runtime can read images, load the exported PNG back and inspect it. Syntactic validity does not guarantee visual correctness: arrows may cross through component interiors, labels may collide with lifelines or other labels, boxes may overlap, alt-frame text may sit on top of a message, or a legend may cover content. If you see any of these, revise the SVG and re-export; repeat until the rendered image is clean. Common fixes:93 - Route arrows through gaps between boxes, not through box interiors94 - Add background rects behind arrow labels (opacity 0.95, matching canvas color)95 - Widen inter-row/inter-column gutters so same-layer arrows have clear corridors96 - Collapse repeated cross-layer arrows into a single "delegates down" rail outside the content area97 - Move legend/notes out of any region where arrows or labels land98 - Increase viewBox height/width rather than packing elements tighter99 - If a filtered element (drop-shadow, blur) is missing one side of its border, move it ≥30px away from that viewBox edge, or remove the filter and rely on color/contrast for visual separation100 Skip this step silently if image reading is unavailable — do not guess.101102## Diagram Types & Layout Rules103104### Architecture Diagram105Nodes = services/components. Group into **horizontal layers** (top→bottom or left→right).106- Typical layers: Client → Gateway/LB → Services → Data/Storage107- Use `<rect>` dashed containers to group related services in the same layer108- Arrow direction follows data/request flow109- ViewBox: `0 0 960 600` standard, `0 0 960 800` for tall stacks110111### Data Flow Diagram112Emphasizes **what data moves where**. Focus on data transformation.113- Label every arrow with the data type (e.g., "embeddings", "query", "context")114- Use wider arrows (`stroke-width: 2.5`) for primary data paths115- Dashed arrows for control/trigger flows116- Color arrows by data category (not just Agent/RAG — use semantics)117118### Flowchart / Process Flow119Sequential decision/process steps.120- Top-to-bottom preferred; left-to-right for wide flows121- Diamond shapes for decisions, rounded rects for processes, parallelograms for I/O122- Keep node labels short (≤3 words); put detail in sub-labels123- Align nodes on a grid: x positions snap to 120px intervals, y to 80px124125### Agent Architecture Diagram126Shows how an AI agent reasons, uses tools, and manages memory.127Key conceptual layers to always consider:128- **Input layer**: User, query, trigger129- **Agent core**: LLM, reasoning loop, planner130- **Memory layer**: Short-term (context window), Long-term (vector/graph DB), Episodic131- **Tool layer**: Tool calls, APIs, search, code execution132- **Output layer**: Response, action, side-effects133Use cyclic arrows (loop arcs) to show iterative reasoning. Separate memory types visually.134135### Memory Architecture Diagram (Mem0, MemGPT-style)136Specialized agent diagram focused on memory operations.137- Show memory **write path** and **read path** separately (different arrow colors)138- Memory tiers: Working Memory → Short-term → Long-term → External Store139- Label memory operations: `store()`, `retrieve()`, `forget()`, `consolidate()`140- Use stacked rects or layered cylinders for storage tiers141142### Sequence Diagram143Time-ordered message exchanges between participants.144- Participants as vertical **lifelines** (top labels + vertical dashed lines)145- Messages as horizontal arrows between lifelines, top-to-bottom time order146- Activation boxes (thin filled rects on lifeline) show active processing147- Group with `<rect>` loop/alt frames with label in top-left corner148- ViewBox height = 80 + (num_messages × 50)149150### Comparison / Feature Matrix151Side-by-side comparison of approaches, systems, or components.152- Column headers = systems, row headers = attributes153- Row height: 40px; column width: min 120px; header row height: 50px154- Checked cell: tinted background (e.g. `#dcfce7`) + `✓` checkmark; unsupported: `#f9fafb` fill155- Alternating row fills (`#f9fafb` / `#ffffff`) for readability156- Max readable columns: 5; beyond that, split into two diagrams157158### Timeline / Gantt159Horizontal time axis showing durations, phases, and milestones.160- X-axis = time (weeks/months/quarters); Y-axis = items/tasks/phases161- Bars: rounded rects, colored by category, labeled inside or beside162- Milestone markers: diamond or filled circle at specific x position with label above163- ViewBox: `0 0 960 400` typical; wider for many time periods: `0 0 1200 400`164165### Mind Map / Concept Map166Radial layout from central concept.167- Central node at `cx=480, cy=280`168- First-level branches: evenly distributed around center (360/N degrees)169- Second-level branches: branch off first-level at 30-45° offset170- Use curved `<path>` with cubic bezier for branches, not straight lines171172### Class Diagram (UML)173Static structure showing classes, attributes, methods, and relationships.174- **Class box**: 3-compartment rect (name / attributes / methods), min width 160px175 - Top compartment: class name, bold, centered (abstract = *italic*)176 - Middle: attributes with visibility (`+` public, `-` private, `#` protected)177 - Bottom: method signatures, same visibility notation178- **Relationships**:179 - Inheritance (extends): solid line + hollow triangle arrowhead, child → parent180 - Implementation (interface): dashed line + hollow triangle, class → interface181 - Association: solid line + open arrowhead, label with multiplicity (1, 0..*, 1..*)182 - Aggregation: solid line + hollow diamond on container side183 - Composition: solid line + filled diamond on container side184 - Dependency: dashed line + open arrowhead185- **Interface**: `<<interface>>` stereotype above name, or circle/lollipop notation186- **Enum**: compartment rect with `<<enumeration>>` stereotype, values in bottom187- Layout: parent classes top, children below; interfaces to the left/right of implementors188- ViewBox: `0 0 960 600` standard; `0 0 960 800` for deep hierarchies189190### Use Case Diagram (UML)191System functionality from user perspective.192- **Actor**: stick figure (circle head + body line) placed outside system boundary193 - Label below figure, 13-14px194 - Primary actors on left, secondary/supporting on right195- **Use case**: ellipse with label centered inside, min 140×60px196 - Keep names verb phrases: "Create Order", "Process Payment"197- **System boundary**: large rect with dashed border + system name in top-left198- **Relationships**:199 - Include: dashed arrow `<<include>>` from base to included use case200 - Extend: dashed arrow `<<extend>>` from extension to base use case201 - Generalization: solid line + hollow triangle (specialized → general)202- Layout: system boundary centered, actors outside, use cases inside203- ViewBox: `0 0 960 600` standard204205### State Machine Diagram (UML)206Lifecycle states and transitions of an entity.207- **State**: rounded rect with state name, min 120×50px208 - Internal activities: small text `entry/ action`, `exit/ action`, `do/ activity`209 - **Initial state**: filled black circle (r=8), one outgoing arrow210 - **Final state**: filled circle (r=8) inside hollow circle (r=12)211 - **Choice**: small hollow diamond, guard labels on outgoing arrows `[condition]`212- **Transition**: arrow with optional label `event [guard] / action`213 - Guard conditions in square brackets214 - Actions after `/`215- **Composite/nested state**: larger rect containing sub-states, with name tab216- **Fork/join**: thick horizontal or vertical black bar (synchronization)217- Layout: initial state top-left, final state bottom-right, flow top-to-bottom218- ViewBox: `0 0 960 600` standard219220### ER Diagram (Entity-Relationship)221Database schema and data relationships.222- **Entity**: rect with entity name in header (bold), attributes below223 - Primary key attribute: underlined224 - Foreign key: italic or marked with (FK)225 - Min width: 160px; attribute font-size: 12px226- **Relationship**: diamond shape on connecting line227 - Label inside diamond: "has", "belongs to", "enrolls in"228 - Cardinality labels near entity: `1`, `N`, `0..1`, `0..*`, `1..*`229- **Weak entity**: double-bordered rect with double diamond relationship230- **Associative entity**: diamond + rect hybrid (rect with diamond inside)231- Line style: solid for identifying relationships, dashed for non-identifying232- Layout: entities in 2-3 rows, relationships between related entities233- ViewBox: `0 0 960 600` standard; wider `0 0 1200 600` for many entities234235### Network Topology236Physical or logical network infrastructure.237- **Devices**: icon-like rects or rounded rects238 - Router: circle with cross arrows239 - Switch: rect with arrow grid240 - Server: stacked rect (rack icon)241 - Firewall: brick-pattern rect or shield shape242 - Load Balancer: horizontal split rect with arrows243 - Cloud: cloud path (overlapping arcs)244- **Connections**: lines between device centers245 - Ethernet/wired: solid line, label bandwidth246 - Wireless: dashed line with WiFi symbol247 - VPN: dashed line with lock icon248- **Subnets/Zones**: dashed rect containers with zone label (DMZ, Internal, External)249- **Labels**: device hostname + IP below, 12-13px250- Layout: tiered top-to-bottom (Internet → Edge → Core → Access → Endpoints)251- ViewBox: `0 0 960 600` standard252253## UML Coverage Map254255Full mapping of UML 14 diagram types to supported diagram types:256257| UML Diagram | Supported As | Notes |258|-------------|-------------|-------|259| Class | Class Diagram | Full UML notation |260| Component | Architecture Diagram | Use colored fills per component type |261| Deployment | Architecture Diagram | Add node/instance labels |262| Package | Architecture Diagram | Use dashed grouping containers |263| Composite Structure | Architecture Diagram | Nested rects within components |264| Object | Class Diagram | Instance boxes with underlined name |265| Use Case | Use Case Diagram | Full actor/ellipse/relationship |266| Activity | Flowchart / Process Flow | Add fork/join bars |267| State Machine | State Machine Diagram | Full UML notation |268| Sequence | Sequence Diagram | Add alt/opt/loop frames |269| Communication | — | Approximate with Sequence (swap axes) |270| Timing | Timeline | Adapt time axis |271| Interaction Overview | Flowchart | Combine activity + sequence fragments |272| ER Diagram | ER Diagram | Chen/Crow's foot notation |273274## Shape Vocabulary275276Map semantic concepts to consistent shapes across all diagram types:277278| Concept | Shape | Notes |279|---------|-------|-------|280| User / Human | Circle + body path | Stick figure or avatar |281| LLM / Model | Rounded rect with brain/spark icon or gradient fill | Use accent color |282| Agent / Orchestrator | Hexagon or rounded rect with double border | Signals "active controller" |283| Memory (short-term) | Rounded rect, dashed border | Ephemeral = dashed |284| Memory (long-term) | Cylinder (database shape) | Persistent = solid cylinder |285| Vector Store | Cylinder with grid lines inside | Add 3 horizontal lines |286| Graph DB | Circle cluster (3 overlapping circles) | |287| Tool / Function | Gear-like rect or rect with wrench icon | |288| API / Gateway | Hexagon (single border) | |289| Queue / Stream | Horizontal tube (pipe shape) | |290| File / Document | Folded-corner rect | |291| Browser / UI | Rect with 3-dot titlebar | |292| Decision | Diamond | Flowcharts only |293| Process / Step | Rounded rect | Standard box |294| External Service | Rect with cloud icon or dashed border | |295| Data / Artifact | Parallelogram | I/O in flowcharts |296297## Arrow Semantics298299Always assign arrow meaning, not just color:300301| Flow Type | Color | Stroke | Dash | Meaning |302|-----------|-------|--------|------|---------|303| Primary data flow | blue `#2563eb` | 2px solid | none | Main request/response path |304| Control / trigger | orange `#ea580c` | 1.5px solid | none | One system triggering another |305| Memory read | green `#059669` | 1.5px solid | none | Retrieval from store |306| Memory write | green `#059669` | 1.5px | `5,3` | Write/store operation |307| Async / event | gray `#6b7280` | 1.5px | `4,2` | Non-blocking, event-driven |308| Embedding / transform | purple `#7c3aed` | 1px solid | none | Data transformation |309| Feedback / loop | purple `#7c3aed` | 1.5px curved | none | Iterative reasoning loop |310311Always include a **legend** when 2+ arrow types are used.312313## Layout Rules & Validation314315**Spacing**:316- Same-layer nodes: 80px horizontal, 120px vertical between layers317- Canvas margins: 40px minimum, 60px between node edges318- Snap to 8px grid: horizontal 120px intervals, vertical 120px intervals319320**Arrow Labels** (CRITICAL):321- MUST have background rect: `<rect fill="canvas_bg" opacity="0.95"/>` with 4px horizontal, 2px vertical padding322- Place mid-arrow, ≤3 words, stagger by 15-20px when multiple arrows converge323- Maintain 10px safety distance from nodes324325**Arrow Routing**:326- Prefer orthogonal (L-shaped) paths to minimize crossings327- Anchor arrows on component edges, not geometric centers328- Route around dense node clusters, use different y-offsets for parallel arrows329- Jump-over arcs (5px radius) for unavoidable crossings330331**Post-Generation Arrow Optimization**:332333When a user asks to "优化箭头" / "fix arrow routing" / "optimize the diagram" on an already-generated diagram, preserve all nodes, containers, styles, and layout — only modify the `arrows` entries in the JSON data, then re-render with `generate-from-template.py`.334335Available arrow override fields (in recommended order of use):336337| Field | Type | When to Use |338|-------|------|-------------|339| `source_port` / `target_port` | `"left"` / `"right"` / `"top"` / `"bottom"` | Arrow exits/enters from the wrong edge |340| `corridor_x` | `[x, ...]` | Hint vertical segments toward this x lane (soft preference) |341| `corridor_y` | `[y, ...]` | Hint horizontal segments toward this y lane (soft preference) |342| `route_points` | `[[x1,y1], [x2,y2], ...]` | Force exact waypoints (bypasses auto-routing); keep segments orthogonal |343| `routing_padding` | number (default: 24) | *(Advanced)* Adjust obstacle clearance for this arrow |344| `port_clearance` | number | *(Advanced)* Adjust first-segment offset from node edge |345346Optimization steps:3471. Read the existing SVG — identify which arrows overlap, cross nodes, or look misaligned3482. Find those arrows in the JSON data by `source` / `target` pair3493. Add `source_port` / `target_port` if the exit/entry direction is wrong; add `corridor_x` / `corridor_y` to space parallel arrows apart; use `route_points` only when hints alone cannot resolve the path3504. Re-run `generate-from-template.py` with the updated JSON and validate with `validate-svg.sh`351352Example — spacing two overlapping arrows into separate corridors:353```json354{ "source": "nodeA", "target": "nodeB", "corridor_y": [280] }355{ "source": "nodeC", "target": "nodeD", "corridor_y": [320] }356```357358**Line Overlap Prevention** (CRITICAL - most common bug on Codex):359When two arrows must cross each other, ALWAYS use jump-over arcs to prevent visual overlap:360- Crossing horizontal arrows: add a small semicircle arc (radius 5px, stroke same color as arrow, fill none) that "jumps over" the other line361- SVG pattern for jump-over: use a white/matching-background arc on the lower layer, then draw the upper arc on top362- Multiple crossings: stagger arc radii (5px, 7px, 9px) so arcs don't overlap each other363- Never let two arrows' straight-line segments cross without a jump-over arc364365**Validation Checklist** (run before finalizing):3661. **Arrow-Component Collision**: Arrows MUST NOT pass through component interiors (route around with orthogonal paths)3672. **Text Overflow**: All text MUST fit with 8px padding (estimate: `text.length × 7px ≤ shape_width - 16px`)3683. **Arrow-Text Alignment**: Arrow endpoints MUST connect to shape edges (not floating); all arrow labels MUST have background rects3694. **Container Discipline**: Prefer arrows entering and leaving section containers through open gaps between components, not through inner component bodies3705. **Filter Boundary Safety**: For every element with `filter="url(...)"`, verify `(element_x + element_width + filter_extension) ≤ viewBox_width` AND `element_x ≥ filter_extension`. The default filter region extends 10-20% beyond bbox; staying near viewBox edges causes Chrome/cairosvg to clip the element's edge-side stroke (one side of the border vanishes while other sides render correctly)371372## SVG Technical Rules373374- ViewBox: `0 0 960 600` default; `0 0 960 800` tall; `0 0 1200 600` wide375- Fonts: embed via `<style>font-family: ...</style>` — no external `@import` (cairosvg / rsvg-convert cannot fetch external URLs)376- `<defs>`: arrow markers, gradients, filters, clip paths377- Text: minimum 12px, prefer 13-14px labels, 11px sub-labels, 16-18px titles378- All arrows: `<marker>` with `markerEnd`, sized `markerWidth="10" markerHeight="7"`379- Drop shadows: `<feDropShadow>` in `<filter>`, apply sparingly (key nodes only)380- Curved paths: use `M x1,y1 C cx1,cy1 cx2,cy2 x2,y2` cubic bezier for loops/feedback arrows381- Clip content: use `<clipPath>` if text might overflow a node box382383## SVG Generation & Error Prevention384385**MANDATORY: Python List Method** (ALWAYS use this):386```python387python3 << 'EOF'388lines = []389lines.append('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 960 700">')390lines.append(' <defs>')391# ... each line separately392lines.append('</svg>')393394with open('/path/to/output.svg', 'w') as f:395 f.write('\n'.join(lines))396print("SVG generated successfully")397EOF398```399400**Why mandatory**: Prevents character truncation, typos, and syntax errors. Each line is independent and easy to verify.401402**Pre-Tool-Call Checklist** (CRITICAL - use EVERY time):4031. ✅ Can I write out the COMPLETE command/content right now?4042. ✅ Do I have ALL required parameters ready?4053. ✅ Have I checked for syntax errors in my prepared content?406407**If ANY answer is NO**: STOP. Do NOT call the tool. Prepare the content first.408409**Error Recovery Protocol**:410- **First error**: Analyze root cause, apply targeted fix411- **Second error**: Switch method entirely (Python list → chunked generation)412- **Third error**: STOP and report to user - do NOT loop endlessly413- **Never**: Retry the same failing command or call tools with empty parameters414415**Validation** (run after generation):416```bash417python3 -c "import xml.etree.ElementTree as ET; ET.parse('file.svg')" && echo "✓ Valid XML"418# Or use cairosvg as a render-time check:419python3 -c "import cairosvg; cairosvg.svg2png(url='file.svg', write_to='/tmp/test.png')" && echo "✓ Renders" && rm /tmp/test.png420```421422**If using `generate-from-template.py`**:423- Prefer `source` / `target` node ids in arrow JSON so the generator can snap to node edges424- Keep `x1,y1,x2,y2` as hints or fallback coordinates, not the main routing primitive425- Let the generator choose orthogonal routes; avoid hardcoding center-to-center straight lines unless the path is guaranteed clear426427**Common Syntax Errors to Avoid**:428- ❌ `yt-anchor` → ✅ `y="60" text-anchor="middle"`429- ❌ `x="390` (missing y) → ✅ `x="390" y="250"`430- ❌ `fill=#fff` → ✅ `fill="#ffffff"`431- ❌ `marker-end=` → ✅ `marker-end="url(#arrow)"`432- ❌ `L 29450` → ✅ `L 290,220`433- ❌ Missing `</svg>` at end434- ❌ Element with `filter` near viewBox edge — filter region extends 20% (default) or more beyond bbox; if that region exceeds viewBox, Chrome/cairosvg clip the filter rendering AND can drop the element's own stroke on that side. Keep filtered elements at least `max(20% of element size, shadow blur radius × 3)` away from viewBox edges, or omit the filter.435436## Output437438- **Default**: `./[derived-name].svg` and `./[derived-name].png` in current directory439- **Custom**: user specifies path with `--output /path/` or `输出到 /path/`440- **PNG export**: see **SVG → PNG Conversion** below441442## SVG → PNG Conversion443444### Method Comparison445446| Tool | Install | Render Quality | Notes |447|------|---------|----------------|-------|448| `rsvg-convert` | System (often preinstalled) | ⚠️ Fair | Drops some CSS styles and `<foreignObject>` elements — missing borders/text on complex SVGs |449| **`cairosvg` (recommended)** | `pip install cairosvg` | ✅ Good | Solid CSS support; clearly better than rsvg-convert |450| `puppeteer` (headless Chrome) | `npm install puppeteer` | ✅✅ Best | Real browser engine; 100% fidelity but heavy (Node + Chromium) |451452### Recommended: cairosvg (Python one-liner)453454```bash455# Single file (2x resolution for retina/docs)456python3 -c "import cairosvg; cairosvg.svg2png(url='input.svg', write_to='output.png', scale=2)"457458# Batch convert all SVGs in a directory459python3 -c "460import cairosvg, os, glob461d = 'docs/00-core'462for svg in sorted(glob.glob(os.path.join(d, '*.svg'))):463 png = svg.replace('.svg', '.png')464 cairosvg.svg2png(url=svg, write_to=png, scale=2)465 print(f'Done: {os.path.basename(svg)} -> {os.path.basename(png)}')466"467```468469> `scale=2` produces 2x resolution PNG, ideal for high-DPI screens and embedded docs.470471### Fallback: rsvg-convert (simple but may drop styles)472473```bash474# Single file475rsvg-convert -w 1920 file.svg -o file.png476477# Batch (not recommended — complex SVGs may lose elements)478for f in docs/00-core/*.svg; do rsvg-convert -o "${f%.svg}.png" "$f"; done479480# 2x resolution481for f in docs/00-core/*.svg; do rsvg-convert -z 2 -o "${f%.svg}.png" "$f"; done482```483484### Highest Fidelity: puppeteer (headless Chrome)485486```bash487npm install puppeteer # auto-downloads Chromium488node svg2png.js [directory]489```490491<details>492<summary>svg2png.js — full puppeteer script</summary>493494```javascript495const puppeteer = require('puppeteer');496const fs = require('fs');497const path = require('path');498499(async () => {500 const dir = process.argv[2] || '.';501 const svgFiles = fs.readdirSync(dir).filter(f => f.endsWith('.svg'));502503 const browser = await puppeteer.launch({504 headless: 'new',505 args: ['--no-sandbox', '--disable-setuid-sandbox']506 });507508 for (const file of svgFiles) {509 const svgPath = path.resolve(dir, file);510 const pngPath = svgPath.replace(/\.svg$/, '.png');511 const svgContent = fs.readFileSync(svgPath, 'utf-8');512513 const wMatch = svgContent.match(/width="(\d+)/);514 const hMatch = svgContent.match(/height="(\d+)/);515 const vbMatch = svgContent.match(/viewBox="[^"]*\s(\d+)\s(\d+)"/);516517 let width = wMatch ? parseInt(wMatch[1]) : (vbMatch ? parseInt(vbMatch[1]) : 1200);518 let height = hMatch ? parseInt(hMatch[1]) : (vbMatch ? parseInt(vbMatch[2]) : 800);519520 const scale = 2;521 const page = await browser.newPage();522 await page.setViewport({ width, height, deviceScaleFactor: scale });523524 const html = `<!DOCTYPE html>525<html><head><style>526 body { margin: 0; padding: 0; background: transparent; }527 img { display: block; }528</style></head>529<body>530 <img src="data:image/svg+xml;base64,${Buffer.from(svgContent).toString('base64')}" width="${width}" height="${height}" />531</body></html>`;532533 await page.setContent(html, { waitUntil: 'networkidle0' });534 await page.screenshot({ path: pngPath, type: 'png', omitBackground: true });535 await page.close();536537 console.log(`Done: ${file} -> ${path.basename(pngPath)} (${width}x${height} @${scale}x)`);538 }539540 await browser.close();541})();542```543544</details>545546### Gotchas (lessons learned)547548- `rsvg-convert` renders SVGs containing `<foreignObject>`, CSS `filter`, or complex `<style>` blocks **incompletely** — missing borders / missing text are the typical symptoms549- `cairosvg` (built on Cairo) has much better CSS support than rsvg and is sufficient for most cases550- If the SVG was generated by a browser (D3.js, Mermaid, etc.), only headless Chrome (puppeteer) renders it 100% faithfully551- **Chrome headless CLI `--window-size=W,H` is not the drawable area** — even in `--headless=new` mode, browser chrome (scrollbars, internal UI surfaces) consumes ~15-20% of both width and height, so the actual SVG viewport is only ~0.84×W by ~0.84×H. Symptom: SVG content past `x ≈ 0.84 × W` or `y ≈ 0.84 × H` is cut off and renders as a solid white band, even though the SVG file itself is correct. Typical failure modes: a Legend in the top-right corner loses its right border; a bottom-row container loses its bottom dashed line. Fix: pass window dimensions **≥ SVG width × 1.2 AND SVG height × 1.2**, then crop the raw screenshot back to `(SVG_width × scale, SVG_height × scale)` with PIL or ImageMagick. Example: for a 1280×580 SVG at 3× DPR, use `--window-size=1600,800` then crop the output to 3840×1740. The Puppeteer / `page.setViewport()` path does NOT have this issue — it sets a precise viewport regardless of window UI.552553### Picking a Method5545551. **Default** → `cairosvg` (pip install once, one-line conversion, good fidelity)5562. **No Python available** → `rsvg-convert` (acceptable for simple flat-color diagrams)5573. **Browser-generated SVG or pixel-perfect required** → `puppeteer`558559## Styles560561| # | Name | Background | Best For |562|---|------|-----------|----------|563| 1 | **Flat Icon** (default) | White | Blogs, docs, presentations |564| 2 | **Dark Terminal** | `#0f0f1a` | GitHub, dev articles |565| 3 | **Blueprint** | `#0a1628` | Architecture docs |566| 4 | **Notion Clean** | White, minimal | Notionnce |567| 5 | **Glassmorphism** | Dark gradient | Product sites, keynotes |568| 6 | **Claude Official** | Warm cream `#f8f6f3` | Anthropic-style diagrams |569| 7 | **OpenAI Official** | Pure white `#ffffff` | OpenAI-style diagrams |570571Load `references/style-N.md` for exact color tokens and SVG patterns.572573## Style Selection574575**Default**: Style 1 (Flat Icon) for most diagrams. Load `references/style-diagram-matrix.md` for detailed style-to-diagram-type recommendations.576577These patterns appear frequently — internalize them:578579**RAG Pipeline**: Query → Embed → VectorSearch → Retrieve → Augment → LLM → Response580**Agentic RAG**: adds Agent loop with Tool use between Query and LLM581**Agentic Search**: Query → Planner → [Search Tool / Calculator / Code] → Synthesizer → Response582**Mem0 / Memory Layer**: Input → Memory Manager → [Write: VectorDB + GraphDB] / [Read: Retrieve+Rank] → Context583**Agent Memory Types**: Sensory (raw input) → Working (context window) → Episodic (past interactions) → Semantic (facts) → Procedural (skills)584**Multi-Agent**: Orchestrator → [SubAgent A / SubAgent B / SubAgent C] → Aggregator → Output585**Tool Call Flow**: LLM → Tool Selector → Tool Execution → Result Parser → LLM (loop)