claude-canvas 1.0.5 → 1.0.6

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.
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  <h1 align="center">claude-canvas</h1>
6
6
 
7
7
  <p align="center">
8
- <strong>A visual canvas for Claude Code instead of asking questions in the terminal, Claude can draw diagrams, wireframes, and mockups on a shared canvas and collect visual feedback from the user.</strong>
8
+ <strong>Give Claude Code eyes and a whiteboard. Claude draws diagrams, wireframes, and mockups on a shared canvas, asks visual questions, and collects your feedback all without leaving the terminal.</strong>
9
9
  </p>
10
10
 
11
11
  <p align="center">
@@ -19,48 +19,53 @@
19
19
  <p align="center">
20
20
  <a href="#installation">Installation</a> &bull;
21
21
  <a href="#quick-start">Quick Start</a> &bull;
22
- <a href="#cli-reference">CLI Reference</a> &bull;
23
- <a href="#visual-qa">Visual Q&A</a> &bull;
22
+ <a href="#visual-qa--ask">Visual Q&A</a> &bull;
23
+ <a href="#drawing">Drawing</a> &bull;
24
24
  <a href="#interactive-canvas">Interactive Canvas</a> &bull;
25
25
  <a href="#claude-code-skill">Claude Code Skill</a> &bull;
26
- <a href="#architecture">Architecture</a>
26
+ <a href="#cli-reference">CLI Reference</a>
27
27
  </p>
28
28
 
29
29
  ---
30
30
 
31
31
  ## What is claude-canvas?
32
32
 
