
Excalidraw
- 41 installs
- 14 repo stars
- Updated July 30, 2026
- kv0906/cc-skills
Helps with ai & agent building tasks.
About
excalidraw is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted development.
- excalidraw
- AI & Agent Building
- AI-coding skill
Excalidraw by the numbers
- 41 all-time installs (skills.sh)
- +1 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #8,148 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/kv0906/cc-skills --skill excalidrawAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 41 |
|---|---|
| repo stars | ★ 14 |
| Last updated | July 30, 2026 |
| Repository | kv0906/cc-skills ↗ |
What it does
Helps with ai & agent building tasks.
Files
Excalidraw Diagram Generator
Create Excalidraw-compatible JSON diagrams. Output .excalidraw.json files.
JSON Schema
{
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [],
"appState": {
"gridSize": null,
"viewBackgroundColor": "#ffffff"
},
"files": {}
}Coordinate System
- Origin: Top-left corner (0, 0)
- X-axis: Increases rightward
- Y-axis: Increases downward
- Unit: Pixels
Grid-Based Layout System
Use a 20px grid for alignment. Standard positions:
GRID_UNIT = 20
COLUMN_WIDTH = 200 # Element + gap
ROW_HEIGHT = 150 # Element + gap
Position formula:
x = START_X + (column * COLUMN_WIDTH)
y = START_Y + (row * ROW_HEIGHT)
Recommended START_X = 50, START_Y = 100Standard Element Sizes
| Element | Width | Height | Use Case |
|---|---|---|---|
| Small box | 120 | 60 | Labels, simple steps |
| Standard box | 160 | 80 | Process steps |
| Large box | 200 | 100 | Detailed nodes |
| Wide box | 240 | 80 | Long text |
| Diamond | 100 | 100 | Decision points |
| Circle | 80 | 80 | Start/End nodes |
| Icon circle | 90 | 80 | With emoji |
Text Centering Formula
CRITICAL: To center text inside a shape:
text_x = shape_x + (shape_width - text_width) / 2
text_y = shape_y + (shape_height - text_height) / 2Text Size Reference
| Font Size | Char Width | Line Height | Use |
|---|---|---|---|
| 11 | ~6px | 15px | Labels, annotations |
| 12 | ~7px | 16px | Secondary text |
| 14 | ~8px | 18px | Body text |
| 16 | ~9px | 20px | Primary text |
| 18 | ~10px | 24px | Headings |
| 20 | ~11px | 26px | Titles |
| 28 | ~16px | 35px | Icons/Emoji |
Estimate text_width: char_count * char_width Estimate text_height: line_count * line_height
Centering Example
Shape: x=100, y=100, width=160, height=80
Text: "Process" (7 chars), fontSize=16
text_width = 7 * 9 = 63
text_height = 1 * 20 = 20
text_x = 100 + (160 - 63) / 2 = 148.5 ≈ 148
text_y = 100 + (80 - 20) / 2 = 130Element Types
Common Properties (required for all)
{
"id": "unique-id",
"type": "rectangle",
"x": 100,
"y": 100,
"width": 160,
"height": 80,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 100,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
}Type-Specific Properties
Rectangle: Add "roundness": {"type": 3} for rounded corners
Text:
{
"type": "text",
"text": "Content\nLine 2",
"fontSize": 16,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle"
}- fontFamily: 1=Virgil (hand), 2=Helvetica, 3=Cascadia (mono)
Arrow/Line:
{
"type": "arrow",
"points": [[0, 0], [100, 0]],
"startArrowhead": null,
"endArrowhead": "arrow"
}- Points are relative to element's x,y
- Arrowheads:
null,"arrow","bar","dot","triangle"
Arrow Positioning
Horizontal Arrow (Left to Right)
From shape at (x1, y1, w1, h1) to shape at (x2, y2, w2, h2):
arrow_x = x1 + w1 # Right edge of source
arrow_y = y1 + h1/2 # Vertical center
gap = x2 - (x1 + w1) # Space between shapes
points = [[0, 0], [gap, 0]]Vertical Arrow (Top to Bottom)
arrow_x = x1 + w1/2 # Horizontal center
arrow_y = y1 + h1 # Bottom edge of source
gap = y2 - (y1 + h1)
points = [[0, 0], [0, gap]]Diagonal/Curved Arrow
points = [[0, 0], [dx/2, dy], [dx, dy]] # Curved pathColor Palette
| Color | Stroke | Background | Use |
|---|---|---|---|
| Blue | #1971c2 | #a5d8ff | Primary, info |
| Green | #2f9e44 | #b2f2bb | Success, start |
| Orange | #e8590c | #ffc9c9 | Warning, action |
| Red | #e03131 | #ffc9c9 | Error, end |
| Purple | #9c36b5 | #eebefa | Special, loop |
| Yellow | #f08c00 | #ffec99 | Highlight |
| Teal | #099268 | #96f2d7 | Secondary |
| Gray | #868e96 | #dee2e6 | Neutral, labels |
| Black | #1e1e1e | - | Text, borders |
Z-Order (Element Array Order)
Elements render in array order. First = back, last = front.
Correct order: 1. Background shapes (containers, frames) 2. Connection lines/arrows 3. Foreground shapes (nodes, boxes) 4. Text labels 5. Icons/overlays
Layout Patterns
Horizontal Flow (Left to Right)
COL_GAP = 60 # Gap between elements
Element 1: x=50, y=100, w=160, h=80
Arrow 1: x=210, y=140, points=[[0,0],[60,0]]
Element 2: x=270, y=100, w=160, h=80
Arrow 2: x=430, y=140, points=[[0,0],[60,0]]
Element 3: x=490, y=100, w=160, h=80Vertical Flow (Top to Bottom)
ROW_GAP = 50
Element 1: x=100, y=50, w=160, h=80
Arrow 1: x=180, y=130, points=[[0,0],[0,50]]
Element 2: x=100, y=180, w=160, h=80Decision Branch (Diamond)
Diamond: x=300, y=200, w=100, h=100
Center: (350, 250)
Yes path (up-right):
arrow_x=350, arrow_y=200
points=[[0,0], [0,-50], [100,-50]]
No path (down-right):
arrow_x=350, arrow_y=300
points=[[0,0], [0,50], [100,50]]Feedback Loop (Return Arrow)
From bottom-right back to left:
Start: (800, 400)
points=[
[0, 0], # Start
[0, 80], # Down
[-400, 80], # Left
[-400, -150] # Up to target
]Complete Node Example
[
{
"id": "node1-box",
"type": "rectangle",
"x": 100, "y": 100, "width": 160, "height": 80,
"strokeColor": "#1971c2",
"backgroundColor": "#a5d8ff",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 100,
"version": 1,
"isDeleted": false,
"boundElements": [{"id": "arrow1", "type": "arrow"}],
"roundness": {"type": 3},
"link": null,
"locked": false
},
{
"id": "node1-text",
"type": "text",
"x": 130, "y": 130,
"width": 100, "height": 20,
"text": "Process Step",
"fontSize": 16,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 101,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
}
]Positioning Checklist
Before generating: 1. ☐ Define grid: START_X, START_Y, COLUMN_WIDTH, ROW_HEIGHT 2. ☐ List all elements with row/column positions 3. ☐ Calculate exact x,y using formulas 4. ☐ Calculate text positions using centering formula 5. ☐ Calculate arrow start points and relative endpoints 6. ☐ Order elements correctly for z-order 7. ☐ Assign unique IDs and incrementing seeds
Templates
- Basic flowchart:
assets/flowchart-template.excalidraw.json - Processing loop:
references/processing-loop-template.md - Element specs:
references/elements.md
Output
1. Save as .excalidraw.json 2. Copy to /mnt/user-data/outputs/ 3. Tell user: "Open at excalidraw.com → Menu → Open"
{
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [
{
"id": "start",
"type": "ellipse",
"x": 100,
"y": 100,
"width": 120,
"height": 60,
"strokeColor": "#2f9e44",
"backgroundColor": "#b2f2bb",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 100,
"version": 1,
"isDeleted": false,
"boundElements": [{"id": "arrow1", "type": "arrow"}],
"link": null,
"locked": false
},
{
"id": "start-text",
"type": "text",
"x": 130,
"y": 118,
"width": 60,
"height": 25,
"text": "Start",
"fontSize": 18,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 101,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "arrow1",
"type": "arrow",
"x": 160,
"y": 165,
"width": 0,
"height": 50,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 102,
"version": 1,
"isDeleted": false,
"points": [[0, 0], [0, 50]],
"startBinding": {"elementId": "start", "focus": 0, "gap": 5},
"endBinding": {"elementId": "process1", "focus": 0, "gap": 5},
"startArrowhead": null,
"endArrowhead": "arrow",
"link": null,
"locked": false
},
{
"id": "process1",
"type": "rectangle",
"x": 80,
"y": 220,
"width": 160,
"height": 70,
"strokeColor": "#1971c2",
"backgroundColor": "#a5d8ff",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 200,
"version": 1,
"isDeleted": false,
"boundElements": [
{"id": "arrow1", "type": "arrow"},
{"id": "arrow2", "type": "arrow"}
],
"roundness": {"type": 3},
"link": null,
"locked": false
},
{
"id": "process1-text",
"type": "text",
"x": 110,
"y": 242,
"width": 100,
"height": 25,
"text": "Process 1",
"fontSize": 16,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 201,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "arrow2",
"type": "arrow",
"x": 160,
"y": 295,
"width": 0,
"height": 50,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 202,
"version": 1,
"isDeleted": false,
"points": [[0, 0], [0, 50]],
"startBinding": {"elementId": "process1", "focus": 0, "gap": 5},
"endBinding": {"elementId": "decision1", "focus": 0, "gap": 5},
"startArrowhead": null,
"endArrowhead": "arrow",
"link": null,
"locked": false
},
{
"id": "decision1",
"type": "diamond",
"x": 80,
"y": 350,
"width": 160,
"height": 100,
"strokeColor": "#f08c00",
"backgroundColor": "#ffec99",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 300,
"version": 1,
"isDeleted": false,
"boundElements": [
{"id": "arrow2", "type": "arrow"},
{"id": "arrow3-yes", "type": "arrow"},
{"id": "arrow3-no", "type": "arrow"}
],
"link": null,
"locked": false
},
{
"id": "decision1-text",
"type": "text",
"x": 115,
"y": 387,
"width": 90,
"height": 25,
"text": "Condition?",
"fontSize": 14,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 301,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "arrow3-yes",
"type": "arrow",
"x": 160,
"y": 455,
"width": 0,
"height": 50,
"strokeColor": "#2f9e44",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 302,
"version": 1,
"isDeleted": false,
"points": [[0, 0], [0, 50]],
"startBinding": {"elementId": "decision1", "focus": 0, "gap": 5},
"endBinding": {"elementId": "end", "focus": 0, "gap": 5},
"startArrowhead": null,
"endArrowhead": "arrow",
"link": null,
"locked": false
},
{
"id": "yes-label",
"type": "text",
"x": 170,
"y": 470,
"width": 30,
"height": 20,
"text": "Yes",
"fontSize": 12,
"fontFamily": 1,
"textAlign": "left",
"verticalAlign": "middle",
"strokeColor": "#2f9e44",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 303,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "arrow3-no",
"type": "arrow",
"x": 245,
"y": 400,
"width": 80,
"height": 0,
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 304,
"version": 1,
"isDeleted": false,
"points": [[0, 0], [80, 0]],
"startBinding": {"elementId": "decision1", "focus": 0, "gap": 5},
"endBinding": {"elementId": "process2", "focus": 0, "gap": 5},
"startArrowhead": null,
"endArrowhead": "arrow",
"link": null,
"locked": false
},
{
"id": "no-label",
"type": "text",
"x": 270,
"y": 378,
"width": 25,
"height": 20,
"text": "No",
"fontSize": 12,
"fontFamily": 1,
"textAlign": "left",
"verticalAlign": "middle",
"strokeColor": "#e03131",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 305,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "process2",
"type": "rectangle",
"x": 330,
"y": 365,
"width": 160,
"height": 70,
"strokeColor": "#1971c2",
"backgroundColor": "#a5d8ff",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 400,
"version": 1,
"isDeleted": false,
"boundElements": [
{"id": "arrow3-no", "type": "arrow"},
{"id": "arrow4", "type": "arrow"}
],
"roundness": {"type": 3},
"link": null,
"locked": false
},
{
"id": "process2-text",
"type": "text",
"x": 360,
"y": 387,
"width": 100,
"height": 25,
"text": "Process 2",
"fontSize": 16,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 401,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "arrow4",
"type": "arrow",
"x": 410,
"y": 360,
"width": 0,
"height": 105,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 402,
"version": 1,
"isDeleted": false,
"points": [[0, 0], [0, -105], [-250, -105]],
"startBinding": {"elementId": "process2", "focus": 0, "gap": 5},
"endBinding": {"elementId": "process1", "focus": 0, "gap": 5},
"startArrowhead": null,
"endArrowhead": "arrow",
"link": null,
"locked": false
},
{
"id": "end",
"type": "ellipse",
"x": 100,
"y": 510,
"width": 120,
"height": 60,
"strokeColor": "#e03131",
"backgroundColor": "#ffc9c9",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 500,
"version": 1,
"isDeleted": false,
"boundElements": [{"id": "arrow3-yes", "type": "arrow"}],
"link": null,
"locked": false
},
{
"id": "end-text",
"type": "text",
"x": 138,
"y": 528,
"width": 45,
"height": 25,
"text": "End",
"fontSize": 18,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 501,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
}
],
"appState": {
"gridSize": null,
"viewBackgroundColor": "#ffffff"
},
"files": {}
}
Excalidraw Elements Reference
Complete specification for all Excalidraw element types.
Table of Contents
1. Common Properties 2. Rectangle 3. Ellipse 4. Diamond 5. Text 6. Arrow 7. Line 8. Frame 9. Image
---
Common Properties
Every element requires these properties:
{
"id": "string", // Unique identifier
"type": "string", // Element type
"x": 0, // X position (top-left corner)
"y": 0, // Y position (top-left corner)
"width": 100, // Width in pixels
"height": 50, // Height in pixels
"strokeColor": "#1e1e1e", // Border/stroke color
"backgroundColor": "transparent", // Fill color or "transparent"
"fillStyle": "solid", // "solid" | "hachure" | "cross-hatch"
"strokeWidth": 1, // 1 (thin) | 2 (medium) | 4 (thick)
"roughness": 1, // 0 (architect) | 1 (artist) | 2 (cartoonist)
"opacity": 100, // 0-100
"angle": 0, // Rotation in radians
"seed": 1, // Random seed for hand-drawn effect
"version": 1, // Element version
"isDeleted": false,
"boundElements": null, // Array of bound elements or null
"link": null, // Hyperlink or null
"locked": false
}Property Details
strokeColor / backgroundColor
Hex color codes. Common options:
- Transparent:
"transparent" - Black:
"#1e1e1e" - White:
"#ffffff" - Colors: See color palette in SKILL.md
fillStyle
"solid": Solid fill"hachure": Diagonal lines (hand-drawn look)"cross-hatch": Cross-hatched lines
roughness
0: Clean, architect style1: Hand-drawn, artist style (default)2: Sketchy, cartoonist style
boundElements
Array of objects linking this element to others:
"boundElements": [
{"id": "arrow1", "type": "arrow"},
{"id": "text1", "type": "text"}
]---
Rectangle
{
"type": "rectangle",
"roundness": {"type": 3} // Optional: rounded corners
// ... common properties
}Roundness Options
nullor omitted: Sharp corners{"type": 3}: Rounded corners (proportional to size){"type": 2}: Less rounded
---
Ellipse
{
"type": "ellipse"
// ... common properties
}Circle: Set equal width and height.
---
Diamond
{
"type": "diamond"
// ... common properties
}Used for decision points in flowcharts.
---
Text
{
"type": "text",
"text": "Your text here\nSecond line",
"fontSize": 20, // Pixels
"fontFamily": 1, // 1=Virgil(hand), 2=Helvetica, 3=Cascadia(code)
"textAlign": "center", // "left" | "center" | "right"
"verticalAlign": "middle", // "top" | "middle"
"lineHeight": 1.25, // Optional
"baseline": 18 // Optional
// ... common properties
}Font Families
1: Virgil (hand-drawn style) - default2: Helvetica (clean sans-serif)3: Cascadia (monospace/code)
Multi-line Text
Use \n for line breaks in the text property.
---
Arrow
{
"type": "arrow",
"points": [[0, 0], [100, 0]], // Relative coordinates
"startBinding": null, // Link to start element
"endBinding": null, // Link to end element
"startArrowhead": null, // null | "arrow" | "bar" | "dot" | "triangle"
"endArrowhead": "arrow" // null | "arrow" | "bar" | "dot" | "triangle"
// ... common properties
}Points Array
- Relative to element's x,y position
- Minimum 2 points for straight line
- Add more points for curves/bends
// Straight horizontal arrow (50px)
"points": [[0, 0], [50, 0]]
// Right-angle arrow (down then right)
"points": [[0, 0], [0, 50], [100, 50]]
// Curved path with multiple segments
"points": [[0, 0], [25, -20], [50, 0], [75, 20], [100, 0]]Bindings
Connect arrows to shapes:
"startBinding": {
"elementId": "rectangle1",
"focus": 0, // -1 to 1, position on element edge
"gap": 5 // Space between arrow and element
}Arrowhead Types
null: No arrowhead"arrow": Standard arrow (>)"bar": Perpendicular line (|)"dot": Circle"triangle": Filled triangle
---
Line
{
"type": "line",
"points": [[0, 0], [100, 50]],
"startBinding": null,
"endBinding": null
// ... common properties
}Same as arrow but no arrowheads. Use for connectors without direction.
---
Frame
{
"type": "frame",
"name": "Frame Name" // Displayed label
// ... common properties
}Use frames to group elements visually.
---
Image
{
"type": "image",
"fileId": "abc123", // Reference to files object
"scale": [1, 1] // X and Y scale
// ... common properties
}Files Object
Images require an entry in the root files object:
"files": {
"abc123": {
"mimeType": "image/png",
"id": "abc123",
"dataURL": "data:image/png;base64,iVBORw0KGgo...",
"created": 1690295874454,
"lastRetrieved": 1690295874454
}
}---
Element Grouping
Group elements by adding them to the same group:
{
"id": "el1",
"groupIds": ["group1"],
// ...
},
{
"id": "el2",
"groupIds": ["group1"],
// ...
}Nested groups: "groupIds": ["innerGroup", "outerGroup"]
---
Z-Order
Elements render in array order. First element = back, last element = front.
To layer correctly: 1. Background shapes first 2. Connecting lines/arrows 3. Foreground shapes 4. Text on top
Processing Loop with Conditional Branching Template
Generic template for systems with: Input → Processor → Condition → Output/Action branches with feedback loop.
Use Cases
- AI agent tool-calling loops
- Order processing workflows
- Request handling systems
- API gateway routing
- Approval workflows
- Error handling pipelines
Template Variables
| Variable | Description | Examples |
|---|---|---|
{{INPUT_TEXT}} | Initial input/request | "Process order #123", "User query", "API request" |
{{INPUT_LABEL}} | Label for input arrow | "Request", "Query", "Order", "Message" |
{{PROCESSOR_TITLE}} | Main processor node title | "Order Processor", "Router", "Agent", "Handler" |
{{PROCESSOR_ICON}} | Emoji for processor | "🧠", "⚙️", "🔄", "📦" |
{{CAPABILITY_1}} | First capability/tool | "Validator", "Database", "API Call" |
{{CAPABILITY_1_COLOR}} | Color for capability 1 | "#868e96" (gray) |
{{CAPABILITY_2}} | Second capability/tool | "Notifier", "Logger", "Cache" |
{{CAPABILITY_2_COLOR}} | Color for capability 2 | "#1971c2" (blue) |
{{CONDITION_LABEL}} | Decision point label | "Route", "Validate", "Check", "Condition" |
{{OUTPUT_LABEL}} | Direct output path label | "Response", "Complete", "Success", "Done" |
{{OUTPUT_TEXT}} | Final output text | "Order confirmed", "Result: OK", "Done" |
{{ACTION_LABEL}} | Action path label | "Process", "Execute", "Handle", "Action" |
{{ACTION_ARGS}} | Action parameters | "id: 123\ntype: fulfillment" |
{{EXECUTOR_TITLE}} | Executor node title | "Executor", "Worker", "Handler", "Service" |
{{EXECUTOR_RESULT}} | Execution result | "success", "completed", "processed" |
{{FEEDBACK_LABEL}} | Feedback loop label | "Result", "Callback", "Response", "Update" |
Layout Coordinates
┌─────────────────────────────────────────────────────────────────────────────┐
│ Y=55-75: Direct output text │
│ │
│ Y=95-130: Node labels │
│ │
│ Y=155-235: Main flow (Processor → Condition → branches) │
│ │
│ Y=245-370: Executor area │
│ │
│ Y=380-510: Feedback loop path │
└─────────────────────────────────────────────────────────────────────────────┘
X positions:
- Input: 20-230
- Processor Node: 320-500
- Condition: 590-660
- Executor Node: 755-915Color Scheme
| Element | Stroke | Background | Purpose |
|---|---|---|---|
| Processor icon | #e03131 | #ffc9c9 | Main processing unit |
| Condition diamond | #1e1e1e | #1e1e1e | Decision point |
| Output arrow | #2f9e44 | - | Success/completion path |
| Action arrow | #e8590c | - | Processing/action path |
| Feedback arrow | #9c36b5 | - | Return/callback loop |
| Node boxes | #868e96 | transparent | Containers |
JSON Template
{
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [
{
"id": "input-text",
"type": "text",
"x": 20,
"y": 180,
"width": 200,
"height": 30,
"text": "{{INPUT_TEXT}}",
"fontSize": 16,
"fontFamily": 1,
"textAlign": "left",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 100,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "arrow-input",
"type": "arrow",
"x": 230,
"y": 195,
"width": 80,
"height": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 101,
"version": 1,
"isDeleted": false,
"points": [[0, 0], [80, 0]],
"startArrowhead": null,
"endArrowhead": "arrow",
"link": null,
"locked": false
},
{
"id": "label-input",
"type": "text",
"x": 245,
"y": 165,
"width": 80,
"height": 25,
"text": "{{INPUT_LABEL}}",
"fontSize": 12,
"fontFamily": 3,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#868e96",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 102,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "processor-box",
"type": "rectangle",
"x": 320,
"y": 120,
"width": 180,
"height": 150,
"strokeColor": "#868e96",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 200,
"version": 1,
"isDeleted": false,
"boundElements": null,
"roundness": {"type": 3},
"link": null,
"locked": false
},
{
"id": "processor-label",
"type": "text",
"x": 320,
"y": 95,
"width": 180,
"height": 20,
"text": "{{PROCESSOR_TITLE}}",
"fontSize": 11,
"fontFamily": 3,
"textAlign": "left",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 201,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "processor-icon-bg",
"type": "ellipse",
"x": 365,
"y": 155,
"width": 90,
"height": 80,
"strokeColor": "#e03131",
"backgroundColor": "#ffc9c9",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 202,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "processor-icon",
"type": "text",
"x": 388,
"y": 182,
"width": 45,
"height": 25,
"text": "{{PROCESSOR_ICON}}",
"fontSize": 28,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 203,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "capability-1",
"type": "text",
"x": 340,
"y": 245,
"width": 70,
"height": 20,
"text": "{{CAPABILITY_1}}",
"fontSize": 12,
"fontFamily": 2,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "{{CAPABILITY_1_COLOR}}",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 204,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "capability-2",
"type": "text",
"x": 420,
"y": 245,
"width": 80,
"height": 20,
"text": "{{CAPABILITY_2}}",
"fontSize": 12,
"fontFamily": 2,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "{{CAPABILITY_2_COLOR}}",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 205,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "arrow-to-condition",
"type": "arrow",
"x": 505,
"y": 195,
"width": 80,
"height": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 300,
"version": 1,
"isDeleted": false,
"points": [[0, 0], [80, 0]],
"startArrowhead": null,
"endArrowhead": "arrow",
"link": null,
"locked": false
},
{
"id": "condition-diamond",
"type": "diamond",
"x": 590,
"y": 160,
"width": 70,
"height": 70,
"strokeColor": "#1e1e1e",
"backgroundColor": "#1e1e1e",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 0,
"opacity": 100,
"angle": 0,
"seed": 400,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "condition-label",
"type": "text",
"x": 580,
"y": 130,
"width": 90,
"height": 25,
"text": "{{CONDITION_LABEL}}",
"fontSize": 12,
"fontFamily": 3,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 401,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "arrow-output",
"type": "arrow",
"x": 625,
"y": 155,
"width": 120,
"height": 80,
"strokeColor": "#2f9e44",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 500,
"version": 1,
"isDeleted": false,
"points": [[0, 0], [60, -80], [120, -80]],
"startArrowhead": null,
"endArrowhead": "arrow",
"link": null,
"locked": false
},
{
"id": "label-output",
"type": "text",
"x": 660,
"y": 55,
"width": 60,
"height": 20,
"text": "{{OUTPUT_LABEL}}",
"fontSize": 12,
"fontFamily": 3,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#2f9e44",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 501,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "output-text",
"type": "text",
"x": 755,
"y": 60,
"width": 120,
"height": 30,
"text": "{{OUTPUT_TEXT}}",
"fontSize": 16,
"fontFamily": 1,
"textAlign": "left",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 502,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "arrow-action",
"type": "arrow",
"x": 625,
"y": 235,
"width": 120,
"height": 80,
"strokeColor": "#e8590c",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 600,
"version": 1,
"isDeleted": false,
"points": [[0, 0], [60, 80], [120, 80]],
"startArrowhead": null,
"endArrowhead": "arrow",
"link": null,
"locked": false
},
{
"id": "label-action",
"type": "text",
"x": 665,
"y": 300,
"width": 55,
"height": 20,
"text": "{{ACTION_LABEL}}",
"fontSize": 12,
"fontFamily": 3,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#e8590c",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 601,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "action-args",
"type": "text",
"x": 720,
"y": 330,
"width": 180,
"height": 35,
"text": "{{ACTION_ARGS}}",
"fontSize": 11,
"fontFamily": 3,
"textAlign": "left",
"verticalAlign": "middle",
"strokeColor": "#868e96",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 602,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "executor-box",
"type": "rectangle",
"x": 755,
"y": 270,
"width": 160,
"height": 100,
"strokeColor": "#868e96",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 700,
"version": 1,
"isDeleted": false,
"boundElements": null,
"roundness": {"type": 3},
"link": null,
"locked": false
},
{
"id": "executor-label",
"type": "text",
"x": 755,
"y": 245,
"width": 100,
"height": 20,
"text": "{{EXECUTOR_TITLE}}",
"fontSize": 12,
"fontFamily": 3,
"textAlign": "left",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 701,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "executor-capability-1",
"type": "text",
"x": 775,
"y": 295,
"width": 70,
"height": 20,
"text": "{{CAPABILITY_1}}",
"fontSize": 12,
"fontFamily": 2,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "{{CAPABILITY_1_COLOR}}",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 702,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "executor-capability-2",
"type": "text",
"x": 850,
"y": 295,
"width": 60,
"height": 20,
"text": "{{CAPABILITY_2}}",
"fontSize": 11,
"fontFamily": 2,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "{{CAPABILITY_2_COLOR}}",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 703,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "executor-description",
"type": "text",
"x": 755,
"y": 380,
"width": 220,
"height": 35,
"text": "Executes action and\nreturns result: {{EXECUTOR_RESULT}}",
"fontSize": 11,
"fontFamily": 3,
"textAlign": "left",
"verticalAlign": "middle",
"strokeColor": "#868e96",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 704,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "arrow-feedback",
"type": "arrow",
"x": 835,
"y": 375,
"width": 425,
"height": 130,
"strokeColor": "#9c36b5",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 800,
"version": 1,
"isDeleted": false,
"points": [[0, 0], [0, 130], [-425, 130], [-425, -100]],
"startArrowhead": null,
"endArrowhead": "arrow",
"link": null,
"locked": false
},
{
"id": "label-feedback",
"type": "text",
"x": 450,
"y": 490,
"width": 80,
"height": 20,
"text": "{{FEEDBACK_LABEL}}",
"fontSize": 12,
"fontFamily": 3,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#9c36b5",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 801,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
}
],
"appState": {
"gridSize": null,
"viewBackgroundColor": "#ffffff"
},
"files": {}
}Example Configurations
AI Agent Tool Loop
INPUT_TEXT: "What is magic_function(3)"
INPUT_LABEL: Human message
PROCESSOR_TITLE: Assistant Node (LLM w/ bound tools)
PROCESSOR_ICON: 🧠
CAPABILITY_1: Magic Fxn
CAPABILITY_2: Web Search
CONDITION_LABEL: Tools Condition
OUTPUT_LABEL: Response
OUTPUT_TEXT: The result is 5
ACTION_LABEL: Tool call
ACTION_ARGS: arguments: '{"input":3}'\nname: magic_function
EXECUTOR_TITLE: Tool Node
EXECUTOR_RESULT: '5'
FEEDBACK_LABEL: Tool messageOrder Processing System
INPUT_TEXT: "Order #12345"
INPUT_LABEL: New Order
PROCESSOR_TITLE: Order Processor
PROCESSOR_ICON: 📦
CAPABILITY_1: Inventory
CAPABILITY_2: Payment
CONDITION_LABEL: Validate
OUTPUT_LABEL: Complete
OUTPUT_TEXT: Order Confirmed
ACTION_LABEL: Fulfill
ACTION_ARGS: items: 3\nwarehouse: US-West
EXECUTOR_TITLE: Fulfillment Service
EXECUTOR_RESULT: shipped
FEEDBACK_LABEL: Status UpdateAPI Gateway Router
INPUT_TEXT: "GET /api/users/123"
INPUT_LABEL: HTTP Request
PROCESSOR_TITLE: API Gateway
PROCESSOR_ICON: 🔀
CAPABILITY_1: Auth
CAPABILITY_2: RateLimit
CONDITION_LABEL: Route
OUTPUT_LABEL: Cached
OUTPUT_TEXT: 200 OK (from cache)
ACTION_LABEL: Forward
ACTION_ARGS: service: user-svc\nmethod: GET
EXECUTOR_TITLE: Microservice
EXECUTOR_RESULT: user_data
FEEDBACK_LABEL: ResponseApproval Workflow
INPUT_TEXT: "Expense Report $5,000"
INPUT_LABEL: Submit
PROCESSOR_TITLE: Approval Engine
PROCESSOR_ICON: ✅
CAPABILITY_1: Policy
CAPABILITY_2: Budget
CONDITION_LABEL: Review
OUTPUT_LABEL: Auto-Approve
OUTPUT_TEXT: Approved
ACTION_LABEL: Escalate
ACTION_ARGS: approver: manager\namount: $5,000
EXECUTOR_TITLE: Manager Review
EXECUTOR_RESULT: approved
FEEDBACK_LABEL: DecisionVariations
Remove Feedback Loop
Delete: arrow-feedback, label-feedback
Add Third Capability
Duplicate capability elements, adjust positions:
- Y=265 for third row in both nodes
Multiple Executors
Duplicate executor section, shift Y by +150px each