@dannote/figma-use 0.2.0 → 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 +58 -1
- package/README.md +115 -10
- package/SKILL.md +35 -2
- package/dist/.figma-render-1768690678858.tsx +3 -0
- package/dist/.figma-render-1768690686527.tsx +3 -0
- package/dist/cli/index.js +26216 -2551
- package/dist/proxy/index.js +7360 -7
- package/package.json +4 -2
- package/packages/plugin/dist/main.js +311 -25
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,61 @@ 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
|
+
|
|
41
|
+
## [0.2.1] - 2025-01-17
|
|
42
|
+
|
|
43
|
+
### Added
|
|
44
|
+
|
|
45
|
+
- **`profile` command** — performance profiling via Chrome DevTools Protocol
|
|
46
|
+
- Profile any command: `figma-use profile "get components --limit 20"`
|
|
47
|
+
- Shows time breakdown (Figma WASM vs JS vs GC)
|
|
48
|
+
- Lists top functions by CPU time
|
|
49
|
+
- Requires Figma with `--remote-debugging-port=9222`
|
|
50
|
+
- `get components --name` — filter components by name
|
|
51
|
+
- `get components --limit` — limit results (default 50)
|
|
52
|
+
- `get components --page` — filter by page
|
|
53
|
+
- `find --type` now works without `--name`
|
|
54
|
+
|
|
55
|
+
### Changed
|
|
56
|
+
|
|
57
|
+
- `get components` uses early-exit recursion for better performance on large files
|
|
58
|
+
- `node tree --depth` now affects node count check (won't block with high depth limit)
|
|
59
|
+
|
|
60
|
+
### Fixed
|
|
61
|
+
|
|
62
|
+
- Variant components no longer crash when accessing `componentPropertyDefinitions`
|
|
63
|
+
- 86 tests passing
|
|
64
|
+
|
|
10
65
|
## [0.2.0] - 2025-01-17
|
|
11
66
|
|
|
12
67
|
### Added
|
|
@@ -113,7 +168,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
113
168
|
- Export commands: PNG/SVG/PDF export, screenshot
|
|
114
169
|
- Inline styling: `--fill`, `--stroke`, `--radius` etc. on create commands
|
|
115
170
|
|
|
116
|
-
[unreleased]: https://github.com/dannote/figma-use/compare/v0.
|
|
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
|
|
173
|
+
[0.2.1]: https://github.com/dannote/figma-use/compare/v0.2.0...v0.2.1
|
|
117
174
|
[0.2.0]: https://github.com/dannote/figma-use/compare/v0.1.5...v0.2.0
|
|
118
175
|
[0.1.5]: https://github.com/dannote/figma-use/compare/v0.1.4...v0.1.5
|
|
119
176
|
[0.1.4]: https://github.com/dannote/figma-use/compare/v0.1.3...v0.1.4
|
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 /
|
|
33
|
-
│ CLI │ HTTP│ proxy │
|
|
34
|
-
│
|
|
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
|
-
|
|
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
|
|
|
@@ -93,8 +105,9 @@ All create commands support inline styling — no need for separate `set` calls.
|
|
|
93
105
|
```bash
|
|
94
106
|
figma-use node get <id> # Get node properties
|
|
95
107
|
figma-use node tree [id] # Get formatted tree (default: current page)
|
|
96
|
-
figma-use node tree --depth 2 # Limit tree depth
|
|
108
|
+
figma-use node tree --depth 2 # Limit tree depth (also limits node count check)
|
|
97
109
|
figma-use node tree -i # Only interactive elements
|
|
110
|
+
figma-use node tree --force # Skip 500 node limit
|
|
98
111
|
figma-use node children <id> # Get child nodes
|
|
99
112
|
figma-use node delete <id> # Delete node
|
|
100
113
|
figma-use node clone <id> # Clone node
|
|
@@ -225,8 +238,10 @@ figma-use viewport zoom-to-fit <ids...>
|
|
|
225
238
|
```bash
|
|
226
239
|
figma-use find --name "Button"
|
|
227
240
|
figma-use find --name "Icon" --type FRAME
|
|
241
|
+
figma-use find --type INSTANCE --limit 50 # Limit results (default: 100)
|
|
228
242
|
figma-use get pages
|
|
229
|
-
figma-use get components
|
|
243
|
+
figma-use get components --name "Button" # Filter by name
|
|
244
|
+
figma-use get components --limit 50 # Limit results (default: 50)
|
|
230
245
|
figma-use get styles
|
|
231
246
|
```
|
|
232
247
|
|
|
@@ -243,6 +258,80 @@ figma-use group ungroup <id>
|
|
|
243
258
|
figma-use group flatten "1:2,1:3"
|
|
244
259
|
```
|
|
245
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
|
+
|
|
246
335
|
### Advanced
|
|
247
336
|
|
|
248
337
|
```bash
|
|
@@ -255,6 +344,22 @@ figma-use eval "await figma.loadFontAsync({family: 'Inter', style: 'Bold'})"
|
|
|
255
344
|
figma-use import --svg "<svg>...</svg>" --x 0 --y 0
|
|
256
345
|
```
|
|
257
346
|
|
|
347
|
+
### Performance Profiling
|
|
348
|
+
|
|
349
|
+
Profile any command using Chrome DevTools Protocol:
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
# Start Figma with debug port
|
|
353
|
+
/Applications/Figma.app/Contents/MacOS/Figma --remote-debugging-port=9222
|
|
354
|
+
|
|
355
|
+
# Profile a command
|
|
356
|
+
figma-use profile "get components --limit 20"
|
|
357
|
+
figma-use profile "node tree --depth 2"
|
|
358
|
+
figma-use profile "find --type INSTANCE"
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Output shows time breakdown (Figma WASM vs JS vs GC) and top functions by CPU time.
|
|
362
|
+
|
|
258
363
|
## Output Format
|
|
259
364
|
|
|
260
365
|
Human-readable by default:
|
package/SKILL.md
CHANGED
|
@@ -52,8 +52,9 @@ figma-use create text --x 0 --y 0 --text "Hello" \
|
|
|
52
52
|
```bash
|
|
53
53
|
figma-use node get <id> # Get properties
|
|
54
54
|
figma-use node tree [id] # Get formatted tree (see structure at a glance)
|
|
55
|
-
figma-use node tree --depth 2 # Limit tree depth
|
|
55
|
+
figma-use node tree --depth 2 # Limit tree depth (also limits node count)
|
|
56
56
|
figma-use node tree -i # Only interactive elements
|
|
57
|
+
figma-use node tree --force # Skip 500 node limit
|
|
57
58
|
figma-use node children <id> # List children
|
|
58
59
|
figma-use node move <id> --x 100 --y 200
|
|
59
60
|
figma-use node resize <id> --width 300 --height 200
|
|
@@ -133,7 +134,9 @@ figma-use viewport zoom-to-fit <ids...>
|
|
|
133
134
|
```bash
|
|
134
135
|
figma-use find --name "Button"
|
|
135
136
|
figma-use find --type FRAME
|
|
136
|
-
figma-use
|
|
137
|
+
figma-use find --type INSTANCE # All instances on page
|
|
138
|
+
figma-use get components --name "Button" # Filter components by name
|
|
139
|
+
figma-use get components --limit 50 # Limit results
|
|
137
140
|
```
|
|
138
141
|
|
|
139
142
|
### Boolean & Group
|
|
@@ -145,6 +148,36 @@ figma-use group create "1:2,1:3"
|
|
|
145
148
|
figma-use group ungroup <id>
|
|
146
149
|
```
|
|
147
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
|
+
|
|
148
181
|
### Eval (Arbitrary Code)
|
|
149
182
|
|
|
150
183
|
```bash
|