33
- **claude-canvas** gives [Claude Code](https://claude.ai/code) a visual canvas. It runs a local server that opens a browser-based drawing surface where Claude can send draw commands (shapes, arrows, text, freehand paths) via CLI or HTTP API, and users can draw interactively too. Communication happens in real-time over WebSocket.
33
+ [Claude Code](https://claude.ai/code) is powerful, but it's stuck in text. When Claude needs to show you a layout, compare design options, or ask "which of these do you prefer?" a terminal isn't enough.
34
34
 
35
- It also serves as a **visual Q&A tool** Claude can send structured questions alongside canvas drawings, and users answer by picking options, typing text, or drawing directly on the canvas.
35
+ **claude-canvas** is a shared visual canvas that lets Claude **draw diagrams and ask visual questions**, and lets you **answer by clicking, typing, or drawing** right in the browser.
36
36
 
37
37
  <p align="center">
38
- <img src="docs/screenshots/ui-drawing.png" alt="claude-canvas UIarchitecture diagram with toolbar and canvas" width="700" />
38
+ <img src="docs/screenshots/ui-ask.png" alt="Visual Q&AClaude draws layout options, user picks one" width="700" />
39
39
  </p>
40
40
 
41
+ ### What it solves
42
+
43
+ - **"Which layout do you prefer?"** — Claude draws the options, you click your choice
44
+ - **"What should this look like?"** — Claude sketches a wireframe, you annotate it
45
+ - **"Here's the architecture"** — Claude draws a diagram you can actually see, not ASCII art
46
+ - **"Name this feature"** — Claude shows context on canvas, you type your answer
47
+
48
+ ### How It Works
49
+
50
+ 1. **`claude-canvas start`** — opens a browser tab with a shared canvas
51
+ 2. **Claude draws** diagrams, wireframes, or mockups on the canvas
52
+ 3. **Claude asks** visual questions — a floating panel appears with your options
53
+ 4. **You answer** by clicking choices, typing text, or drawing on the canvas
54
+ 5. **Claude gets your answers** automatically when you click Done — no extra steps
55
+
41
56
  ### Key Features
42
57
 
43
- - **Sketchy hand-drawn aesthetic** — powered by [Rough.js](https://roughjs.com), all shapes render with a natural, whiteboard feel
44
- - **Bidirectional drawing** — Claude draws via CLI/API, users draw interactively in the browser
45
- - **Visual Q&A system** — ask structured questions with per-question canvas drawings, collect answers programmatically
58
+ - **Visual Q&A** — structured questions with per-question canvas drawings, answers returned automatically
59
+ - **Shared drawing surface** — Claude draws via CLI, you draw interactively in the browser, both in real-time
60
+ - **Hand-drawn aesthetic** — powered by [Rough.js](https://roughjs.com), everything looks like a natural whiteboard sketch
46
61
  - **Multiple fill styles** — hachure, solid, zigzag, cross-hatch, dots, dashed, and wireframe outlines
47
- - **Session management** — run multiple isolated canvas sessions simultaneously
48
- - **Real-time sync** — WebSocket-powered instant updates between CLI and browser
49
- - **Export options** — save as PNG, SVG, or JSON
50
- - **Claude Code skill** — install the skill so Claude automatically knows when and how to use the canvas
62
+ - **Export** — save as PNG, SVG, or JSON
63
+ - **Claude Code skill** — install once, Claude automatically uses the canvas when it makes sense
51
64
 
52
65
  <p align="center">
53
- <img src="docs/screenshots/fill-styles.png" alt="Fill styles gallery hachure, solid, zigzag, cross-hatch, dots" width="700" />
66
+ <img src="docs/screenshots/ui-drawing.png" alt="claude-canvas UIarchitecture diagram with toolbar and canvas" width="700" />
54
67
  </p>
55
68
 
56
- ### How It Works
57
-
58
- 1. **`claude-canvas start`** launches a local Express + WebSocket server and opens a browser tab
59
- 2. **Claude Code** sends draw commands and questions via the CLI (which hits the HTTP API)
60
- 3. The **server broadcasts** commands to the browser over WebSocket in real-time
61
- 4. **Users interact** directly on the canvas — drawing, answering questions, or annotating Claude's work
62
- 5. **`claude-canvas screenshot`** captures the canvas state and returns answers to any pending questions
63
-
64
69
  ---
65
70
 
66
71
  ## Installation
@@ -114,24 +119,37 @@ This opens a browser tab with a fresh canvas and returns session info:
114
119
  {"sessionId": "a1b2c3d4", "port": 7890, "url": "http://127.0.0.1:7890", "pid": 1234}
115
120
  ```
116
121
 
117
- **2. Draw something:**
122
+ **2. Ask a visual question:**
118
123
 
119
124
  ```bash
120
- claude-canvas draw '{"commands": [
121
- {"type": "rect", "x": 50, "y": 50, "width": 200, "height": 100, "label": "Frontend"},
122
- {"type": "rect", "x": 350, "y": 50, "width": 200, "height": 100, "label": "Backend"},
123
- {"type": "arrow", "x1": 250, "y1": 100, "x2": 350, "y2": 100, "label": "API"}
125
+ claude-canvas ask '{"questions": [
126
+ {
127
+ "id": "q1",
128
+ "text": "Which layout do you prefer?",
129
+ "type": "single",
130
+ "options": ["Sidebar", "Top Nav"],
131
+ "commands": [
132
+ {"type": "rect", "x": 50, "y": 50, "width": 200, "height": 150, "label": "Sidebar"},
133
+ {"type": "rect", "x": 300, "y": 50, "width": 200, "height": 150, "label": "Top Nav"}
134
+ ]
135
+ }
124
136
  ]}'
125
137
  ```
126
138
 
127
- **3. Take a screenshot:**
139
+ The command blocks. In the browser, answer the question and click Done. The command returns:
128
140
 
129
- ```bash
130
- claude-canvas screenshot
141
+ ```json
142
+ {"ok": true, "status": "answered", "path": "/tmp/claude-canvas/canvas-123.png", "answers": [{"questionId": "q1", "value": "Sidebar"}]}
131
143
  ```
132
144
 
133
- ```json
134
- {"ok": true, "path": "/tmp/claude-canvas/canvas-123.png", "answers": []}
145
+ **3. Or just draw:**
146
+
147
+ ```bash
148
+ claude-canvas draw '{"commands": [
149
+ {"type": "rect", "x": 50, "y": 50, "width": 200, "height": 100, "label": "Frontend"},
150
+ {"type": "rect", "x": 350, "y": 50, "width": 200, "height": 100, "label": "Backend"},
151
+ {"type": "arrow", "x1": 250, "y1": 100, "x2": 350, "y2": 100, "label": "API"}
152
+ ]}'
135
153
  ```
136
154
 
137
155
  **4. Stop the session when done:**
@@ -142,43 +160,114 @@ claude-canvas stop --all
142
160
 
143
161
  ---
144
162
 
145
- ## CLI Reference
163
+ ## Visual Q&A / Ask
146
164
 
147
- All commands accept `-s, --session <id>`. You can omit it when only one session is running.
165
+ The core feature of claude-canvas. Claude sends structured questions with visual context each question gets its own canvas drawing. A floating panel appears in the browser where you answer by clicking options, typing text, or drawing.
148
166
 
149
- ### Session Management
167
+ The `ask` command **blocks until you click Done**, then returns all answers and a screenshot in one call. No polling, no extra steps.
150
168
 
151
- | Command | Description |
152
- |---------|-------------|
153
- | `claude-canvas start` | Start a new canvas session (opens browser) |
154
- | `claude-canvas start -p 8080` | Start on a specific port |
155
- | `claude-canvas stop -s <id>` | Stop a specific session |
156
- | `claude-canvas stop --all` | Stop all running sessions |
169
+ ### The Flow
157
170
 
158
- ### Drawing
171
+ <p align="center">
172
+ <img src="docs/screenshots/qa-flow-diagram.png" alt="Visual Q&A flow — Claude asks, user answers, answers returned automatically" width="500" />
173
+ </p>
174
+
175
+ <p align="center">
176
+ <img src="docs/screenshots/ui-ask.png" alt="Visual Q&A — Claude draws layout options, user picks one" width="700" />
177
+ </p>
178
+
179
+ Users select answers via interactive pill buttons. Selected answers are highlighted:
180
+
181
+ <p align="center">
182
+ <img src="docs/screenshots/ui-ask-answered.png" alt="Visual Q&A — answer selected" width="700" />
183
+ </p>
184
+
185
+ ### Sending Questions
159
186
 
160
187
  ```bash
