figma-local 1.0.0 → 1.1.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/README.md +87 -16
- package/package.json +8 -6
- package/plugin/code.js +178 -0
- package/plugin/manifest.json +14 -0
- package/plugin/ui.html +285 -0
- package/skills/figma-css/SKILL.md +119 -0
- package/skills/figma-document/SKILL.md +129 -0
- package/skills/figma-inspect/SKILL.md +98 -0
- package/skills/figma-local/SKILL.md +170 -0
- package/skills/figma-measure/SKILL.md +59 -0
- package/skills/figma-styles/SKILL.md +114 -0
- package/src/daemon.js +1 -1
- package/src/index.js +1772 -25
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# figma-
|
|
1
|
+
# figma-local
|
|
2
2
|
|
|
3
3
|
> Control Figma Desktop with Claude Code. Design tokens, shadcn/ui components, AI prompt export, lint, and more — no API key required.
|
|
4
4
|
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
## What is this?
|
|
14
14
|
|
|
15
|
-
**figma-
|
|
15
|
+
**figma-local** connects directly to Figma Desktop and lets you — or Claude Code — control it with natural language and `fig` commands.
|
|
16
16
|
|
|
17
17
|
- **Write** — Create frames, components, design tokens, icons, and full UI kits
|
|
18
18
|
- **Read** — Extract design context in a lean staged format (91–97% fewer tokens than raw data dumps)
|
|
@@ -54,13 +54,13 @@ Gives you `fig` and `fig-start` globally on your PATH.
|
|
|
54
54
|
### curl (one-line)
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
|
-
curl -fsSL https://raw.githubusercontent.com/thepreakerebi/figma-
|
|
57
|
+
curl -fsSL https://raw.githubusercontent.com/thepreakerebi/figma-local/main/install.sh | bash
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
### Homebrew
|
|
61
61
|
|
|
62
62
|
```bash
|
|
63
|
-
brew tap thepreakerebi/figma-
|
|
63
|
+
brew tap thepreakerebi/figma-local
|
|
64
64
|
brew install figma-cli
|
|
65
65
|
```
|
|
66
66
|
|
|
@@ -73,7 +73,7 @@ npx figma-local read
|
|
|
73
73
|
### From source
|
|
74
74
|
|
|
75
75
|
```bash
|
|
76
|
-
git clone https://github.com/thepreakerebi/figma-
|
|
76
|
+
git clone https://github.com/thepreakerebi/figma-local.git
|
|
77
77
|
cd figma-cli
|
|
78
78
|
npm install && npm install -g .
|
|
79
79
|
```
|
|
@@ -99,7 +99,7 @@ npm install && npm install -g .
|
|
|
99
99
|
2. Hamburger menu → **Plugins → Development → Import plugin from manifest...**
|
|
100
100
|
3. Navigate to the `plugin/` folder in this repo (or `$(npm root -g)/figma-local/plugin/`)
|
|
101
101
|
4. Select `manifest.json` → click **Open**
|
|
102
|
-
5. Right-click **
|
|
102
|
+
5. Right-click **Figma Local** in the plugin list → **Add to toolbar**
|
|
103
103
|
|
|
104
104
|
### 2. Connect
|
|
105
105
|
|
|
@@ -107,14 +107,14 @@ npm install && npm install -g .
|
|
|
107
107
|
fig-start --safe
|
|
108
108
|
```
|
|
109
109
|
|
|
110
|
-
This starts the daemon, waits for you to click
|
|
110
|
+
This starts the daemon, waits for you to click Figma Local in Figma, then launches Claude Code.
|
|
111
111
|
|
|
112
112
|
---
|
|
113
113
|
|
|
114
114
|
## Every session after that
|
|
115
115
|
|
|
116
116
|
```
|
|
117
|
-
1. Open Figma → click
|
|
117
|
+
1. Open Figma → click Figma Local in the toolbar
|
|
118
118
|
2. In terminal: fig-start --safe
|
|
119
119
|
```
|
|
120
120
|
|
|
@@ -127,14 +127,60 @@ Claude Code reads `CLAUDE.md` and knows every command automatically.
|
|
|
127
127
|
### Read & understand your canvas
|
|
128
128
|
|
|
129
129
|
```bash
|
|
130
|
-
fig read # List all frames
|
|
131
|
-
fig read "Login Screen" #
|
|
132
|
-
fig read "Login Screen" --tokens #
|
|
130
|
+
fig read # List all frames on the current page
|
|
131
|
+
fig read "Login Screen" # Get the layout tree, components, and design tokens for that frame
|
|
132
|
+
fig read "Login Screen" --tokens # Show only the design tokens (colors, spacing) that frame uses
|
|
133
|
+
fig read --selection # Read whatever you have selected right now in Figma
|
|
134
|
+
fig read --link "https://..." # Read a specific node from a Figma selection link
|
|
133
135
|
fig find "Button" # Find nodes by name
|
|
134
136
|
fig node tree # Layer hierarchy
|
|
135
137
|
fig canvas info # Raw canvas info
|
|
136
138
|
```
|
|
137
139
|
|
|
140
|
+
### Inspect design specs
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
fig inspect # Full specs for the selected element (spacing, colors, fonts, effects)
|
|
144
|
+
fig inspect --node "123:456" # Inspect a specific node by ID
|
|
145
|
+
fig inspect --json # Raw JSON output
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Returns dimensions, padding, gap, colors (hex + rgba), typography (font family, size, weight, line-height, letter-spacing), border radius, strokes, shadows, opacity, and variable bindings (name + resolved value + per-mode values for Light/Dark) — all in **px and rem**.
|
|
149
|
+
|
|
150
|
+
### Generate CSS / Tailwind from design
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
fig css # CSS for current selection (rem units)
|
|
154
|
+
fig css --px # CSS in px units
|
|
155
|
+
fig css --tailwind # Tailwind utility classes
|
|
156
|
+
fig css --link "https://..." # CSS from a Figma link
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Measure spacing
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
fig measure # Select 2 elements in Figma, get the spacing between them
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Extract style guide from a frame
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
fig styles "Login Screen" # All text styles, colors, spacing values, and radii used
|
|
169
|
+
fig styles --selection # Styles from current selection
|
|
170
|
+
fig styles --json # Raw JSON
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Document a component (full recursive spec)
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
fig document # Document selected component — all children, all specs
|
|
177
|
+
fig document --json # Structured JSON for coding agents
|
|
178
|
+
fig document --link "https://..." # Document from a Figma link
|
|
179
|
+
fig document --tokens-only # Just the design tokens used
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Returns a complete breakdown: summary, all unique design tokens (colors, typography, spacing, radii, shadows), and a recursive tree of every element with full specs. One command gives a coding agent everything it needs to replicate the component.
|
|
183
|
+
|
|
138
184
|
### Design tokens
|
|
139
185
|
|
|
140
186
|
```bash
|
|
@@ -247,7 +293,7 @@ fig fj connect "ID1" "ID2"
|
|
|
247
293
|
| | Safe Mode | Yolo Mode |
|
|
248
294
|
|-|-----------|-----------|
|
|
249
295
|
| How | Plugin bridge | Direct CDP |
|
|
250
|
-
| Setup per session | Start
|
|
296
|
+
| Setup per session | Start Figma Local plugin | Nothing (after one-time patch) |
|
|
251
297
|
| Speed | Standard | ~10× faster |
|
|
252
298
|
| Extra permissions | None | macOS: Full Disk Access / Windows: Admin |
|
|
253
299
|
| Command | `fig connect --safe` | `fig connect` |
|
|
@@ -271,7 +317,7 @@ The daemon runs only on `127.0.0.1` (never exposed to the network) and is protec
|
|
|
271
317
|
| 1 MB request/message body cap | Memory exhaustion from oversized payloads |
|
|
272
318
|
| Plugin input validation | Code size cap (512 KB), batch size cap (50), strict field types |
|
|
273
319
|
| Rate limiting | Max 30 evals per 10 s per connection |
|
|
274
|
-
| Idle auto-shutdown | Daemon stops after
|
|
320
|
+
| Idle auto-shutdown | Daemon stops after 1 hour of inactivity |
|
|
275
321
|
|
|
276
322
|
The session token is generated fresh on every `fig connect`, stored at `~/.figma-ds-cli/.daemon-token` with `chmod 600` (owner-read only).
|
|
277
323
|
|
|
@@ -286,6 +332,31 @@ fig-start --safe --here # launch from your project dir; Claude sees both you
|
|
|
286
332
|
|
|
287
333
|
---
|
|
288
334
|
|
|
335
|
+
## Claude Code Plugin (Skills)
|
|
336
|
+
|
|
337
|
+
figma-local ships as a Claude Code plugin with 6 skills that teach coding agents how to use it automatically:
|
|
338
|
+
|
|
339
|
+
| Skill | Triggers on |
|
|
340
|
+
|-------|------------|
|
|
341
|
+
| **figma-local** | "read the design", "what's on the canvas", "Figma to code" |
|
|
342
|
+
| **figma-inspect** | "get specs", "what font/color/spacing", "design specs" |
|
|
343
|
+
| **figma-css** | "generate CSS", "Tailwind classes", "convert to CSS" |
|
|
344
|
+
| **figma-styles** | "style guide", "extract colors/fonts", "spacing scale" |
|
|
345
|
+
| **figma-measure** | "measure spacing", "gap between elements" |
|
|
346
|
+
| **figma-document** | "document this component", "full spec sheet", "deep breakdown" |
|
|
347
|
+
|
|
348
|
+
### Install the skills
|
|
349
|
+
|
|
350
|
+
Install via [skills.sh](https://skills.sh):
|
|
351
|
+
|
|
352
|
+
```bash
|
|
353
|
+
npx skills add thepreakerebi/figma-local
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Once installed, restart Claude Code. It automatically knows all `fig` commands and uses them when your tasks involve Figma designs.
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
289
360
|
## For teams
|
|
290
361
|
|
|
291
362
|
```bash
|
|
@@ -299,7 +370,7 @@ npm install -g figma-local
|
|
|
299
370
|
Pin a version for consistency:
|
|
300
371
|
|
|
301
372
|
```bash
|
|
302
|
-
npm install -g
|
|
373
|
+
npm install -g figma-local@1.0.0
|
|
303
374
|
```
|
|
304
375
|
|
|
305
376
|
---
|
|
@@ -311,7 +382,7 @@ npm uninstall -g figma-local
|
|
|
311
382
|
rm -rf ~/.figma-cli ~/.figma-ds-cli
|
|
312
383
|
```
|
|
313
384
|
|
|
314
|
-
Remove the plugin in Figma: Plugins → Development → right-click
|
|
385
|
+
Remove the plugin in Figma: Plugins → Development → right-click Figma Local → Remove.
|
|
315
386
|
|
|
316
387
|
---
|
|
317
388
|
|
|
@@ -320,7 +391,7 @@ Remove the plugin in Figma: Plugins → Development → right-click FigCli → R
|
|
|
320
391
|
Issues and PRs welcome. For major changes, open an issue first to discuss.
|
|
321
392
|
|
|
322
393
|
```bash
|
|
323
|
-
git clone https://github.com/thepreakerebi/figma-
|
|
394
|
+
git clone https://github.com/thepreakerebi/figma-local.git
|
|
324
395
|
cd figma-cli
|
|
325
396
|
npm install
|
|
326
397
|
node src/index.js --help
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "figma-local",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Control Figma Desktop with Claude Code. Smart read, write, and AI-prompt export. No API key required.",
|
|
5
5
|
"author": "elvke",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
},
|
|
13
13
|
"files": [
|
|
14
14
|
"src",
|
|
15
|
-
"bin"
|
|
15
|
+
"bin",
|
|
16
|
+
"plugin",
|
|
17
|
+
"skills"
|
|
16
18
|
],
|
|
17
19
|
"keywords": [
|
|
18
20
|
"figma",
|
|
@@ -25,11 +27,11 @@
|
|
|
25
27
|
],
|
|
26
28
|
"repository": {
|
|
27
29
|
"type": "git",
|
|
28
|
-
"url": "git+https://github.com/thepreakerebi/figma-
|
|
30
|
+
"url": "git+https://github.com/thepreakerebi/figma-local.git"
|
|
29
31
|
},
|
|
30
|
-
"homepage": "https://github.com/thepreakerebi/figma-
|
|
32
|
+
"homepage": "https://github.com/thepreakerebi/figma-local",
|
|
31
33
|
"bugs": {
|
|
32
|
-
"url": "https://github.com/thepreakerebi/figma-
|
|
34
|
+
"url": "https://github.com/thepreakerebi/figma-local/issues"
|
|
33
35
|
},
|
|
34
36
|
"scripts": {
|
|
35
37
|
"setup-alias": "bash bin/setup-alias.sh",
|
package/plugin/code.js
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Figma CLI Bridge Plugin — code.js
|
|
3
|
+
*
|
|
4
|
+
* Safe Mode: Connects to CLI daemon via WebSocket.
|
|
5
|
+
* No debug port, no patching required.
|
|
6
|
+
*
|
|
7
|
+
* Security hardening:
|
|
8
|
+
* - All incoming messages from the UI are validated before execution
|
|
9
|
+
* - Code and batch payloads are size-capped
|
|
10
|
+
* - Batch arrays are length-capped
|
|
11
|
+
* - Notify text is sanitised (no arbitrary HTML/script injection)
|
|
12
|
+
* - Rate limiting: max 30 evals per 10-second window
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
// ── Constants ──────────────────────────────────────────────────
|
|
16
|
+
const MAX_CODE_BYTES = 512 * 1024; // 512 KB max per eval code string
|
|
17
|
+
const MAX_BATCH_COUNT = 50; // Max codes in a single eval-batch
|
|
18
|
+
const MAX_NOTIFY_CHARS = 200; // Max chars shown in Figma notification
|
|
19
|
+
|
|
20
|
+
// ── Rate limiter ───────────────────────────────────────────────
|
|
21
|
+
// Prevents a rogue daemon (or compromised WebSocket) from flooding
|
|
22
|
+
// the plugin with eval calls.
|
|
23
|
+
const RATE_WINDOW_MS = 10000;
|
|
24
|
+
const RATE_MAX = 30;
|
|
25
|
+
let rateCount = 0;
|
|
26
|
+
let rateWindowStart = Date.now();
|
|
27
|
+
|
|
28
|
+
function isRateAllowed() {
|
|
29
|
+
const now = Date.now();
|
|
30
|
+
if (now - rateWindowStart > RATE_WINDOW_MS) {
|
|
31
|
+
rateCount = 0;
|
|
32
|
+
rateWindowStart = now;
|
|
33
|
+
}
|
|
34
|
+
if (rateCount >= RATE_MAX) return false;
|
|
35
|
+
rateCount++;
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ── Input validators ───────────────────────────────────────────
|
|
40
|
+
function isValidId(id) {
|
|
41
|
+
return typeof id === 'number' && Number.isFinite(id) && id >= 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function isValidCode(code) {
|
|
45
|
+
return typeof code === 'string' && code.length > 0 && code.length <= MAX_CODE_BYTES;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function sanitiseNotify(text) {
|
|
49
|
+
if (typeof text !== 'string') return 'Unknown error';
|
|
50
|
+
// Strip anything that looks like HTML tags, keep plain text only
|
|
51
|
+
return text.replace(/<[^>]*>/g, '').slice(0, MAX_NOTIFY_CHARS);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Show minimal UI (needed for WebSocket connection)
|
|
55
|
+
figma.showUI(__html__, {
|
|
56
|
+
width: 200,
|
|
57
|
+
height: 92
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Execute code with auto-return and timeout protection
|
|
61
|
+
async function executeCode(code, timeoutMs = 25000) {
|
|
62
|
+
let trimmed = code.trim();
|
|
63
|
+
|
|
64
|
+
// Don't add return if code already starts with return
|
|
65
|
+
if (!trimmed.startsWith('return ')) {
|
|
66
|
+
const isSimpleExpr = !trimmed.includes(';');
|
|
67
|
+
const isIIFE = trimmed.startsWith('(function') || trimmed.startsWith('(async function');
|
|
68
|
+
const isArrowIIFE = trimmed.startsWith('(() =>') || trimmed.startsWith('(async () =>');
|
|
69
|
+
|
|
70
|
+
if (isSimpleExpr || isIIFE || isArrowIIFE) {
|
|
71
|
+
trimmed = `return ${trimmed}`;
|
|
72
|
+
} else {
|
|
73
|
+
const lastSemicolon = trimmed.lastIndexOf(';');
|
|
74
|
+
if (lastSemicolon !== -1) {
|
|
75
|
+
const beforeLast = trimmed.substring(0, lastSemicolon + 1);
|
|
76
|
+
const lastStmt = trimmed.substring(lastSemicolon + 1).trim();
|
|
77
|
+
if (lastStmt && !lastStmt.startsWith('return ')) {
|
|
78
|
+
trimmed = beforeLast + ' return ' + lastStmt;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
|
|
85
|
+
const fn = new AsyncFunction('figma', `return (async () => { ${trimmed} })()`);
|
|
86
|
+
|
|
87
|
+
// Execute with timeout protection
|
|
88
|
+
const execPromise = fn(figma);
|
|
89
|
+
const timeoutPromise = new Promise((_, reject) =>
|
|
90
|
+
setTimeout(() => reject(new Error(`Execution timeout (${timeoutMs/1000}s)`)), timeoutMs)
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
return Promise.race([execPromise, timeoutPromise]);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Handle messages from UI (WebSocket bridge)
|
|
97
|
+
figma.ui.onmessage = async (msg) => {
|
|
98
|
+
if (!msg || typeof msg.type !== 'string') return;
|
|
99
|
+
|
|
100
|
+
// ── Single eval ─────────────────────────────────────────────
|
|
101
|
+
if (msg.type === 'eval') {
|
|
102
|
+
// Validate id and code before doing anything
|
|
103
|
+
if (!isValidId(msg.id)) return;
|
|
104
|
+
if (!isValidCode(msg.code)) {
|
|
105
|
+
figma.ui.postMessage({ type: 'result', id: msg.id, error: 'Invalid or oversized code payload' });
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (!isRateAllowed()) {
|
|
109
|
+
figma.ui.postMessage({ type: 'result', id: msg.id, error: 'Rate limit exceeded — slow down' });
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
const result = await executeCode(msg.code);
|
|
114
|
+
figma.ui.postMessage({ type: 'result', id: msg.id, result });
|
|
115
|
+
} catch (error) {
|
|
116
|
+
figma.ui.postMessage({ type: 'result', id: msg.id, error: error.message });
|
|
117
|
+
}
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// ── Batch eval ──────────────────────────────────────────────
|
|
122
|
+
if (msg.type === 'eval-batch') {
|
|
123
|
+
if (!isValidId(msg.id)) return;
|
|
124
|
+
if (!Array.isArray(msg.codes)) {
|
|
125
|
+
figma.ui.postMessage({ type: 'batch-result', id: msg.id, results: [{ success: false, error: 'codes must be an array' }] });
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
// Cap array length
|
|
129
|
+
if (msg.codes.length > MAX_BATCH_COUNT) {
|
|
130
|
+
figma.ui.postMessage({ type: 'batch-result', id: msg.id, results: [{ success: false, error: `Batch too large (max ${MAX_BATCH_COUNT})` }] });
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
// Validate each code string
|
|
134
|
+
for (const c of msg.codes) {
|
|
135
|
+
if (!isValidCode(c)) {
|
|
136
|
+
figma.ui.postMessage({ type: 'batch-result', id: msg.id, results: [{ success: false, error: 'Invalid or oversized code in batch' }] });
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
if (!isRateAllowed()) {
|
|
141
|
+
figma.ui.postMessage({ type: 'batch-result', id: msg.id, results: [{ success: false, error: 'Rate limit exceeded' }] });
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
const results = [];
|
|
145
|
+
for (const code of msg.codes) {
|
|
146
|
+
try {
|
|
147
|
+
const result = await executeCode(code);
|
|
148
|
+
results.push({ success: true, result });
|
|
149
|
+
} catch (error) {
|
|
150
|
+
results.push({ success: false, error: error.message });
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
figma.ui.postMessage({ type: 'batch-result', id: msg.id, results });
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// ── Connection lifecycle (no eval, safe to handle directly) ──
|
|
158
|
+
if (msg.type === 'connected') {
|
|
159
|
+
figma.notify('✓ Figma Local connected', { timeout: 2000 });
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (msg.type === 'disconnected') {
|
|
163
|
+
figma.notify('Figma Local disconnected', { timeout: 2000 });
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (msg.type === 'error') {
|
|
167
|
+
// Sanitise before displaying in Figma UI
|
|
168
|
+
figma.notify('Figma Local: ' + sanitiseNotify(msg.message), { error: true });
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// Keep plugin alive
|
|
174
|
+
figma.on('close', () => {
|
|
175
|
+
// Plugin closed
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
console.log('Figma DS CLI plugin started');
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Figma Local",
|
|
3
|
+
"id": "figma-cli-bridge",
|
|
4
|
+
"api": "1.0.0",
|
|
5
|
+
"main": "code.js",
|
|
6
|
+
"ui": "ui.html",
|
|
7
|
+
"capabilities": [],
|
|
8
|
+
"enableProposedApi": false,
|
|
9
|
+
"editorType": ["figma", "figjam"],
|
|
10
|
+
"networkAccess": {
|
|
11
|
+
"allowedDomains": ["*"],
|
|
12
|
+
"reasoning": "Connects to local CLI daemon for command execution"
|
|
13
|
+
}
|
|
14
|
+
}
|