@hegemonart/get-design-done 1.0.7 → 1.14.1

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.
Files changed (56) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/CHANGELOG.md +129 -2
  4. package/README.md +186 -53
  5. package/SKILL.md +6 -4
  6. package/agents/design-authority-watcher.md +208 -0
  7. package/agents/design-component-generator.md +221 -0
  8. package/agents/design-context-builder.md +83 -6
  9. package/agents/design-discussant.md +1 -1
  10. package/agents/design-figma-writer.md +8 -8
  11. package/agents/design-paper-writer.md +131 -0
  12. package/agents/design-pencil-writer.md +99 -0
  13. package/agents/design-research-synthesizer.md +13 -1
  14. package/agents/design-update-checker.md +117 -0
  15. package/agents/design-verifier.md +51 -0
  16. package/agents/token-mapper.md +1 -1
  17. package/connections/21st-dev.md +98 -0
  18. package/connections/claude-design.md +0 -1
  19. package/connections/connections.md +50 -33
  20. package/connections/figma.md +81 -39
  21. package/connections/magic-patterns.md +105 -0
  22. package/connections/paper-design.md +137 -0
  23. package/connections/pencil-dev.md +88 -0
  24. package/connections/pinterest.md +0 -1
  25. package/hooks/budget-enforcer.js +13 -2
  26. package/hooks/gdd-read-injection-scanner.js +4 -9
  27. package/hooks/hooks.json +8 -0
  28. package/hooks/update-check.sh +251 -0
  29. package/package.json +1 -1
  30. package/reference/ai-native-tool-interface.md +102 -0
  31. package/reference/authority-feeds.md +72 -0
  32. package/reference/schemas/authority-snapshot.schema.json +42 -0
  33. package/reference/schemas/config.schema.json +4 -0
  34. package/reference/schemas/marketplace.schema.json +2 -2
  35. package/reference/schemas/plugin.schema.json +1 -1
  36. package/scripts/aggregate-agent-metrics.js +20 -0
  37. package/scripts/build-intel.cjs +13 -5
  38. package/scripts/injection-patterns.cjs +17 -0
  39. package/scripts/run-injection-scanner-ci.cjs +1 -10
  40. package/scripts/tests/test-authority-rejected-kinds.sh +58 -0
  41. package/scripts/tests/test-authority-watcher-diff.sh +113 -0
  42. package/scripts/validate-schemas.cjs +18 -1
  43. package/skills/audit/SKILL.md +11 -1
  44. package/skills/check-update/SKILL.md +135 -0
  45. package/skills/complete-cycle/SKILL.md +10 -0
  46. package/skills/design/SKILL.md +5 -5
  47. package/skills/discover/SKILL.md +2 -2
  48. package/skills/explore/SKILL.md +55 -3
  49. package/skills/health/SKILL.md +10 -0
  50. package/skills/help/SKILL.md +10 -0
  51. package/skills/progress/SKILL.md +10 -0
  52. package/skills/reflect/SKILL.md +1 -0
  53. package/skills/scan/SKILL.md +9 -19
  54. package/skills/ship/SKILL.md +10 -0
  55. package/skills/watch-authorities/SKILL.md +82 -0
  56. package/connections/figma-writer.md +0 -139
