@hegemonart/get-design-done 1.14.7 → 1.15.0
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 +14 -2
- package/CHANGELOG.md +84 -0
- package/README.md +18 -0
- package/SKILL.md +2 -0
- package/agents/a11y-mapper.md +25 -0
- package/agents/design-auditor.md +92 -8
- package/agents/design-context-builder.md +6 -0
- package/agents/design-executor.md +5 -2
- package/agents/design-pattern-mapper.md +2 -0
- package/agents/design-start-writer.md +221 -0
- package/agents/design-verifier.md +11 -0
- package/agents/motion-mapper.md +45 -0
- package/agents/token-mapper.md +36 -0
- package/agents/visual-hierarchy-mapper.md +29 -0
- package/hooks/first-run-nudge.sh +82 -0
- package/hooks/hooks.json +8 -0
- package/package.json +14 -2
- package/reference/anti-patterns.md +69 -0
- package/reference/audit-scoring.md +34 -3
- package/reference/brand-voice.md +199 -0
- package/reference/checklists.md +30 -3
- package/reference/data/google-fonts.csv +51 -0
- package/reference/data/palettes.csv +41 -0
- package/reference/data/styles.csv +39 -0
- package/reference/design-system-guidance.md +177 -0
- package/reference/design-systems-catalog.md +151 -0
- package/reference/framer-motion-patterns.md +411 -0
- package/reference/gestalt.md +219 -0
- package/reference/iconography.md +231 -0
- package/reference/motion.md +102 -0
- package/reference/palette-catalog.md +82 -0
- package/reference/performance.md +304 -0
- package/reference/registry.json +257 -27
- package/reference/review-format.md +2 -2
- package/reference/start-interview.md +84 -0
- package/reference/style-vocabulary.md +62 -0
- package/reference/surfaces.md +114 -0
- package/reference/typography.md +80 -0
- package/reference/visual-hierarchy-layout.md +306 -0
- package/scripts/lib/detect-ui-root.cjs +187 -0
- package/scripts/lib/start-findings-engine.cjs +405 -0
- package/skills/start/SKILL.md +166 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-start-writer
|
|
3
|
+
description: "Writes .design/START-REPORT.md — 7 fixed sections plus a machine-readable JSON block. Consumes the findings-engine output, interview answers, and detection result from .design/.start-context.json. Never writes STATE.md. Parameter-free: reads the context JSON path from the prompt and emits the report."
|
|
4
|
+
tools: Read, Write, Grep, Glob
|
|
5
|
+
color: green
|
|
6
|
+
|
|
7
|
+
model: haiku
|
|
8
|
+
default-tier: haiku
|
|
9
|
+
tier-rationale: "Formatting + light synthesis over a bounded ~3KB input; Haiku is the correct tier per Phase 10.1 D-14 (Haiku = writers/formatters with fixed schemas)."
|
|
10
|
+
|
|
11
|
+
parallel-safe: always
|
|
12
|
+
typical-duration-seconds: 10
|
|
13
|
+
reads-only: false
|
|
14
|
+
writes:
|
|
15
|
+
- ".design/START-REPORT.md"
|
|
16
|
+
|
|
17
|
+
allowed-read-paths:
|
|
18
|
+
- ".design/.start-context.json"
|
|
19
|
+
- ".design/START-REPORT.md"
|
|
20
|
+
allowed-write-paths:
|
|
21
|
+
- ".design/START-REPORT.md"
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Role
|
|
25
|
+
|
|
26
|
+
Write `.design/START-REPORT.md` for `/gdd:start`. The report is the single artifact the user sees after a first-run scan. It must feel like GDD understood the project, not like it printed a generic checklist. One best_first_proof, one suggested next command, no ambiguity.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Required Reading
|
|
31
|
+
|
|
32
|
+
- `.design/.start-context.json` — produced by `skills/start/SKILL.md` before spawning this agent. Contains detection result, interview answers, and the findings-engine output.
|
|
33
|
+
|
|
34
|
+
## Inputs
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"schema_version": "1.0",
|
|
39
|
+
"detected": {
|
|
40
|
+
"kind": "next-app-router | src-components | monorepo-ui-pkg | ...",
|
|
41
|
+
"path": "relative/path/to/components",
|
|
42
|
+
"framework": "next | vite | cra | ...",
|
|
43
|
+
"design_system": "tailwind | css-modules | ...",
|
|
44
|
+
"confidence": 0.85
|
|
45
|
+
},
|
|
46
|
+
"interview": {
|
|
47
|
+
"pain": "free text or empty",
|
|
48
|
+
"target_area": "relative/path",
|
|
49
|
+
"budget": "fast | balanced | thorough",
|
|
50
|
+
"framework_confirmed": true,
|
|
51
|
+
"design_system_confirmed": true,
|
|
52
|
+
"figma_workflow": "figma | canvas | neither | skip"
|
|
53
|
+
},
|
|
54
|
+
"scan": {
|
|
55
|
+
"findings": [{"id":"F1","category":"transition-all","title":"...","file":"...","line":123,"severity":"minor","evidence":"...","visibleDelta":true,"blastRadius":"single-file"}],
|
|
56
|
+
"bestFirstProofId": "F1",
|
|
57
|
+
"partial": false,
|
|
58
|
+
"inspected": {"files": 42, "root": "..."}
|
|
59
|
+
},
|
|
60
|
+
"generated_at": "2026-04-24T01:00:00Z"
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Output contract
|
|
67
|
+
|
|
68
|
+
Write `.design/START-REPORT.md` exactly matching this shape. **All seven H2 sections must be present, in this order, even if empty.** The JSON block at the very end is mandatory.
|
|
69
|
+
|
|
70
|
+
```markdown
|
|
71
|
+
# GDD First-Run Report
|
|
72
|
+
|
|
73
|
+
> Generated <generated_at> by `/gdd:start`. This report does not start a pipeline cycle — it is a 0→1 proof path. Run the suggested next command to continue.
|
|
74
|
+
|
|
75
|
+
## What I inspected
|
|
76
|
+
|
|
77
|
+
- **UI root:** `<detected.path>` (`<detected.kind>`, confidence `<detected.confidence>`)
|
|
78
|
+
- **Framework:** `<detected.framework>` — <one-sentence confirmation or override note>
|
|
79
|
+
- **Design system:** `<detected.design_system>` — <one-sentence note>
|
|
80
|
+
- **Files scanned:** `<scan.inspected.files>`
|
|
81
|
+
- **Pain hint:** <`interview.pain` or "none given">
|
|
82
|
+
- **Budget:** `<interview.budget>` <"(timed out — partial scan)" if `scan.partial`>
|
|
83
|
+
|
|
84
|
+
## Three findings
|
|
85
|
+
|
|
86
|
+
<For each finding F1..F3, emit:>
|
|
87
|
+
|
|
88
|
+
### <Fn> — <title>
|
|
89
|
+
|
|
90
|
+
**Severity:** `<severity>` · **Evidence:** `<file>:<line>` · **Blast radius:** `<blastRadius>`
|
|
91
|
+
|
|
92
|
+
<one-sentence plain-English rationale pointing at the evidence line>
|
|
93
|
+
|
|
94
|
+
**Fix sketch:** <one-sentence concrete fix — e.g., "Replace `transition` with `transition-transform` on the wrapper.">
|
|
95
|
+
|
|
96
|
+
<End per-finding block>
|
|
97
|
+
|
|
98
|
+
## Best first proof
|
|
99
|
+
|
|
100
|
+
**Pick:** `<bestFirstProofId>` — <re-state the finding title>
|
|
101
|
+
|
|
102
|
+
<one paragraph: why this one. Cite the rubric condition that tipped the pick — single-file, non-ambiguous, visible delta, no token migration, low blast radius. If `bestFirstProofId` is null, write: "No finding qualified for a single-command fix under the safe-fix rubric — the report recommends the pipeline entry point below instead.">
|
|
103
|
+
|
|
104
|
+
## Suggested next command
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
<exact command — one of:>
|
|
108
|
+
/gdd:fast "<concrete description of the single fix>"
|
|
109
|
+
/gdd:brief
|
|
110
|
+
/gdd:scan
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
<one-line rationale: why this command and not the others.>
|
|
114
|
+
|
|
115
|
+
## Visual Proof Readiness
|
|
116
|
+
|
|
117
|
+
| Surface | Status | Unlock |
|
|
118
|
+
|---------|--------|--------|
|
|
119
|
+
| Preview MCP | <ok \| unconfigured \| unavailable> | <`/gdd:connections preview` or "already configured"> |
|
|
120
|
+
| Storybook | <…> | <…> |
|
|
121
|
+
| Figma | <…> | <`/gdd:connections figma` or "already configured"> |
|
|
122
|
+
| Canvas (.canvas) | <…> | <…> |
|
|
123
|
+
|
|
124
|
+
<one-line note if `interview.figma_workflow` picked a specific surface — nudge toward that one first.>
|
|
125
|
+
|
|
126
|
+
## Full pipeline path
|
|
127
|
+
|
|
128
|
+
If you want more than a single fix, the full pipeline would do this on this project: `/gdd:brief` to capture the design problem, `/gdd:explore` to inventory your components and interview for context, `/gdd:plan` to decompose the work, `/gdd:design` to execute, and `/gdd:verify` to score the result. The pipeline writes `.design/STATE.md` and runs across a real design cycle.
|
|
129
|
+
|
|
130
|
+
## Connections / writeback optional
|
|
131
|
+
|
|
132
|
+
If you want to push design decisions back into Figma, paper.design, pencil.dev, or a Claude Design handoff bundle, run `/gdd:connections` to wire up the surfaces. Writeback is never required — the pipeline runs code-first by default.
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
```json
|
|
137
|
+
{
|
|
138
|
+
"schema_version": "1.0",
|
|
139
|
+
"generated_at": "<ISO-8601>",
|
|
140
|
+
"detected": {...copy verbatim from context...},
|
|
141
|
+
"findings": [...copy findings array with id, title, file, line, severity, category, blast_radius...],
|
|
142
|
+
"best_first_proof": "<bestFirstProofId or null>",
|
|
143
|
+
"suggested_command": { "kind": "fast|brief|scan", "text": "<exact command>" },
|
|
144
|
+
"visual_proof_readiness": { "preview": "...", "storybook": "...", "figma": "...", "canvas": "..." }
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Section-by-section rules
|
|
152
|
+
|
|
153
|
+
### What I inspected
|
|
154
|
+
|
|
155
|
+
- Always list the six bullets. Mark "(timed out — partial scan)" only when `scan.partial === true`.
|
|
156
|
+
- Never invent fields — only surface what is in the context JSON.
|
|
157
|
+
|
|
158
|
+
### Three findings
|
|
159
|
+
|
|
160
|
+
- Emit up to three entries. If fewer than three findings exist, emit what exists and add one italic note below: `> Only <N> finding raised — the engine did not hit its cap.`
|
|
161
|
+
- Every finding block includes the evidence file:line. No finding may omit file:line.
|
|
162
|
+
- Fix sketch is one concrete sentence — not a general principle, not a tutorial.
|
|
163
|
+
|
|
164
|
+
### Best first proof
|
|
165
|
+
|
|
166
|
+
- Reference `bestFirstProofId` exactly. If it is null, write the fallback paragraph.
|
|
167
|
+
- Cite which rubric conditions the winning finding satisfies.
|
|
168
|
+
|
|
169
|
+
### Suggested next command
|
|
170
|
+
|
|
171
|
+
- If `bestFirstProofId` is non-null → emit `/gdd:fast "<task>"` where `<task>` is a one-line description tied to the finding's fix sketch.
|
|
172
|
+
- If `bestFirstProofId` is null AND there are findings → emit `/gdd:brief` with rationale "the findings need a design decision the rubric cannot make for you."
|
|
173
|
+
- If no findings at all → emit `/gdd:scan` with rationale "this codebase looks healthy at first glance — a full audit confirms."
|
|
174
|
+
|
|
175
|
+
### Visual Proof Readiness
|
|
176
|
+
|
|
177
|
+
- Always include all four rows. Unknown surfaces default to `unconfigured`.
|
|
178
|
+
- Check `interview.figma_workflow` — if the user picked `figma`, `canvas`, or `neither`, phrase the unlock line to match.
|
|
179
|
+
|
|
180
|
+
### Full pipeline path
|
|
181
|
+
|
|
182
|
+
- Keep the paragraph short — one sentence of what the pipeline does plus the command sequence. Do not rephrase per run.
|
|
183
|
+
|
|
184
|
+
### Connections / writeback optional
|
|
185
|
+
|
|
186
|
+
- Keep the paragraph short. Never assert which surface is best; point at `/gdd:connections`.
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## JSON block
|
|
191
|
+
|
|
192
|
+
The JSON block at the bottom is the contract future `/gdd:fast` / `/gdd:do` invocations will consume. Shape:
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"schema_version": "1.0",
|
|
197
|
+
"generated_at": "ISO-8601",
|
|
198
|
+
"detected": { "root", "kind", "framework", "design_system", "confidence" },
|
|
199
|
+
"findings": [{ "id", "title", "file", "line", "severity", "category", "blast_radius" }],
|
|
200
|
+
"best_first_proof": "F1" | null,
|
|
201
|
+
"suggested_command": { "kind": "fast" | "brief" | "scan", "text": "/gdd:fast \"...\"" },
|
|
202
|
+
"visual_proof_readiness": { "preview", "storybook", "figma", "canvas" }
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
- Finding IDs stay stable `F1`..`F3`.
|
|
207
|
+
- `text` is always a ready-to-run command, single-line.
|
|
208
|
+
- All string values are JSON-safe — escape embedded quotes.
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Do Not
|
|
213
|
+
|
|
214
|
+
- Do not write `.design/STATE.md`, `.design/config.json`, or any source file.
|
|
215
|
+
- Do not invent findings that are not in the context JSON.
|
|
216
|
+
- Do not re-score or re-rank findings — the engine already picked `bestFirstProofId` deterministically.
|
|
217
|
+
- Do not add marketing prose, emojis, or playful copy.
|
|
218
|
+
- Do not emit more than three findings.
|
|
219
|
+
- Do not omit any of the seven H2 sections — even empty, they must exist for downstream regression fixtures.
|
|
220
|
+
|
|
221
|
+
## START-WRITER COMPLETE
|
|
@@ -120,6 +120,11 @@ Anti-Patterns (weight 10%):
|
|
|
120
120
|
Motion (weight 5%):
|
|
121
121
|
Score: [N]/10
|
|
122
122
|
Evidence: [easing values, reduced-motion presence, duration range]
|
|
123
|
+
|
|
124
|
+
Micro-Polish (qualitative supplement — from DESIGN-AUDIT.md Pillar 7):
|
|
125
|
+
Score: [N]/4 (not weighted into the 0–100 total; reported as supplementary signal)
|
|
126
|
+
Violations flagged: [list BAN/MIFB hits from mapper micro-polish sections]
|
|
127
|
+
Notes: [brief summary — 0 violations = clean; list categories with hits]
|
|
123
128
|
```
|
|
124
129
|
|
|
125
130
|
**Weighted total:**
|
|
@@ -128,6 +133,8 @@ Score = (Accessibility × 0.25) + (Visual Hierarchy × 0.20) + (Typography × 0.
|
|
|
128
133
|
+ (Color × 0.15) + (Layout × 0.10) + (Anti-Patterns × 0.10) + (Motion × 0.05)
|
|
129
134
|
```
|
|
130
135
|
|
|
136
|
+
Note: Micro-Polish is a qualitative supplement (drawn from DESIGN-AUDIT.md Pillar 7) and is reported alongside the weighted total but does not alter the 0–100 score. If Pillar 7 score is 1 or 2 and violations are systemic, flag as a MINOR or MAJOR gap in Phase 5.
|
|
137
|
+
|
|
131
138
|
**Delta vs baseline:**
|
|
132
139
|
```
|
|
133
140
|
Before: [baseline_score from DESIGN-CONTEXT.md]/100
|
|
@@ -149,6 +156,8 @@ Before → After
|
|
|
149
156
|
─────────────────────────────────
|
|
150
157
|
Total: [baseline]/100 → [new]/100 ([+N] improvement)
|
|
151
158
|
Grade: [before grade] → [after grade]
|
|
159
|
+
─────────────────────────────────
|
|
160
|
+
Micro-Polish (suppl.): [N]/4 — [N] violations *(not weighted)*
|
|
152
161
|
━━━━━━━━━━━━━━━━━━━━━
|
|
153
162
|
```
|
|
154
163
|
|
|
@@ -383,6 +392,7 @@ If no `.pen` files: skip silently. Print: `pencil.dev spec diff: no .pen files
|
|
|
383
392
|
|
|
384
393
|
Collect all failures from Phases 1–4:
|
|
385
394
|
- Phase 1: category scores still below 7 (despite design pass)
|
|
395
|
+
- Phase 1 (micro-polish supplement): Pillar 7 score of 1 or 2 with systemic violations → MINOR or MAJOR gap
|
|
386
396
|
- Phase 2: `✗ FAIL` must-haves
|
|
387
397
|
- Phase 3: NNG scores of 0 or 1 on any heuristic
|
|
388
398
|
- Phase 4: visual UAT `no` responses
|
|
@@ -487,6 +497,7 @@ cosmetics: N
|
|
|
487
497
|
| Anti-Patterns | [N]/10 | [N]/10 | [±N] | 10% | [N] |
|
|
488
498
|
| Motion | [N]/10 | [N]/10 | [±N] | 5% | [N] |
|
|
489
499
|
| **Total** | **[N]/100** | **[N]/100** | **[±N]** | | |
|
|
500
|
+
| Micro-Polish *(suppl.)* | [N]/4 | [N]/4 | [±N] | — | *(not weighted)* |
|
|
490
501
|
|
|
491
502
|
Grade: [before] → [after]
|
|
492
503
|
|
package/agents/motion-mapper.md
CHANGED
|
@@ -94,6 +94,51 @@ generated: [ISO 8601]
|
|
|
94
94
|
## Score
|
|
95
95
|
Reduced-motion compliance: [Full | Partial | None]
|
|
96
96
|
Motion consistency: [Consistent | Mixed | Chaotic]
|
|
97
|
+
|
|
98
|
+
## Micro-motion findings
|
|
99
|
+
|
|
100
|
+
After the standard motion inventory, emit a "Micro-motion findings" section with grep-driven hits:
|
|
101
|
+
|
|
102
|
+
### Patterns to scan for:
|
|
103
|
+
|
|
104
|
+
1. **transition:all violations**
|
|
105
|
+
- Grep: `transition:\s*all|transition-property:\s*all`
|
|
106
|
+
- Also Tailwind bare: `className="[^"]*\btransition\b[^-]` (transition class without modifier)
|
|
107
|
+
- Report: file:line, the exact declaration, fix pointer → replace with specific properties
|
|
108
|
+
|
|
109
|
+
2. **will-change:all violations**
|
|
110
|
+
- Grep: `will-change:\s*all`
|
|
111
|
+
- Report: file:line, the declaration, fix pointer → `will-change: transform`
|
|
112
|
+
|
|
113
|
+
3. **Keyframe-driven interactive elements**
|
|
114
|
+
- Grep: `animation:.*forwards|@keyframes.*\{` on elements that also have `:hover` or `:active` or `onClick`
|
|
115
|
+
- Report: these should use CSS transitions, not keyframe animations
|
|
116
|
+
|
|
117
|
+
4. **Missing AnimatePresence initial={false}**
|
|
118
|
+
- Grep: `<AnimatePresence(?![^>]*initial=\{false\})` — AnimatePresence without initial={false}
|
|
119
|
+
- Report: file:line; check if the wrapped component is persistent UI (not route-level transitions)
|
|
120
|
+
|
|
121
|
+
5. **Icon cross-fade with wrong bounce**
|
|
122
|
+
- Grep: `bounce:\s*[^0]` inside framer-motion spring config near icon-related components
|
|
123
|
+
- Report: bounce must be 0 for icon animations; non-zero bounce creates invasive pop effect
|
|
124
|
+
|
|
125
|
+
6. **scale-on-press outside canonical range**
|
|
126
|
+
- Grep: `scale.*0\.9[578]|scale.*0\.9[0-4]|whileTap.*scale.*0\.9[578]`
|
|
127
|
+
- Report: file:line; canonical press scale is 0.96 — not 0.95, 0.97, 0.98
|
|
128
|
+
|
|
129
|
+
### Output format for this section:
|
|
130
|
+
```
|
|
131
|
+
## Micro-motion findings
|
|
132
|
+
|
|
133
|
+
| Finding | File | Line | Issue | Fix |
|
|
134
|
+
|---------|------|------|-------|-----|
|
|
135
|
+
| transition:all | src/components/Button.tsx | 23 | `transition: all 200ms` | Replace with `transition: background-color 200ms, color 200ms` |
|
|
136
|
+
| ... | ... | ... | ... | ... |
|
|
137
|
+
|
|
138
|
+
Total: N violations found. (0 = clean)
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
If no violations found, emit: `## Micro-motion findings — CLEAN (0 violations)`
|
|
97
142
|
```
|
|
98
143
|
|
|
99
144
|
## Constraints
|
package/agents/token-mapper.md
CHANGED
|
@@ -94,6 +94,42 @@ figma_augmented: [true|false]
|
|
|
94
94
|
|
|
95
95
|
## Observations
|
|
96
96
|
- [Dominant color space, typography scale coherence, grid adherence]
|
|
97
|
+
|
|
98
|
+
## Micro-polish token findings
|
|
99
|
+
|
|
100
|
+
After the standard token inventory, scan and report:
|
|
101
|
+
|
|
102
|
+
1. **Tinted image outlines**
|
|
103
|
+
- Grep: `outline-(slate|zinc|neutral|gray|stone|blue|red|green|yellow|purple|orange)-\d+` on `<img>` elements
|
|
104
|
+
- Grep CSS: `img\s*\{[^}]*outline:[^}]*#[0-9a-fA-F]{3,8}`
|
|
105
|
+
- Fix: `outline: 1px solid rgba(0,0,0,0.08)` or `rgba(255,255,255,0.08)` only
|
|
106
|
+
|
|
107
|
+
2. **Shadow tokens drifting from 3-layer formula**
|
|
108
|
+
- Grep for `box-shadow` values that use a single layer or non-rgba values
|
|
109
|
+
- Flag: shadows that don't follow the 3-layer pattern (0 1px 2px / 0 4px 8px / 0 8px 16px)
|
|
110
|
+
- Report as informational (not hard violation) unless the design system has a shadow token system
|
|
111
|
+
|
|
112
|
+
3. **Missing root-level font-smoothing**
|
|
113
|
+
- Grep: `-webkit-font-smoothing` and `-moz-osx-font-smoothing`
|
|
114
|
+
- If found NOT on `:root` or `body` → flag as per-element misapplication
|
|
115
|
+
- If not found at all → flag as missing root antialiasing
|
|
116
|
+
|
|
117
|
+
4. **Missing tabular-nums on dynamic numerals**
|
|
118
|
+
- Grep for elements with className containing: `price`, `counter`, `timer`, `count`, `amount`, `balance`, `total`
|
|
119
|
+
- Check if they have `font-variant-numeric: tabular-nums` or Tailwind `tabular-nums` class
|
|
120
|
+
- Report missing instances
|
|
121
|
+
|
|
122
|
+
### Output format:
|
|
123
|
+
```
|
|
124
|
+
## Micro-polish token findings
|
|
125
|
+
|
|
126
|
+
| Finding | File | Line | Issue | Fix |
|
|
127
|
+
|---------|------|------|-------|-----|
|
|
128
|
+
| tinted-outline | ... | ... | `outline-slate-200` on img | Use `outline: 1px solid rgba(0,0,0,0.08)` |
|
|
129
|
+
| missing-tabular-nums | ... | ... | `.price` element lacks tabular-nums | Add `font-variant-numeric: tabular-nums` |
|
|
130
|
+
|
|
131
|
+
Total: N findings. (0 = clean)
|
|
132
|
+
```
|
|
97
133
|
```
|
|
98
134
|
|
|
99
135
|
## Constraints
|
|
@@ -86,6 +86,35 @@ Scale coherence: [Well-defined | Flat | Inverted | Chaotic]
|
|
|
86
86
|
|
|
87
87
|
## Score
|
|
88
88
|
Overall hierarchy health: [Well-defined | Flat | Inverted]
|
|
89
|
+
|
|
90
|
+
## Micro-polish hierarchy findings
|
|
91
|
+
|
|
92
|
+
After the standard visual hierarchy map, scan and report:
|
|
93
|
+
|
|
94
|
+
1. **Same border-radius on nested surfaces**
|
|
95
|
+
- Grep (Tailwind): look for identical `rounded-*` class on a container AND its immediate child within a padded block
|
|
96
|
+
- Grep CSS: `border-radius:\s*[0-9]+` appearing on both parent and child in the same component
|
|
97
|
+
- Fix: apply concentric formula `innerRadius = outerRadius − padding`
|
|
98
|
+
|
|
99
|
+
2. **Headings without text-wrap:balance**
|
|
100
|
+
- Grep: `<h[1-3]` elements or `.heading`, `.title` elements without `text-wrap: balance` or Tailwind `text-balance`
|
|
101
|
+
- Report: file:line; add `text-wrap: balance` to all headings
|
|
102
|
+
|
|
103
|
+
3. **Missing text-wrap:pretty on body text**
|
|
104
|
+
- Grep: `<p>`, `.body`, `.description`, `.caption` without `text-wrap: pretty` or `text-pretty`
|
|
105
|
+
- This is an informational finding (enhancement, not violation)
|
|
106
|
+
|
|
107
|
+
### Output format:
|
|
108
|
+
```
|
|
109
|
+
## Micro-polish hierarchy findings
|
|
110
|
+
|
|
111
|
+
| Finding | Severity | File | Description | Fix |
|
|
112
|
+
|---------|----------|------|-------------|-----|
|
|
113
|
+
| same-radius-nested | HIGH | ... | Card (rounded-xl) + inner button (rounded-xl) at 16px padding | inner should be rounded-none (16-16=0) |
|
|
114
|
+
| heading-no-balance | MED | ... | h2 missing text-wrap:balance | Add text-balance class |
|
|
115
|
+
|
|
116
|
+
Total: N findings.
|
|
117
|
+
```
|
|
89
118
|
```
|
|
90
119
|
|
|
91
120
|
## Constraints
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# get-design-done — first-run nudge (Phase 14.7)
|
|
3
|
+
# SessionStart hook. Silent-on-failure by policy: exits 0 on every error path.
|
|
4
|
+
# Prints exactly one restrained line pointing at /gdd:start when all gates pass,
|
|
5
|
+
# and nothing otherwise.
|
|
6
|
+
|
|
7
|
+
set -u # intentionally no -e: we want to fall through to exit 0
|
|
8
|
+
|
|
9
|
+
# Silent logger — writes nothing by default. Set GDD_NUDGE_DEBUG=1 to enable stderr.
|
|
10
|
+
log() {
|
|
11
|
+
if [ "${GDD_NUDGE_DEBUG:-0}" = "1" ]; then
|
|
12
|
+
printf '[gdd first-run-nudge] %s\n' "$*" >&2
|
|
13
|
+
fi
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
DESIGN_DIR="$(pwd)/.design"
|
|
17
|
+
STATE="${DESIGN_DIR}/STATE.md"
|
|
18
|
+
CONFIG="${DESIGN_DIR}/config.json"
|
|
19
|
+
DISMISS_FLAG="${HOME:-$USERPROFILE}/.claude/gdd-nudge-dismissed"
|
|
20
|
+
|
|
21
|
+
# Gate 1 — repo already has GDD state, suppress.
|
|
22
|
+
has_design_state() {
|
|
23
|
+
[ -f "${CONFIG}" ] || [ -f "${STATE}" ]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
# Gate 2 — per-install dismissal flag.
|
|
27
|
+
is_dismissed() {
|
|
28
|
+
[ -f "${DISMISS_FLAG}" ]
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
# Gate 3 — STATE.md stage belongs to an active pipeline window.
|
|
32
|
+
# Inherits the shape used by Phase 13.3 update-check.sh.
|
|
33
|
+
read_state_stage() {
|
|
34
|
+
[ -f "${STATE}" ] || { printf ''; return; }
|
|
35
|
+
grep -E '^stage:' "${STATE}" 2>/dev/null | head -n1 | \
|
|
36
|
+
sed -E 's/^stage:[[:space:]]*"?([^"[:space:]]+)"?.*/\1/'
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
is_active_stage() {
|
|
40
|
+
local s
|
|
41
|
+
s="$(read_state_stage)"
|
|
42
|
+
case "${s}" in
|
|
43
|
+
plan|design|verify|executing|discussing) return 0 ;;
|
|
44
|
+
*) return 1 ;;
|
|
45
|
+
esac
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# Gate 4 — recent session history has a gdd:* command. We cannot reliably read
|
|
49
|
+
# session history from a hook in all runtimes; when the signal is unavailable,
|
|
50
|
+
# treat it as "unknown → not suppressed". This preserves the nudge's
|
|
51
|
+
# usefulness without creating false suppression.
|
|
52
|
+
has_recent_gdd_command() {
|
|
53
|
+
# Placeholder: no portable transcript path exposed to SessionStart hooks today.
|
|
54
|
+
# Keep the function for future wiring; for now always returns non-zero (unknown).
|
|
55
|
+
return 1
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
# MANDATORY sourcing guard: unit tests source this script to test the helper
|
|
59
|
+
# functions without executing the main flow. Non-negotiable.
|
|
60
|
+
if [ "${BASH_SOURCE[0]}" = "$0" ]; then
|
|
61
|
+
if has_design_state; then
|
|
62
|
+
log "design state present — suppress"
|
|
63
|
+
exit 0
|
|
64
|
+
fi
|
|
65
|
+
if is_dismissed; then
|
|
66
|
+
log "dismissal flag present — suppress"
|
|
67
|
+
exit 0
|
|
68
|
+
fi
|
|
69
|
+
if is_active_stage; then
|
|
70
|
+
log "active stage — suppress"
|
|
71
|
+
exit 0
|
|
72
|
+
fi
|
|
73
|
+
if has_recent_gdd_command; then
|
|
74
|
+
log "recent gdd:* command detected — suppress"
|
|
75
|
+
exit 0
|
|
76
|
+
fi
|
|
77
|
+
# All gates passed — emit the locked one-line nudge.
|
|
78
|
+
printf 'Tip: run /gdd:start to let GDD inspect this codebase and suggest one first fix.\n'
|
|
79
|
+
exit 0
|
|
80
|
+
fi
|
|
81
|
+
# When sourced (BASH_SOURCE != $0), fall through with function definitions loaded
|
|
82
|
+
# and without side effects.
|
package/hooks/hooks.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hegemonart/get-design-done",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.0",
|
|
4
4
|
"description": "A Claude Code plugin for systematic design improvement",
|
|
5
5
|
"author": "Hegemon",
|
|
6
6
|
"homepage": "https://github.com/hegemonart/get-design-done",
|
|
@@ -54,7 +54,19 @@
|
|
|
54
54
|
"self-improvement",
|
|
55
55
|
"reflection",
|
|
56
56
|
"tested",
|
|
57
|
-
"ci"
|
|
57
|
+
"ci",
|
|
58
|
+
"iconography",
|
|
59
|
+
"brand-voice",
|
|
60
|
+
"performance-budget",
|
|
61
|
+
"framer-motion",
|
|
62
|
+
"motion-design",
|
|
63
|
+
"micro-polish",
|
|
64
|
+
"surfaces",
|
|
65
|
+
"make-interfaces-feel-better",
|
|
66
|
+
"palette-catalog",
|
|
67
|
+
"style-vocabulary",
|
|
68
|
+
"industry-palettes",
|
|
69
|
+
"ui-style-vocabulary"
|
|
58
70
|
],
|
|
59
71
|
"skills": [
|
|
60
72
|
"SKILL.md"
|
|
@@ -334,3 +334,72 @@ grep -rn "bounce\|elastic" src/ --include="*.css"
|
|
|
334
334
|
- [ ] Bounce or elastic easing anywhere?
|
|
335
335
|
|
|
336
336
|
If YES to any → rewrite that element before proceeding.
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
### BAN-10: Same Border-Radius on Nested Surfaces
|
|
341
|
+
|
|
342
|
+
Applying the same `border-radius` to a container and an element inside it (when the element is separated by padding) makes the inner element appear to "float" — the radii should be concentric, not equal.
|
|
343
|
+
|
|
344
|
+
**Grep (Tailwind):**
|
|
345
|
+
```
|
|
346
|
+
(rounded-\w+)[^"]*"[^>]*>\s*<[^>]*\1
|
|
347
|
+
```
|
|
348
|
+
**Grep (CSS):** Look for identical `border-radius` values in parent and child selectors within the same component.
|
|
349
|
+
|
|
350
|
+
**Fix:** Apply the concentric formula: `innerRadius = outerRadius − padding`. See `reference/surfaces.md`.
|
|
351
|
+
|
|
352
|
+
Source: jakubkrehel/make-interfaces-feel-better (MIT)
|
|
353
|
+
|
|
354
|
+
---
|
|
355
|
+
|
|
356
|
+
### BAN-11: Tinted Image Outline
|
|
357
|
+
|
|
358
|
+
Using a colored outline on images (e.g., `outline-slate-200`, `outline-gray-300`, or a hex-value outline color) competes visually with the image content and creates color contamination.
|
|
359
|
+
|
|
360
|
+
**Grep (Tailwind):**
|
|
361
|
+
```
|
|
362
|
+
outline-(slate|zinc|neutral|gray|stone|blue|red|green|yellow|purple)-\d+
|
|
363
|
+
```
|
|
364
|
+
applied to `<img>` elements.
|
|
365
|
+
|
|
366
|
+
**Grep (CSS):**
|
|
367
|
+
```
|
|
368
|
+
img\s*\{[^}]*outline:\s*[^}]*#[0-9a-fA-F]{3,8}
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
**Fix:** Use `outline: 1px solid rgba(0,0,0,0.08)` (light) or `outline: 1px solid rgba(255,255,255,0.08)` (dark). Pure black or white at low opacity only. See `reference/surfaces.md`.
|
|
372
|
+
|
|
373
|
+
Source: jakubkrehel/make-interfaces-feel-better (MIT)
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
### BAN-12: `transition: all`
|
|
378
|
+
|
|
379
|
+
`transition: all` animates every animatable CSS property on the element, including layout-triggering properties (width, height, padding, margin). This causes layout recalculation on EVERY transition, creating jank and unexpected visual effects (e.g., a hover transition that also animates the element's size if any dimensions change).
|
|
380
|
+
|
|
381
|
+
**Grep (CSS):**
|
|
382
|
+
```
|
|
383
|
+
transition:\s*all
|
|
384
|
+
transition-property:\s*all
|
|
385
|
+
```
|
|
386
|
+
**Grep (Tailwind):** bare `\btransition\b` class (without a modifier like `transition-transform` or `transition-[specific-property]`).
|
|
387
|
+
|
|
388
|
+
**Fix:** Specify the exact properties to animate. For hover effects: `transition: background-color 150ms, color 150ms, opacity 150ms`. For motion: `transition: transform 200ms, opacity 200ms`.
|
|
389
|
+
|
|
390
|
+
Source: jakubkrehel/make-interfaces-feel-better (MIT)
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
### BAN-13: `will-change: all`
|
|
395
|
+
|
|
396
|
+
`will-change: all` promotes every animatable property to its own GPU compositor layer, consuming GPU memory for each property. On complex components this can allocate hundreds of MB of texture memory per instance, causing performance degradation and potential crashes on mobile.
|
|
397
|
+
|
|
398
|
+
**Grep:**
|
|
399
|
+
```
|
|
400
|
+
will-change:\s*all
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Fix:** Restrict to specific compositing-safe properties: `will-change: transform`, `will-change: opacity`, `will-change: filter`, or `will-change: clip-path`. Remove entirely after animation completes. See `reference/motion.md` will-change section.
|
|
404
|
+
|
|
405
|
+
Source: jakubkrehel/make-interfaces-feel-better (MIT)
|
|
@@ -124,7 +124,7 @@ Check for:
|
|
|
124
124
|
- Content max-width enforced (prose: 65ch, layout: 1200–1440px)
|
|
125
125
|
- Mobile breakpoint respected (no horizontal scroll)
|
|
126
126
|
|
|
127
|
-
### 6. Anti-Pattern Compliance (Weight:
|
|
127
|
+
### 6. Anti-Pattern Compliance (Weight: 5%)
|
|
128
128
|
|
|
129
129
|
Score = 10 − (number of hard-ban violations × 3) − (number of AI-slop tells × 1), minimum 0.
|
|
130
130
|
|
|
@@ -155,8 +155,9 @@ Score = (Accessibility × 0.25)
|
|
|
155
155
|
+ (Typography × 0.15)
|
|
156
156
|
+ (Color × 0.15)
|
|
157
157
|
+ (Layout × 0.10)
|
|
158
|
-
+ (Anti-Patterns × 0.
|
|
158
|
+
+ (Anti-Patterns × 0.05)
|
|
159
159
|
+ (Motion × 0.05)
|
|
160
|
+
+ (Micro-polish × 0.05)
|
|
160
161
|
```
|
|
161
162
|
|
|
162
163
|
| Grade | Score | Meaning |
|
|
@@ -184,8 +185,9 @@ Baseline score: [N/100]
|
|
|
184
185
|
| Typography | /10 | 15% | |
|
|
185
186
|
| Color | /10 | 15% | |
|
|
186
187
|
| Layout | /10 | 10% | |
|
|
187
|
-
| Anti-Patterns | /10 |
|
|
188
|
+
| Anti-Patterns | /10 | 5% | |
|
|
188
189
|
| Motion | /10 | 5% | |
|
|
190
|
+
| Micro-polish | /10 | 5% | |
|
|
189
191
|
| **Total** | | | **/100** |
|
|
190
192
|
|
|
191
193
|
### Findings
|
|
@@ -203,3 +205,32 @@ Baseline score: [N/100]
|
|
|
203
205
|
| ... | | |
|
|
204
206
|
| **Total** | /40 | **= NNG Score:** /100 |
|
|
205
207
|
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
<!-- BREAKING: Anti-Pattern Compliance pillar weight changed 10%→5% in v1.15.0; Micro-polish pillar added at 5%. Cross-cycle score comparisons should account for this change. -->
|
|
212
|
+
|
|
213
|
+
### 8. Micro-polish (Weight: 5%)
|
|
214
|
+
|
|
215
|
+
Text-wrap, font-smoothing, tabular-nums, concentric radius, image outlines, hit areas, canonical press scale, will-change discipline.
|
|
216
|
+
|
|
217
|
+
| Score | Criteria |
|
|
218
|
+
|---|---|
|
|
219
|
+
| 10 | All 14 micro-polish checklist items pass |
|
|
220
|
+
| 7–9 | 2–3 violations found |
|
|
221
|
+
| 4–6 | 7 or more violations, core items failing (press scale, transition:all) |
|
|
222
|
+
| 0–3 | Most items fail or not considered |
|
|
223
|
+
|
|
224
|
+
Check for (see `reference/checklists.md` Micro-Polish Check gate):
|
|
225
|
+
- Headings: `text-wrap: balance`; body/captions: `text-wrap: pretty`
|
|
226
|
+
- Font smoothing at `:root` only
|
|
227
|
+
- Dynamic numbers: `font-variant-numeric: tabular-nums`
|
|
228
|
+
- Nested elements: concentric radius (`innerRadius = outerRadius − padding`)
|
|
229
|
+
- Images: `outline: 1px solid rgba(0,0,0,0.08)` — no tinted outlines
|
|
230
|
+
- Interactive elements <40px: `::after` hit-area extension to 40×40
|
|
231
|
+
- Press feedback: `scale(0.96)` exactly
|
|
232
|
+
- `AnimatePresence` on persistent UI: `initial={false}`
|
|
233
|
+
- Icon cross-fade spring: `bounce: 0`
|
|
234
|
+
- No `transition: all` (BAN-12)
|
|
235
|
+
- No `will-change: all` (BAN-13)
|
|
236
|
+
- `prefers-reduced-motion` respected
|