@dannote/figma-use 0.2.1 → 0.3.0

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/CHANGELOG.md CHANGED
@@ -7,6 +7,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.0] - 2025-01-17
11
+
12
+ ### Added
13
+
14
+ - **`render` command** — render React/TSX components directly to Figma
15
+ - From file: `figma-use render ./Card.figma.tsx`
16
+ - From stdin: `echo '<Frame style={{...}} />' | figma-use render --stdin`
17
+ - With props: `--props '{"title": "Hello"}'`
18
+ - Into parent: `--parent "1:23"`
19
+ - Dry run: `--dryRun` outputs NodeChanges JSON
20
+ - **Multiplayer WebSocket connection pooling** in proxy
21
+ - First render: ~4s (establishes connection)
22
+ - Subsequent renders: ~0.4s (10x faster!)
23
+ - Connections auto-close after 5min idle
24
+ - **React components** — `Frame`, `Text`, `Rectangle`, `Ellipse`, `Line`, `Star`, `Polygon`, `Vector`, `Component`, `Instance`, `Group`, `Page`, `View`
25
+ - **JSX intrinsic elements** — PascalCase in JSX, lowercase in output
26
+ - **culori integration** — robust color parsing (hex, rgb(), hsl(), named colors)
27
+ - `/render` endpoint in proxy for direct NodeChanges submission
28
+ - `/status` endpoint now shows multiplayer connection pool
29
+
30
+ ### Changed
31
+
32
+ - Proxy now holds persistent WebSocket connections to Figma multiplayer
33
+ - Architecture diagram updated to show dual communication paths
34
+ - 143 tests passing
35
+
36
+ ### Fixed
37
+
38
+ - TypeScript strict mode errors in tests
39
+ - NodeChanges validation before sending (must have guid)
40
+
10
41
  ## [0.2.1] - 2025-01-17
11
42
 
12
43
  ### Added
@@ -137,7 +168,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
137
168
  - Export commands: PNG/SVG/PDF export, screenshot
138
169
  - Inline styling: `--fill`, `--stroke`, `--radius` etc. on create commands
139
170
 
140
- [unreleased]: https://github.com/dannote/figma-use/compare/v0.2.1...HEAD
171
+ [unreleased]: https://github.com/dannote/figma-use/compare/v0.3.0...HEAD
172
+ [0.3.0]: https://github.com/dannote/figma-use/compare/v0.2.1...v0.3.0
141
173
  [0.2.1]: https://github.com/dannote/figma-use/compare/v0.2.0...v0.2.1
142
174
  [0.2.0]: https://github.com/dannote/figma-use/compare/v0.1.5...v0.2.0
143
175
  [0.1.5]: https://github.com/dannote/figma-use/compare/v0.1.4...v0.1.5
package/README.md CHANGED
@@ -27,16 +27,28 @@ figma-use gives AI agents **full read/write control** over Figma.
27
27
  ## How it works
28
28
 
29
29
  ```
30
- ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
31
- │ │ │ │ │ │
32
- │ AI Agent / │────▶│ figma-use │────▶│ Figma │
33
- │ CLI │ HTTP│ proxy │ WS │ Plugin │
34
- │◀────│ :38451 │◀────│
35
- │ │ │ │ │ │
36
- └─────────────────┘ └─────────────────┘ └─────────────────┘
30
+ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
31
+ │ │ │ │ │ │
32
+ │ AI Agent / │─────▶│ figma-use │─────▶│ Figma │
33
+ │ CLI │ HTTP │ proxy │ WS │ Plugin │
34
+ │◀─────│ :38451 │◀─────│
35
+ │ │ │ │ │ │
36
+ └─────────────────┘ └────────┬────────┘ └─────────────────┘
37
+
38
+ │ WebSocket (persistent)
39
+
40
+ ┌─────────────────┐
41
+ │ Figma │
42
+ │ Multiplayer │
43
+ │ Server │
44
+ └─────────────────┘
37
45
  ```
38
46
 
39
- The CLI sends commands to a local proxy server, which forwards them via WebSocket to a Figma plugin. The plugin executes commands using the Figma API and returns results.
47
+ Two communication paths:
48
+ - **Plugin API** — most commands go through the Figma plugin for full API access
49
+ - **Multiplayer WebSocket** — the `render` command writes directly to Figma's multiplayer server for ~100x faster node creation
50
+
51
+ The proxy maintains persistent connections for fast repeated operations.
40
52
 
41
53
  ## Installation
42
54
 
@@ -226,10 +238,10 @@ figma-use viewport zoom-to-fit <ids...>
226
238
  ```bash
227
239
  figma-use find --name "Button"
228
240
  figma-use find --name "Icon" --type FRAME
229
- figma-use find --type INSTANCE # Find all instances on current page
241
+ figma-use find --type INSTANCE --limit 50 # Limit results (default: 100)
230
242
  figma-use get pages
231
243
  figma-use get components --name "Button" # Filter by name
232
- figma-use get components --limit 50 # Limit results (default: 100)
244
+ figma-use get components --limit 50 # Limit results (default: 50)
233
245
  figma-use get styles
234
246
  ```
235
247
 
@@ -246,6 +258,80 @@ figma-use group ungroup <id>
246
258
  figma-use group flatten "1:2,1:3"