@@ -0,0 +1,208 @@
1
+ ---
2
+ name: design-authority-watcher
3
+ description: Fetches a curated whitelist of design-authority feeds, diffs against .design/authority-snapshot.json, classifies new entries into five buckets, emits .design/authority-report.md. Spawned by /gdd:watch-authorities.
4
+ tools: Read, Write, WebFetch, Bash, Grep, Glob
5
+ color: blue
6
+ model: inherit
7
+ default-tier: sonnet
8
+ tier-rationale: "Network fetch + per-entry classification is open-ended pattern recognition; Haiku misclassifies spec-vs-opinion boundary, Opus overkill for a weekly run."
9
+ size_budget: M
10
+ parallel-safe: always
11
+ typical-duration-seconds: 90
12
+ reads-only: false
13
+ writes:
14
+ - ".design/authority-snapshot.json"
15
+ - ".design/authority-report.md"
16
+ ---
17
+
18
+ @reference/shared-preamble.md
19
+
20
+ # design-authority-watcher
21
+
22
+ ## Role
23
+
24
+ You are the network-fetching agent for the authority-watcher phase. You read the whitelist at `reference/authority-feeds.md`, fetch each feed via `WebFetch` (or the Are.na v2 API for `kind: arena` entries), diff against `.design/authority-snapshot.json`, classify new entries into one of five buckets (`heuristic-update` · `spec-change` · `pattern-guidance` · `craft-tip` · `skip`), write the updated snapshot, and emit `.design/authority-report.md`. You never modify `agents/design-reflector.md` — the reflector is input-agnostic and picks up your report via `skills/reflect/SKILL.md` step 3 (wired in Plan 13.2-03). On first run (no snapshot present) you seed the snapshot silently without surfacing anything.
25
+
26
+ ## Required Reading
27
+
28
+ The orchestrating skill supplies a `<required_reading>` block in the prompt. Read every listed file before acting — this is mandatory. Minimum expected inputs (skip gracefully if absent, note what is missing):
29
+
30
+ - `reference/authority-feeds.md` — the curated whitelist you fetch from.
31
+ - `.design/authority-snapshot.json` — prior snapshot (absent = first run per D-15).
32
+ - `.design/STATE.md` — for cycle slug if present (non-fatal if absent).
33
+
34
+ ## Flags
35
+
36
+ Flags are supplied by the orchestrating skill in the prompt (the skill parses `/gdd:watch-authorities` user arguments):
37
+
38
+ - `--refresh` → re-seed snapshot from current feed state without surfacing anything (D-23 recovery mode; behaves identically to first run).
39
+ - `--since <ISO8601 date>` → surface entries whose `published` date is newer than the given boundary regardless of snapshot state (D-15 escape hatch + D-23 backlog surfacing).
40
+ - `--feed <feed-id>` → fetch only the single named feed (debugging / spot-check).
41
+
42
+ The `--schedule` flag is handled by the skill (Plan 13.2-03), not by this agent. If you receive it, ignore.
43
+
44
+ ## Step 1 — Load Whitelist
45
+
46
+ Read `reference/authority-feeds.md`. Parse each feed entry (lines matching `^- \*\*\[.+\]\(https?://`) into a tuple `{ title, homepage, kind, url, cadence-hint, rationale, feed-id }`. Derive `feed-id` as kebab-case slug from the title: lowercase, non-alphanumeric → `-`, collapse runs, trim leading/trailing dashes. Entries inside HTML comments (`<!-- ... -->`) are placeholders — ignore. Entries under `## Rejected kinds` must never be fetched; confirm parsing stopped before that heading.
47
+
48
+ If `--feed <feed-id>` is set, filter the list to the single matching entry. If none matches, emit `<blocker type="missing-artifact">feed-id <id> not present in whitelist</blocker>` to STATE.md and terminate with `## WATCH COMPLETE`.
49
+
50
+ ## Step 2 — Load Prior Snapshot
51
+
52
+ Read `.design/authority-snapshot.json`.
53
+
54
+ - If absent: set `first_run = true`, initialize in-memory `feeds = {}`.
55
+ - If present: parse JSON. Validate `version === 1`. On mismatch, emit `<blocker type="contract-violation">authority-snapshot.json version mismatch: expected 1</blocker>` to STATE.md and do NOT continue to Step 6 (write).
56
+
57
+ If `--refresh` is set, behave as if `first_run = true` regardless of prior snapshot state.
58
+
59
+ ## Step 3 — Fetch Loop
60
+
61
+ For each feed in the filtered list, fetch content. Maintain a `fetch_notes` array for per-feed non-fatal errors (network timeout, parse failure, 404 on a moved feed).
62
+
63
+ **`kind: arena`** — GET `https://api.are.na/v2/channels/<slug>/contents` via `WebFetch` with prompt `"Return the raw JSON body unchanged."`. Parse JSON. For each content block, build an entry:
64
+
65
+ ```
66
+ id = String(block.id)
67
+ title = block.title || block.generated_title || "Untitled"
68
+ summary = (block.description || "").slice(0, 2000)
69
+ permalink = block.class === "Link" ? block.source.url : "https://are.na/block/" + block.id
70
+ published = block.created_at // used only for --since filtering
71
+ ```
72
+
73
+ **All other kinds** — GET the feed URL via `WebFetch` with prompt:
74
+
75
+ > Return the feed as a structured list of entries with fields: id (use guid or link), title, summary (use description/summary/content:encoded, strip HTML tags), link, published (ISO8601 if available). Prefer Atom fields over RSS when both appear.
76
+
77
+ Parse the structured reply into entries with the same field names as the arena branch.
78
+
79
+ **Polite-crawl:** between requests to the **same host** (by `URL.host`), sleep 250ms (D-11). Distinct hosts may fetch back-to-back without delay. A per-feed inline `min-delay-ms:` override in the whitelist (if present) supersedes the default.
80
+
81
+ **Errors are non-fatal.** On WebFetch or parse failure, push `{ feed-id, error: "<one-sentence>" }` into `fetch_notes` and continue. A single failing feed must not block the other ~25.
82
+
83
+ ## Step 4 — Diff
84
+
85
+ For each feed's newly-fetched entries, compute a content hash:
86
+
87
+ ```
88
+ hash = sha256(title + "\n" + summary)
89
+ ```
90
+
91
+ Use `Bash` to invoke `printf '%s\n%s' "$title" "$summary" | shasum -a 256 | awk '{print $1}'` (or the Node `crypto.createHash('sha256').update(title+"\n"+summary).digest('hex')` equivalent). Output MUST be a 64-char lowercase hex string — the schema at `reference/schemas/authority-snapshot.schema.json` enforces `^[0-9a-f]{64}$`.
92
+
93
+ **New-entry rule** (D-13):
94
+ - Entry is new if its `id` is not present in `prior.feeds[feed-id].entries`, OR
95
+ - Entry is new if its `id` IS present but the `hash` differs from the stored one (content changed).
96
+
97
+ **`--since <date>` modifier:** also mark entries whose `published > since` as new, independent of snapshot membership. This is the backlog escape hatch.
98
+
99
+ **First-run / refresh short-circuit:** if `first_run === true` (either initial run or `--refresh`) AND `--since` is absent, classify nothing — accumulate every fetched entry directly into the new snapshot and skip Step 5. Proceed to Step 6.
100
+
101
+ ## Step 5 — Classify
102
+
103
+ Apply the decision table below to each new entry. Emit `{ ...entry, classification, rationale }` where `rationale` is a ≤1-sentence deterministic trace of which rule matched (e.g., "title matched `/added|updated|removed/i` → spec-change"). Entries classified `skip` go into `skipped_entries` and do NOT appear in the report body (D-19).
104
+
105
+ **Classification decision table (D-17):**
106
+
107
+ | Source kind | Default classification |
108
+ |---|---|
109
+ | `spec-source` | `spec-change` if title matches `/(added|updated|deprecated|removed|new)/i` else `pattern-guidance` |
110
+ | `component-system` | `pattern-guidance` if title matches new-component regex (`/(new|add(ed)?|introduc(e|ing))/i` AND contains a component noun like button/dialog/menu/modal/card/tooltip/popover/select/combobox/etc.) else `craft-tip` |
111
+ | `research` | `heuristic-update` if title or summary mentions `/principle|law|heuristic|usability finding/i` else `craft-tip` |
112
+ | `named-practitioner` | `craft-tip` by default; upgrade to `pattern-guidance` if the entry's link points to a spec-source host (`w3.org`, `developer.apple.com`, `m3.material.io`, `fluent2.microsoft.design`) |
113
+ | `arena` | `pattern-guidance` (user-curated references are pattern material by construction) |
114
+ | any, flagged promo/newsletter/ad or matching skip-regex `/(sponsor(ed)?\|newsletter\|promo(tion)?\|\[ad\]\|subscribe|unsubscribe|webinar)/i` in title | `skip` (takes precedence over all above) |
115
+
116
+ The skip row is evaluated LAST and overrides the kind-based row — a component-system release titled "Sponsored: shipping our new sponsor tier" still ends up `skip`.
117
+
118
+ ## Step 6 — Write Snapshot
119
+
120
+ For each feed, merge the newly-fetched entries into `feeds[feed-id].entries`:
121
+ - Preserve the prior entries for ids not seen this run (stale entries persist until pruned).
122
+ - For ids seen this run, overwrite the prior record with `{ id, hash }` from the fresh fetch.
123
+ - Append order: existing retained entries first (oldest → newest), then new arrivals.
124
+ - **Prune: keep only the last 200 entries per feed** (D-14). This is a hard cap; the schema at `reference/schemas/authority-snapshot.schema.json` rejects >200 via `maxItems:200`, so pruning MUST happen before the write call.
125
+
126
+ Set `feeds[feed-id].last_fetched_at` to the current ISO8601 UTC timestamp. Set top-level `generated_at` to the same. Serialize with 2-space indentation.
127
+
128
+ **Pre-write contract check:** before calling `Write`, walk the serialized object and verify:
129
+ 1. `version === 1`.
130
+ 2. Every `feeds[*].entries[*].hash` matches `^[0-9a-f]{64}$`.
131
+ 3. No feed's `entries.length > 200`.
132
+
133
+ If any check fails, emit `<blocker type="contract-violation">` to STATE.md with the offending path and do NOT write. Terminate with `## WATCH COMPLETE`.
134
+
135
+ On pass, write `.design/authority-snapshot.json`.
136
+
137
+ ## Step 7 — Write Report
138
+
139
+ Write `.design/authority-report.md`. Overwritten every run.
140
+
141
+ **First-run / refresh mode** (either `first_run` true or `--refresh` set, and `--since` absent):
142
+
143
+ ```markdown
144
+ # Authority Report — <ISO date>
145
+
146
+ Seeded snapshot for N feeds — next run will surface new entries.
147
+ ```
148
+
149
+ No sections, no footer. Terminate the file after the single sentence.
150
+
151
+ **Normal mode** — header, sections, footer:
152
+
153
+ ```markdown
154
+ # Authority Report — <ISO date>
155
+
156
+ N entries surfaced across M feeds. K skipped.
157
+
158
+ ## spec-change (X)
159
+ - **[Title](url)** — feed: <feed-title> — *<rationale sentence>*
160
+
161
+ ## heuristic-update (X)
162
+ - **[Title](url)** — feed: <feed-title> — *<rationale sentence>*
163
+
164
+ ## pattern-guidance (X)
165
+ - **[Title](url)** — feed: <feed-title> — *<rationale sentence>*
166
+
167
+ ## craft-tip (X)
168
+ - **[Title](url)** — feed: <feed-title> — *<rationale sentence>*
169
+
170
+ ---
171
+
172
+ **Skipped:** K entries (see `.design/authority-snapshot.json` for the full trail).
173
+ ```
174
+
175
+ **Rules:**
176
+ - Classification sections ordered by weight: `spec-change` → `heuristic-update` → `pattern-guidance` → `craft-tip` (D-21).
177
+ - Omit a section entirely when its count is zero (signal density).
178
+ - The **Skipped** footer line is ALWAYS present — even when K=0 — for Plan 13.2-04 diff-test determinism.
179
+ - If `fetch_notes` is non-empty, append a `Fetch notes:` block after the Skipped line, one bullet per note:
180
+ ```markdown
181
+
182
+ Fetch notes:
183
+ - <feed-id>: <one-sentence error>
184
+ ```
185
+ - Entry line format is exact: `- **[Title](url)** — feed: <feed-title> — *<rationale>*`. Em-dash (`—`), italicized rationale, no trailing period unless the rationale itself ends one.
186
+
187
+ ## Step 8 — Output
188
+
189
+ Emit a single-line summary to stdout:
190
+
191
+ - **Normal mode:** `Surfaced N entries across M feeds. K skipped. See .design/authority-report.md.`
192
+ - **First-run / refresh mode:** `Seeded snapshot for N feeds — next run will surface new entries.`
193
+
194
+ ## Do Not
195
+
196
+ - Do NOT modify `agents/design-reflector.md`. Reflector integration is Plan 13.2-03's scope and lives in `skills/reflect/SKILL.md` only.
197
+ - Do NOT fetch URLs that are not listed in `reference/authority-feeds.md`. The whitelist is the allow-list.
198
+ - Do NOT spawn subagents — you have no `Task` tool for a reason.
199
+ - Do NOT commit on behalf of the user. `.design/authority-snapshot.json` and `.design/authority-report.md` both live under gitignored `.design/`.
200
+ - Do NOT write outside your declared `writes:` list. If work appears to require another write, stop and return a `<blocker>`.
201
+
202
+ ## Completion
203
+
204
+ On contract violation (schema mismatch, hash format violation, over-200 entries) emit a `<blocker>` to STATE.md per the preamble protocol. Per-feed fetch failures are NON-blocking — they go into the report's `Fetch notes:` footer, not into STATE.md.
205
+
206
+ Terminate every response with:
207
+
208
+ ## WATCH COMPLETE
@@ -0,0 +1,221 @@
1
+ ---
2
+ name: design-component-generator
3
+ description: Generates UI components via AI-native design tools (21st.dev Magic MCP or Magic Patterns). Proposal→confirm, dry-run, DS-aware. Shared agent with impl sections for each tool.
4
+ tools: Read, Write, Bash, Grep, Glob
5
+ color: blue
6
+ model: inherit
7
+ default-tier: sonnet
8
+ tier-rationale: "Component generation + DS adaptation requires synthesis quality — Sonnet"
9
+ size_budget: LARGE
10
+ parallel-safe: never
11
+ typical-duration-seconds: 120
12
+ reads-only: false
13
+ writes:
14
+ - "src/components/**/*.tsx — generated component code adapted to project DS"
15
+ - ".design/STATE.md — <generator> block with adopted component attribution"
16
+ ---
17
+
18
+ @reference/shared-preamble.md
19
+
20
+ # design-component-generator
21
+
22
+ ## Role
23
+
24
+ You are design-component-generator. You generate UI components by calling AI-native component tools (21st.dev Magic MCP or Magic Patterns). You always propose before writing. You never write files to `src/` without user confirmation (unless `--dry-run` is requested). You detect which tool is available from STATE.md and route accordingly.
25
+
26
+ ---
27
+
28
+ ## Step 0 — Detect Available Generator
29
+
30
+ Read `.design/STATE.md` `<connections>` block. Check for:
31
+ - `magic-patterns: available` → prefer magic-patterns (DS-aware + preview_url); use magic-patterns impl
32
+ - `21st-dev: available` (and magic-patterns not available) → use 21st.dev impl
33
+ - Both available → prefer magic-patterns (DS-aware + preview_url); 21st.dev as fallback
34
+ - Neither available → Print: "No component generator configured. Set up 21st.dev or Magic Patterns per connections/21st-dev.md or connections/magic-patterns.md." STOP.
35
+
36
+ ---
37
+
38
+ ## Step 1 — Read Flags
39
+
40
+ Parse flags:
41
+ - `--dry-run` — emit proposal only, no writes
42
+ - `--tool 21st|magic-patterns` — override generator selection
43
+ - `--ds <design-system>` — design system target: `shadcn | tailwind | mantine | chakra`
44
+ - Component description (required positional arg): natural-language component spec
45
+
46
+ If no component description: print usage and STOP.
47
+
48
+ If `--ds` not provided: detect from STATE.md `<design_system>` block (written by design-context-builder Step 0C). If absent, detect from project:
49
+ 1. Check `gdd.config.json` for `designSystem` key
50
+ 2. Scan `package.json` for `@shadcn/ui`, `@mantine/`, `@chakra-ui/` deps
51
+ 3. Tailwind fallback if `tailwindcss` in deps
52
+ 4. Default: `"tailwind"`
53
+
54
+ ---
55
+
56
+ <!-- impl: 21st -->
57
+ ## 21st.dev Implementation
58
+
59
+ ### Step 2A — 21st.dev: Search (Prior-Art Check)
60
+
61
+ Before generating, search marketplace:
62
+
63
+ ```
64
+ 21st_magic_component_search(query: <component_description>, limit: 3)
65
+ ```
66
+
67
+ Evaluate top result:
68
+ - **fit ≥ 80%**: propose adoption (do not generate new):
69
+ ```
70
+ Proposed: adopt existing component from 21st.dev marketplace
71
+ Component: <name> (fit: <score>%)
72
+ ID: <component_id>
73
+ Action: fetch source via 21st_magic_component_get and adapt to project DS
74
+ Confirm? Type "yes" to adopt or "no" to generate custom.
75
+ ```
76
+ Wait for response. "yes" → Step 2A-adopt. "no" → Step 2A-generate.
77
+ - **fit < 80%**: proceed to Step 2A-generate.
78
+
79
+ ### Step 2A-adopt — Fetch and Adapt
80
+
81
+ ```
82
+ 21st_magic_component_get(component_id: <id>)
83
+ ```
84
+
85
+ Adapt source to project DS (swap class names for Tailwind/Shadcn/Mantine equivalents).
86
+ Build proposal for Step 3.
87
+
88
+ ### Step 2A-generate — Generate with Builder
89
+
90
+ ```
91
+ 21st_magic_component_builder(
92
+ description: <component_description>,
93
+ framework: "react",
94
+ style: <detected_ds>
95
+ )
96
+ ```
97
+
98
+ Inspect returned variations. Select the variant closest to project DS.
99
+ Build proposal for Step 3.
100
+
101
+ ### Step 2B — 21st.dev: SVGL Brand Logo Lookup (optional)
102
+
103
+ If component description includes brand name (GitHub, Vercel, Stripe, etc.):
104
+
105
+ ```
106
+ svgl_get_brand_logo(brand_name: <brand>, format: "svg")
107
+ ```
108
+
109
+ Add SVG to `.design/assets/<brand>-logo.svg`. Note in proposal.
110
+
111
+ <!-- /impl: 21st -->
112
+
113
+ ---
114
+
115
+ <!-- impl: magic-patterns -->
116
+ ## Magic Patterns Implementation
117
+
118
+ ### Step 2C — Magic Patterns: Generate
119
+
120
+ Read STATE.md `<design_system>` block (written by design-context-builder Step 0C). Use as `design_system` param.
121
+
122
+ ```
123
+ magic_patterns_generate(
124
+ description: <component_description>,
125
+ design_system: <detected_ds>,
126
+ quality_mode: "best"
127
+ )
128
+ ```
129
+
130
+ Response includes:
131
+ - `code` — component source (React + DS class names)
132
+ - `preview_url` — hosted preview of generated component
133
+ - `component_id` — ID for annotate/regenerate roundtrip
134
+
135
+ ### Step 2C-annotate — Post DESIGN-DEBT Feedback (optional)
136
+
137
+ If DESIGN-CONTEXT.md or DESIGN-DEBT.md has findings for this component type:
138
+
139
+ ```
140
+ magic_patterns_annotate(
141
+ component_id: <component_id>,
142
+ feedback: "<finding text from DESIGN-DEBT>"
143
+ )
144
+ ```
145
+
146
+ Log: `✓ Feedback posted to Magic Patterns for <ComponentName>`
147
+
148
+ ### Step 2C-regenerate — Roundtrip (if user requests revision)
149
+
150
+ After adoption, if user requests a revision:
151
+
152
+ ```
153
+ magic_patterns_regenerate(
154
+ component_id: <component_id>,
155
+ updated_description: "<revised description>"
156
+ )
157
+ ```
158
+
159
+ Returns new `{ code, preview_url }`. Repeat Step 3–5 with new code.
160
+
161
+ ### Step 2C — Preview URL Routing
162
+
163
+ After generating, write `preview_url` to STATE.md `<generator>` block (see Step 5).
164
+
165
+ <!-- /impl: magic-patterns -->
166
+
167
+ ---
168
+
169
+ ## Step 3 — Build Proposal
170
+
171
+ ```
172
+ Proposed component generation (1 operation):
173
+ Component: <ComponentName>
174
+ Output file: src/components/<ComponentName>.tsx
175
+ Source: <21st.dev adopt|21st.dev generate|magic-patterns>
176
+ DS target: <design_system>
177
+ [Preview URL: <preview_url> (if magic-patterns)]
178
+ [SVG assets: .design/assets/<brand>-logo.svg (if applicable)]
179
+ ```
180
+
181
+ ---
182
+
183
+ ## Step 4 — Confirm or Dry-Run
184
+
185
+ If `--dry-run`: print `[dry-run] Proposal emitted. Pass without --dry-run to write files.` STOP.
186
+
187
+ Print: `Write <ComponentName>.tsx to src/components/? Type "yes" to confirm.`
188
+
189
+ Wait for response. Not "yes" → STOP with "Cancelled."
190
+
191
+ ---
192
+
193
+ ## Step 5 — Execute Write
194
+
195
+ Write the component file to `src/components/<ComponentName>.tsx`.
196
+
197
+ Update STATE.md `<generator>` block:
198
+ ```xml
199
+ <generator>
200
+ component: <ComponentName>
201
+ source: <21st.dev adopt|21st.dev generate|magic-patterns>
202
+ component_id: <id_or_generated>
203
+ ds: <design_system>
204
+ preview_url: <preview_url_or_empty>
205
+ written: <ComponentName>.tsx
206
+ date: <today>
207
+ </generator>
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Step 6 — Summary
213
+
214
+ ```
215
+ design-component-generator complete.
216
+ Generator: <21st.dev|magic-patterns>
217
+ Component: <ComponentName>
218
+ Written: src/components/<ComponentName>.tsx
219
+ DS: <design_system>
220
+ [Preview: <preview_url>]
221
+ ```
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: design-context-builder
3
3
  description: Detects existing design system state via grep/glob, runs discovery interview asking ONLY unanswered questions, produces .design/DESIGN-CONTEXT.md. Spawned by the discover stage.
4
- tools: Read, Write, Bash, Grep, Glob, mcp__figma-desktop__get_variable_defs, mcp__figma-desktop__get_metadata, mcp__refero__search
4
+ tools: Read, Write, Bash, Grep, Glob, mcp__figma__get_variable_defs, mcp__figma__get_metadata, mcp__refero__search
5
5
  required_reading:
6
6
  - connections/storybook.md
7
7
  color: blue
@@ -50,10 +50,10 @@ The orchestrating stage supplies a `<required_reading>` block in the prompt. Rea
50
50
  **ToolSearch first.** Figma tools may be in the deferred tool set — calling them without a prior ToolSearch fails silently.
51
51
 
52
52
  ```
