@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.
@@ -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, mcp__figma__use_figma, mcp__figma__get_variable_defs, mcp__figma__get_metadata
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 mcp__figma__use_figma) — annotations, token bindings, Code Connect mappings"
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: "select:mcp__figma__use_figma", max_results: 1 })
33
- → Empty result → Write to output: "Figma remote MCP not available. Register it with: claude mcp add figma --transport http https://mcp.figma.com/v1/sse Then restart the session." → STOP (do not proceed).
34
- Non-empty → proceed to Step 1
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: `mcp__figma__use_figma` is the remote Figma MCP (registered as server `figma`). Reads (`mcp__figma__get_metadata`, `mcp__figma__get_variable_defs`) live on the same server. As of v1.0.7.1, there is no separate read-only desktop MCPthe remote MCP is the single supported Figma connection.
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 using the remote MCP (reads and writes share the same server):
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
- ToolSearch({ query: "select:mcp__figma__get_metadata,mcp__figma__get_variable_defs", max_results: 2 })
79
- mcp__figma__get_metadata() // lightweight layer outline
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 `mcp__figma__use_figma` with the appropriate operation payload.
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
- mcp__figma__use_figma({
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
- mcp__figma__use_figma({
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
- mcp__figma__use_figma({
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
- mcp__figma__use_figma({
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
- mcp__figma__use_figma({
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
- mcp__figma__use_figma({
291
+ {P}use_figma({
291
292
  operation: "send_code_connect_mappings"
292
293
  })
293
294
  ```
@@ -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 `mcp__figma__get_variable_defs` to augment with named Figma variables.
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) | Uses `mcp__figma__*` tools (remote Figma MCP; reads + writes) |
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
- One probe covers both reads and writes the remote Figma MCP is a single server exposing `get_metadata`, `get_variable_defs`, `get_design_context`, `get_screenshot`, and `use_figma` together.
86
+ The probe is variant-agnosticit 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 check:
90
- ToolSearch({ query: "select:mcp__figma__get_metadata", max_results: 1 })
91
- → Empty result → figma: not_configured (skip all Figma steps)
92
- Non-empty result → proceed to Step A2
93
-
94
- Step A2 Live tool call:
95
- call mcp__figma__get_metadata
96
- Success → figma: available (reads AND use_figma writes both available)
97
- Error figma: unavailable (skip all Figma steps)
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
  ```
@@ -1,6 +1,11 @@
1
1
  # Figma MCP — Connection Specification
2
2
 
3
- This file is the connection specification for the Figma MCP (remote, read + write) within the get-design-done pipeline. One server exposes both read tools (`get_metadata`, `get_design_context`, `get_variable_defs`, `get_screenshot`) and the write tool `use_figma`. See `connections/connections.md` for the full connection index and capability matrix.
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. No desktop app install required.
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
- **Install command (Claude Code):**
30
+ ### Option B — Manual remote MCP install
15
31
 
16
32
  ```
17
- claude mcp add figma --transport http https://mcp.figma.com/v1/sse
33
+ claude mcp add --transport http figma https://mcp.figma.com/mcp
18
34
  ```
19
35
 
20
- After running this command, restart the Claude Code session. On first use, Claude Code prompts you to complete the OAuth flow at `mcp.figma.com`. One `claude mcp add` unlocks both reads and writes — there is no separate writer MCP.
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: "select:mcp__figma__get_metadata,mcp__figma__use_figma", max_results: 2 })
49
+ ToolSearch({ query: "figma get_metadata use_figma", max_results: 10 })
28
50
  ```
29
51
 
30
- Expect two non-empty results. If results are empty, the remote MCP is not registered re-run the install command above and restart the session.
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 the legacy dual-MCP setup:**
54
+ **Migration from older plugin versions:**
33
55
 
34
- Earlier versions of this plugin used two separate Figma MCPs — `figma-desktop` (local HTTP, read-only) and `figma` (remote, writes-only). As of **v1.0.7.1**, the remote MCP exposes full read parity and is the single supported Figma connection. If you installed `figma-desktop` previously, you can remove it:
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
- All tools use the `mcp__figma__` prefix (remote MCP).
47
-
48
- | Tool | Full name | Returns | Pipeline use |
49
- |------|-----------|---------|--------------|
50
- | `get_metadata` | `mcp__figma__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 |
51
- | `get_variable_defs` | `mcp__figma__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 |
52
- | `get_design_context` | `mcp__figma__get_design_context` | Structured React+Tailwind component tree of the current Figma selection | **In scope (secondary)** — discover: existing design decisions for established Figma systems |
53
- | `get_screenshot` | `mcp__figma__get_screenshot` | Screenshot image of the selected Figma layer or frame | **In scope (opt-in)** visual reference capture for discovery; not invoked by default |
54
- | `use_figma` | `mcp__figma__use_figma` | Write operation result | **In scope** — figma-write: all three modes (annotate, tokenize, mappings) |
55
- | `get_code_connect_map` | `mcp__figma__get_code_connect_map` | Maps Figma component instances to code file paths | Out of scope this phase (reserved for future Code Connect work) |
56
- | `add_code_connect_map` | `mcp__figma__add_code_connect_map` | Adds Code Connect mapping entries | Out of scope this phase (reserved for future Code Connect work) |
57
- | `create_design_system_rules` | `mcp__figma__create_design_system_rules` | Generates rule files for design system alignment during code generation | Out of scope this phase |
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. 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.
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, `mcp__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.
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
- One probe covers both reads and writes the remote MCP is a single server that exposes `get_metadata`, `get_variable_defs`, `get_design_context`, `get_screenshot`, and `use_figma` together. Presence of `get_metadata` implies `use_figma` is available on the same server.
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 check:
110
- ToolSearch({ query: "select:mcp__figma__get_metadata", max_results: 1 })
111
- → Empty result → figma: not_configured (MCP not registered; OAuth not completed)
112
- Non-empty result → proceed to Step 2
113
-
114
- Step 2 Live tool call:
115
- call mcp__figma__get_metadata
116
- Success → figma: available (reads AND writes both available on this server)
117
- Error → figma: unavailable (auth expired, rate-limited, or no file open)
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` returned a successful response; both reads and `use_figma` writes are expected to work |
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` | ToolSearch returned empty for `mcp__figma__*` — MCP not registered |
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. There is no separate `figma_writer:` key — one remote server, one status.
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 `mcp__figma__*` tool invocation. This applies at every stage entry, even if Figma was `available` in a previous run — tool availability can change between sessions.
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
- - **No `figma-desktop` fallback.** As of v1.0.7.1 the desktop MCP is no longer a supported read path. If you need offline/no-network reads for some reason, run the pipeline's non-Figma fallbacks (grep-based token extraction, interview-only decisions).
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hegemonart/get-design-done",
3
- "version": "1.14.2",
3
+ "version": "1.14.4",
4
4
  "description": "A Claude Code plugin for systematic design improvement",
5
5
  "author": "Hegemon",
6
6
  "homepage": "https://github.com/hegemonart/get-design-done",
@@ -14,8 +14,7 @@
14
14
  "repository",
15
15
  "license",
16
16
  "keywords",
17
- "skills",
18
- "hooks"
17
+ "skills"
19
18
  ],
20
19
  "properties": {
21
20
  "name": {
@@ -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();
@@ -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: "select:mcp__figma__get_metadata", max_results: 1 })
26
- A2. Empty result figma: not_configured (skip all Figma paths)
27
- Non-empty result call mcp__figma__get_metadata
28
- Success → figma: available
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