161
- # Send draw commands as JSON
162
- claude-canvas draw '{"commands": [...]}'
188
+ claude-canvas ask '{"questions": [
189
+ {
190
+ "id": "q1",
191
+ "text": "Which layout do you prefer?",
192
+ "type": "single",
193
+ "options": ["Layout A", "Layout B", "Layout C"],
194
+ "commands": [
195
+ {"type": "rect", "x": 80, "y": 80, "width": 200, "height": 150, "label": "Layout A"},
196
+ {"type": "rect", "x": 350, "y": 80, "width": 200, "height": 150, "label": "Layout B"}
197
+ ]
198
+ },
199
+ {
200
+ "id": "q2",
201
+ "text": "What should the title be?",
202
+ "type": "text"
203
+ }
204
+ ]}'
205
+ ```
206
+
207
+ ### Question Types
208
+
209
+ | Type | Description | User interaction | Answer format |
210
+ |------|------------|------------------|---------------|
211
+ | `single` | Pick one option | Radio-style pill buttons | `"value": "Option A"` |
212
+ | `multi` | Pick multiple options | Toggle pill buttons | `"value": ["Option A", "Option C"]` |
213
+ | `text` | Free text input | Text field | `"value": "user's text"` |
214
+ | `canvas` | Draw on canvas | Freeform drawing | `"value": "see canvas"` + snapshot PNG |
163
215
 
164
- # Read from stdin (useful for large payloads)
165
- echo '{"commands": [...]}' | claude-canvas draw -
216
+ ### Response
166
217
 
167
- # Render instantly without animation
168
- claude-canvas draw --no-animate '{"commands": [...]}'
218
+ The `ask` command blocks and returns:
219
+
220
+ ```json
221
+ {
222
+ "ok": true,
223
+ "status": "answered",
224
+ "path": "/tmp/claude-canvas/canvas-123.png",
225
+ "answers": [
226
+ {"questionId": "q1", "value": "Layout A"},
227
+ {"questionId": "q2", "value": "My Custom Title"}
228
+ ]
229
+ }
169
230
  ```
170
231
 
171
- ### Canvas Operations
232
+ If the browser disconnects before the user submits:
172
233
 
173
- | Command | Description |
174
- |---------|-------------|
175
- | `claude-canvas clear` | Clear all objects from the canvas |
176
- | `claude-canvas clear --layer claude` | Clear only Claude's objects (keep user drawings) |
177
- | `claude-canvas screenshot` | Capture canvas as PNG and collect Q&A answers |
178
- | `claude-canvas export -f png` | Export as PNG |
179
- | `claude-canvas export -f svg` | Export as SVG |
180
- | `claude-canvas export -f json` | Export as JSON |
181
- | `claude-canvas export -f png --labels` | Export with shape labels included |
234
+ ```json
235
+ {
236
+ "ok": false,
237
+ "status": "disconnected",
238
+ "error": "Browser disconnected before answers were submitted"
239
+ }
240
+ ```
241
+
242
+ ### Canvas-Type Answers
243
+
244
+ For `canvas`-type questions, Claude draws a diagram and the user responds by drawing directly on the canvas. The answer includes a snapshot of what the user drew:
245
+
246
+ <p align="center">
247
+ <img src="docs/screenshots/ui-canvas-answer.png" alt="Canvas Q&A — Claude draws a wireframe, user annotates with freehand drawings" width="700" />
248
+ </p>
249
+
250
+ ```json
251
+ {"questionId": "q3", "value": "see canvas", "canvasSnapshot": "/tmp/claude-canvas/canvas-q3-456.png"}
252
+ ```
253
+
254
+ ---
255
+
256
+ ## Drawing
257
+
258
+ Claude can draw shapes, diagrams, and wireframes on the canvas with the `draw` command:
259
+
260
+ ```bash
261
+ claude-canvas draw '{"commands": [
262
+ {"type": "rect", "x": 50, "y": 50, "width": 200, "height": 100, "label": "Frontend"},
263
+ {"type": "rect", "x": 350, "y": 50, "width": 200, "height": 100, "label": "Backend"},
264
+ {"type": "arrow", "x1": 250, "y1": 100, "x2": 350, "y2": 100, "label": "API"}
265
+ ]}'
266
+ ```
267
+
268
+ <p align="center">
269
+ <img src="docs/screenshots/fill-styles.png" alt="Fill styles gallery — hachure, solid, zigzag, cross-hatch, dots" width="700" />
270
+ </p>
182
271
 
183
272
  <details>
184
273
  <summary><strong>DrawCommand Types</strong> (click to expand)</summary>
@@ -238,7 +327,8 @@ For structured flowcharts:
238
327
 
239
328
  </details>
240
329
 
241
- ### Fill Styles
330
+ <details>
331
+ <summary><strong>Fill Styles</strong> (click to expand)</summary>
242
332
 
243
333
  Shapes default to `"hachure"`. Set `fillStyle` on any shape:
244
334
 
@@ -253,83 +343,7 @@ Shapes default to `"hachure"`. Set `fillStyle` on any shape:
253
343
  | `zigzag-line` | Zigzag line pattern |
254
344
  | `none` | No fill (wireframe outline only) |
255
345
 
256
- ---
257
-
258
- ## Visual Q&A
259
-
260
- The Q&A system lets Claude send structured questions with visual context. A floating panel appears in the browser where users can answer by clicking options, typing text, or drawing.
261
-
262
- <p align="center">
263
- <img src="docs/screenshots/ui-ask.png" alt="Visual Q&A — question panel with layout options" width="700" />
264
- </p>
265
-
266
- Users select answers via interactive pill buttons. Selected answers are highlighted:
267
-
268
- <p align="center">
269
- <img src="docs/screenshots/ui-ask-answered.png" alt="Visual Q&A — answer selected" width="700" />
270
- </p>
271
-
272
- ### Sending Questions
273
-
274
- ```bash
275
- claude-canvas ask '{"questions": [
276
- {
277
- "id": "q1",
278
- "text": "Which layout do you prefer?",
279
- "type": "single",
280
- "options": ["Layout A", "Layout B", "Layout C"],
281
- "commands": [
282
- {"type": "rect", "x": 80, "y": 80, "width": 200, "height": 150, "label": "Layout A"},
283
- {"type": "rect", "x": 350, "y": 80, "width": 200, "height": 150, "label": "Layout B"}
284
- ]
285
- },
286
- {
287
- "id": "q2",
288
- "text": "What should the title be?",
289
- "type": "text"
290
- }
291
- ]}'
292
- ```
293
-
294
- ### Question Types
295
-
296
- | Type | Description | User interaction | Answer format |
297
- |------|------------|------------------|---------------|
298
- | `single` | Pick one option | Radio-style pill buttons | `"value": "Option A"` |
299
- | `multi` | Pick multiple options | Toggle pill buttons | `"value": ["Option A", "Option C"]` |
300
- | `text` | Free text input | Text field | `"value": "user's text"` |
301
- | `canvas` | Draw on canvas | Freeform drawing | `"value": "see canvas"` + snapshot PNG |
302
-
303
- ### Collecting Answers
304
-
305
- After sending questions, call `screenshot` to retrieve answers:
306
-
307
- ```bash
308
- claude-canvas screenshot
309
- ```
310
-
311
- ```json
312
- {
313
- "ok": true,
314
- "path": "/tmp/claude-canvas/canvas-123.png",
315
- "answers": [
316
- {"questionId": "q1", "value": "Layout A"},
317
- {"questionId": "q2", "value": "My Custom Title"}
318
- ]
319
- }
320
- ```
321
-
322
- For `canvas`-type questions, Claude draws a diagram and the user responds by drawing directly on the canvas. The answer includes a snapshot of what the user drew:
323
-
324
- <p align="center">
325
- <img src="docs/screenshots/ui-canvas-answer.png" alt="Canvas Q&A — Claude draws a wireframe, user annotates with freehand drawings" width="700" />
326
- </p>
327
-
328
- ```json
329
- {"questionId": "q3", "value": "see canvas", "canvasSnapshot": "/tmp/claude-canvas/canvas-q3-456.png"}
330
- ```
331
-
332
- ---
346
+ </details>
333
347
 
334
348
  ## Interactive Canvas
335
349
 
@@ -399,27 +413,34 @@ You don't need to explicitly tell Claude to use the canvas. The skill teaches Cl
399
413
 
400
414
  ---
401
415
 
402
- ## Architecture
416
+ ## CLI Reference
403
417
 
404
- ```
405
- ┌─────────────────┐
406
- │ Claude Code │
407
- │ (CLI / Skill) │
408
- └────────┬────────┘
409
- HTTP API
410
- ┌────────▼────────┐
411
- │ Express Server
412
- │ + WebSocket │
413
- └────────┬────────┘
414
- WebSocket
415
- ┌────────▼────────┐
416
- │ Browser Canvas
417
- │ React + Fabric
418
- └─────────────────┘
419
- ```
418
+ All commands accept `-s, --session <id>`. You can omit it when only one session is running.
419
+
420
+ | Command | Description |
421
+ |---------|-------------|
422
+ | `claude-canvas start` | Start a new canvas session (opens browser) |
423
+ | `claude-canvas start -p 8080` | Start on a specific port |
424
+ | `claude-canvas stop -s <id>` | Stop a specific session |
425
+ | `claude-canvas stop --all` | Stop all running sessions |
426
+ | `claude-canvas ask '<json>'` | Send visual questions, block until answered |
427
+ | `claude-canvas draw '<json>'` | Send draw commands to the canvas |
428
+ | `claude-canvas draw --no-animate '<json>'` | Draw without animation |
429
+ | `claude-canvas clear` | Clear all objects from the canvas |
430
+ | `claude-canvas clear --layer claude` | Clear only Claude's objects |
431
+ | `claude-canvas screenshot` | Capture canvas as PNG |
432
+ | `claude-canvas export -f png\|svg\|json` | Export canvas in various formats |
433
+ | `claude-canvas setup` | Install/update the Claude Code skill |
434
+ | `claude-canvas update` | Update to the latest version |
435
+
436
+ Both `ask` and `draw` accept `-` to read JSON from stdin.
437
+
438
+ ---
439
+
440
+ ## Architecture
420
441
 
421
442
  <p align="center">
422
- <img src="docs/screenshots/architecture-diagram.png" alt="Architecture diagram drawn on claude-canvas" width="700" />
443
+ <img src="docs/screenshots/architecture-flow.png" alt="Architecture Claude Code sends commands via HTTP API to Express server, which syncs with browser canvas over WebSocket" width="600" />
423
444
  </p>
424
445
 
425
446
  <details>
@@ -3181,13 +3181,16 @@ var import_node_fs = require("node:fs");
3181
3181
  var import_node_path = require("node:path");
3182
3182
  var import_node_os = require("node:os");
3183
3183
  var import_node_readline = require("node:readline");
3184
- var import_node_url = require("node:url");
3185
- var import_meta = {};
3184
+ function getCurrentDir() {
3185
+ if (typeof __dirname !== "undefined") return __dirname;
3186
+ const { fileURLToPath } = require("node:url");
3187
+ const meta = (0, eval)("import.meta");
3188
+ return (0, import_node_path.dirname)(fileURLToPath(meta.url));
3189
+ }
3186
3190
  function getVersion() {
3187
- if (true) return "1.0.5";
3191
+ if (true) return "1.0.6";
3188
3192
  try {
3189
- const dir = (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
3190
- const pkg = JSON.parse((0, import_node_fs.readFileSync)((0, import_node_path.resolve)(dir, "../../package.json"), "utf-8"));
3193
+ const pkg = JSON.parse((0, import_node_fs.readFileSync)((0, import_node_path.resolve)(getCurrentDir(), "../../package.json"), "utf-8"));
3191
3194
  return pkg.version;
3192
3195
  } catch {
3193
3196
  return "0.0.0-dev";
@@ -3323,7 +3326,7 @@ program2.command("update").description("Check for updates and install the latest
3323
3326
  const skillDestDir = (0, import_node_path.join)((0, import_node_os.homedir)(), ".claude", "skills", "claude-canvas");
3324
3327
  const skillDest = (0, import_node_path.join)(skillDestDir, "SKILL.md");
3325
3328
  if ((0, import_node_fs.existsSync)(skillDest)) {
3326
- const updateBaseDir = typeof __dirname !== "undefined" ? __dirname : (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
3329
+ const updateBaseDir = getCurrentDir();
3327
3330
  const skillSourceDir = (0, import_node_path.resolve)(updateBaseDir, "../../src/skill/claude-canvas");
3328
3331
  const skillSource = (0, import_node_path.join)(skillSourceDir, "SKILL.md");
3329
3332
  if ((0, import_node_fs.existsSync)(skillSource)) {
@@ -3341,7 +3344,7 @@ program2.command("update").description("Check for updates and install the latest
3341
3344
  }
3342
3345
  });
3343
3346
  program2.command("setup").description("Install or update the Claude Code skill for canvas").action(async () => {
3344
- const baseDir = typeof __dirname !== "undefined" ? __dirname : (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
3347
+ const baseDir = getCurrentDir();
3345
3348
  const skillSourceDir = (0, import_node_path.resolve)(baseDir, "../../src/skill/claude-canvas");
3346
3349
  const skillSource = (0, import_node_path.join)(skillSourceDir, "SKILL.md");
3347
3350
  const skillDestDir = (0, import_node_path.join)((0, import_node_os.homedir)(), ".claude", "skills", "claude-canvas");