@hegemonart/get-design-done 1.14.2 → 1.14.4
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +2 -3
- package/CHANGELOG.md +35 -0
- package/README.md +67 -24
- package/README.zh-CN.md +353 -0
- package/agents/design-context-builder.md +5 -3
- package/agents/design-discussant.md +1 -1
- package/agents/design-figma-writer.md +19 -18
- package/agents/token-mapper.md +1 -1
- package/connections/connections.md +23 -11
- package/connections/figma.md +104 -40
- package/package.json +1 -1
- package/reference/schemas/plugin.schema.json +1 -2
- package/scripts/install.cjs +154 -0
- package/skills/discover/SKILL.md +12 -5
- package/skills/explore/SKILL.md +58 -21
- package/skills/figma-write/SKILL.md +3 -4
- package/skills/scan/SKILL.md +22 -10
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: design-figma-writer
|
|
3
3
|
description: Writes design decisions back to Figma — annotations, token bindings, Code Connect mappings, and implementation-status write-back. Operates in proposal→confirm mode by default. Accepts --dry-run (emit proposal without executing) and --confirm-shared (required for writes to team library components).
|
|
4
|
-
tools: Read, Write, Bash, Grep, Glob,
|
|
4
|
+
tools: Read, Write, Bash, Grep, Glob, {P}use_figma, mcp__figma__get_variable_defs, mcp__figma__get_metadata, mcp__Figma__use_figma, mcp__Figma__get_variable_defs, mcp__Figma__get_metadata
|
|
5
5
|
color: purple
|
|
6
6
|
model: inherit
|
|
7
7
|
default-tier: sonnet
|
|
@@ -11,7 +11,7 @@ parallel-safe: never
|
|
|
11
11
|
typical-duration-seconds: 120
|
|
12
12
|
reads-only: false
|
|
13
13
|
writes:
|
|
14
|
-
- "Figma file (via
|
|
14
|
+
- "Figma file (via {resolved_prefix}use_figma — remote MCP only) — annotations, token bindings, Code Connect mappings"
|
|
15
15
|
---
|
|
16
16
|
|
|
17
17
|
@reference/shared-preamble.md
|
|
@@ -26,15 +26,17 @@ You are design-figma-writer. You write design decisions from `.design/DESIGN-CON
|
|
|
26
26
|
|
|
27
27
|
## Step 0 — Remote MCP Probe
|
|
28
28
|
|
|
29
|
-
Run this probe at agent entry before any other action:
|
|
29
|
+
Writes require a remote Figma MCP variant (`use_figma` is remote-only). Run this probe at agent entry before any other action:
|
|
30
30
|
|
|
31
31
|
```
|
|
32
|
-
ToolSearch({ query: "
|
|
33
|
-
|
|
34
|
-
→
|
|
32
|
+
ToolSearch({ query: "figma use_figma", max_results: 10 })
|
|
33
|
+
|
|
34
|
+
Parse tool names matching /^mcp__([^_]*figma[^_]*)__use_figma$/i → write-capable prefix set.
|
|
35
|
+
Empty → Write to output: "Figma remote MCP not available (writes require the remote server, not desktop). Preferred install: `claude plugin install figma@claude-plugins-official`. Manual: `claude mcp add --transport http figma https://mcp.figma.com/mcp`. Then restart the session." → STOP.
|
|
36
|
+
One+ → pick prefix via tiebreaker (1) `figma` > others (2) non-`figma-desktop` (3) alphabetical. Record resolved prefix for use in Steps 1–5.
|
|
35
37
|
```
|
|
36
38
|
|
|
37
|
-
Note:
|
|
39
|
+
Note: the remote Figma MCP (canonical server name `figma`, URL `https://mcp.figma.com/mcp`) exposes both reads (`get_metadata`, `get_variable_defs`) and writes (`use_figma`) on the same server. The desktop MCP (`figma-desktop`) exposes reads only and cannot be used for writes — this agent STOPs if only a desktop variant is detected.
|
|
38
40
|
|
|
39
41
|
---
|
|
40
42
|
|
|
@@ -72,12 +74,11 @@ Read `.design/DESIGN-CONTEXT.md`. Extract the relevant data for the selected mod
|
|
|
72
74
|
- For `tokenize`: color/spacing/type literal values that could map to Figma variables — look for hex values, spacing scales, and typography sizes in the decisions section
|
|
73
75
|
- For `mappings`: component names and their source file paths — look for component listings, file paths, and implementation references
|
|
74
76
|
|
|
75
|
-
Also read the active Figma file structure
|
|
77
|
+
Also read the active Figma file structure. Use the resolved prefix from Step 0 (written here as `{P}` for short — e.g., `mcp__figma__`). Reads and writes share the same server:
|
|
76
78
|
|
|
77
79
|
```
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
mcp__figma__get_variable_defs() // for tokenize mode — variable names and values
|
|
80
|
+
{P}get_metadata() // lightweight layer outline
|
|
81
|
+
{P}get_variable_defs() // for tokenize mode — variable names and values
|
|
81
82
|
```
|
|
82
83
|
|
|
83
84
|
If `get_metadata` errors (no file accessible), write: "No Figma file is accessible. Open the target file in Figma and retry." and STOP.
|
|
@@ -157,12 +158,12 @@ Wait for user response. If response is not "yes", STOP with "Cancelled."
|
|
|
157
158
|
|
|
158
159
|
## Step 5 — Execute Writes
|
|
159
160
|
|
|
160
|
-
For each operation in the proposal, call `
|
|
161
|
+
For each operation in the proposal, call `{P}use_figma` with the appropriate operation payload.
|
|
161
162
|
|
|
162
163
|
For `annotate`:
|
|
163
164
|
|
|
164
165
|
```javascript
|
|
165
|
-
|
|
166
|
+
{P}use_figma({
|
|
166
167
|
operation: "add_comment",
|
|
167
168
|
layerId: "<layer-id>",
|
|
168
169
|
message: "<annotation text>"
|
|
@@ -172,7 +173,7 @@ mcp__figma__use_figma({
|
|
|
172
173
|
For `tokenize`:
|
|
173
174
|
|
|
174
175
|
```javascript
|
|
175
|
-
|
|
176
|
+
{P}use_figma({
|
|
176
177
|
operation: "set_variable_binding",
|
|
177
178
|
nodeId: "<node-id>",
|
|
178
179
|
field: "fills[0].color",
|
|
@@ -183,7 +184,7 @@ mcp__figma__use_figma({
|
|
|
183
184
|
For `mappings`:
|
|
184
185
|
|
|
185
186
|
```javascript
|
|
186
|
-
|
|
187
|
+
{P}use_figma({
|
|
187
188
|
operation: "set_code_connect",
|
|
188
189
|
componentId: "<component-id>",
|
|
189
190
|
filePath: "<relative-path>",
|
|
@@ -266,7 +267,7 @@ If user says "edit": allow user to modify proposal, then re-confirm.
|
|
|
266
267
|
|
|
267
268
|
For each confirmed annotation:
|
|
268
269
|
```javascript
|
|
269
|
-
|
|
270
|
+
{P}use_figma({
|
|
270
271
|
operation: "add_comment",
|
|
271
272
|
layerId: "<frame-node-id>",
|
|
272
273
|
message: "Implementation: <status> — verified <ISO date>"
|
|
@@ -277,7 +278,7 @@ mcp__figma__use_figma({
|
|
|
277
278
|
|
|
278
279
|
For each confirmed Code Connect mapping:
|
|
279
280
|
```javascript
|
|
280
|
-
|
|
281
|
+
{P}use_figma({
|
|
281
282
|
operation: "set_code_connect",
|
|
282
283
|
componentId: "<component-node-id>",
|
|
283
284
|
filePath: "<relative-code-path>",
|
|
@@ -287,7 +288,7 @@ mcp__figma__use_figma({
|
|
|
287
288
|
|
|
288
289
|
After all individual mappings, send the batch:
|
|
289
290
|
```javascript
|
|
290
|
-
|
|
291
|
+
{P}use_figma({
|
|
291
292
|
operation: "send_code_connect_mappings"
|
|
292
293
|
})
|
|
293
294
|
```
|
package/agents/token-mapper.md
CHANGED
|
@@ -63,7 +63,7 @@ grep -rEn "box-shadow\s*:|shadow-(sm|md|lg|xl|2xl)" src/ --include="*.css" --inc
|
|
|
63
63
|
|
|
64
64
|
### Figma augmentation
|
|
65
65
|
|
|
66
|
-
If STATE.md `<connections>` has `figma: available`, call `
|
|
66
|
+
If STATE.md `<connections>` has `figma: available`, read the `prefix=` field on that line and call `{prefix}get_variable_defs` to augment with named Figma variables. Works with both remote (`mcp__figma__`) and desktop (`mcp__figma-desktop__`) variants — `get_variable_defs` is available on both.
|
|
67
67
|
|
|
68
68
|
## Output Format — `.design/map/tokens.md`
|
|
69
69
|
|
|
@@ -8,7 +8,7 @@ This directory contains connection specifications for external tools and MCPs th
|
|
|
8
8
|
|
|
9
9
|
| Connection | Status | Spec File | Notes |
|
|
10
10
|
|-----------|--------|-----------|-------|
|
|
11
|
-
| Figma | Active | [`connections/figma.md`](connections/figma.md) |
|
|
11
|
+
| Figma | Active | [`connections/figma.md`](connections/figma.md) | Auto-detects any Figma MCP variant (remote reads+writes, desktop reads-only); prefix resolved at probe time |
|
|
12
12
|
| Refero | Active | [`connections/refero.md`](connections/refero.md) | Uses `mcp__refero__*` tools (verify names via ToolSearch) |
|
|
13
13
|
| Preview | Active | [`connections/preview.md`](connections/preview.md) | Uses `mcp__Claude_Preview__*` tools |
|
|
14
14
|
| Storybook | Active | [`connections/storybook.md`](connections/storybook.md) | HTTP probe: `localhost:6006/index.json` |
|
|
@@ -83,18 +83,30 @@ refero: not_configured
|
|
|
83
83
|
|
|
84
84
|
**Figma probe (execute at stage entry, after reading STATE.md):**
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
The probe is variant-agnostic — it resolves any server whose prefix matches `/figma/i` (e.g., `figma`, `Figma`, `figma-desktop`, UUID-prefixed remote instances) and records the resolved prefix plus writes capability. Remote MCP exposes `use_figma` (writes-capable). Desktop MCP exposes reads only.
|
|
87
87
|
|
|
88
88
|
```
|
|
89
|
-
Step A1 — ToolSearch
|
|
90
|
-
ToolSearch({ query: "
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
89
|
+
Step A1 — Keyword ToolSearch:
|
|
90
|
+
ToolSearch({ query: "figma get_metadata use_figma", max_results: 10 })
|
|
91
|
+
|
|
92
|
+
Parse tool names for:
|
|
93
|
+
/^mcp__([^_]*figma[^_]*)__get_metadata$/i → read-capable prefix set
|
|
94
|
+
/^mcp__([^_]*figma[^_]*)__use_figma$/i → write-capable prefix set
|
|
95
|
+
|
|
96
|
+
Empty read set → figma: not_configured (skip all Figma steps)
|
|
97
|
+
One+ matches → proceed to Step A2
|
|
98
|
+
|
|
99
|
+
Step A2 — Tiebreaker selection:
|
|
100
|
+
Preference order when multiple read prefixes match:
|
|
101
|
+
(1) both-sets > reads-only
|
|
102
|
+
(2) `figma` > others
|
|
103
|
+
(3) non-`figma-desktop` > desktop
|
|
104
|
+
(4) alphabetical
|
|
105
|
+
|
|
106
|
+
Step A3 — Live tool call on resolved prefix:
|
|
107
|
+
call mcp__<prefix>__get_metadata
|
|
108
|
+
→ Success → figma: available (prefix=mcp__<prefix>__, writes=<true|false>)
|
|
109
|
+
→ Error → figma: unavailable (skip all Figma steps)
|
|
98
110
|
|
|
99
111
|
Write figma status to STATE.md <connections>.
|
|
100
112
|
```
|
package/connections/figma.md
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
# Figma MCP — Connection Specification
|
|
2
2
|
|
|
3
|
-
This file is the connection specification for the Figma MCP
|
|
3
|
+
This file is the connection specification for the Figma MCP within the get-design-done pipeline. Figma publishes two MCP variants, both officially supported:
|
|
4
|
+
|
|
5
|
+
- **Remote MCP** (`https://mcp.figma.com/mcp`) — full read + write. Exposes read tools (`get_metadata`, `get_design_context`, `get_variable_defs`, `get_screenshot`, `get_figjam`, `search_design_system`) and remote-only write tools (`use_figma`, `generate_figma_design`, `create_new_file`, `whoami`).
|
|
6
|
+
- **Desktop MCP** (local HTTP, served by the Figma desktop app in Dev Mode) — reads only. Exposes the same read tools but not `use_figma`. Useful for offline/no-network reads.
|
|
7
|
+
|
|
8
|
+
The pipeline auto-detects any server whose name matches `/figma/i` (e.g., `figma`, `Figma`, `figma-desktop`, UUID-prefixed instances) and records the resolved prefix plus `writes` capability in `STATE.md`. See `connections/connections.md` for the full connection index and capability matrix.
|
|
4
9
|
|
|
5
10
|
---
|
|
6
11
|
|
|
@@ -9,29 +14,46 @@ This file is the connection specification for the Figma MCP (remote, read + writ
|
|
|
9
14
|
**Prerequisites:**
|
|
10
15
|
|
|
11
16
|
- A Figma account (OAuth on first use at `mcp.figma.com`).
|
|
12
|
-
- Figma file access for any file you intend to read or write.
|
|
17
|
+
- Figma file access for any file you intend to read or write.
|
|
18
|
+
- (Optional for desktop variant) Figma desktop app running with the target file open in Dev Mode.
|
|
19
|
+
|
|
20
|
+
### Option A — Claude Code plugin (preferred)
|
|
21
|
+
|
|
22
|
+
Anthropic publishes an official Figma plugin that bundles the MCP configuration plus Figma's agent skills:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
claude plugin install figma@claude-plugins-official
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Restart the Claude Code session after install. OAuth prompts on first tool call.
|
|
13
29
|
|
|
14
|
-
|
|
30
|
+
### Option B — Manual remote MCP install
|
|
15
31
|
|
|
16
32
|
```
|
|
17
|
-
claude mcp add
|
|
33
|
+
claude mcp add --transport http figma https://mcp.figma.com/mcp
|
|
18
34
|
```
|
|
19
35
|
|
|
20
|
-
|
|
36
|
+
Restart the session. OAuth prompts on first tool call. One install unlocks both reads and writes.
|
|
37
|
+
|
|
38
|
+
> **Note:** The legacy server URL `https://mcp.figma.com/v1/sse` is superseded. Current canonical URL is `https://mcp.figma.com/mcp` (Streamable HTTP). Remove any prior registration using the old URL: `claude mcp remove figma` then re-run the install command above.
|
|
39
|
+
|
|
40
|
+
### Option C — Desktop MCP (reads only)
|
|
41
|
+
|
|
42
|
+
The Figma desktop app exposes a local MCP server on Dev Mode. This path is useful when writes are not needed and network access is restricted. Desktop MCP is typically registered under the server name `figma-desktop` — follow the Figma desktop app's Dev Mode instructions for your Figma version.
|
|
21
43
|
|
|
22
44
|
**Verification:**
|
|
23
45
|
|
|
24
46
|
After session restart, run:
|
|
25
47
|
|
|
26
48
|
```
|
|
27
|
-
ToolSearch({ query: "
|
|
49
|
+
ToolSearch({ query: "figma get_metadata use_figma", max_results: 10 })
|
|
28
50
|
```
|
|
29
51
|
|
|
30
|
-
|
|
52
|
+
The probe accepts any server prefix matching `/figma/i`. At least one result with a `get_metadata` tool is required for reads. A matching `use_figma` tool is required for writes (remote only).
|
|
31
53
|
|
|
32
|
-
**Migration from
|
|
54
|
+
**Migration from older plugin versions:**
|
|
33
55
|
|
|
34
|
-
|
|
56
|
+
Plugin versions before v1.0.7.1 used two separate Figma MCPs — `figma-desktop` (reads) and `figma` (writes). As of v1.0.7.1, the remote MCP exposes full read parity, so a single remote install is sufficient for most users. The desktop MCP remains supported as a reads-only fallback and is auto-detected alongside remote. If you only want the remote path, remove desktop:
|
|
35
57
|
|
|
36
58
|
```
|
|
37
59
|
claude mcp remove figma-desktop
|
|
@@ -43,26 +65,45 @@ No data is lost — the remote MCP reads the same Figma files.
|
|
|
43
65
|
|
|
44
66
|
## Tools
|
|
45
67
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
|
51
|
-
|
|
52
|
-
| `
|
|
53
|
-
| `
|
|
54
|
-
| `
|
|
55
|
-
| `
|
|
56
|
-
| `
|
|
57
|
-
| `
|
|
68
|
+
Tool names take the form `mcp__<prefix>__<tool>` where `<prefix>` is the resolved server name from the probe (commonly `figma` for remote or `figma-desktop` for local). The pipeline discovers the prefix at runtime — see **Availability Probe** below. The `mcp__figma__` examples shown here assume a server registered as `figma`.
|
|
69
|
+
|
|
70
|
+
**Reads (available on remote and desktop):**
|
|
71
|
+
|
|
72
|
+
| Tool | Returns | Pipeline use |
|
|
73
|
+
|------|---------|--------------|
|
|
74
|
+
| `get_metadata` | Lightweight outline: node IDs, names, types, position/size. Also the availability probe. | **In scope** — probe (works without a selection); metadata snapshot for figma-write proposal review |
|
|
75
|
+
| `get_variable_defs` | Variable collection tree: collection ID, mode names, variable names (hierarchical, e.g. `colors/primary/500`), resolved values, descriptions, scopes | **In scope** — scan: token augmentation (CONN-03); discover: decisions pre-population (CONN-04); figma-write: tokenize mode source |
|
|
76
|
+
| `get_design_context` | Structured React+Tailwind component tree of the current Figma selection | **In scope (secondary)** — discover: existing design decisions for established Figma systems |
|
|
77
|
+
| `get_screenshot` | Screenshot image of the selected Figma layer or frame | **In scope (opt-in)** — visual reference capture for discovery; not invoked by default |
|
|
78
|
+
| `get_figjam` | FigJam diagram metadata (XML) plus node screenshots | Out of scope this phase (not part of the design pipeline) |
|
|
79
|
+
| `search_design_system` | Matching components, variables, and styles across connected libraries for a text query | Out of scope this phase (reserved for future Code Connect work) |
|
|
80
|
+
| `get_code_connect_map` | Maps Figma component instances to code file paths | Out of scope this phase (reserved for future Code Connect work) |
|
|
81
|
+
| `add_code_connect_map` | Adds Code Connect mapping entries | Out of scope this phase (reserved for future Code Connect work) |
|
|
82
|
+
| `get_code_connect_suggestions` | Suggested Code Connect mappings between Figma and code components | Out of scope this phase |
|
|
83
|
+
| `send_code_connect_mappings` | Confirms and finalizes Code Connect mappings | Out of scope this phase |
|
|
84
|
+
| `create_design_system_rules` | Generates rule files for design system alignment during code generation | Out of scope this phase |
|
|
85
|
+
|
|
86
|
+
**Writes (remote only):**
|
|
87
|
+
|
|
88
|
+
| Tool | Returns | Pipeline use |
|
|
89
|
+
|------|---------|--------------|
|
|
90
|
+
| `use_figma` | Write operation result | **In scope** — figma-write: all three modes (annotate, tokenize, mappings) |
|
|
91
|
+
| `generate_figma_design` | Imports/converts a web page into Figma design layers | Out of scope this phase |
|
|
92
|
+
| `generate_diagram` | Generates a FigJam diagram from Mermaid syntax | Out of scope this phase |
|
|
93
|
+
| `create_new_file` | Creates a new blank Figma Design or FigJam file | Out of scope this phase |
|
|
94
|
+
| `whoami` | Authenticated user identity, plans, and seat types | Optional — useful for surfacing Dev seat status before a write |
|
|
58
95
|
|
|
59
96
|
`get_metadata` is preferred for probing because it works without a file or selection open, keeping the probe lightweight. `get_variable_defs` is the primary workhorse for token extraction and decisions pre-population. `use_figma` is the single entry point for every write.
|
|
60
97
|
|
|
98
|
+
**Remote-only tools** (`use_figma`, `generate_figma_design`, `create_new_file`, `whoami`, `generate_diagram`): absent from the desktop MCP. When the probe resolves to a desktop-only prefix, stages that require these tools either STOP (figma-write) or fall back silently.
|
|
99
|
+
|
|
61
100
|
---
|
|
62
101
|
|
|
63
102
|
## Writes (`use_figma`)
|
|
64
103
|
|
|
65
|
-
`use_figma` is the single write tool
|
|
104
|
+
`use_figma` is the single write tool and is **remote only**. The `design-figma-writer` agent (`agents/design-figma-writer.md`) wraps it in a **proposal → confirm** UX — it builds a numbered operation list and presents it to the user before executing any write. The user must confirm before `use_figma` is called.
|
|
105
|
+
|
|
106
|
+
If the resolved probe prefix points to a desktop variant (no `use_figma`), figma-write STOPs early and instructs the user to register the remote MCP. No partial writes, no silent failures.
|
|
66
107
|
|
|
67
108
|
### Three Modes
|
|
68
109
|
|
|
@@ -99,22 +140,34 @@ Both scan and discover call `get_variable_defs` with no explicit selection to re
|
|
|
99
140
|
|
|
100
141
|
## Availability Probe
|
|
101
142
|
|
|
102
|
-
**Call ToolSearch first — always.** In Claude Code sessions with many MCP servers,
|
|
143
|
+
**Call ToolSearch first — always.** In Claude Code sessions with many MCP servers, Figma tools may be in the deferred tool set (not loaded into context at session start). Calling a deferred tool directly fails silently or errors. ToolSearch loads the tools into context and confirms their presence in a single call.
|
|
103
144
|
|
|
104
|
-
|
|
145
|
+
The probe is **variant-agnostic**: it accepts any server prefix matching `/figma/i` (e.g., `figma`, `Figma`, `figma-desktop`, `3860b164-...` UUID-prefixed remote instances) and records both the resolved prefix and the writes capability.
|
|
105
146
|
|
|
106
147
|
**Figma probe sequence:**
|
|
107
148
|
|
|
108
149
|
```
|
|
109
|
-
Step 1 — ToolSearch
|
|
110
|
-
ToolSearch({ query: "
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
150
|
+
Step 1 — Keyword ToolSearch:
|
|
151
|
+
ToolSearch({ query: "figma get_metadata use_figma", max_results: 10 })
|
|
152
|
+
|
|
153
|
+
Parse results for tool names matching:
|
|
154
|
+
- /^mcp__([^_]*figma[^_]*)__get_metadata$/i → captures read-capable prefixes
|
|
155
|
+
- /^mcp__([^_]*figma[^_]*)__use_figma$/i → captures write-capable prefixes
|
|
156
|
+
|
|
157
|
+
No read match → figma: not_configured (no Figma MCP registered)
|
|
158
|
+
One or more matches → proceed to Step 2
|
|
159
|
+
|
|
160
|
+
Step 2 — Tiebreaker selection:
|
|
161
|
+
Preference order when multiple prefixes match:
|
|
162
|
+
1. Prefer prefixes that appear in BOTH the read set and the write set
|
|
163
|
+
2. Among remaining prefixes, prefer `figma` (canonical remote server name)
|
|
164
|
+
3. Among remaining prefixes, prefer non-`figma-desktop`
|
|
165
|
+
4. Alphabetical
|
|
166
|
+
|
|
167
|
+
Step 3 — Live tool call on resolved prefix:
|
|
168
|
+
call mcp__<prefix>__get_metadata
|
|
169
|
+
→ Success → figma: available (prefix=mcp__<prefix>__, writes=<true|false>)
|
|
170
|
+
→ Error → figma: unavailable (auth expired, rate-limited, or no file open)
|
|
118
171
|
```
|
|
119
172
|
|
|
120
173
|
Write the result to `.design/STATE.md` `<connections>` immediately after probing.
|
|
@@ -150,24 +203,35 @@ Stages do not append a `<blocker>` for a missing Figma connection — Figma is a
|
|
|
150
203
|
|
|
151
204
|
## STATE.md Integration
|
|
152
205
|
|
|
153
|
-
Every stage writes its probe result to `.design/STATE.md` under the `<connections>` section:
|
|
206
|
+
Every stage writes its probe result to `.design/STATE.md` under the `<connections>` section. The format carries three fields for Figma: status, resolved tool prefix, and writes capability.
|
|
154
207
|
|
|
155
208
|
```xml
|
|
156
209
|
<connections>
|
|
157
|
-
figma: available
|
|
210
|
+
figma: available (prefix=mcp__figma__, writes=true)
|
|
158
211
|
refero: not_configured
|
|
159
212
|
</connections>
|
|
160
213
|
```
|
|
161
214
|
|
|
215
|
+
Other examples:
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
figma: available (prefix=mcp__figma-desktop__, writes=false)
|
|
219
|
+
figma: available (prefix=mcp__Figma__, writes=false)
|
|
220
|
+
figma: unavailable
|
|
221
|
+
figma: not_configured
|
|
222
|
+
```
|
|
223
|
+
|
|
162
224
|
**Status values:**
|
|
163
225
|
|
|
164
226
|
| Value | Meaning |
|
|
165
227
|
|-------|---------|
|
|
166
|
-
| `available` | `get_metadata`
|
|
228
|
+
| `available` | A matching `get_metadata` tool was resolved and the live call succeeded. The `writes=` flag indicates whether `use_figma` is also present on the same prefix. |
|
|
167
229
|
| `unavailable` | Tool is in the session but errored (auth expired, no file open, rate-limited) |
|
|
168
|
-
| `not_configured` |
|
|
230
|
+
| `not_configured` | No server matching `/figma/i` exposes `get_metadata` — MCP not registered |
|
|
231
|
+
|
|
232
|
+
**Consumer contract.** Agents that call Figma tools MUST read the resolved prefix from STATE.md and construct tool names dynamically (`{prefix}get_variable_defs`, `{prefix}use_figma`), rather than hardcoding `mcp__figma__`. Agents that need writes MUST additionally check `writes=true` and STOP early with a clear message when false.
|
|
169
233
|
|
|
170
|
-
The `<connections>` schema is minimal by design. Traceability of which outputs came from Figma is handled via source annotations in DESIGN.md (`source: figma-variables`) and DESIGN-CONTEXT.md ("pre-populated from Figma variables"), not via richer STATE.md fields.
|
|
234
|
+
The `<connections>` schema is minimal by design. Traceability of which outputs came from Figma is handled via source annotations in DESIGN.md (`source: figma-variables`) and DESIGN-CONTEXT.md ("pre-populated from Figma variables"), not via richer STATE.md fields.
|
|
171
235
|
|
|
172
236
|
---
|
|
173
237
|
|
|
@@ -179,10 +243,10 @@ The `<connections>` schema is minimal by design. Traceability of which outputs c
|
|
|
179
243
|
|
|
180
244
|
- **Multi-mode variables (Light/Dark).** Variables may carry values for multiple modes. When present, extract both: `#3B82F6 (light) / #60A5FA (dark)`. DESIGN.md can note dark-mode token existence in the color section.
|
|
181
245
|
|
|
182
|
-
- **Deferred-tool loading.** Always call `ToolSearch` before any
|
|
246
|
+
- **Deferred-tool loading.** Always call `ToolSearch` before any Figma tool invocation. This applies at every stage entry, even if Figma was `available` in a previous run — tool availability and the resolved prefix can change between sessions.
|
|
183
247
|
|
|
184
248
|
- **All writes require user confirmation.** The proposal→confirm UX in `design-figma-writer` ensures the user reviews all operations before any write is executed. There is no auto-approve mode. See `agents/design-figma-writer.md` for the proposal contract.
|
|
185
249
|
|
|
186
250
|
- **OAuth re-auth.** If `get_metadata` starts returning auth errors after previously working, the OAuth session expired. Re-running the MCP install command is not required — the session refreshes on the next tool call that returns a `reauth` hint. A clean `claude mcp remove figma && claude mcp add ...` is always safe.
|
|
187
251
|
|
|
188
|
-
- **
|
|
252
|
+
- **Desktop MCP reads-only.** The desktop MCP (typically `figma-desktop`) exposes read tools only. It is auto-detected by the probe and is a supported fallback when writes are not needed. Stages that require writes (figma-write) STOP with an instruction to register the remote MCP.
|
package/package.json
CHANGED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// npx @hegemonart/get-design-done
|
|
5
|
+
// One-command installer for the get-design-done Claude Code plugin.
|
|
6
|
+
//
|
|
7
|
+
// Registers the github.com/hegemonart/get-design-done marketplace and enables
|
|
8
|
+
// the plugin in ~/.claude/settings.json (or $CLAUDE_CONFIG_DIR/settings.json).
|
|
9
|
+
// Claude Code fetches the plugin payload from the marketplace on next launch.
|
|
10
|
+
//
|
|
11
|
+
// Usage:
|
|
12
|
+
// npx @hegemonart/get-design-done # install
|
|
13
|
+
// npx @hegemonart/get-design-done --dry-run # show what would change
|
|
14
|
+
// npx @hegemonart/get-design-done --help
|
|
15
|
+
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const path = require('path');
|
|
18
|
+
const os = require('os');
|
|
19
|
+
|
|
20
|
+
const REPO = 'hegemonart/get-design-done';
|
|
21
|
+
const MARKETPLACE_NAME = 'get-design-done';
|
|
22
|
+
const PLUGIN_NAME = 'get-design-done';
|
|
23
|
+
const ENABLED_KEY = `${PLUGIN_NAME}@${MARKETPLACE_NAME}`;
|
|
24
|
+
|
|
25
|
+
const args = new Set(process.argv.slice(2));
|
|
26
|
+
|
|
27
|
+
if (args.has('--help') || args.has('-h')) {
|
|
28
|
+
process.stdout.write(
|
|
29
|
+
[
|
|
30
|
+
'npx @hegemonart/get-design-done — install the plugin',
|
|
31
|
+
'',
|
|
32
|
+
'Registers the github.com/hegemonart/get-design-done marketplace and',
|
|
33
|
+
'enables the get-design-done plugin in your Claude Code settings.',
|
|
34
|
+
'',
|
|
35
|
+
'Flags:',
|
|
36
|
+
' --dry-run Print the diff without writing',
|
|
37
|
+
' --help, -h Show this message',
|
|
38
|
+
'',
|
|
39
|
+
'Environment:',
|
|
40
|
+
' CLAUDE_CONFIG_DIR Override the Claude config directory',
|
|
41
|
+
' (default: ~/.claude)',
|
|
42
|
+
'',
|
|
43
|
+
'After install, restart Claude Code to load the plugin.',
|
|
44
|
+
'',
|
|
45
|
+
].join('\n'),
|
|
46
|
+
);
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const DRY_RUN = args.has('--dry-run');
|
|
51
|
+
|
|
52
|
+
function resolveConfigDir() {
|
|
53
|
+
if (process.env.CLAUDE_CONFIG_DIR && process.env.CLAUDE_CONFIG_DIR.trim()) {
|
|
54
|
+
return process.env.CLAUDE_CONFIG_DIR.trim();
|
|
55
|
+
}
|
|
56
|
+
return path.join(os.homedir(), '.claude');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function loadSettings(settingsPath) {
|
|
60
|
+
if (!fs.existsSync(settingsPath)) return {};
|
|
61
|
+
try {
|
|
62
|
+
const raw = fs.readFileSync(settingsPath, 'utf8');
|
|
63
|
+
if (!raw.trim()) return {};
|
|
64
|
+
return JSON.parse(raw);
|
|
65
|
+
} catch (err) {
|
|
66
|
+
process.stderr.write(
|
|
67
|
+
`get-design-done installer: cannot parse ${settingsPath} as JSON\n` +
|
|
68
|
+
` ${err.message}\n` +
|
|
69
|
+
` Fix the file manually or delete it, then re-run.\n`,
|
|
70
|
+
);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function mergeSettings(existing) {
|
|
76
|
+
const next = { ...existing };
|
|
77
|
+
|
|
78
|
+
const marketplaces = { ...(next.extraKnownMarketplaces || {}) };
|
|
79
|
+
const marketplaceEntry = {
|
|
80
|
+
source: { source: 'github', repo: REPO },
|
|
81
|
+
};
|
|
82
|
+
const marketplaceChanged =
|
|
83
|
+
JSON.stringify(marketplaces[MARKETPLACE_NAME]) !==
|
|
84
|
+
JSON.stringify(marketplaceEntry);
|
|
85
|
+
marketplaces[MARKETPLACE_NAME] = marketplaceEntry;
|
|
86
|
+
next.extraKnownMarketplaces = marketplaces;
|
|
87
|
+
|
|
88
|
+
const enabled = { ...(next.enabledPlugins || {}) };
|
|
89
|
+
const enabledChanged = enabled[ENABLED_KEY] !== true;
|
|
90
|
+
enabled[ENABLED_KEY] = true;
|
|
91
|
+
next.enabledPlugins = enabled;
|
|
92
|
+
|
|
93
|
+
return { next, changed: marketplaceChanged || enabledChanged };
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function atomicWrite(target, contents) {
|
|
97
|
+
const tmp = `${target}.tmp-${process.pid}`;
|
|
98
|
+
fs.writeFileSync(tmp, contents, { encoding: 'utf8', mode: 0o600 });
|
|
99
|
+
fs.renameSync(tmp, target);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function main() {
|
|
103
|
+
const configDir = resolveConfigDir();
|
|
104
|
+
const settingsPath = path.join(configDir, 'settings.json');
|
|
105
|
+
|
|
106
|
+
if (!fs.existsSync(configDir)) {
|
|
107
|
+
if (DRY_RUN) {
|
|
108
|
+
process.stdout.write(
|
|
109
|
+
`[dry-run] would create ${configDir}\n`,
|
|
110
|
+
);
|
|
111
|
+
} else {
|
|
112
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const existing = loadSettings(settingsPath);
|
|
117
|
+
const { next, changed } = mergeSettings(existing);
|
|
118
|
+
const formatted = `${JSON.stringify(next, null, 2)}\n`;
|
|
119
|
+
|
|
120
|
+
if (!changed) {
|
|
121
|
+
process.stdout.write(
|
|
122
|
+
`get-design-done is already registered in ${settingsPath}\n` +
|
|
123
|
+
`Nothing to do. Restart Claude Code if you haven't yet.\n`,
|
|
124
|
+
);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (DRY_RUN) {
|
|
129
|
+
process.stdout.write(
|
|
130
|
+
`[dry-run] would update ${settingsPath}\n` +
|
|
131
|
+
` extraKnownMarketplaces["${MARKETPLACE_NAME}"] = { source: { source: "github", repo: "${REPO}" } }\n` +
|
|
132
|
+
` enabledPlugins["${ENABLED_KEY}"] = true\n`,
|
|
133
|
+
);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
atomicWrite(settingsPath, formatted);
|
|
138
|
+
|
|
139
|
+
process.stdout.write(
|
|
140
|
+
[
|
|
141
|
+
`✓ get-design-done registered in ${settingsPath}`,
|
|
142
|
+
` marketplace: github:${REPO}`,
|
|
143
|
+
` plugin: ${ENABLED_KEY}`,
|
|
144
|
+
'',
|
|
145
|
+
'Next steps:',
|
|
146
|
+
' 1. Restart Claude Code (or run /reload-plugins).',
|
|
147
|
+
' 2. Claude Code will fetch the plugin on first launch.',
|
|
148
|
+
' 3. Verify with: /plugin list',
|
|
149
|
+
'',
|
|
150
|
+
].join('\n'),
|
|
151
|
+
);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
main();
|
package/skills/discover/SKILL.md
CHANGED
|
@@ -19,13 +19,20 @@ user-invocable: true
|
|
|
19
19
|
- Otherwise: normal transition — set frontmatter stage=discover, <position> stage=discover, status=in_progress, task_progress=0/1.
|
|
20
20
|
2. **Probe connection availability** — ToolSearch runs FIRST because MCP tools may be in the deferred tool set. This is the canonical probe pattern (spec lives in `connections/connections.md`; copied inline because SKILL.md has no include mechanism — if the probe pattern changes, update all stages that copied it).
|
|
21
21
|
|
|
22
|
-
**A — Figma probe:**
|
|
22
|
+
**A — Figma probe (variant-agnostic):**
|
|
23
23
|
|
|
24
24
|
```
|
|
25
|
-
A1. ToolSearch({ query: "
|
|
26
|
-
A2.
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
A1. ToolSearch({ query: "figma get_metadata use_figma", max_results: 10 })
|
|
26
|
+
A2. Parse tool names matching /^mcp__([^_]*figma[^_]*)__(get_metadata|use_figma)$/i
|
|
27
|
+
into read-capable and write-capable prefix sets.
|
|
28
|
+
A3. Empty read set → figma: not_configured (skip all Figma paths)
|
|
29
|
+
One or more matches → pick prefix via tiebreaker:
|
|
30
|
+
(1) both-sets > reads-only,
|
|
31
|
+
(2) `figma` > others,
|
|
32
|
+
(3) non-`figma-desktop` > desktop,
|
|
33
|
+
(4) alphabetical.
|
|
34
|
+
A4. Call {prefix}get_metadata:
|
|
35
|
+
Success → figma: available (prefix=mcp__<prefix>__, writes=<true|false>)
|
|
29
36
|
Error → figma: unavailable
|
|
30
37
|
```
|
|
31
38
|
|