excalidraw-agent-cli 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- excalidraw_agent_cli-1.1.0/LICENSE +21 -0
- excalidraw_agent_cli-1.1.0/PKG-INFO +516 -0
- excalidraw_agent_cli-1.1.0/README.md +491 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/__init__.py +3 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/__main__.py +6 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/cli.py +1043 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/core/__init__.py +1 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/core/elements.py +766 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/core/export.py +242 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/core/project.py +230 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/core/session.py +191 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/export_helper/__init__.py +0 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/export_helper/export.js +621 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/export_helper/package-lock.json +1753 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/export_helper/package.json +19 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/SKILL.md +297 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/cli-reference.md +335 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/color-palette.md +185 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/architecture.md +237 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/class-diagram.md +314 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/er-diagram.md +292 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/flowchart.md +183 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/gantt.md +210 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/mindmap.md +338 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/sequence.md +268 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/state-diagram.md +220 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-type-rubric.md +53 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/layout-rules.md +574 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/patterns.md +342 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/utils/__init__.py +1 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/utils/backend.py +168 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/utils/repl_skin.py +498 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli.egg-info/PKG-INFO +516 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli.egg-info/SOURCES.txt +40 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli.egg-info/dependency_links.txt +1 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli.egg-info/entry_points.txt +2 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli.egg-info/requires.txt +2 -0
- excalidraw_agent_cli-1.1.0/excalidraw_agent_cli.egg-info/top_level.txt +1 -0
- excalidraw_agent_cli-1.1.0/pyproject.toml +48 -0
- excalidraw_agent_cli-1.1.0/setup.cfg +4 -0
- excalidraw_agent_cli-1.1.0/tests/test_core.py +499 -0
- excalidraw_agent_cli-1.1.0/tests/test_e2e.py +472 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Bhushan Karayilthekkoot
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: excalidraw-agent-cli
|
|
3
|
+
Version: 1.1.0
|
|
4
|
+
Summary: Agentic CLI for Excalidraw — create, edit, and export diagrams from the command line or from AI agents.
|
|
5
|
+
License: MIT
|
|
6
|
+
Project-URL: Homepage, https://github.com/bhushanlaware/excalidraw-agent-cli
|
|
7
|
+
Project-URL: Issues, https://github.com/bhushanlaware/excalidraw-agent-cli/issues
|
|
8
|
+
Keywords: excalidraw,cli,diagram,agentic,ai
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Environment :: Console
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
18
|
+
Classifier: Topic :: Utilities
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: click>=8.0.0
|
|
23
|
+
Requires-Dist: prompt-toolkit>=3.0.0
|
|
24
|
+
Dynamic: license-file
|
|
25
|
+
|
|
26
|
+
# excalidraw-agent-cli
|
|
27
|
+
|
|
28
|
+
> Tell Claude what to draw. It picks the diagram type, plans the layout, writes the script, renders it, reads the PNG, and iterates until it passes a 7-point visual checklist. You get a hand-drawn Excalidraw diagram in seconds — `.excalidraw` + `.svg` + `.png`.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install excalidraw-agent-cli
|
|
32
|
+
excalidraw-agent-cli install-skill # one-time — teach Claude to diagram
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Then in any Claude Code session:
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
"Draw a system architecture for a three-tier web app"
|
|
39
|
+
"Create a flowchart for the user signup and email verification process"
|
|
40
|
+
"Diagram the CI/CD pipeline as a feedback loop"
|
|
41
|
+
"Visualize the JWT authentication flow between browser, gateway, auth service, and DB"
|
|
42
|
+
"Show the microservices architecture with an event bus and async fan-out"
|
|
43
|
+
"Mind map the React & TypeScript ecosystem"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## What it does
|
|
49
|
+
|
|
50
|
+
The CLI lets AI agents build `.excalidraw` files element-by-element — no browser needed, pure JSON mutations, real Excalidraw rendering. There are two generation modes, and the bundled skill knows which to use:
|
|
51
|
+
|
|
52
|
+

