@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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/CHANGELOG.md +129 -2
- package/README.md +186 -53
- package/SKILL.md +6 -4
- package/agents/design-authority-watcher.md +208 -0
- package/agents/design-component-generator.md +221 -0
- package/agents/design-context-builder.md +83 -6
- package/agents/design-discussant.md +1 -1
- package/agents/design-figma-writer.md +8 -8
- package/agents/design-paper-writer.md +131 -0
- package/agents/design-pencil-writer.md +99 -0
- package/agents/design-research-synthesizer.md +13 -1
- package/agents/design-update-checker.md +117 -0
- package/agents/design-verifier.md +51 -0
- package/agents/token-mapper.md +1 -1
- package/connections/21st-dev.md +98 -0
- package/connections/claude-design.md +0 -1
- package/connections/connections.md +50 -33
- package/connections/figma.md +81 -39
- package/connections/magic-patterns.md +105 -0
- package/connections/paper-design.md +137 -0
- package/connections/pencil-dev.md +88 -0
- package/connections/pinterest.md +0 -1
- package/hooks/budget-enforcer.js +13 -2
- package/hooks/gdd-read-injection-scanner.js +4 -9
- package/hooks/hooks.json +8 -0
- package/hooks/update-check.sh +251 -0
- package/package.json +1 -1
- package/reference/ai-native-tool-interface.md +102 -0
- package/reference/authority-feeds.md +72 -0
- package/reference/schemas/authority-snapshot.schema.json +42 -0
- package/reference/schemas/config.schema.json +4 -0
- package/reference/schemas/marketplace.schema.json +2 -2
- package/reference/schemas/plugin.schema.json +1 -1
- package/scripts/aggregate-agent-metrics.js +20 -0
- package/scripts/build-intel.cjs +13 -5
- package/scripts/injection-patterns.cjs +17 -0
- package/scripts/run-injection-scanner-ci.cjs +1 -10
- package/scripts/tests/test-authority-rejected-kinds.sh +58 -0
- package/scripts/tests/test-authority-watcher-diff.sh +113 -0
- package/scripts/validate-schemas.cjs +18 -1
- package/skills/audit/SKILL.md +11 -1
- package/skills/check-update/SKILL.md +135 -0
- package/skills/complete-cycle/SKILL.md +10 -0
- package/skills/design/SKILL.md +5 -5
- package/skills/discover/SKILL.md +2 -2
- package/skills/explore/SKILL.md +55 -3
- package/skills/health/SKILL.md +10 -0
- package/skills/help/SKILL.md +10 -0
- package/skills/progress/SKILL.md +10 -0
- package/skills/reflect/SKILL.md +1 -0
- package/skills/scan/SKILL.md +9 -19
- package/skills/ship/SKILL.md +10 -0
- package/skills/watch-authorities/SKILL.md +82 -0
- 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,
|
|
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: "
|
|
53
|
+
ToolSearch({ query: "select:mcp__figma__get_variable_defs", max_results: 1 })
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
-
Then call `
|
|
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
|
|
95
|
+
Proceed to Step 0A regardless of whether Step 0 ran or was skipped.
|
|
96
96
|
|
|
97
|
-
## Step
|
|
97
|
+
## Step 0A — paper.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
|
|
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 `
|
|
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,
|
|
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
|
|
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
|
|
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: "
|
|
79
|
-
|
|
80
|
-
|
|
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
|
|
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.
|
|
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
|
|