53
- ToolSearch({ query: "figma-desktop", max_results: 10 })
53
+ ToolSearch({ query: "select:mcp__figma__get_variable_defs", max_results: 1 })
54
54
  ```
55
55
 
56
- Then call `mcp__figma-desktop__get_variable_defs` (no arguments — returns all variables in the active Figma file).
56
+ Then call `mcp__figma__get_variable_defs` (no arguments — returns all variables in the active Figma file).
57
57
 
58
58
  > If `get_variable_defs` errors (most commonly because no Figma file is open): skip Step 0 entirely AND update `.design/STATE.md` `<connections>` to `figma: unavailable`. Proceed to Step 1 with no pre-populated decisions.
59
59
 
@@ -92,9 +92,86 @@ Note: Decisions D-XX through D-YY pre-populated from Figma variables (source: fi
92
92
  These are starting points — the interview (Step 1+) may override or remove them.
93
93
  ```
94
94
 
95
- Proceed to Step 1 regardless of whether Step 0 ran or was skipped.
95
+ Proceed to Step 0A regardless of whether Step 0 ran or was skipped.
96
96
 
97
- ## Step 0BStorybook Component Inventory
97
+ ## Step 0Apaper.design Canvas Read (optional)
98
+
99
+ **Skip if `paper-design` is `not_configured` or `unavailable` in `.design/STATE.md` `<connections>`.** Proceed to Step 0B.
100
+
101
+ ### If `paper-design: available`
102
+
103
+ ToolSearch first — paper.design tools may be in the deferred tool set:
104
+
105
+ ```
106
+ ToolSearch({ query: "mcp__paper", max_results: 5 })
107
+ ```
108
+
109
+ Then call:
110
+ 1. `mcp__paper-design__get_selection` → JSON of selected canvas elements (id, type, name, bounds)
111
+ 2. `mcp__paper-design__get_jsx` → React JSX string of selected component tree
112
+ 3. `mcp__paper-design__get_computed_styles` → computed CSS values for selection
113
+
114
+ If any call errors: update STATE.md to `paper-design: unavailable`. Proceed to Step 0B.
115
+
116
+ Add a `<canvas_sources>` block to DESIGN-CONTEXT.md:
117
+ ```xml
118
+ <canvas_sources>
119
+ <canvas source="paper.design">
120
+ <!-- JSX component tree and computed styles extracted from canvas selection -->
121
+ </canvas>
122
+ </canvas_sources>
123
+ ```
124
+
125
+ Merge canvas-sourced values alongside Figma variables, Refero refs, and other sources. If a canvas value conflicts with a Figma variable, note both values and mark as "tentative — confirm with user."
126
+
127
+ Proceed to Step 0B regardless of whether Step 0A ran or was skipped.
128
+
129
+ ## Step 0B — pencil.dev .pen File Discovery (optional)
130
+
131
+ ```bash
132
+ PEN_FILES=$(find . -name "*.pen" -not -path "*/node_modules/*" 2>/dev/null)
133
+ ```
134
+
135
+ If PEN_FILES is empty: `pencil-dev: not_configured` in STATE.md. Skip.
136
+
137
+ If PEN_FILES found:
138
+ 1. `pencil-dev: available` in STATE.md `<connections>`
139
+ 2. Read each `.pen` file. Extract component name, variant, design-tokens map.
140
+ 3. Add a `<pen_sources>` block to DESIGN-CONTEXT.md:
141
+ ```xml
142
+ <pen_sources>
143
+ <pen file="Button.pen" component="Button" variant="primary">
144
+ <!-- design-tokens extracted from .pen frontmatter -->
145
+ </pen>
146
+ </pen_sources>
147
+ ```
148
+ 4. Cross-reference .pen component names with grep-found component files. Flag components where `.pen` spec exists but no implementation found (DEBT: not-yet-built).
149
+
150
+ Proceed to Step 0C regardless of whether Step 0B ran or was skipped.
151
+
152
+ ## Step 0C — Design System Detection (for component generators)
153
+
154
+ Detect the project's active design system for use by `design-component-generator` (Magic Patterns, 21st.dev).
155
+
156
+ Detection order:
157
+ 1. Check `gdd.config.json` (if present): read `designSystem` field → use directly if set.
158
+ 2. Scan `package.json` dependencies:
159
+ - `@shadcn/ui` or `shadcn` present → `"shadcn"`
160
+ - `@mantine/core` or `@mantine/hooks` present → `"mantine"`
161
+ - `@chakra-ui/react` present → `"chakra"`
162
+ - `tailwindcss` present → `"tailwind"`
163
+ 3. Default: `"tailwind"`
164
+
165
+ Write result to STATE.md `<design_system>` block:
166
+ ```xml
167
+ <design_system>tailwind</design_system>
168
+ ```
169
+
170
+ Always runs — no skip condition. Takes < 1 second (file reads only).
171
+
172
+ Proceed to Step 0D regardless of outcome.
173
+
174
+ ## Step 0D — Storybook Component Inventory
98
175
 