|
|
53
|
+
|
|
54
|
+
**Approach A — Dagre** (default): Write `graph.json` with nodes, edges, and optional zones. No coordinates needed — `dagre-layout.js` auto-computes all positions. Use for everything: architecture, flowcharts, mind maps, ER, state, CI/CD, data pipelines.
|
|
55
|
+
|
|
56
|
+
**Approach B — CLI** (sequence diagrams only): Write a bash script calling `element add` and `element connect` with explicit `x,y` coordinates. Use only for sequence diagrams — lifelines require precise horizontal alignment that layout algorithms can't guarantee.
|
|
57
|
+
|
|
58
|
+
Both produce identical output: the same `.excalidraw` JSON, the same Puppeteer rendering, the same hand-drawn aesthetic.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## The skill pipeline
|
|
63
|
+
|
|
64
|
+
Install the skill once. After that, just describe what you want — Claude runs this pipeline automatically:
|
|
65
|
+
|
|
66
|
+

|
|
67
|
+
|
|
68
|
+
The self-inspection loop is what makes this more than one-shot generation. Claude reads the exported PNG with its vision, checks 7 quality items (labels readable, arrows directed correctly, no text overflow, colors consistent with the recipe, title clearance), and iterates up to 3 times if anything fails.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Install
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
pip install excalidraw-agent-cli
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Requires Node.js ≥ 18** for SVG/PNG export (`brew install node` or [nodejs.org](https://nodejs.org)).
|
|
79
|
+
Node dependencies are auto-installed on first export into `~/.cache/excalidraw-agent-cli/` — nothing else needed.
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## Install the Claude Code skill
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Global — available in every Claude Code session on this machine
|
|
87
|
+
excalidraw-agent-cli install-skill
|
|
88
|
+
|
|
89
|
+
# Into a specific project — committed to git, shared with the team
|
|
90
|
+
excalidraw-agent-cli install-skill --codebase .
|
|
91
|
+
|
|
92
|
+
# Overwrite an existing installation
|
|
93
|
+
excalidraw-agent-cli install-skill --force
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
After installation, just describe what you want in natural language. Claude picks the diagram type, chooses dagre or CLI based on the complexity, loads the matching layout recipe, generates the script, exports, inspects, and iterates.
|
|
97
|
+
|
|
98
|
+
| Install mode | Path | When to use |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| Global (default) | `~/.claude/skills/excalidraw/` | Your personal machine — available everywhere |
|
|
101
|
+
| Codebase | `./.claude/skills/excalidraw/` | Team projects — checked into git |
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## What the skill contains
|
|
106
|
+
|
|
107
|
+
The skill is a set of reference files Claude loads on demand. It never loads everything at once — just `SKILL.md` plus the files relevant to the current diagram type.
|
|
108
|
+
|
|
109
|
+

|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
~/.claude/skills/excalidraw/
|
|
113
|
+
├── SKILL.md ← workflow, quality checklist, philosophy
|
|
114
|
+
└── references/
|
|
115
|
+
├── color-palette.md ← semantic hex pairs (bg + stroke) per concept type
|
|
116
|
+
├── cli-reference.md ← full CLI syntax, bash helper patterns
|
|
117
|
+
├── patterns.md ← visual pattern library (fan-out, swim lanes, cycles...)
|
|
118
|
+
├── layout-rules.md ← 26 layout rules, label-width formula, coordinate templates
|
|
119
|
+
├── diagram-type-rubric.md ← decision table: which diagram type for which request
|
|
120
|
+
├── dagre-reference.md ← graph.json schema, when to use dagre, zone patterns
|
|
121
|
+
└── diagram-recipes/
|
|
122
|
+
├── flowchart.md ← coordinate grid, color defaults, pitfalls
|
|
123
|
+
├── sequence.md
|
|
124
|
+
├── mindmap.md
|
|
125
|
+
├── architecture.md
|
|
126
|
+
├── er-diagram.md
|
|
127
|
+
├── class-diagram.md
|
|
128
|
+
├── state-diagram.md
|
|
129
|
+
└── gantt.md
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Each recipe gives Claude a layout template, semantic color defaults, and a pitfall list for that diagram type. The 26 layout rules enforce constraints like minimum label width, zone clearance, and arrow label placement — so diagrams don't break as complexity grows.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Example prompts and outputs
|
|
137
|
+
|
|
138
|
+
These were all generated by Claude using this skill — the prompt is shown alongside each result.
|
|
139
|
+
|
|
140
|
+
### Dagre approach — complex graphs
|
|
141
|
+
|
|
142
|
+
**Prompt**: *"Create a mind map of modern software engineering. Five main branches: Frontend, Backend, Data, DevOps, Architecture. Each branch should expand into subcategories and then specific tools and technologies."*
|
|
143
|
+
|
|
144
|
+

|
|
145
|
+
|
|
146
|
+
50+ nodes, 3 levels, asymmetric branch depths — Dagre handles all positions.
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
**Prompt**: *"Diagram the React & TypeScript ecosystem as a mind map. Six branches: State Management (with Redux → Toolkit/Saga/Thunk as sub-levels), Routing, Testing, Build Tools, Type System, UI Libraries. No arrowheads — this is associative, not directed."*
|
|
151
|
+
|
|
152
|
+

|
|
153
|
+
|
|
154
|
+
44 nodes, intentionally different branch depths. The asymmetry is structural — not manually positioned.
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
**Prompt**: *"Draw a Kubernetes cluster architecture. Four zones: External Traffic, Control Plane, Worker Nodes, Storage. Show the full component graph: Ingress → kube-apiserver, kubelet, etcd, scheduler, controller-manager, kube-proxy, pods, PersistentVolume."*
|
|
159
|
+
|
|
160
|
+

|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
**Prompt**: *"Show the full cloud-native SaaS platform stack: CDN/WAF edge, API Gateway, 6 domain services (User, Product, Order, Inventory, Notification, Billing), platform layer (Kafka, Redis, Vault, LaunchDarkly), data tier (PostgreSQL, Elasticsearch, InfluxDB), and observability (Prometheus, Jaeger, Loki). Use solid arrows for sync calls, dashed for async."*
|
|
165
|
+
|
|
166
|
+

|
|
167
|
+
|
|
168
|
+
7 zones, 32 nodes, 44 edges. Zone bounding boxes are computed automatically.
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
**Prompt**: *"Draw a user signup flowchart. Start with 'User signs up' → validate email (Email valid? diamond) → yes: Hash password → Save to Postgres → Send verify email → Account created. No branch: Return 422."*
|
|
173
|
+
|
|
174
|
+

|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
**Prompt**: *"Draw a three-tier architecture with swim lane zones: CLIENTS (Web App, Mobile App, Partner API), SERVICES (API Gateway, Auth Service, Core API, Notification Svc), DATA (PostgreSQL, Redis Cache, SQS Queue). Use color coding: blue for clients, green for services, purple for data."*
|
|
179
|
+
|
|
180
|
+

|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
**Prompt**: *"Show a microservices architecture with 4 zones: CLIENT LAYER (Web App, Mobile App), GATEWAY (API Gateway), SERVICES (Auth Service, Order Service), BACKENDS / ASYNC (Redis Cache, EventBus SNS, Notification Svc). Labeled arrows, dashed for async connections."*
|
|
185
|
+
|
|
186
|
+

|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
### Not just programming — any domain
|
|
191
|
+
|
|
192
|
+
**Prompt**: *"Draw an org chart for a startup: CEO → CTO / VP Product / VP Design. CTO manages Backend EM, Frontend EM, DevOps Lead. Each EM has a Senior Engineer and two Engineers."*
|
|
193
|
+
|
|
194
|
+

|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
**Prompt**: *"Draw a customer journey map for e-commerce with five phases: Awareness, Consideration, Purchase, Post-Purchase, Retention. Solid arrows within each phase, dashed arrows between phases."*
|
|
199
|
+
|
|
200
|
+

|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
**Prompt**: *"Draw a 'What to cook tonight?' decision flowchart with time and preference questions leading to 8 meal outcomes. Add a dashed try-again arrow from 'Order takeout' back to the start."*
|
|
205
|
+
|
|
206
|
+

|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
**Prompt**: *"Visualize a Claude Code session debugging a memory leak — no template. OOM alert → 3 parallel reads → 3 competing hypotheses (diamonds) → investigate each in parallel, two dead ends (gray, ❌ ruled out), one winner (green, ✅ found in pool.js:47) → fix → load test → verified. Gray out the dead-end paths, make the winning path bolder."*
|
|
211
|
+
|
|
212
|
+
This one has no template. The prompt describes the story, and the graph structure carries the meaning: diamond = hypothesis, ellipse = observation, blue = gathering information, yellow = uncertain, green = resolved, gray = ruled out.
|
|
213
|
+
|
|
214
|
+

|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
### CLI approach — sequence diagrams only
|
|
219
|
+
|
|
220
|
+
**Prompt**: *"Draw a JWT authentication sequence diagram with 4 participants: Browser, API Gateway, Auth Service, PostgreSQL. Show the full login flow: POST /auth/login, verify credentials, SELECT user, return JWT, then a protected request with Authorization header, token validation, and the successful response."*
|
|
221
|
+
|
|
222
|
+

|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Visual style guide
|
|
227
|
+
|
|
228
|
+
All styling options rendered as output images. Applies to both dagre and CLI approaches.
|
|
229
|
+
|
|
230
|
+
### Fill styles
|
|
231
|
+
|
|
232
|
+

|
|
233
|
+
|
|
234
|
+
`none` (default) = transparent background, border only. `solid` = flat color fill, automatically used when a fill color is specified. `hachure` and `cross-hatch` are opt-in for the hand-drawn texture look. Zone backgrounds always use `solid`.
|
|
235
|
+
|
|
236
|
+
### Roughness levels
|
|
237
|
+
|
|
238
|
+

|
|
239
|
+
|
|
240
|
+
`0` = clean vector. `1` (default) = hand-drawn wobble. `2` = very sketchy. Use `--roughness 0` or `--clean` for presentation-ready output.
|
|
241
|
+
|
|
242
|
+
### Font families
|
|
243
|
+
|
|
244
|
+

|
|
245
|
+
|
|
246
|
+
`virgil` (default) = Excalidraw's handwritten font. `normal` = Helvetica. `mono` = Cascadia Code. In dagre: `--font virgil|normal|mono`. Per-element in CLI: `--ff 1|2|3`.
|
|
247
|
+
|
|
248
|
+
### Shapes
|
|
249
|
+
|
|
250
|
+

|
|
251
|
+
|
|
252
|
+
`rectangle` (default), `ellipse` (mind map nodes, root), `diamond` (decisions in flowcharts).
|
|
253
|
+
|
|
254
|
+
### Arrow styles
|
|
255
|
+
|
|
256
|
+

|
|
257
|
+
|
|
258
|
+
`solid` for primary flow, `dashed` for async/secondary, `dotted` for weak/hub-to-spoke connectors, plain line (`--end-arrowhead none`) for mind map spokes. Bidirectional: `--start-arrowhead arrow --end-arrowhead arrow`.
|
|
259
|
+
|
|
260
|
+
### Semantic color palette
|
|
261
|
+
|
|
262
|
+

|
|
263
|
+
|
|
264
|
+
Colors are semantic — the same `bg`/`stroke` pair everywhere for the same concept type. The dark Root node requires `fillStyle: solid` (set automatically by dagre when `textColor` is white).
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Dagre layout — complex graphs without coordinates
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
# 1. Write graph.json — nodes, edges, zones; no x/y
|
|
272
|
+
cat > arch.json << 'EOF'
|
|
273
|
+
{
|
|
274
|
+
"direction": "TB",
|
|
275
|
+
"title": "My Architecture",
|
|
276
|
+
"zones": [
|
|
277
|
+
{ "id": "web", "label": "WEB TIER", "fill": "#dbeafe", "stroke": "#93c5fd",
|
|
278
|
+
"labelColor": "#1e40af", "nodeIds": ["nginx", "cdn"] }
|
|
279
|
+
],
|
|
280
|
+
"nodes": [
|
|
281
|
+
{ "id": "nginx", "label": "Nginx", "fill": "#bfdbfe", "stroke": "#1e40af" },
|
|
282
|
+
{ "id": "api", "label": "API", "fill": "#86efac", "stroke": "#15803d" },
|
|
283
|
+
{ "id": "db", "label": "Postgres", "fill": "#ddd6fe", "stroke": "#6d28d9" }
|
|
284
|
+
],
|
|
285
|
+
"edges": [
|
|
286
|
+
{ "from": "nginx", "to": "api", "stroke": "#15803d" },
|
|
287
|
+
{ "from": "api", "to": "db", "stroke": "#6d28d9", "style": "dashed" }
|
|
288
|
+
]
|
|
289
|
+
}
|
|
290
|
+
EOF
|
|
291
|
+
|
|
292
|
+
# 2. Compute layout → full .excalidraw with all positions
|
|
293
|
+
DAGRE=$(python3 -c "import excalidraw_agent_cli,os; print(os.path.join(os.path.dirname(excalidraw_agent_cli.__file__),'..','dagre-layout.js'))")
|
|
294
|
+
node "$DAGRE" arch.json --output arch.excalidraw
|
|
295
|
+
|
|
296
|
+
# 3. Export
|
|
297
|
+
excalidraw-agent-cli --project arch.excalidraw export png --output arch.png --overwrite
|
|
298
|
+
excalidraw-agent-cli --project arch.excalidraw export svg --output arch.svg --overwrite
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### graph.json schema
|
|
302
|
+
|
|
303
|
+
**Top-level**
|
|
304
|
+
|
|
305
|
+
| Key | Values | Description |
|
|
306
|
+
|-----|--------|-------------|
|
|
307
|
+
| `direction` | `LR`, `TB`, `RL`, `BT` | Layout direction (`LR` for mind maps, `TB` for architectures) |
|
|
308
|
+
| `rankSep` | integer (default 80) | Gap between rank levels |
|
|
309
|
+
| `nodeSep` | integer (default 40) | Gap between nodes in same rank |
|
|
310
|
+
| `title` | string | Title above the diagram |
|
|
311
|
+
| `arrowhead` | `"none"` | Set globally for mind maps (no arrowheads on any edge) |
|
|
312
|
+
|
|
313
|
+
**Node fields** — `id`, `label`, `width`, `height`, `fill`, `stroke`, `textColor`, `fillStyle`, `shape` (`rectangle`/`diamond`/`ellipse`), `rounded`, `fontSize`
|
|
314
|
+
|
|
315
|
+
**Edge fields** — `from`, `to`, `label`, `stroke`, `style` (`solid`/`dashed`/`dotted`), `width`
|
|
316
|
+
|
|
317
|
+
**Zone fields** — `id`, `label`, `labelColor`, `fill`, `stroke`, `nodeIds` (bounding box auto-sized)
|
|
318
|
+
|
|
319
|
+
### dagre-layout.js flags
|
|
320
|
+
|
|
321
|
+
```
|
|
322
|
+
node "$DAGRE" graph.json --output out.excalidraw
|
|
323
|
+
|
|
324
|
+
--roughness 0|1|2 0=clean, 1=hand-drawn (default), 2=very rough
|
|
325
|
+
--font virgil|normal|mono
|
|
326
|
+
--fill hachure|solid global default fill style (per-node fillStyle overrides this)
|
|
327
|
+
--arrow-width N arrow stroke width (default 1.5)
|
|
328
|
+
--node-width N node border width (default 2)
|
|
329
|
+
--clean shortcut: roughness=0, font=mono, fill=solid
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
**Dark node auto-rule**: if a node has `textColor: "#ffffff"`, `dagre-layout.js` automatically applies `fillStyle: solid` and `roughness: 0` — you don't need to set these manually.
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## CLI scripting
|
|
337
|
+
|
|
338
|
+
```bash
|
|
339
|
+
export PATH="/path/to/.venv/bin:/path/to/node/bin:$PATH"
|
|
340
|
+
CLI="excalidraw-agent-cli"
|
|
341
|
+
OUTDIR="${DIAGRAM_DIR:-$(pwd)}" # override via DIAGRAM_DIR env var, default = cwd
|
|
342
|
+
P="$OUTDIR/my-diagram.excalidraw"
|
|
343
|
+
|
|
344
|
+
# Helpers
|
|
345
|
+
add() {
|
|
346
|
+
$CLI --project "$P" --json element add "$@" \
|
|
347
|
+
| python3 -c "import sys,json;print(json.load(sys.stdin)['id'])"
|
|
348
|
+
}
|
|
349
|
+
conn() {
|
|
350
|
+
local from="$1" to="$2" label="$3" color="$4" style="$5"
|
|
351
|
+
local args=("--from" "$from" "--to" "$to" "--start-arrowhead" "none" "--end-arrowhead" "arrow")
|
|
352
|
+
[[ -n "$label" ]] && args+=("-l" "$label")
|
|
353
|
+
[[ -n "$color" ]] && args+=("--stroke" "$color")
|
|
354
|
+
[[ -n "$style" ]] && args+=("--stroke-style" "$style")
|
|
355
|
+
$CLI --project "$P" element connect "${args[@]}" > /dev/null
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
rm -f "$P"
|
|
359
|
+
$CLI project new --name "my-diagram" --output "$P" > /dev/null
|
|
360
|
+
|
|
361
|
+
# Add nodes
|
|
362
|
+
A=$(add rectangle --x 200 --y 200 -w 180 -h 80 \
|
|
363
|
+
--label "API Gateway" --bg "#86efac" --stroke "#15803d")
|
|
364
|
+
B=$(add rectangle --x 480 --y 200 -w 160 -h 80 \
|
|
365
|
+
--label "Auth Service" --bg "#fed7aa" --stroke "#c2410c")
|
|
366
|
+
|
|
367
|
+
# Connect
|
|
368
|
+
conn "$A" "$B" "authenticates" "#c2410c" "solid"
|
|
369
|
+
|
|
370
|
+
# Export
|
|
371
|
+
$CLI --project "$P" export png --output "$OUTDIR/my-diagram.png" --overwrite
|
|
372
|
+
$CLI --project "$P" export svg --output "$OUTDIR/my-diagram.svg" --overwrite
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## All commands
|
|
378
|
+
|
|
379
|
+
```
|
|
380
|
+
project new / open / save / info / validate
|
|
381
|
+
element add rectangle / ellipse / diamond / text / arrow / line / frame
|
|
382
|
+
element list / get / update / delete / move / connect
|
|
383
|
+
export svg / png / json
|
|
384
|
+
session status / undo / redo / history
|
|
385
|
+
backend check
|
|
386
|
+
install-skill [--global] [--codebase DIR] [--force]
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
Global flags (go **before** the subcommand):
|
|
390
|
+
|
|
391
|
+
```
|
|
392
|
+
--project -p Path to .excalidraw file
|
|
393
|
+
--json Output as JSON (required for agent/scripting use)
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## Element reference
|
|
399
|
+
|
|
400
|
+
### Shapes: `rectangle` / `ellipse` / `diamond`
|
|
401
|
+
|
|
402
|
+
| Flag | Description | Default |
|
|
403
|
+
|------|-------------|---------|
|
|
404
|
+
| `--x`, `--y` | Canvas position (top-left corner) | required |
|
|
405
|
+
| `-w`, `-h` | Width and height in px | `180 × 80` |
|
|
406
|
+
| `--label` / `-l` | Text inside the shape | none |
|
|
407
|
+
| `--bg` | Fill color (hex) | `#ffffff` |
|
|
408
|
+
| `--stroke` | Border color (hex) | `#1e1e1e` |
|
|
409
|
+
| `--fill-style` | `hachure`, `solid`, `cross-hatch`, `dots`, `zigzag` | `hachure` |
|
|
410
|
+
| `--sw` | Stroke width in px | `1` |
|
|
411
|
+
| `--roughness` | `0` clean · `1` default · `2` sketchy | `1` |
|
|
412
|
+
| `--opacity` | 0–100 | `100` |
|
|
413
|
+
| `--roundness` | Flag — rounds corners (rectangles only) | off |
|
|
414
|
+
|
|
415
|
+
### Text (free-floating)
|
|
416
|
+
|
|
417
|
+
| Flag | Description |
|
|
418
|
+
|------|-------------|
|
|
419
|
+
| `-t` / positional | Text content |
|
|
420
|
+
| `--fs` | Font size (min 12) |
|
|
421
|
+
| `--ff` | Font family: `1` Virgil · `2` Helvetica · `3` Cascadia Code |
|
|
422
|
+
| `--color` | Text color (hex) |
|
|
423
|
+
|
|
424
|
+
### `element connect`
|
|
425
|
+
|
|
426
|
+
| Flag | Values | Default |
|
|
427
|
+
|------|--------|---------|
|
|
428
|
+
| `--from` | source element ID | required |
|
|
429
|
+
| `--to` | target element ID | required |
|
|
430
|
+
| `-l` / `--label` | Arrow label | none |
|
|
431
|
+
| `--stroke` | hex color | `#1e1e1e` |
|
|
432
|
+
| `--sw` | stroke width | `2` |
|
|
433
|
+
| `--stroke-style` | `solid`, `dashed`, `dotted` | `solid` |
|
|
434
|
+
| `--start-arrowhead` | `arrow`, `bar`, `dot`, `triangle`, `circle`, or omit for none | none |
|
|
435
|
+
| `--end-arrowhead` | `arrow`, `bar`, `dot`, `triangle`, `circle`, `none` | `arrow` |
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
## Semantic color palette
|
|
440
|
+
|
|
441
|
+
| Concept | `--bg` | `--stroke` |
|
|
442
|
+
|---------|--------|------------|
|
|
443
|
+
| Clients / Users | `#bfdbfe` | `#1e40af` |
|
|
444
|
+
| Gateway / Routing | `#bbf7d0` | `#15803d` |
|
|
445
|
+
| Services / API | `#86efac` | `#15803d` |
|
|
446
|
+
| Async / Queue | `#fef08a` | `#92400e` |
|
|
447
|
+
| Data / Storage | `#ddd6fe` | `#6d28d9` |
|
|
448
|
+
| Security / Auth | `#fed7aa` | `#c2410c` |
|
|
449
|
+
| Observability | `#fecdd3` | `#be123c` |
|
|
450
|
+
| Decision diamond | `#fef3c7` | `#b45309` |
|
|
451
|
+
| Start / Trigger | `#dbeafe` | `#1e40af` |
|
|
452
|
+
| End / Success | `#a7f3d0` | `#047857` |
|
|
453
|
+
| Error / Reject | `#fecaca` | `#b91c1c` |
|
|
454
|
+
| Root / Dark emphasis | `#1e293b` | `#e2e8f0` |
|
|
455
|
+
|
|
456
|
+
Arrow color conventions:
|
|
457
|
+
|
|
458
|
+
| Relationship | `--stroke` |
|
|
459
|
+
|---|---|
|
|
460
|
+
| Primary call / request | `#1e1e1e` |
|
|
461
|
+
| Async / event | `#92400e` |
|
|
462
|
+
| Error / failure | `#dc2626` |
|
|
463
|
+
| Data read/write | `#6d28d9` |
|
|
464
|
+
| Auth / security | `#c2410c` |
|
|
465
|
+
| Hub-to-spoke connector | `#94a3b8` |
|
|
466
|
+
|
|
467
|
+
---
|
|
468
|
+
|
|
469
|
+
## How rendering works
|
|
470
|
+
|
|
471
|
+
```
|
|
472
|
+
excalidraw-agent-cli (Python)
|
|
473
|
+
│ element add / connect / update
|
|
474
|
+
│ → builds .excalidraw JSON in memory
|
|
475
|
+
▼
|
|
476
|
+
.excalidraw file
|
|
477
|
+
│
|
|
478
|
+
├── export png/svg → Node.js (Puppeteer) → raster/vector output
|
|
479
|
+
└── export json → raw .excalidraw file (editable in excalidraw.com)
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
The Python layer handles all element state — no Excalidraw installation required. Node.js is invoked only for raster/vector export and auto-installs its dependencies (~52 MB) on first use into `~/.cache/excalidraw-agent-cli/`.
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## How `--json` mode works for agents
|
|
487
|
+
|
|
488
|
+
Every `element add` returns a JSON object including the element's `id`:
|
|
489
|
+
|
|
490
|
+
```bash
|
|
491
|
+
$ excalidraw-agent-cli --project "$P" --json element add rectangle \
|
|
492
|
+
--x 200 --y 200 -w 180 -h 80 --label "API Gateway"
|
|
493
|
+
|
|
494
|
+
{
|
|
495
|
+
"status": "added",
|
|
496
|
+
"id": "a3f2c1d0-...",
|
|
497
|
+
"type": "rectangle",
|
|
498
|
+
"x": 200, "y": 200,
|
|
499
|
+
"width": 180, "height": 80,
|
|
500
|
+
"label": "API Gateway"
|
|
501
|
+
}
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
The `id` is passed to `element connect --from` / `--to`, enabling reliable wiring without coordinate heuristics. This is what makes it agent-friendly.
|
|
505
|
+
|
|
506
|
+
---
|
|
507
|
+
|
|
508
|
+
## More examples
|
|
509
|
+
|
|
510
|
+
See [`examples/GALLERY.md`](./examples/GALLERY.md) for all examples with full prompts, approach notes, and previews.
|
|
511
|
+
|
|
512
|
+
---
|
|
513
|
+
|
|
514
|
+
## License
|
|
515
|
+
|
|
516
|
+
MIT — see [LICENSE](LICENSE)
|