247
259
  ```
248
260
 
261
+ ### Render React Components
262
+
263
+ Render TSX/JSX components directly to Figma via WebSocket (bypasses plugin API for ~100x speed):
264
+
265
+ ```bash
266
+ # From file
267
+ figma-use render ./Card.figma.tsx
268
+
269
+ # With props
270
+ figma-use render ./Card.figma.tsx --props '{"title": "Hello", "items": ["A", "B"]}'
271
+
272
+ # JSX snippet from stdin
273
+ echo '<Frame style={{width: 200, height: 100, backgroundColor: "#FF0000"}} />' | figma-use render --stdin
274
+
275
+ # Nested elements
276
+ echo '<Frame style={{padding: 20, gap: 10}}>
277
+ <Text style={{fontSize: 24}}>Title</Text>
278
+ <Rectangle style={{width: 100, height: 50, backgroundColor: "#3B82F6"}} />
279
+ </Frame>' | figma-use render --stdin
280
+
281
+ # Full component from stdin (with imports/exports)
282
+ cat component.tsx | figma-use render --stdin
283
+
284
+ # Into specific parent
285
+ figma-use render ./Card.figma.tsx --parent "1:23"
286
+
287
+ # Dry run (output NodeChanges JSON without sending)
288
+ figma-use render ./Card.figma.tsx --dryRun
289
+ ```
290
+
291
+ **Important:** The `render` command requires:
292
+ 1. Figma running with remote debugging: `figma --remote-debugging-port=9222`
293
+ 2. Proxy server running: `figma-use proxy`
294
+
295
+ The proxy maintains persistent WebSocket connections for fast repeated renders:
296
+ - First render: ~4s (establishes connection)
297
+ - Subsequent renders: ~0.4s (reuses connection)
298
+
299
+ Example component (`Card.figma.tsx`):
300
+
301
+ ```tsx
302
+ import * as React from 'react'
303
+ import { Frame, Text, Rectangle } from '@dannote/figma-use/components'
304
+
305
+ interface CardProps {
306
+ title: string
307
+ items: string[]
308
+ }
309
+
310
+ export default function Card({ title, items }: CardProps) {
311
+ return (
312
+ <Frame name="Card" style={{
313
+ width: 300,
314
+ flexDirection: 'column',
315
+ padding: 24,
316
+ gap: 16,
317
+ backgroundColor: '#FFFFFF',
318
+ borderRadius: 12,
319
+ }}>
320
+ <Text name="Title" style={{ fontSize: 24, fontWeight: 'bold', color: '#000' }}>
321
+ {title}
322
+ </Text>
323
+ <Frame name="Items" style={{ flexDirection: 'column', gap: 8 }}>
324
+ {items.map((item, i) => (
325
+ <Text key={i} style={{ fontSize: 16, color: '#666' }}>{item}</Text>
326
+ ))}
327
+ </Frame>
328
+ </Frame>
329
+ )
330
+ }
331
+ ```
332
+
333
+ Available elements: `Frame`, `Rectangle`, `Ellipse`, `Text`, `Line`, `Star`, `Polygon`, `Vector`, `Component`, `Instance`, `Group`, `Page`, `View`
334
+
249
335
  ### Advanced
250
336
 
251
337
  ```bash
package/SKILL.md CHANGED
@@ -148,6 +148,36 @@ figma-use group create "1:2,1:3"
148
148
  figma-use group ungroup <id>
149
149
  ```
150
150
 
151
+ ### Render React Components
152
+
153
+ Render TSX/JSX directly to Figma (~100x faster than plugin API):
154
+
155
+ ```bash
156
+ # From file
157
+ figma-use render ./Card.figma.tsx
158
+
159
+ # JSX snippet from stdin
160
+ echo '<Frame style={{width: 200, height: 100, backgroundColor: "#FF0000"}} />' | figma-use render --stdin
161
+
162
+ # Nested elements
163
+ echo '<Frame style={{padding: 20, gap: 10, flexDirection: "column"}}>
164
+ <Text style={{fontSize: 24, color: "#000"}}>Title</Text>
165
+ <Rectangle style={{width: 100, height: 50, backgroundColor: "#3B82F6"}} />
166
+ </Frame>' | figma-use render --stdin
167
+
168
+ # With props
169
+ figma-use render ./Card.figma.tsx --props '{"title": "Hello"}'
170
+
171
+ # Into specific parent
172
+ figma-use render ./Card.figma.tsx --parent "1:23"
173
+ ```
174
+
175
+ **Requires:**
176
+ 1. Figma with `figma --remote-debugging-port=9222`
177
+ 2. Proxy running: `figma-use proxy`
178
+
179
+ Available elements: `Frame`, `Rectangle`, `Ellipse`, `Text`, `Line`, `Star`, `Polygon`, `Vector`, `Component`, `Instance`, `Group`
180
+
151
181
  ### Eval (Arbitrary Code)
152
182
 
153
183
  ```bash
@@ -0,0 +1,3 @@
1
+ import * as React from 'react'
2
+ const Frame: React.FC<any> = ({ children, ...props }) => React.createElement('frame', props, children)
3
+ export default () => (<Frame style={{width: 200, height: 100, backgroundColor: "#FF0000"}} />)
@@ -0,0 +1,3 @@
1
+ import * as React from 'react'
2
+ const Frame: React.FC<any> = ({ children, ...props }) => React.createElement('frame', props, children)
3
+ export default () => (<Frame style={{width: 200, height: 100, backgroundColor: "#FF0000"}} />)