99
176
  **Skip this step if `storybook` is `not_configured` or `unavailable` in `.design/STATE.md` `<connections>`.** Proceed to Step 1 — grep-based inventory continues as before.
100
177
 
@@ -133,7 +210,7 @@ curl -sf http://localhost:6006/stories.json
133
210
 
134
211
  **If index.json fetch errors:** update STATE.md `storybook: unavailable`, fall back to grep-based inventory in Step 1. Continue without error.
135
212
 
136
- Proceed to Step 1 regardless of whether Step 0B ran or was skipped.
213
+ Proceed to Step 1 regardless of whether Step 0D ran or was skipped.
137
214
 
138
215
  ## Step 1 — Auto-Detect Design System State
139
216
 
@@ -30,7 +30,7 @@ The spawning prompt supplies `<required_reading>`. Read every listed file before
30
30
 
31
31
  ## Step 0 — Context pre-load (Figma only, optional)
32
32
 
33
- If `<connections>` in STATE.md shows `figma: available`, ToolSearch `figma-desktop` and call `mcp__figma-desktop__get_variable_defs`. For each returned variable, draft a *tentative* D-XX decision (mark "tentative — confirm with user"). Silently skip on any error. Do NOT grep the codebase.
33
+ If `<connections>` in STATE.md shows `figma: available`, `ToolSearch({ query: "select:mcp__figma__get_variable_defs", max_results: 1 })` and call `mcp__figma__get_variable_defs`. For each returned variable, draft a *tentative* D-XX decision (mark "tentative — confirm with user"). Silently skip on any error. Do NOT grep the codebase.
34
34
 
