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.
Files changed (42) hide show
  1. excalidraw_agent_cli-1.1.0/LICENSE +21 -0
  2. excalidraw_agent_cli-1.1.0/PKG-INFO +516 -0
  3. excalidraw_agent_cli-1.1.0/README.md +491 -0
  4. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/__init__.py +3 -0
  5. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/__main__.py +6 -0
  6. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/cli.py +1043 -0
  7. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/core/__init__.py +1 -0
  8. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/core/elements.py +766 -0
  9. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/core/export.py +242 -0
  10. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/core/project.py +230 -0
  11. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/core/session.py +191 -0
  12. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/export_helper/__init__.py +0 -0
  13. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/export_helper/export.js +621 -0
  14. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/export_helper/package-lock.json +1753 -0
  15. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/export_helper/package.json +19 -0
  16. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/SKILL.md +297 -0
  17. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/cli-reference.md +335 -0
  18. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/color-palette.md +185 -0
  19. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/architecture.md +237 -0
  20. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/class-diagram.md +314 -0
  21. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/er-diagram.md +292 -0
  22. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/flowchart.md +183 -0
  23. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/gantt.md +210 -0
  24. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/mindmap.md +338 -0
  25. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/sequence.md +268 -0
  26. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-recipes/state-diagram.md +220 -0
  27. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/diagram-type-rubric.md +53 -0
  28. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/layout-rules.md +574 -0
  29. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/skill/references/patterns.md +342 -0
  30. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/utils/__init__.py +1 -0
  31. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/utils/backend.py +168 -0
  32. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli/utils/repl_skin.py +498 -0
  33. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli.egg-info/PKG-INFO +516 -0
  34. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli.egg-info/SOURCES.txt +40 -0
  35. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli.egg-info/dependency_links.txt +1 -0
  36. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli.egg-info/entry_points.txt +2 -0
  37. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli.egg-info/requires.txt +2 -0
  38. excalidraw_agent_cli-1.1.0/excalidraw_agent_cli.egg-info/top_level.txt +1 -0
  39. excalidraw_agent_cli-1.1.0/pyproject.toml +48 -0
  40. excalidraw_agent_cli-1.1.0/setup.cfg +4 -0
  41. excalidraw_agent_cli-1.1.0/tests/test_core.py +499 -0
  42. 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
+ ![Two Generation Approaches](./docs/two-approaches.svg)
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
+ ![Skill Generation Pipeline](./docs/skill-pipeline.png)
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
+ ![Skill File Structure](./docs/skill-files.png)
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
+ ![Software Engineering Mind Map](./examples/mindmap-software-eng/mindmap-software-eng.svg)
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
+ ![React Ecosystem](./examples/react-ecosystem/react-ecosystem.svg)
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
+ ![Kubernetes Cluster](./examples/k8s-cluster/k8s-cluster.svg)
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
+ ![SaaS Platform](./examples/saas-platform/saas-platform.svg)
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
+ ![Flowchart](./examples/flowchart/flowchart.svg)
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
+ ![Architecture](./examples/arch/arch.svg)
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
+ ![Microservices](./examples/microservices/microservices.svg)
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
+ ![Org Chart](./examples/org-chart/org-chart.svg)
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
+ ![Customer Journey](./examples/customer-journey/customer-journey.svg)
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
+ ![Recipe Flowchart](./examples/recipe-flowchart/recipe-flowchart.svg)
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
+ ![Agent Debug Session](./examples/agent-debug-session/agent-debug-session.svg)
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
+ ![Auth Sequence](./examples/auth-sequence/auth-sequence.svg)
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
+ ![Fill Styles](./examples/style-guide/fill-styles.svg)
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
+ ![Roughness Levels](./examples/style-guide/roughness.svg)
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
+ ![Font Families](./examples/style-guide/fonts.svg)
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
+ ![Shapes](./examples/style-guide/shapes.svg)
251
+
252
+ `rectangle` (default), `ellipse` (mind map nodes, root), `diamond` (decisions in flowcharts).
253
+
254
+ ### Arrow styles
255
+
256
+ ![Arrow Styles](./examples/style-guide/arrow-styles.svg)
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
+ ![Color Palette](./examples/style-guide/color-palette.svg)
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)