@hegemonart/get-design-done 1.0.7 → 1.13.3
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 +82 -0
- package/README.md +57 -19
- package/SKILL.md +6 -4
- package/agents/design-authority-watcher.md +208 -0
- package/agents/design-context-builder.md +3 -3
- package/agents/design-discussant.md +1 -1
- package/agents/design-figma-writer.md +8 -8
- package/agents/design-update-checker.md +117 -0
- package/agents/token-mapper.md +1 -1
- package/connections/claude-design.md +0 -1
- package/connections/connections.md +10 -23
- package/connections/figma.md +81 -39
- package/connections/pinterest.md +0 -1
- package/hooks/hooks.json +8 -0
- package/hooks/update-check.sh +238 -0
- package/package.json +1 -1
- 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/tests/test-authority-rejected-kinds.sh +58 -0
- package/scripts/tests/test-authority-watcher-diff.sh +109 -0
- package/scripts/validate-schemas.cjs +18 -1
- package/skills/audit/SKILL.md +11 -1
- package/skills/check-update/SKILL.md +133 -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 +2 -2
- 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,133 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-check-update
|
|
3
|
+
description: "Manual plugin-update check. Shows cached state by default; --refresh bypasses the 24h TTL; --dismiss hides the nudge until a newer release ships; --prompt spawns design-update-checker for a richer summary."
|
|
4
|
+
argument-hint: "[--refresh] [--dismiss] [--prompt]"
|
|
5
|
+
tools: Read, Write, Bash, Task
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# /gdd:check-update
|
|
9
|
+
|
|
10
|
+
**Role:** Manual entry point for the plugin-update checker. The SessionStart hook (`hooks/update-check.sh`) already runs on its own 24h cadence and writes `.design/update-cache.json` + `.design/update-available.md`. This command lets the user inspect / force / dismiss / enrich that state on demand.
|
|
11
|
+
|
|
12
|
+
## Flags
|
|
13
|
+
|
|
14
|
+
| Flag | Effect |
|
|
15
|
+
|---|---|
|
|
16
|
+
| *(none)* | Print cached state (latest_tag, delta, is_newer). If the cache is older than 24h, trigger `--refresh` implicitly. |
|
|
17
|
+
| `--refresh` | Invoke `hooks/update-check.sh --refresh` — bypasses the 24h TTL and re-fetches immediately. |
|
|
18
|
+
| `--dismiss` | Write `update_dismissed: "<latest_tag>"` to `.design/config.json` atomically and delete `.design/update-available.md`. Sticky until a newer release ships. |
|
|
19
|
+
| `--prompt` | Spawn `design-update-checker` agent (Haiku) to produce a 3–5-line "what this release changes for you" summary. Does not alter the banner or cache. |
|
|
20
|
+
|
|
21
|
+
Flags can be combined: `--refresh --prompt` is valid (re-fetch, then enrich). `--dismiss` is the only flag that mutates `.design/config.json`.
|
|
22
|
+
|
|
23
|
+
## Steps
|
|
24
|
+
|
|
25
|
+
1. **Parse flags.** Detect `--refresh`, `--dismiss`, `--prompt` in `$ARGUMENTS`. Any unknown flag: print `Unknown flag: <flag>` and exit.
|
|
26
|
+
|
|
27
|
+
2. **--refresh path** (if `--refresh` in flags):
|
|
28
|
+
Run the hot-path hook with the refresh flag:
|
|
29
|
+
```bash
|
|
30
|
+
bash "${CLAUDE_PLUGIN_ROOT:-$(pwd)}/hooks/update-check.sh" --refresh
|
|
31
|
+
```
|
|
32
|
+
This re-fetches `/releases/latest`, rewrites `.design/update-cache.json`, and re-renders `.design/update-available.md` subject to the same state/dismissal gates.
|
|
33
|
+
|
|
34
|
+
3. **Read cache.** After any optional refresh, read `.design/update-cache.json`. If it does not exist:
|
|
35
|
+
- Print: `No cache. Network may be unreachable or the hook has not run yet. Try /gdd:check-update --refresh.`
|
|
36
|
+
- Exit.
|
|
37
|
+
|
|
38
|
+
4. **Dismiss path** (if `--dismiss` in flags):
|
|
39
|
+
Compute new config contents and write atomically. The python heredoc receives CONFIG_PATH and LATEST_TAG via the ENVIRONMENT (env-prefix form — `KEY=VALUE python3 <<PY`), NOT via trailing argv. Passing `python3 -c '...' KEY=VALUE` makes Python treat the assignments as `sys.argv`, which the old draft did incorrectly; env-prefix form is the portable fix.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
CONFIG_PATH=".design/config.json"
|
|
43
|
+
LATEST_TAG="$(grep -E '"latest_tag"' .design/update-cache.json | head -n1 | sed -E 's/.*"latest_tag"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/')"
|
|
44
|
+
[ -n "$LATEST_TAG" ] || { echo 'No latest_tag in cache — nothing to dismiss.'; exit 0; }
|
|
45
|
+
|
|
46
|
+
mkdir -p .design
|
|
47
|
+
|
|
48
|
+
# Env-prefix form: CONFIG_PATH and LATEST_TAG are placed into the child process env,
|
|
49
|
+
# then python3 reads them via os.environ. Heredoc body is flat at column 0 (required —
|
|
50
|
+
# any leading indentation breaks Python parsing in a heredoc).
|
|
51
|
+
CONFIG_PATH="$CONFIG_PATH" LATEST_TAG="$LATEST_TAG" python3 <<'PY'
|
|
52
|
+
import json, os, sys, tempfile
|
|
53
|
+
|
|
54
|
+
config_path = os.environ['CONFIG_PATH']
|
|
55
|
+
latest_tag = os.environ['LATEST_TAG']
|
|
56
|
+
|
|
57
|
+
# Load existing config if present; otherwise start fresh. Preserve every unknown key.
|
|
58
|
+
try:
|
|
59
|
+
with open(config_path, 'r', encoding='utf-8') as f:
|
|
60
|
+
data = json.load(f)
|
|
61
|
+
if not isinstance(data, dict):
|
|
62
|
+
data = {}
|
|
63
|
+
except (FileNotFoundError, json.JSONDecodeError):
|
|
64
|
+
data = {}
|
|
65
|
+
|
|
66
|
+
# Set ONLY the dismissal key — every other pre-existing key is preserved verbatim.
|
|
67
|
+
data['update_dismissed'] = latest_tag
|
|
68
|
+
|
|
69
|
+
# Atomic write: write to tmp on the SAME filesystem, then os.replace() (POSIX rename(2)).
|
|
70
|
+
target_dir = os.path.dirname(config_path) or '.'
|
|
71
|
+
fd, tmp_path = tempfile.mkstemp(prefix='config.', suffix='.tmp', dir=target_dir)
|
|
72
|
+
try:
|
|
73
|
+
with os.fdopen(fd, 'w', encoding='utf-8') as f:
|
|
74
|
+
json.dump(data, f, indent=2)
|
|
75
|
+
f.write('\n')
|
|
76
|
+
os.replace(tmp_path, config_path) # atomic on same filesystem
|
|
77
|
+
except Exception as exc:
|
|
78
|
+
try:
|
|
79
|
+
os.unlink(tmp_path)
|
|
80
|
+
except OSError:
|
|
81
|
+
pass
|
|
82
|
+
sys.exit(1)
|
|
83
|
+
PY
|
|
84
|
+
|
|
85
|
+
# Remove the rendered banner (user dismissed — stop showing it until a newer release ships).
|
|
86
|
+
rm -f .design/update-available.md
|
|
87
|
+
echo "Dismissed $LATEST_TAG. The nudge will return when a newer release ships."
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
D-14 atomic-write invariant: `os.replace()` (POSIX `rename(2)`) is atomic on the same filesystem — an interrupted write leaves the original config intact. The `json.load → set single key → json.dump` round-trip guarantees every unknown top-level key (e.g. `model_profile`, `parallelism`) is preserved verbatim.
|
|
91
|
+
|
|
92
|
+
5. **Print default state** (always, unless the skill exited early):
|
|
93
|
+
```
|
|
94
|
+
━━━ /gdd:check-update ━━━
|
|
95
|
+
Current: v<X.Y.Z>
|
|
96
|
+
Latest: v<A.B.C> (delta: <major|minor|patch|off-cadence|none>)
|
|
97
|
+
Newer: <true|false>
|
|
98
|
+
Checked: <ISO time of checked_at>
|
|
99
|
+
Dismissed: <tag or "no">
|
|
100
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
101
|
+
```
|
|
102
|
+
Parse these fields from `.design/update-cache.json` using `grep + sed` (no jq dependency). Read dismissal from `.design/config.json` via the same pattern as hooks/update-check.sh:
|
|
103
|
+
```bash
|
|
104
|
+
[ -f .design/config.json ] && grep -E '"update_dismissed"' .design/config.json | sed -E 's/.*"update_dismissed"[[:space:]]*:[[:space:]]*"([^"]+)".*/\1/'
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
6. **--prompt path** (if `--prompt` in flags):
|
|
108
|
+
Spawn the `design-update-checker` agent via the Task tool. Pass as context:
|
|
109
|
+
- `current_tag` — from `.design/update-cache.json`
|
|
110
|
+
- `latest_tag` — from `.design/update-cache.json`
|
|
111
|
+
- `delta` — from `.design/update-cache.json`
|
|
112
|
+
- `release_body` — the `changelog_excerpt` from the cache (may be pre-truncated to 500 chars; that's fine — the agent knows)
|
|
113
|
+
|
|
114
|
+
Display the agent's inline response verbatim below the state banner. The agent ends with `## UPDATE-CHECKER COMPLETE` — the skill's own completion marker (below) is the final line.
|
|
115
|
+
|
|
116
|
+
## Defaults
|
|
117
|
+
|
|
118
|
+
- No flags → behave as: `--refresh (only if cache >24h old) → print state`. Silent no-op if cache is fresh and there is no newer version.
|
|
119
|
+
|
|
120
|
+
## Do Not
|
|
121
|
+
|
|
122
|
+
- Do not fetch from GitHub in this skill directly — always go through `hooks/update-check.sh --refresh` so the caching + state-guard + dismissal logic stays in one place.
|
|
123
|
+
- Do not modify `.design/update-available.md` except to delete it on `--dismiss`. The hot-path hook is the only writer of that banner (D-06).
|
|
124
|
+
- Do not rewrite `.design/config.json` wholesale — the atomic python rewrite preserves every unknown key (D-14).
|
|
125
|
+
- Do not pass variables to the python heredoc via trailing `KEY=VALUE` argv — that assigns to `sys.argv`, not `os.environ`. Use env-prefix form only.
|
|
126
|
+
|
|
127
|
+
## Completion marker
|
|
128
|
+
|
|
129
|
+
Last line of output:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
## CHECK-UPDATE COMPLETE
|
|
133
|
+
```
|
|
@@ -30,4 +30,14 @@ Closes the current cycle: marks CYCLES.md entry complete, archives pipeline arti
|
|
|
30
30
|
- Do not delete source files in `src/` — only archive `.design/` artifacts.
|
|
31
31
|
- Do not auto-start a new cycle — user invokes `/gdd:new-cycle` explicitly.
|
|
32
32
|
|
|
33
|
+
## Step 6 — Update notice (post-closeout surface)
|
|
34
|
+
|
|
35
|
+
After the archive has been written and STATE.md has been cleared for the next cycle, emit the plugin-update banner if one is present:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
[ -f .design/update-available.md ] && cat .design/update-available.md
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Written by `hooks/update-check.sh`; suppressed mid-pipeline and when the latest release is dismissed.
|
|
42
|
+
|
|
33
43
|
## COMPLETE-CYCLE COMPLETE
|
package/skills/design/SKILL.md
CHANGED
|
@@ -41,7 +41,7 @@ Skip if `auto_mode=true`.
|
|
|
41
41
|
|
|
42
42
|
## Pre-execution — Project-local conventions
|
|
43
43
|
|
|
44
|
-
When spawning the executor, include any `./.claude/skills/design-*-conventions.md` files in `<required_reading>` so the executor sees project-local design conventions (typography, color, layout, motion, component, interaction decisions codified from prior sketch wrap-ups). Also include any `~/.claude/gdd/global-skills/*.md` files if the directory exists � global skills are cross-project conventions that inform but do not override project-local D-XX decisions.
|
|
44
|
+
When spawning the executor, include any `./.claude/skills/design-*-conventions.md` files in `<required_reading>` so the executor sees project-local design conventions (typography, color, layout, motion, component, interaction decisions codified from prior sketch wrap-ups). Also include any `~/.claude/gdd/global-skills/*.md` files if the directory exists � global skills are cross-project conventions that inform but do not override project-local D-XX decisions.
|
|
45
45
|
|
|
46
46
|
---
|
|
47
47
|
|
|
@@ -256,13 +256,13 @@ Next: /get-design-done:verify
|
|
|
256
256
|
|
|
257
257
|
After design-executor has finished and DESIGN-PLAN.md tasks are complete:
|
|
258
258
|
|
|
259
|
-
1. Read `
|
|
260
|
-
- If `
|
|
261
|
-
- If `
|
|
259
|
+
1. Read `figma:` status from `.design/STATE.md` `<connections>` (the unified remote MCP covers both reads and writes as of v1.0.7.1):
|
|
260
|
+
- If `figma: not_configured` or `figma: unavailable` or absent → skip this block entirely (no prompt, no output)
|
|
261
|
+
- If `figma: available` → proceed to step 2
|
|
262
262
|
|
|
263
263
|
2. Offer the user a prompt:
|
|
264
264
|
```
|
|
265
|
-
figma-
|
|
265
|
+
figma write-back is available — propagate design decisions back to Figma?
|
|
266
266
|
Modes: annotate (layer comments) | tokenize (variable bindings) | mappings (Code Connect)
|
|
267
267
|
Run figma-write? (y/N):
|
|
268
268
|
```
|
package/skills/discover/SKILL.md
CHANGED
|
@@ -22,9 +22,9 @@ user-invocable: true
|
|
|
22
22
|
**A — Figma probe:**
|
|
23
23
|
|
|
24
24
|
```
|
|
25
|
-
A1. ToolSearch({ query: "select:
|
|
25
|
+
A1. ToolSearch({ query: "select:mcp__figma__get_metadata", max_results: 1 })
|
|
26
26
|
A2. Empty result → figma: not_configured (skip all Figma paths)
|
|
27
|
-
Non-empty result → call
|
|
27
|
+
Non-empty result → call mcp__figma__get_metadata
|
|
28
28
|
Success → figma: available
|
|
29
29
|
Error → figma: unavailable
|
|
30
30
|
```
|
package/skills/explore/SKILL.md
CHANGED
|
@@ -19,9 +19,9 @@ Probe connection availability and update `.design/STATE.md` `<connections>`:
|
|
|
19
19
|
|
|
20
20
|
**A — Figma probe:**
|
|
21
21
|
```
|
|
22
|
-
ToolSearch({ query: "select:
|
|
22
|
+
ToolSearch({ query: "select:mcp__figma__get_metadata", max_results: 1 })
|
|
23
23
|
Empty → figma: not_configured
|
|
24
|
-
Non-empty → call
|
|
24
|
+
Non-empty → call mcp__figma__get_metadata; success → available; error → unavailable
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
**B — Refero probe:**
|
package/skills/health/SKILL.md
CHANGED
|
@@ -45,4 +45,14 @@ Health: 5 / 6 checks passing.
|
|
|
45
45
|
━━━━━━━━━━━━━━━━━━━━━
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
## Update notice (safe-window surface)
|
|
49
|
+
|
|
50
|
+
After the health table, emit the plugin-update banner if one is present:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
[ -f .design/update-available.md ] && cat .design/update-available.md
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Written by `hooks/update-check.sh`; suppressed mid-pipeline and when the latest release is dismissed.
|
|
57
|
+
|
|
48
58
|
## HEALTH COMPLETE
|
package/skills/help/SKILL.md
CHANGED
|
@@ -73,4 +73,14 @@ Lifecycle:
|
|
|
73
73
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
+
## Update notice (safe-window surface)
|
|
77
|
+
|
|
78
|
+
After the command reference, emit the plugin-update banner if one is present:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
[ -f .design/update-available.md ] && cat .design/update-available.md
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Written by `hooks/update-check.sh`; suppressed mid-pipeline and when the latest release is dismissed.
|
|
85
|
+
|
|
76
86
|
## HELP COMPLETE
|
package/skills/progress/SKILL.md
CHANGED
|
@@ -57,4 +57,14 @@ Seeds ready: 0
|
|
|
57
57
|
━━━━━━━━━━━━━━━━━━━━━━
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
+
## Step 4 — Update notice (safe-window surface)
|
|
61
|
+
|
|
62
|
+
After printing the pipeline state, emit the plugin-update banner if one is present. This file is written by `hooks/update-check.sh` subject to the state-machine guard (mid-pipeline stages suppress it) and per-version dismissal.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
[ -f .design/update-available.md ] && cat .design/update-available.md
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
No-op when: no new release exists, state-machine guard is active (stage in plan|design|verify), or the latest tag has been dismissed via `/gdd:check-update --dismiss`.
|
|
69
|
+
|
|
60
70
|
## PROGRESS COMPLETE
|
package/skills/reflect/SKILL.md
CHANGED
|
@@ -27,6 +27,7 @@ Run `design-reflector` on demand against the current (or specified) cycle. Produ
|
|
|
27
27
|
.design/agent-metrics.json
|
|
28
28
|
.design/learnings/question-quality.jsonl
|
|
29
29
|
.design/cycles/<slug>/CYCLE-SUMMARY.md
|
|
30
|
+
.design/authority-report.md
|
|
30
31
|
```
|
|
31
32
|
Use the resolved slug where `<slug>` appears.
|
|
32
33
|
|
package/skills/scan/SKILL.md
CHANGED
|
@@ -39,17 +39,17 @@ At scan entry, before running any step:
|
|
|
39
39
|
|
|
40
40
|
Run both probes below. MCP tools may be in the deferred tool set — **always call ToolSearch first**; without it, a deferred tool invocation fails silently.
|
|
41
41
|
|
|
42
|
-
**Figma probe:**
|
|
42
|
+
**Figma probe (single probe covers both reads and writes — remote MCP exposes `get_metadata`, `get_variable_defs`, `use_figma` on the same server):**
|
|
43
43
|
|
|
44
44
|
```
|
|
45
45
|
Step A1 — ToolSearch check:
|
|
46
|
-
ToolSearch({ query: "select:
|
|
46
|
+
ToolSearch({ query: "select:mcp__figma__get_metadata", max_results: 1 })
|
|
47
47
|
→ Empty result → figma: not_configured (skip all Figma steps)
|
|
48
48
|
→ Non-empty result → proceed to Step A2
|
|
49
49
|
|
|
50
50
|
Step A2 — Live tool call:
|
|
51
|
-
call
|
|
52
|
-
→ Success → figma: available
|
|
51
|
+
call mcp__figma__get_metadata
|
|
52
|
+
→ Success → figma: available (reads AND use_figma writes both available)
|
|
53
53
|
→ Error → figma: unavailable (skip all Figma steps)
|
|
54
54
|
```
|
|
55
55
|
|
|
@@ -66,7 +66,9 @@ Note: scan probes **both** connections because the State Integration block is th
|
|
|
66
66
|
|
|
67
67
|
### Phase 8 Connection Probes
|
|
68
68
|
|
|
69
|
-
Run all
|
|
69
|
+
Run all 4 Phase 8 probes at scan entry. Results are written to STATE.md `<connections>` so downstream stages (verify, compare, darkmode, plan, design) do not re-probe unless needed.
|
|
70
|
+
|
|
71
|
+
Note: as of v1.0.7.1, Figma is a single connection (`figma:` key) covering reads + writes — no separate `figma_writer:` probe. The Wave A Figma probe above is the sole Figma availability check.
|
|
70
72
|
|
|
71
73
|
**preview:**
|
|
72
74
|
|
|
@@ -118,17 +120,6 @@ Step C2 — Token check:
|
|
|
118
120
|
Write: chromatic: <status> to STATE.md <connections>
|
|
119
121
|
```
|
|
120
122
|
|
|
121
|
-
**figma_writer:**
|
|
122
|
-
|
|
123
|
-
```
|
|
124
|
-
ToolSearch({ query: "select:mcp__figma__use_figma", max_results: 1 })
|
|
125
|
-
→ Empty result → figma_writer: not_configured
|
|
126
|
-
→ Non-empty result → figma_writer: available
|
|
127
|
-
|
|
128
|
-
Write: figma_writer: <status> to STATE.md <connections>
|
|
129
|
-
Note: ToolSearch-only probe (same pattern as Refero). No live call at scan time.
|
|
130
|
-
```
|
|
131
|
-
|
|
132
123
|
**graphify:**
|
|
133
124
|
|
|
134
125
|
```
|
|
@@ -145,7 +136,7 @@ Step G2 — Graph file check:
|
|
|
145
136
|
Write: graphify: <status> to STATE.md <connections>
|
|
146
137
|
```
|
|
147
138
|
|
|
148
|
-
After all
|
|
139
|
+
After all 4 probes, STATE.md `<connections>` contains all 4 status entries (plus the Wave A `figma:` and `refero:` probes = 6 total entries). Downstream plans (08-02 through 08-05) read these values without re-probing.
|
|
149
140
|
|
|
150
141
|
### Write STATE.md
|
|
151
142
|
|
|
@@ -158,7 +149,6 @@ refero: <available | not_configured>
|
|
|
158
149
|
preview: <available | unavailable | not_configured>
|
|
159
150
|
storybook: <available | unavailable | not_configured>
|
|
160
151
|
chromatic: <available | unavailable | not_configured>
|
|
161
|
-
figma_writer: <available | not_configured>
|
|
162
152
|
graphify: <available | unavailable | not_configured>
|
|
163
153
|
</connections>
|
|
164
154
|
```
|
|
@@ -238,7 +228,7 @@ Produce a color inventory table:
|
|
|
238
228
|
|
|
239
229
|
### If `figma: available`
|
|
240
230
|
|
|
241
|
-
Call `
|
|
231
|
+
Call `mcp__figma__get_variable_defs` (no arguments — returns all variables in the active Figma file).
|
|
242
232
|
|
|
243
233
|
> If no Figma file is open, the call errors. Treat any error as a graceful skip: update STATE.md `<connections>` to `figma: unavailable` and continue with Step 2 results only.
|
|
244
234
|
|
package/skills/ship/SKILL.md
CHANGED
|
@@ -28,4 +28,14 @@ Closes the verify → merge gap: runs `/gdd:pr-branch` for a clean branch, assem
|
|
|
28
28
|
- Do not include `.design/` or `.planning/` files in the PR branch — that is `/gdd:pr-branch`'s job.
|
|
29
29
|
- Do not skip the verify pre-flight silently — always surface a failure and ask.
|
|
30
30
|
|
|
31
|
+
## Step 7 — Update notice (post-closeout surface)
|
|
32
|
+
|
|
33
|
+
ONLY on the success path — after the PR has been created and the URL has been printed — emit the plugin-update banner. If PR creation failed earlier, skip this step (do not suggest upgrades in the middle of a PR-creation failure).
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
[ -f .design/update-available.md ] && cat .design/update-available.md
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Written by `hooks/update-check.sh`; suppressed mid-pipeline and when the latest release is dismissed.
|
|
40
|
+
|
|
31
41
|
## SHIP COMPLETE
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gdd-watch-authorities
|
|
3
|
+
description: "Fetches the design-authority feed whitelist, diffs against .design/authority-snapshot.json, and writes .design/authority-report.md (consumed by /gdd:reflect). Authority monitoring only — no trend-watching."
|
|
4
|
+
argument-hint: "[--refresh] [--since <date>] [--feed <name>] [--schedule <weekly|daily|monthly>]"
|
|
5
|
+
tools: Read, Write, Task, Bash
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# /gdd:watch-authorities
|
|
9
|
+
|
|
10
|
+
Runs `design-authority-watcher` on demand. Fetches the curated design-authority feed whitelist, diffs against the prior snapshot, classifies new entries into five buckets, and writes `.design/authority-report.md`. Phase 11's reflector picks up the report automatically when you next run `/gdd:reflect`.
|
|
11
|
+
|
|
12
|
+
Authority-monitoring only. Not trend-watching. See `reference/authority-feeds.md` §"Rejected kinds" for what this skill will never fetch.
|
|
13
|
+
|
|
14
|
+
## Steps
|
|
15
|
+
|
|
16
|
+
1. **Parse args.** Extract optional flags: `--refresh`, `--since <date>`, `--feed <name>`, `--schedule <cadence>`. Anything that doesn't match one of these is an error — print `Unknown flag: <arg>. Valid flags: --refresh --since <date> --feed <name> --schedule <weekly|daily|monthly>.` and STOP.
|
|
17
|
+
|
|
18
|
+
Mutual exclusion rules:
|
|
19
|
+
- `--schedule` is handled entirely by this skill — it does not combine with the other three. If `--schedule` is present alongside any of `--refresh | --since | --feed`, print `--schedule cannot combine with other flags. Schedule registration runs this skill with no flags at the configured cadence.` and STOP.
|
|
20
|
+
- `--refresh` and `--since` are mutually exclusive — print `--refresh and --since are mutually exclusive. --refresh re-seeds the snapshot silently; --since surfaces a backlog from a boundary date. Pick one.` and STOP.
|
|
21
|
+
|
|
22
|
+
2. **Handle `--schedule <cadence>` branch** (early-return).
|
|
23
|
+
|
|
24
|
+
If `--schedule` is set:
|
|
25
|
+
- Validate cadence ∈ {`weekly`, `daily`, `monthly`}; else print `Unknown cadence: <value>. Use one of: weekly, daily, monthly.` and STOP.
|
|
26
|
+
- Probe for the scheduled-tasks MCP via ToolSearch:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
ToolSearch({ query: "scheduled-tasks", max_results: 3 })
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
- If the probe returns an empty result set: print `scheduled-tasks MCP not connected. Install it with: claude mcp add scheduled-tasks ... then retry with --schedule.` — this is a documented fallback (not an error). Terminate with `## WATCH COMPLETE` and exit 0.
|
|
33
|
+
- If the probe returns one or more `scheduled-tasks` tools: register the cron. Discover the MCP's registration tool name at runtime from the ToolSearch result and follow its schema. Target command: `/gdd:watch-authorities` with NO flags (the cron invokes the default diff-and-report behavior). Cadence → cron expression mapping:
|
|
34
|
+
- `weekly` → `0 9 * * 1` (Mondays 09:00 local)
|
|
35
|
+
- `daily` → `0 9 * * *` (every day 09:00 local)
|
|
36
|
+
- `monthly` → `0 9 1 * *` (1st of each month 09:00 local)
|
|
37
|
+
- After registration: print `Scheduled /gdd:watch-authorities to run <cadence>.` and terminate with `## WATCH COMPLETE`.
|
|
38
|
+
|
|
39
|
+
3. **Validate `--since <date>`** (if present).
|
|
40
|
+
|
|
41
|
+
Accept ISO8601 (`YYYY-MM-DD` or `YYYY-MM-DDTHH:MM:SSZ`). Sanity-check via Bash `date -d "<value>" +%s` (GNU) or the POSIX equivalent `python3 -c "from datetime import datetime; datetime.fromisoformat('<value>'.replace('Z','+00:00'))"`. On parse failure: print `Invalid --since value: <value>. Use ISO8601 (YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ).` and STOP.
|
|
42
|
+
|
|
43
|
+
If the parsed date is earlier than `2020-01-01`, ask: `Very old --since value: <value>. Did you mean something more recent? Proceed? [y/N]`. On anything other than `y`/`Y`, STOP.
|
|
44
|
+
|
|
45
|
+
4. **Spawn the watcher.**
|
|
46
|
+
|
|
47
|
+
Build the `Task(subagent_type="design-authority-watcher", ...)` prompt. The prompt supplies the agent's required-reading block (watcher step 0), echoes the invocation flags verbatim (watcher Flags section), and instructs the agent to follow its own fetch/diff/classify/write loop:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
Task("design-authority-watcher", """
|
|
51
|
+
<required_reading>
|
|
52
|
+
@reference/authority-feeds.md
|
|
53
|
+
@.design/authority-snapshot.json
|
|
54
|
+
@.design/STATE.md
|
|
55
|
+
</required_reading>
|
|
56
|
+
|
|
57
|
+
Invocation flags: <joined flag list or "none">
|
|
58
|
+
|
|
59
|
+
Fetch the feeds listed in reference/authority-feeds.md, diff against .design/authority-snapshot.json,
|
|
60
|
+
classify new entries per the D-17 decision table, write .design/authority-snapshot.json and
|
|
61
|
+
.design/authority-report.md.
|
|
62
|
+
|
|
63
|
+
Terminate with ## WATCH COMPLETE.
|
|
64
|
+
""")
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`<joined flag list>` is the subset of `--refresh | --since <date> | --feed <name>` actually passed — e.g., `--refresh`, `--since 2026-03-01`, `--feed wai-aria-apg`, `--refresh --feed radix-ui-releases`, or literally `none` when no flags were supplied.
|
|
68
|
+
|
|
69
|
+
5. **Print summary.**
|
|
70
|
+
|
|
71
|
+
After the agent returns:
|
|
72
|
+
- If STATE.md gained a `<blocker type="contract-violation">` on this run (snapshot version mismatch, hash-format violation, or over-200 entries per feed), surface the blocker verbatim and stop — do not print the default "review and reflect" line.
|
|
73
|
+
- Otherwise print the agent's one-line stdout summary (normal mode: `Surfaced N entries across M feeds. K skipped. See .design/authority-report.md.`; first-run / refresh mode: `Seeded snapshot for N feeds — next run will surface new entries.`) followed by: `Review and reflect: /gdd:reflect`.
|
|
74
|
+
|
|
75
|
+
6. **Terminate with `## WATCH COMPLETE`.**
|
|
76
|
+
|
|
77
|
+
## Do Not
|
|
78
|
+
|
|
79
|
+
- Do not modify `agents/design-authority-watcher.md`.
|
|
80
|
+
- Do not modify `agents/design-reflector.md` — Phase 13.2 does not touch the reflector agent (CONTEXT.md D-25).
|
|
81
|
+
- Do not write to `.design/authority-snapshot.json` or `.design/authority-report.md` directly — those are the agent's writes.
|
|
82
|
+
- Do not fetch URLs outside `reference/authority-feeds.md`. The whitelist is the allow-list.
|
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
# Figma Writer — Connection Specification
|
|
2
|
-
|
|
3
|
-
This file is the connection specification for the figma-writer capability within the get-design-done pipeline. The figma-writer is a proposal→confirm write agent (`design-figma-writer`) that wraps the `mcp__figma__use_figma` remote MCP to write design decisions back to Figma. It is distinct from the Figma Desktop MCP read connection documented in `connections/figma.md`. See `connections/connections.md` for the full connection index and capability matrix.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Setup
|
|
8
|
-
|
|
9
|
-
**Prerequisites:**
|
|
10
|
-
|
|
11
|
-
- Figma desktop app installed and running (required for read operations via `mcp__figma-desktop__*`)
|
|
12
|
-
- Dev Mode enabled in the Figma desktop app
|
|
13
|
-
- Remote Figma MCP registered for write operations
|
|
14
|
-
|
|
15
|
-
**Register remote MCP (Claude Code):**
|
|
16
|
-
|
|
17
|
-
```
|
|
18
|
-
claude mcp add figma --transport http https://mcp.figma.com/v1/sse
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
After running this command, restart the Claude Code session. The remote MCP server authenticates via OAuth at `mcp.figma.com`. On first use, Claude Code will prompt you to complete the OAuth flow.
|
|
22
|
-
|
|
23
|
-
**Verification:**
|
|
24
|
-
|
|
25
|
-
After session restart, run:
|
|
26
|
-
|
|
27
|
-
```
|
|
28
|
-
ToolSearch({ query: "select:mcp__figma__use_figma", max_results: 1 })
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Expect a non-empty result listing `mcp__figma__use_figma`. If empty, the remote MCP is not registered — run the registration command above and restart.
|
|
32
|
-
|
|
33
|
-
---
|
|
34
|
-
|
|
35
|
-
## Tools
|
|
36
|
-
|
|
37
|
-
All write operations use the `mcp__figma__` prefix (remote MCP). Read operations use the `mcp__figma-desktop__` prefix (desktop MCP).
|
|
38
|
-
|
|
39
|
-
| Tool | Full name | Returns | Pipeline use |
|
|
40
|
-
|------|-----------|---------|--------------|
|
|
41
|
-
| `use_figma` | `mcp__figma__use_figma` | operation result | all write operations (annotate, tokenize, mappings) |
|
|
42
|
-
|
|
43
|
-
**Important distinction:** `mcp__figma-desktop__*` tools are used for reads only (get_metadata, get_variable_defs). `mcp__figma__use_figma` is the remote MCP used exclusively for writes. The desktop MCP does NOT expose `use_figma` — it is remote-only. Do not attempt to call `mcp__figma-desktop__use_figma` — that tool does not exist.
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## Three Modes
|
|
48
|
-
|
|
49
|
-
The figma-writer operates in one of three modes per invocation:
|
|
50
|
-
|
|
51
|
-
| Mode | Description | Source data | Figma target |
|
|
52
|
-
|------|-------------|-------------|--------------|
|
|
53
|
-
| `annotate` | Write design decision annotations onto Figma layer comments | D-XX decisions from DESIGN-CONTEXT.md | Layer comments on affected frames/components |
|
|
54
|
-
| `tokenize` | Replace hard-coded color/spacing/type literals with Figma variable references | Color/spacing/typography values from DESIGN-CONTEXT.md; existing variables from `get_variable_defs` | Variable bindings on layer fill/stroke/spacing properties |
|
|
55
|
-
| `mappings` | Write Code Connect mappings linking component instances to code file paths | Component names and file paths from DESIGN-CONTEXT.md | Code Connect entries on Figma component nodes |
|
|
56
|
-
|
|
57
|
-
All three modes follow the proposal→confirm UX: the agent builds a numbered operation list and presents it to the user before executing any write. The user must confirm before `use_figma` is called.
|
|
58
|
-
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
## Which Stages Use This Connection
|
|
62
|
-
|
|
63
|
-
| Stage | Agent/Skill | Tool used | Purpose |
|
|
64
|
-
|-------|-------------|-----------|---------|
|
|
65
|
-
| figma-write | `agents/design-figma-writer.md` | `mcp__figma__use_figma` | Write design decisions back to Figma in three modes (annotate/tokenize/mappings) |
|
|
66
|
-
| design | `skills/design/SKILL.md` | (dispatch only) | Offer to spawn design-figma-writer after design-executor completes, when figma_writer: available |
|
|
67
|
-
|
|
68
|
-
---
|
|
69
|
-
|
|
70
|
-
## Availability Probe (ToolSearch-only)
|
|
71
|
-
|
|
72
|
-
The figma-writer probe is ToolSearch-only — no live call at probe time. This matches the Refero connection pattern (opt-in tool, no live call needed to confirm availability).
|
|
73
|
-
|
|
74
|
-
```
|
|
75
|
-
ToolSearch({ query: "select:mcp__figma__use_figma", max_results: 1 })
|
|
76
|
-
→ Empty result → figma_writer: not_configured (skip figma-write entirely; log to STATE.md)
|
|
77
|
-
→ Non-empty result → figma_writer: available
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Write `figma_writer:` status to `.design/STATE.md` `<connections>` immediately after probing.
|
|
81
|
-
|
|
82
|
-
Note: The status key is `figma_writer:` (with underscore). This is distinct from `figma:` (desktop MCP status) and `figma_write:` is not used — the canonical key is `figma_writer:`.
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## Fallback Behavior
|
|
87
|
-
|
|
88
|
-
When `figma_writer` is `not_configured`, the pipeline degrades gracefully — no error is raised.
|
|
89
|
-
|
|
90
|
-
**figma-write stage:**
|
|
91
|
-
- `figma_writer: not_configured` → skip with note: "Figma write skipped — remote MCP not installed. Register with: claude mcp add figma --transport http https://mcp.figma.com/v1/sse"
|
|
92
|
-
|
|
93
|
-
**design stage:**
|
|
94
|
-
- `figma_writer: not_configured` or absent → skip the figma-write dispatch offer entirely (no prompt, no output)
|
|
95
|
-
- `figma_writer: available` → offer opt-in prompt after design-executor completes
|
|
96
|
-
|
|
97
|
-
**Special case — desktop MCP present but remote absent:**
|
|
98
|
-
If `figma: available` (desktop MCP) but `figma_writer: not_configured` (remote MCP absent), the figma-write capability is still not available. Desktop MCP cannot perform writes. Do not offer figma-write dispatch in this state.
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
## STATE.md Integration
|
|
103
|
-
|
|
104
|
-
The scan stage writes the initial `figma_writer:` status. Subsequent stages read from STATE.md without re-probing.
|
|
105
|
-
|
|
106
|
-
Example `<connections>` block after probing:
|
|
107
|
-
|
|
108
|
-
```xml
|
|
109
|
-
<connections>
|
|
110
|
-
figma: available
|
|
111
|
-
figma_writer: available
|
|
112
|
-
refero: not_configured
|
|
113
|
-
</connections>
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
**Status key:** `figma_writer:` (underscore separator)
|
|
117
|
-
|
|
118
|
-
**Status values:**
|
|
119
|
-
|
|
120
|
-
| Value | Meaning |
|
|
121
|
-
|-------|---------|
|
|
122
|
-
| `available` | ToolSearch returned non-empty for `mcp__figma__use_figma` |
|
|
123
|
-
| `not_configured` | ToolSearch returned empty — remote MCP not registered |
|
|
124
|
-
|
|
125
|
-
Note: There is no `unavailable` state for figma_writer — the ToolSearch-only probe cannot detect auth failures. Auth issues surface at execution time when `use_figma` is first called.
|
|
126
|
-
|
|
127
|
-
---
|
|
128
|
-
|
|
129
|
-
## Caveats and Pitfalls
|
|
130
|
-
|
|
131
|
-
1. **`mcp__figma__use_figma` is the remote MCP only.** It is registered as server `figma` via `claude mcp add`. It is NOT the same as the desktop MCP (`mcp__figma-desktop__*`). Running ToolSearch for `figma-desktop` will NOT find `use_figma`. Always use `select:mcp__figma__use_figma` as the probe query.
|
|
132
|
-
|
|
133
|
-
2. **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.
|
|
134
|
-
|
|
135
|
-
3. **Use `--dry-run` to inspect the proposal without risk.** Pass `--dry-run` to emit the full operation list without calling `use_figma`. Safe to run on production Figma files.
|
|
136
|
-
|
|
137
|
-
4. **Use `--confirm-shared` for team library components.** Before any write, the agent detects shared team library components via `get_metadata`. If shared components are in the operation list and `--confirm-shared` was not passed, the agent halts and requires the flag. This prevents accidental modification of team-wide design tokens.
|
|
138
|
-
|
|
139
|
-
5. **Operations execute sequentially, not atomically.** If one operation fails mid-sequence, the agent logs the error and continues with remaining operations. The Figma file may be left in a partially-updated state. The summary lists all failures for manual follow-up.
|