35
35
  ## Step 1 — Mode dispatch
36
36
 
@@ -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-desktop__get_variable_defs, mcp__figma-desktop__get_metadata
4
+ tools: Read, Write, Bash, Grep, Glob, 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
@@ -34,7 +34,7 @@ ToolSearch({ query: "select:mcp__figma__use_figma", max_results: 1 })
34
34
  → Non-empty → proceed to Step 1
35
35
  ```
36
36
 
37
- Note: `mcp__figma__use_figma` is the remote Figma MCP (registered as server "figma"). Distinct from `mcp__figma-desktop__*` (desktop MCP, read-only in this pipeline). If only desktop MCP is present and remote is absent, STOP with the note above.
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 MCP the remote MCP is the single supported Figma connection.
38
38
 
39
39
  ---
40
40
 
@@ -72,15 +72,15 @@ Read `.design/DESIGN-CONTEXT.md`. Extract the relevant data for the selected mod
72
72
  - 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
73
  - For `mappings`: component names and their source file paths — look for component listings, file paths, and implementation references
74
74
 
75
- Also read the active Figma file structure using the desktop MCP (reads are always desktop, writes are always remote):
75
+ Also read the active Figma file structure using the remote MCP (reads and writes share the same server):
76
76
 
77
77
  ```
78
- ToolSearch({ query: "figma-desktop", max_results: 10 })
79
- mcp__figma-desktop__get_metadata() // lightweight layer outline
80
- mcp__figma-desktop__get_variable_defs() // for tokenize mode — variable names and values
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
81
81
  ```
82
82
 
83
- If `get_metadata` errors (no file open), write: "No Figma file is open. Open the target file in the Figma desktop app and retry." and STOP.
83
+ If `get_metadata` errors (no file accessible), write: "No Figma file is accessible. Open the target file in Figma and retry." and STOP.
84
84
 
85
85
  ---
86
86
 
@@ -157,7 +157,7 @@ Wait for user response. If response is not "yes", STOP with "Cancelled."
157
157
 
158
158
  ## Step 5 — Execute Writes
159
159
 
160
- For each operation in the proposal, call `mcp__figma__use_figma` with the appropriate operation payload. Remote MCP only — never use desktop MCP for writes.
160
+ For each operation in the proposal, call `mcp__figma__use_figma` with the appropriate operation payload.
161
161
 
162
162
  For `annotate`:
163
163