@hustle-together/api-dev-tools 3.12.16 → 4.5.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/adr-requests/.gitkeep +10 -0
- package/.claude/agents/adr-researcher.md +109 -0
- package/.claude/agents/visual-analyzer.md +183 -0
- package/.claude/api-dev-state.json +10 -0
- package/.claude/documentation-audit.json +114 -0
- package/.claude/registry.json +289 -0
- package/.claude/settings.json +45 -1
- package/.claude/settings.local.json +1 -7
- package/.claude/workflow-logs/None.json +49 -0
- package/.claude/workflow-logs/session-20251230-143727.json +106 -0
- package/.skills/adr-deep-research/SKILL.md +351 -0
- package/.skills/api-create/SKILL.md +34 -20
- package/.skills/api-research/SKILL.md +130 -0
- package/.skills/docs-update/SKILL.md +205 -0
- package/.skills/hustle-brand/SKILL.md +368 -0
- package/.skills/hustle-build/SKILL.md +365 -38
- package/.skills/parallel-spawn/SKILL.md +212 -0
- package/.skills/ralph-continue/SKILL.md +151 -0
- package/.skills/ralph-loop/SKILL.md +341 -0
- package/.skills/ralph-status/SKILL.md +87 -0
- package/.skills/refactor/SKILL.md +59 -0
- package/.skills/shadcn/SKILL.md +522 -0
- package/.skills/test-all/SKILL.md +210 -0
- package/.skills/test-builds/SKILL.md +208 -0
- package/.skills/test-debug/SKILL.md +212 -0
- package/.skills/test-e2e/SKILL.md +168 -0
- package/.skills/test-review/SKILL.md +707 -0
- package/.skills/test-unit/SKILL.md +143 -0
- package/.skills/test-visual/SKILL.md +301 -0
- package/.skills/token-report/SKILL.md +132 -0
- package/CHANGELOG.md +488 -0
- package/README.md +346 -53
- package/bin/cli.js +359 -123
- package/hooks/__pycache__/api-workflow-check.cpython-314.pyc +0 -0
- package/hooks/__pycache__/auto-answer.cpython-314.pyc +0 -0
- package/hooks/__pycache__/cache-research.cpython-314.pyc +0 -0
- package/hooks/__pycache__/check-api-routes.cpython-314.pyc +0 -0
- package/hooks/__pycache__/check-playwright-setup.cpython-314.pyc +0 -0
- package/hooks/__pycache__/check-storybook-setup.cpython-314.pyc +0 -0
- package/hooks/__pycache__/check-update.cpython-314.pyc +0 -0
- package/hooks/__pycache__/completion-promise-detector.cpython-314.pyc +0 -0
- package/hooks/__pycache__/context-capacity-warning.cpython-314.pyc +0 -0
- package/hooks/__pycache__/detect-interruption.cpython-314.pyc +0 -0
- package/hooks/__pycache__/docs-update-check.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-a11y-audit.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-brand-guide.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-component-type-confirm.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-deep-research.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-disambiguation.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-documentation.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-dry-run.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-environment.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-external-research.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-freshness.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-interview.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-page-components.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-page-data-schema.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-questions-sourced.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-refactor.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-research.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-schema-from-interview.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-schema.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-scope.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-tdd-red.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-ui-disambiguation.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-ui-interview.cpython-314.pyc +0 -0
- package/hooks/__pycache__/enforce-verify.cpython-314.pyc +0 -0
- package/hooks/__pycache__/generate-adr-options.cpython-314.pyc +0 -0
- package/hooks/__pycache__/generate-manifest-entry.cpython-314.pyc +0 -0
- package/hooks/__pycache__/hook_utils.cpython-314.pyc +0 -0
- package/hooks/__pycache__/notify-input-needed.cpython-314.pyc +0 -0
- package/hooks/__pycache__/notify-phase-complete.cpython-314.pyc +0 -0
- package/hooks/__pycache__/ntfy-on-question.cpython-314.pyc +0 -0
- package/hooks/__pycache__/orchestrator-completion.cpython-314.pyc +0 -0
- package/hooks/__pycache__/orchestrator-handoff.cpython-314.pyc +0 -0
- package/hooks/__pycache__/orchestrator-session-startup.cpython-314.pyc +0 -0
- package/hooks/__pycache__/parallel-orchestrator.cpython-314.pyc +0 -0
- package/hooks/__pycache__/periodic-reground.cpython-314.pyc +0 -0
- package/hooks/__pycache__/project-document-prompt.cpython-314.pyc +0 -0
- package/hooks/__pycache__/remote-question-proxy.cpython-314.pyc +0 -0
- package/hooks/__pycache__/remote-question-server.cpython-314.pyc +0 -0
- package/hooks/__pycache__/run-code-review.cpython-314.pyc +0 -0
- package/hooks/__pycache__/run-visual-qa.cpython-314.pyc +0 -0
- package/hooks/__pycache__/session-logger.cpython-314.pyc +0 -0
- package/hooks/__pycache__/session-startup.cpython-314.pyc +0 -0
- package/hooks/__pycache__/track-scope-coverage.cpython-314.pyc +0 -0
- package/hooks/__pycache__/track-token-usage.cpython-314.pyc +0 -0
- package/hooks/__pycache__/track-tool-use.cpython-314.pyc +0 -0
- package/hooks/__pycache__/update-adr-decision.cpython-314.pyc +0 -0
- package/hooks/__pycache__/update-api-showcase.cpython-314.pyc +0 -0
- package/hooks/__pycache__/update-registry.cpython-314.pyc +0 -0
- package/hooks/__pycache__/update-ui-showcase.cpython-314.pyc +0 -0
- package/hooks/__pycache__/verify-after-green.cpython-314.pyc +0 -0
- package/hooks/__pycache__/verify-implementation.cpython-314.pyc +0 -0
- package/hooks/api-workflow-check.py +34 -0
- package/hooks/auto-answer.py +97 -20
- package/{.claude/hooks → hooks}/completion-promise-detector.py +0 -0
- package/{.claude/hooks → hooks}/context-capacity-warning.py +0 -0
- package/{.claude/hooks → hooks}/docs-update-check.py +0 -0
- package/{.claude/hooks → hooks}/enforce-dry-run.py +0 -0
- package/hooks/enforce-external-research.py +25 -0
- package/hooks/enforce-interview.py +20 -0
- package/{.claude/hooks → hooks}/generate-adr-options.py +0 -0
- package/{.claude/hooks → hooks}/hook_utils.py +0 -0
- package/hooks/ntfy-on-question.py +15 -2
- package/hooks/orchestrator-handoff.py +81 -3
- package/{.claude/hooks → hooks}/parallel-orchestrator.py +0 -0
- package/hooks/periodic-reground.py +40 -0
- package/{.claude/hooks → hooks}/remote-question-server.py +0 -0
- package/hooks/run-code-review.py +176 -29
- package/{.claude/hooks → hooks}/run-visual-qa.py +0 -0
- package/hooks/session-logger.py +27 -1
- package/hooks/session-startup.py +113 -0
- package/{.claude/hooks → hooks}/update-adr-decision.py +0 -0
- package/package.json +1 -1
- package/templates/.skills/hustle-interview/SKILL.md +174 -0
- package/templates/adr-viewer/_components/ADRViewer.tsx +326 -0
- package/templates/api-dev-state.json +33 -1
- package/templates/brand-page/page.tsx +645 -0
- package/templates/component/Component.visual.spec.ts +30 -24
- package/templates/eslint-plugin-zod-schema/index.js +446 -0
- package/templates/eslint-plugin-zod-schema/package.json +26 -0
- package/templates/github-workflows/security.yml +274 -0
- package/templates/hustle-build-defaults.json +53 -1
- package/templates/page/page.e2e.test.ts +30 -26
- package/templates/performance-budgets.json +63 -5
- package/templates/registry.json +279 -3
- package/templates/review-dashboard/page.tsx +510 -0
- package/templates/settings.json +74 -7
- package/templates/ui-showcase/_components/UIShowcase.tsx +47 -0
- package/templates/ui-showcase/_components/VisualTestingDashboard.tsx +579 -0
- package/.claude/commands/hustle-combine.md +0 -1089
- package/.claude/commands/hustle-ui-create-page.md +0 -1078
- package/.claude/commands/hustle-ui-create.md +0 -1058
- package/.claude/hooks/auto-answer.py +0 -305
- package/.claude/hooks/cache-research.py +0 -337
- package/.claude/hooks/check-api-routes.py +0 -168
- package/.claude/hooks/check-playwright-setup.py +0 -103
- package/.claude/hooks/check-storybook-setup.py +0 -81
- package/.claude/hooks/check-update.py +0 -132
- package/.claude/hooks/detect-interruption.py +0 -165
- package/.claude/hooks/enforce-a11y-audit.py +0 -202
- package/.claude/hooks/enforce-brand-guide.py +0 -241
- package/.claude/hooks/enforce-component-type-confirm.py +0 -97
- package/.claude/hooks/enforce-freshness.py +0 -184
- package/.claude/hooks/enforce-page-components.py +0 -186
- package/.claude/hooks/enforce-page-data-schema.py +0 -155
- package/.claude/hooks/enforce-questions-sourced.py +0 -146
- package/.claude/hooks/enforce-schema-from-interview.py +0 -248
- package/.claude/hooks/enforce-ui-disambiguation.py +0 -108
- package/.claude/hooks/enforce-ui-interview.py +0 -130
- package/.claude/hooks/generate-manifest-entry.py +0 -1161
- package/.claude/hooks/lib/__init__.py +0 -1
- package/.claude/hooks/lib/greptile.py +0 -355
- package/.claude/hooks/lib/ntfy.py +0 -209
- package/.claude/hooks/notify-input-needed.py +0 -73
- package/.claude/hooks/notify-phase-complete.py +0 -90
- package/.claude/hooks/ntfy-on-question.py +0 -240
- package/.claude/hooks/orchestrator-completion.py +0 -313
- package/.claude/hooks/orchestrator-handoff.py +0 -267
- package/.claude/hooks/orchestrator-session-startup.py +0 -146
- package/.claude/hooks/run-code-review.py +0 -393
- package/.claude/hooks/session-logger.py +0 -323
- package/.claude/hooks/test-orchestrator-reground.py +0 -248
- package/.claude/hooks/track-scope-coverage.py +0 -220
- package/.claude/hooks/track-token-usage.py +0 -121
- package/.claude/hooks/update-api-showcase.py +0 -161
- package/.claude/hooks/update-registry.py +0 -352
- package/.claude/hooks/update-ui-showcase.py +0 -224
- package/.claude/test-auto-answer-bot.py +0 -183
- package/.claude/test-completion-detector.py +0 -263
- package/.claude/test-orchestrator-state.json +0 -20
- package/.claude/test-orchestrator.sh +0 -271
- /package/{.claude/commands → commands}/hustle-build.md +0 -0
- /package/{.claude/hooks → hooks}/lib/__pycache__/__init__.cpython-314.pyc +0 -0
- /package/{.claude/hooks → hooks}/lib/__pycache__/greptile.cpython-314.pyc +0 -0
- /package/{.claude/hooks → hooks}/lib/__pycache__/ntfy.cpython-314.pyc +0 -0
- /package/{.claude/hooks → hooks}/project-document-prompt.py +0 -0
- /package/{.claude/hooks → hooks}/remote-question-proxy.py +0 -0
- /package/{.claude/hooks → hooks}/update-testing-checklist.py +0 -0
|
@@ -1,1058 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Create UI components or pages with 14-phase interview-driven workflow
|
|
3
|
-
argument-hint: [component-name]
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Hustle UI Create
|
|
7
|
-
|
|
8
|
-
**Version:** 4.0.0
|
|
9
|
-
**14-phase workflow for creating UI components and pages**
|
|
10
|
-
|
|
11
|
-
**Usage:** `/hustle-ui-create [component-name] [--auto] [--resume [workflow-id]]`
|
|
12
|
-
|
|
13
|
-
You are creating a UI element using the Hustle Together interview-driven workflow.
|
|
14
|
-
|
|
15
|
-
## Arguments
|
|
16
|
-
|
|
17
|
-
- `[component-name]` - Name of the component to create
|
|
18
|
-
- `--auto` - Fully autonomous mode, auto-answers all questions with comprehensive defaults
|
|
19
|
-
- `--resume [workflow-id]` - Resume an interrupted workflow from its last phase
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## Auto Mode (`--auto`)
|
|
24
|
-
|
|
25
|
-
When `--auto` flag is used:
|
|
26
|
-
|
|
27
|
-
1. **No Interactive Questions:**
|
|
28
|
-
- All questions auto-answered with comprehensive defaults
|
|
29
|
-
- Uses `.claude/hustle-build-defaults.json` for configured answers
|
|
30
|
-
- Falls back to "most comprehensive" option when no default exists
|
|
31
|
-
|
|
32
|
-
2. **Comprehensive Selection Logic:**
|
|
33
|
-
- Selects ALL variants (size, color, state)
|
|
34
|
-
- Enables full accessibility (WCAG 2.1 AA)
|
|
35
|
-
- Enables animations and responsive design
|
|
36
|
-
- Creates all Storybook stories
|
|
37
|
-
|
|
38
|
-
3. **Error Handling:**
|
|
39
|
-
- Test failures: Retry 3x, then log and continue
|
|
40
|
-
- Visual regression: Update baselines automatically
|
|
41
|
-
- Missing packages: Install automatically
|
|
42
|
-
|
|
43
|
-
4. **Logging:**
|
|
44
|
-
- All decisions logged to `.claude/workflow-logs/ui-create/[workflow-id].json`
|
|
45
|
-
- Review with `/hustle-ui-create-review [workflow-id]`
|
|
46
|
-
|
|
47
|
-
---
|
|
48
|
-
|
|
49
|
-
## Resume Mode (`--resume`)
|
|
50
|
-
|
|
51
|
-
When `--resume [workflow-id]` is used:
|
|
52
|
-
|
|
53
|
-
1. Load state from `.claude/api-dev-state.json`
|
|
54
|
-
2. Find the last incomplete phase
|
|
55
|
-
3. Continue from that point
|
|
56
|
-
4. Preserve all previous decisions
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
## Orchestrated Mode
|
|
61
|
-
|
|
62
|
-
When running as part of `/hustle-build`:
|
|
63
|
-
|
|
64
|
-
1. `orchestrated: true` flag is set in state
|
|
65
|
-
2. `shared_decisions` are pre-filled from orchestrator interview
|
|
66
|
-
3. Questions covered by shared_decisions are SKIPPED (e.g., brand guide, testing level)
|
|
67
|
-
4. Only component-specific questions are asked (variants, props)
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
## Pre-Flight Check
|
|
72
|
-
|
|
73
|
-
Before starting, verify state file exists:
|
|
74
|
-
|
|
75
|
-
```bash
|
|
76
|
-
cat .claude/api-dev-state.json 2>/dev/null || echo "Creating new state file"
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## Mode Selection
|
|
80
|
-
|
|
81
|
-
**MANDATORY: Ask user before proceeding:**
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
What would you like to create?
|
|
85
|
-
|
|
86
|
-
A) Component - Isolated reusable UI component
|
|
87
|
-
- Creates component in src/components/[Name]/
|
|
88
|
-
- Adds to UI Showcase page
|
|
89
|
-
- Tests via Storybook + Vitest
|
|
90
|
-
|
|
91
|
-
B) Page - Full page that may use existing components
|
|
92
|
-
- Creates page in src/app/[name]/
|
|
93
|
-
- Selects components from registry
|
|
94
|
-
- Tests via Playwright E2E
|
|
95
|
-
|
|
96
|
-
Please select A or B:
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
**Wait for user response. Do not proceed without explicit selection.**
|
|
100
|
-
|
|
101
|
-
Set `mode` based on response: "component" or "page"
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
# Component Mode (14 Phases)
|
|
106
|
-
|
|
107
|
-
## Phase 1: DISAMBIGUATION
|
|
108
|
-
|
|
109
|
-
**Goal:** AI analyzes component, suggests type, user confirms
|
|
110
|
-
|
|
111
|
-
### Step 1: AI Analysis
|
|
112
|
-
|
|
113
|
-
Analyze the component name and description to determine complexity:
|
|
114
|
-
|
|
115
|
-
**Basic components** (single-purpose, few props):
|
|
116
|
-
|
|
117
|
-
- Button, Input, Icon, Badge, Label, Avatar, Spinner
|
|
118
|
-
|
|
119
|
-
**Complex components** (multi-part, many states, user flows):
|
|
120
|
-
|
|
121
|
-
- ChatWindow, DataTable, Modal, Sidebar, Header, Form, Dashboard
|
|
122
|
-
|
|
123
|
-
### Step 2: Present Suggestion
|
|
124
|
-
|
|
125
|
-
```
|
|
126
|
-
Phase 1: DISAMBIGUATION
|
|
127
|
-
|
|
128
|
-
Based on "[component-name]", I believe this is a:
|
|
129
|
-
|
|
130
|
-
➤ [BASIC/COMPLEX] component
|
|
131
|
-
|
|
132
|
-
Reasoning: [Why you classified it this way]
|
|
133
|
-
|
|
134
|
-
Is this correct?
|
|
135
|
-
A) Yes, proceed with [Basic/Complex]
|
|
136
|
-
B) No, it's actually [the other type]
|
|
137
|
-
|
|
138
|
-
Please confirm:
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
**Wait for user response.**
|
|
142
|
-
|
|
143
|
-
**HOOK: `enforce-component-type-confirm.py` blocks if user doesn't confirm.**
|
|
144
|
-
|
|
145
|
-
Update state:
|
|
146
|
-
|
|
147
|
-
```json
|
|
148
|
-
{
|
|
149
|
-
"workflow": "ui-create-component",
|
|
150
|
-
"element_name": "[component-name]",
|
|
151
|
-
"element_type": "component",
|
|
152
|
-
"ui_config": {
|
|
153
|
-
"component_type": "[basic|complex]",
|
|
154
|
-
"ai_suggested": "[basic|complex]",
|
|
155
|
-
"user_confirmed": true
|
|
156
|
-
},
|
|
157
|
-
"phases": {
|
|
158
|
-
"disambiguation": {
|
|
159
|
-
"status": "complete",
|
|
160
|
-
"component_type": "[selected]"
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
**Note:** Complex components will include Playwright E2E tests in addition to Storybook.
|
|
167
|
-
|
|
168
|
-
---
|
|
169
|
-
|
|
170
|
-
## Phase 2: SCOPE
|
|
171
|
-
|
|
172
|
-
**Goal:** Confirm understanding of component purpose
|
|
173
|
-
|
|
174
|
-
Based on the component name and type, present your understanding:
|
|
175
|
-
|
|
176
|
-
```
|
|
177
|
-
Phase 2: SCOPE CONFIRMATION
|
|
178
|
-
|
|
179
|
-
Based on your input, here's my understanding:
|
|
180
|
-
|
|
181
|
-
Component: [Name]
|
|
182
|
-
Type: [Basic/Complex]
|
|
183
|
-
Purpose: [Your understanding of what this component does]
|
|
184
|
-
|
|
185
|
-
Expected Features:
|
|
186
|
-
- [Feature 1]
|
|
187
|
-
- [Feature 2]
|
|
188
|
-
- [Feature 3]
|
|
189
|
-
|
|
190
|
-
Does this match your expectations?
|
|
191
|
-
A) Yes, proceed
|
|
192
|
-
B) No, let me clarify
|
|
193
|
-
|
|
194
|
-
Please select A or B:
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
**Wait for user response. Loop back if B selected.**
|
|
198
|
-
|
|
199
|
-
Update state with `phases.scope.status = "complete"`
|
|
200
|
-
|
|
201
|
-
---
|
|
202
|
-
|
|
203
|
-
## Phase 3: DESIGN RESEARCH
|
|
204
|
-
|
|
205
|
-
**Goal:** Research design patterns AND check brand guide
|
|
206
|
-
|
|
207
|
-
### Step 3a: Brand Guide Check
|
|
208
|
-
|
|
209
|
-
```
|
|
210
|
-
Phase 3: DESIGN RESEARCH
|
|
211
|
-
|
|
212
|
-
I found your brand guide at .claude/BRAND_GUIDE.md
|
|
213
|
-
|
|
214
|
-
If you need to update your brand guide, NOW is the time!
|
|
215
|
-
1. Open .claude/BRAND_GUIDE.md
|
|
216
|
-
2. Make your changes
|
|
217
|
-
3. Save the file
|
|
218
|
-
4. Then select option A below
|
|
219
|
-
|
|
220
|
-
Should I use the project brand guide?
|
|
221
|
-
A) Yes, use brand guide (default) - I will apply these styles
|
|
222
|
-
B) No, use different reference [provide URL or description]
|
|
223
|
-
|
|
224
|
-
Please select A or B:
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
**Wait for user response.**
|
|
228
|
-
|
|
229
|
-
If A: Read `.claude/BRAND_GUIDE.md` and note key values (colors, spacing, border-radius)
|
|
230
|
-
If B: Ask for URL or description
|
|
231
|
-
|
|
232
|
-
### Step 3b: Design Pattern Research
|
|
233
|
-
|
|
234
|
-
Perform 2-3 targeted searches:
|
|
235
|
-
|
|
236
|
-
1. `[component-name] component best practices accessibility`
|
|
237
|
-
2. `shadcn [component-name] implementation`
|
|
238
|
-
3. `radix [component-name] primitive`
|
|
239
|
-
|
|
240
|
-
Use Context7 for ShadCN/Radix documentation.
|
|
241
|
-
|
|
242
|
-
Document findings in state:
|
|
243
|
-
|
|
244
|
-
```json
|
|
245
|
-
{
|
|
246
|
-
"phases": {
|
|
247
|
-
"design_research": {
|
|
248
|
-
"status": "complete",
|
|
249
|
-
"brand_guide_applied": true,
|
|
250
|
-
"sources": ["source1", "source2"]
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
---
|
|
257
|
-
|
|
258
|
-
## Phase 4: INTERVIEW
|
|
259
|
-
|
|
260
|
-
**Goal:** Deep dive into component requirements
|
|
261
|
-
|
|
262
|
-
Ask 5-10 questions based on research findings. Questions should be GENERATED from research, not template.
|
|
263
|
-
|
|
264
|
-
**Example questions (customize based on research):**
|
|
265
|
-
|
|
266
|
-
```
|
|
267
|
-
Phase 4: INTERVIEW
|
|
268
|
-
|
|
269
|
-
Based on my research, I have some questions about your [Component]:
|
|
270
|
-
|
|
271
|
-
Q1: Design System Base
|
|
272
|
-
Which design system should I use?
|
|
273
|
-
A) ShadCN - Use shadcn/ui components
|
|
274
|
-
B) Radix - Use Radix primitives directly
|
|
275
|
-
C) Custom - Build from scratch
|
|
276
|
-
|
|
277
|
-
Q2: Variants
|
|
278
|
-
Which visual variants does this component need? (select all)
|
|
279
|
-
[ ] Size (sm, md, lg)
|
|
280
|
-
[ ] Color (primary, secondary, destructive)
|
|
281
|
-
[ ] State (disabled, loading, error)
|
|
282
|
-
|
|
283
|
-
Q3: Accessibility Level
|
|
284
|
-
What accessibility standard should we meet?
|
|
285
|
-
A) WCAG 2.1 AA (standard)
|
|
286
|
-
B) WCAG 2.1 AAA (enhanced)
|
|
287
|
-
C) Basic (keyboard nav + aria labels only)
|
|
288
|
-
|
|
289
|
-
Q4: [Research-derived question about specific feature]
|
|
290
|
-
|
|
291
|
-
Q5: [Research-derived question about specific feature]
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
**Wait for all answers before proceeding.**
|
|
295
|
-
|
|
296
|
-
Store all decisions in state:
|
|
297
|
-
|
|
298
|
-
```json
|
|
299
|
-
{
|
|
300
|
-
"phases": {
|
|
301
|
-
"interview": {
|
|
302
|
-
"status": "complete",
|
|
303
|
-
"decisions": {
|
|
304
|
-
"design_system": "shadcn",
|
|
305
|
-
"variants": ["size", "color"],
|
|
306
|
-
"accessibility": "wcag2aa"
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
```
|
|
312
|
-
|
|
313
|
-
---
|
|
314
|
-
|
|
315
|
-
## Phase 5: COMPONENT ANALYSIS
|
|
316
|
-
|
|
317
|
-
**Goal:** Check for existing ShadCN components to use
|
|
318
|
-
|
|
319
|
-
If design system is ShadCN, check `src/components/ui/`:
|
|
320
|
-
|
|
321
|
-
```bash
|
|
322
|
-
ls -la src/components/ui/ 2>/dev/null || echo "No existing ShadCN components"
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
If components found:
|
|
326
|
-
|
|
327
|
-
```
|
|
328
|
-
Phase 5: COMPONENT ANALYSIS
|
|
329
|
-
|
|
330
|
-
Existing ShadCN Components Found:
|
|
331
|
-
|
|
332
|
-
src/components/ui/
|
|
333
|
-
├── button.tsx
|
|
334
|
-
├── input.tsx
|
|
335
|
-
├── label.tsx
|
|
336
|
-
└── card.tsx
|
|
337
|
-
|
|
338
|
-
Your [Component] could use: [Input, Label]
|
|
339
|
-
|
|
340
|
-
Would you like to use these existing components?
|
|
341
|
-
A) Yes, use these (recommended)
|
|
342
|
-
B) No, create new ones
|
|
343
|
-
C) Some - let me specify
|
|
344
|
-
|
|
345
|
-
Please select:
|
|
346
|
-
```
|
|
347
|
-
|
|
348
|
-
**Wait for user response.**
|
|
349
|
-
|
|
350
|
-
Also check registry for custom components:
|
|
351
|
-
|
|
352
|
-
```bash
|
|
353
|
-
cat .claude/registry.json | jq '.components'
|
|
354
|
-
```
|
|
355
|
-
|
|
356
|
-
Update state with dependencies list.
|
|
357
|
-
|
|
358
|
-
---
|
|
359
|
-
|
|
360
|
-
## Phase 6: PROPS SCHEMA
|
|
361
|
-
|
|
362
|
-
**Goal:** Create TypeScript interface from interview answers
|
|
363
|
-
|
|
364
|
-
Based on interview decisions, create props interface:
|
|
365
|
-
|
|
366
|
-
```typescript
|
|
367
|
-
// src/components/[Name]/[Name].types.ts
|
|
368
|
-
|
|
369
|
-
export interface [Name]Props {
|
|
370
|
-
/** Visual variant */
|
|
371
|
-
variant?: 'primary' | 'secondary' | 'destructive';
|
|
372
|
-
|
|
373
|
-
/** Size variant */
|
|
374
|
-
size?: 'sm' | 'md' | 'lg';
|
|
375
|
-
|
|
376
|
-
/** Loading state */
|
|
377
|
-
loading?: boolean;
|
|
378
|
-
|
|
379
|
-
/** Disabled state */
|
|
380
|
-
disabled?: boolean;
|
|
381
|
-
|
|
382
|
-
/** Children content */
|
|
383
|
-
children: React.ReactNode;
|
|
384
|
-
|
|
385
|
-
/** Additional class names */
|
|
386
|
-
className?: string;
|
|
387
|
-
}
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
Present to user:
|
|
391
|
-
|
|
392
|
-
```
|
|
393
|
-
Phase 6: PROPS SCHEMA
|
|
394
|
-
|
|
395
|
-
Here's the TypeScript interface I've created:
|
|
396
|
-
|
|
397
|
-
[Show interface]
|
|
398
|
-
|
|
399
|
-
Does this schema look correct?
|
|
400
|
-
A) Yes, proceed
|
|
401
|
-
B) No, needs changes [specify]
|
|
402
|
-
|
|
403
|
-
Please select:
|
|
404
|
-
```
|
|
405
|
-
|
|
406
|
-
**Wait for approval before proceeding.**
|
|
407
|
-
|
|
408
|
-
---
|
|
409
|
-
|
|
410
|
-
## Phase 7: ENVIRONMENT
|
|
411
|
-
|
|
412
|
-
**Goal:** Verify required packages and Storybook setup
|
|
413
|
-
|
|
414
|
-
Check for required packages:
|
|
415
|
-
|
|
416
|
-
```bash
|
|
417
|
-
cat package.json | jq '.dependencies, .devDependencies' | grep -E "radix|shadcn|class-variance|clsx|tailwind"
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
Check Storybook:
|
|
421
|
-
|
|
422
|
-
```bash
|
|
423
|
-
ls -la .storybook/ 2>/dev/null || echo "Storybook not configured"
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
If Storybook not found:
|
|
427
|
-
|
|
428
|
-
```
|
|
429
|
-
Phase 7: ENVIRONMENT CHECK
|
|
430
|
-
|
|
431
|
-
Storybook is not configured in this project.
|
|
432
|
-
|
|
433
|
-
Would you like me to initialize Storybook?
|
|
434
|
-
A) Yes, run: npx storybook@latest init
|
|
435
|
-
B) No, skip Storybook stories
|
|
436
|
-
|
|
437
|
-
Please select:
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
Report status:
|
|
441
|
-
|
|
442
|
-
```
|
|
443
|
-
Environment Check:
|
|
444
|
-
Packages: [radix, class-variance-authority, clsx]
|
|
445
|
-
Storybook: [Configured/Not configured]
|
|
446
|
-
Tailwind: [Found/Not found]
|
|
447
|
-
|
|
448
|
-
Ready to proceed with TDD?
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
---
|
|
452
|
-
|
|
453
|
-
## Phase 8: TDD RED
|
|
454
|
-
|
|
455
|
-
**Goal:** Write failing tests and Storybook stories
|
|
456
|
-
|
|
457
|
-
### Create Test File
|
|
458
|
-
|
|
459
|
-
```typescript
|
|
460
|
-
// src/components/[Name]/__tests__/[Name].test.tsx
|
|
461
|
-
|
|
462
|
-
import { render, screen } from '@testing-library/react';
|
|
463
|
-
import { describe, it, expect } from 'vitest';
|
|
464
|
-
import { [Name] } from '../[Name]';
|
|
465
|
-
|
|
466
|
-
describe('[Name]', () => {
|
|
467
|
-
it('renders children correctly', () => {
|
|
468
|
-
render(<[Name]>Test Content</[Name]>);
|
|
469
|
-
expect(screen.getByText('Test Content')).toBeInTheDocument();
|
|
470
|
-
});
|
|
471
|
-
|
|
472
|
-
it('applies variant classes', () => {
|
|
473
|
-
const { container } = render(<[Name] variant="primary">Test</[Name]>);
|
|
474
|
-
expect(container.firstChild).toHaveClass('...');
|
|
475
|
-
});
|
|
476
|
-
|
|
477
|
-
it('handles disabled state', () => {
|
|
478
|
-
render(<[Name] disabled>Test</[Name]>);
|
|
479
|
-
expect(screen.getByRole('button')).toBeDisabled();
|
|
480
|
-
});
|
|
481
|
-
|
|
482
|
-
it('shows loading indicator when loading', () => {
|
|
483
|
-
render(<[Name] loading>Test</[Name]>);
|
|
484
|
-
expect(screen.getByRole('button')).toHaveAttribute('aria-busy', 'true');
|
|
485
|
-
});
|
|
486
|
-
});
|
|
487
|
-
```
|
|
488
|
-
|
|
489
|
-
### Create Storybook Story
|
|
490
|
-
|
|
491
|
-
```typescript
|
|
492
|
-
// src/components/[Name]/[Name].stories.tsx
|
|
493
|
-
|
|
494
|
-
import type { Meta, StoryObj } from '@storybook/react';
|
|
495
|
-
import { [Name] } from './[Name]';
|
|
496
|
-
|
|
497
|
-
const meta: Meta<typeof [Name]> = {
|
|
498
|
-
title: 'Components/[Name]',
|
|
499
|
-
component: [Name],
|
|
500
|
-
parameters: { layout: 'centered' },
|
|
501
|
-
tags: ['autodocs'],
|
|
502
|
-
argTypes: {
|
|
503
|
-
variant: { control: 'select', options: ['primary', 'secondary', 'destructive'] },
|
|
504
|
-
size: { control: 'select', options: ['sm', 'md', 'lg'] },
|
|
505
|
-
loading: { control: 'boolean' },
|
|
506
|
-
disabled: { control: 'boolean' },
|
|
507
|
-
},
|
|
508
|
-
};
|
|
509
|
-
|
|
510
|
-
export default meta;
|
|
511
|
-
type Story = StoryObj<typeof meta>;
|
|
512
|
-
|
|
513
|
-
export const Primary: Story = {
|
|
514
|
-
args: { variant: 'primary', children: 'Primary [Name]' },
|
|
515
|
-
};
|
|
516
|
-
|
|
517
|
-
export const Secondary: Story = {
|
|
518
|
-
args: { variant: 'secondary', children: 'Secondary [Name]' },
|
|
519
|
-
};
|
|
520
|
-
|
|
521
|
-
export const Loading: Story = {
|
|
522
|
-
args: { loading: true, children: 'Loading...' },
|
|
523
|
-
};
|
|
524
|
-
|
|
525
|
-
export const Disabled: Story = {
|
|
526
|
-
args: { disabled: true, children: 'Disabled' },
|
|
527
|
-
};
|
|
528
|
-
```
|
|
529
|
-
|
|
530
|
-
### Create Visual Regression Test (Playwright)
|
|
531
|
-
|
|
532
|
-
```typescript
|
|
533
|
-
// src/components/[Name]/__tests__/[Name].visual.spec.ts
|
|
534
|
-
|
|
535
|
-
import { test, expect } from "@playwright/test";
|
|
536
|
-
|
|
537
|
-
const STORYBOOK_URL = process.env.STORYBOOK_URL || "http://localhost:6006";
|
|
538
|
-
|
|
539
|
-
test.describe("[Name] Visual Regression", () => {
|
|
540
|
-
test("Primary variant matches baseline", async ({ page }) => {
|
|
541
|
-
await page.goto(
|
|
542
|
-
`${STORYBOOK_URL}/iframe.html?id=components-[name]--primary`,
|
|
543
|
-
);
|
|
544
|
-
await page.waitForLoadState("networkidle");
|
|
545
|
-
await expect(page.locator("#storybook-root")).toHaveScreenshot(
|
|
546
|
-
"[Name]-primary.png",
|
|
547
|
-
);
|
|
548
|
-
});
|
|
549
|
-
|
|
550
|
-
test("renders correctly on mobile", async ({ page }) => {
|
|
551
|
-
await page.setViewportSize({ width: 375, height: 667 });
|
|
552
|
-
await page.goto(
|
|
553
|
-
`${STORYBOOK_URL}/iframe.html?id=components-[name]--primary`,
|
|
554
|
-
);
|
|
555
|
-
await expect(page.locator("#storybook-root")).toHaveScreenshot(
|
|
556
|
-
"[Name]-mobile.png",
|
|
557
|
-
);
|
|
558
|
-
});
|
|
559
|
-
|
|
560
|
-
test("hover state matches baseline", async ({ page }) => {
|
|
561
|
-
await page.goto(
|
|
562
|
-
`${STORYBOOK_URL}/iframe.html?id=components-[name]--primary`,
|
|
563
|
-
);
|
|
564
|
-
await page.locator("#storybook-root > *").first().hover();
|
|
565
|
-
await page.waitForTimeout(300);
|
|
566
|
-
await expect(page.locator("#storybook-root")).toHaveScreenshot(
|
|
567
|
-
"[Name]-hover.png",
|
|
568
|
-
);
|
|
569
|
-
});
|
|
570
|
-
});
|
|
571
|
-
```
|
|
572
|
-
|
|
573
|
-
### Run Tests (Expect Failure)
|
|
574
|
-
|
|
575
|
-
```bash
|
|
576
|
-
pnpm test src/components/[Name]
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
**Tests MUST fail at this point (component doesn't exist yet).**
|
|
580
|
-
|
|
581
|
-
Update state: `phases.tdd_red.status = "complete"`
|
|
582
|
-
|
|
583
|
-
---
|
|
584
|
-
|
|
585
|
-
## Phase 9: TDD GREEN
|
|
586
|
-
|
|
587
|
-
**Goal:** Implement component to pass tests
|
|
588
|
-
|
|
589
|
-
### Create Component Files
|
|
590
|
-
|
|
591
|
-
```typescript
|
|
592
|
-
// src/components/[Name]/[Name].tsx
|
|
593
|
-
|
|
594
|
-
import * as React from 'react';
|
|
595
|
-
import { cva, type VariantProps } from 'class-variance-authority';
|
|
596
|
-
import { cn } from '@/lib/utils';
|
|
597
|
-
import { [Name]Props } from './[Name].types';
|
|
598
|
-
|
|
599
|
-
const [name]Variants = cva(
|
|
600
|
-
'inline-flex items-center justify-center rounded-md font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2',
|
|
601
|
-
{
|
|
602
|
-
variants: {
|
|
603
|
-
variant: {
|
|
604
|
-
primary: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
|
605
|
-
secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
|
606
|
-
destructive: 'bg-destructive text-destructive-foreground hover:bg-destructive/90',
|
|
607
|
-
},
|
|
608
|
-
size: {
|
|
609
|
-
sm: 'h-8 px-3 text-sm',
|
|
610
|
-
md: 'h-10 px-4 text-base',
|
|
611
|
-
lg: 'h-12 px-6 text-lg',
|
|
612
|
-
},
|
|
613
|
-
},
|
|
614
|
-
defaultVariants: {
|
|
615
|
-
variant: 'primary',
|
|
616
|
-
size: 'md',
|
|
617
|
-
},
|
|
618
|
-
}
|
|
619
|
-
);
|
|
620
|
-
|
|
621
|
-
export function [Name]({
|
|
622
|
-
variant,
|
|
623
|
-
size,
|
|
624
|
-
loading,
|
|
625
|
-
disabled,
|
|
626
|
-
className,
|
|
627
|
-
children,
|
|
628
|
-
...props
|
|
629
|
-
}: [Name]Props) {
|
|
630
|
-
return (
|
|
631
|
-
<button
|
|
632
|
-
className={cn([name]Variants({ variant, size }), className)}
|
|
633
|
-
disabled={disabled || loading}
|
|
634
|
-
aria-busy={loading}
|
|
635
|
-
{...props}
|
|
636
|
-
>
|
|
637
|
-
{loading && <Spinner className="mr-2" />}
|
|
638
|
-
{children}
|
|
639
|
-
</button>
|
|
640
|
-
);
|
|
641
|
-
}
|
|
642
|
-
```
|
|
643
|
-
|
|
644
|
-
### Create Barrel Export
|
|
645
|
-
|
|
646
|
-
```typescript
|
|
647
|
-
// src/components/[Name]/index.ts
|
|
648
|
-
|
|
649
|
-
export { [Name] } from './[Name]';
|
|
650
|
-
export type { [Name]Props } from './[Name].types';
|
|
651
|
-
```
|
|
652
|
-
|
|
653
|
-
### Run Tests (Expect Pass)
|
|
654
|
-
|
|
655
|
-
```bash
|
|
656
|
-
pnpm test src/components/[Name]
|
|
657
|
-
```
|
|
658
|
-
|
|
659
|
-
**All tests MUST pass before proceeding.**
|
|
660
|
-
|
|
661
|
-
Update state: `phases.tdd_green.status = "complete"`
|
|
662
|
-
|
|
663
|
-
---
|
|
664
|
-
|
|
665
|
-
## Phase 10: VERIFY (4-STEP MANDATORY)
|
|
666
|
-
|
|
667
|
-
**Goal:** Comprehensive verification across 4 dimensions
|
|
668
|
-
|
|
669
|
-
### Step 1: Responsive Check
|
|
670
|
-
|
|
671
|
-
Run Storybook at different viewports or use Playwright:
|
|
672
|
-
|
|
673
|
-
```
|
|
674
|
-
Step 1: Responsive Check
|
|
675
|
-
|
|
676
|
-
Desktop (1920px): [Checking...]
|
|
677
|
-
Tablet (768px): [Checking...]
|
|
678
|
-
Mobile (375px): [Checking...]
|
|
679
|
-
```
|
|
680
|
-
|
|
681
|
-
Verify component renders correctly at all sizes.
|
|
682
|
-
|
|
683
|
-
### Step 2: Brand Guide Match
|
|
684
|
-
|
|
685
|
-
Compare implementation to `.claude/BRAND_GUIDE.md`:
|
|
686
|
-
|
|
687
|
-
```
|
|
688
|
-
Step 2: Brand Guide Match
|
|
689
|
-
|
|
690
|
-
Colors: [Matches brand guide]
|
|
691
|
-
Typography: [Matches brand guide]
|
|
692
|
-
Spacing: [Matches brand guide]
|
|
693
|
-
Border Radius: [Matches brand guide]
|
|
694
|
-
Focus Ring: [Matches brand guide]
|
|
695
|
-
```
|
|
696
|
-
|
|
697
|
-
### Step 3: All Tests Passed
|
|
698
|
-
|
|
699
|
-
```
|
|
700
|
-
Step 3: Test Results
|
|
701
|
-
|
|
702
|
-
Unit tests: [X/X passed]
|
|
703
|
-
Storybook stories: [X/X render]
|
|
704
|
-
A11y audit: [WCAG 2.1 AA compliant]
|
|
705
|
-
```
|
|
706
|
-
|
|
707
|
-
Run accessibility audit:
|
|
708
|
-
|
|
709
|
-
```bash
|
|
710
|
-
pnpm dlx @axe-core/cli http://localhost:6006/iframe.html?id=components-[name]--primary
|
|
711
|
-
```
|
|
712
|
-
|
|
713
|
-
### Step 4: Performance Metrics
|
|
714
|
-
|
|
715
|
-
Log memory and re-renders:
|
|
716
|
-
|
|
717
|
-
```
|
|
718
|
-
Step 4: Performance Metrics
|
|
719
|
-
|
|
720
|
-
Memory usage: [X MB]
|
|
721
|
-
Re-renders on mount: [X]
|
|
722
|
-
Re-renders on change: [X]
|
|
723
|
-
Bundle size impact: [+X KB]
|
|
724
|
-
```
|
|
725
|
-
|
|
726
|
-
### Step 5: Visual Regression (Playwright)
|
|
727
|
-
|
|
728
|
-
Run visual regression tests to capture baseline screenshots:
|
|
729
|
-
|
|
730
|
-
```bash
|
|
731
|
-
pnpm playwright test src/components/[Name]/[Name].visual.spec.ts --update-snapshots
|
|
732
|
-
```
|
|
733
|
-
|
|
734
|
-
This creates baseline screenshots in Storybook for:
|
|
735
|
-
|
|
736
|
-
- All variants (primary, secondary, disabled, loading)
|
|
737
|
-
- All sizes (sm, md, lg)
|
|
738
|
-
- All viewports (mobile, tablet, desktop)
|
|
739
|
-
- Interaction states (hover, focus)
|
|
740
|
-
- Dark mode (if supported)
|
|
741
|
-
|
|
742
|
-
```
|
|
743
|
-
Step 5: Visual Regression
|
|
744
|
-
|
|
745
|
-
Variant screenshots: [X/X captured]
|
|
746
|
-
Responsive viewports: [3/3 captured]
|
|
747
|
-
Interaction states: [Hover, Focus captured]
|
|
748
|
-
Dark mode: [Captured if supported]
|
|
749
|
-
```
|
|
750
|
-
|
|
751
|
-
**Present 5-step results:**
|
|
752
|
-
|
|
753
|
-
```
|
|
754
|
-
Phase 10: VERIFICATION (5-Step)
|
|
755
|
-
|
|
756
|
-
Step 1: Responsive Check
|
|
757
|
-
Desktop (1920px) - Renders correctly
|
|
758
|
-
Tablet (768px) - Renders correctly
|
|
759
|
-
Mobile (375px) - Renders correctly
|
|
760
|
-
|
|
761
|
-
Step 2: Brand Guide Match
|
|
762
|
-
Colors match .claude/BRAND_GUIDE.md
|
|
763
|
-
Typography matches
|
|
764
|
-
Spacing matches
|
|
765
|
-
Border radius matches
|
|
766
|
-
|
|
767
|
-
Step 3: All Tests Passed
|
|
768
|
-
Unit tests: 8/8 passed
|
|
769
|
-
Storybook stories: 4/4 render
|
|
770
|
-
A11y audit: WCAG 2.1 AA compliant
|
|
771
|
-
|
|
772
|
-
Step 4: Performance Metrics
|
|
773
|
-
Memory usage: 2.1 MB
|
|
774
|
-
Re-renders on mount: 1 (optimal)
|
|
775
|
-
Re-renders on prop change: 1 (optimal)
|
|
776
|
-
|
|
777
|
-
Step 5: Visual Regression
|
|
778
|
-
Playwright screenshots: 12/12 captured
|
|
779
|
-
Baseline images saved to: __snapshots__/
|
|
780
|
-
|
|
781
|
-
All 5 checks passed!
|
|
782
|
-
|
|
783
|
-
Any issues to fix?
|
|
784
|
-
A) No, all good - proceed
|
|
785
|
-
B) Yes, need to fix [specify]
|
|
786
|
-
```
|
|
787
|
-
|
|
788
|
-
**Wait for user response. Loop back if issues found.**
|
|
789
|
-
|
|
790
|
-
---
|
|
791
|
-
|
|
792
|
-
## Phase 11: CODE REVIEW (Greptile)
|
|
793
|
-
|
|
794
|
-
**Goal:** AI-powered code review before refactoring
|
|
795
|
-
|
|
796
|
-
Run Greptile code review to catch issues early:
|
|
797
|
-
|
|
798
|
-
- Bug detection with full codebase context
|
|
799
|
-
- Security vulnerability scanning (OWASP top 10)
|
|
800
|
-
- Performance issue identification
|
|
801
|
-
- Accessibility concerns
|
|
802
|
-
|
|
803
|
-
**Requires:** GREPTILE_API_KEY + GITHUB_TOKEN
|
|
804
|
-
|
|
805
|
-
Present results:
|
|
806
|
-
|
|
807
|
-
```
|
|
808
|
-
Phase 11: CODE REVIEW
|
|
809
|
-
|
|
810
|
-
Greptile found [N] issue(s):
|
|
811
|
-
|
|
812
|
-
1. [file:line] - [severity] [issue description]
|
|
813
|
-
2. [file:line] - [severity] [issue description]
|
|
814
|
-
|
|
815
|
-
How should I proceed?
|
|
816
|
-
A) Fix all issues in refactor phase
|
|
817
|
-
B) Fix critical only, defer others
|
|
818
|
-
C) Skip - no issues to fix
|
|
819
|
-
```
|
|
820
|
-
|
|
821
|
-
**Wait for user response.**
|
|
822
|
-
|
|
823
|
-
---
|
|
824
|
-
|
|
825
|
-
## Phase 12: TDD REFACTOR
|
|
826
|
-
|
|
827
|
-
**Goal:** Fix code review issues + clean up code while tests pass
|
|
828
|
-
|
|
829
|
-
Refactoring checklist:
|
|
830
|
-
|
|
831
|
-
- [ ] Address Greptile issues (bugs, security, performance)
|
|
832
|
-
- [ ] Extract repeated logic to custom hooks
|
|
833
|
-
- [ ] Optimize re-renders with useMemo/useCallback if needed
|
|
834
|
-
- [ ] Clean up unused imports
|
|
835
|
-
- [ ] Ensure consistent code style
|
|
836
|
-
- [ ] Add JSDoc comments to exported functions
|
|
837
|
-
|
|
838
|
-
Run tests after each refactor:
|
|
839
|
-
|
|
840
|
-
```bash
|
|
841
|
-
pnpm test src/components/[Name]
|
|
842
|
-
```
|
|
843
|
-
|
|
844
|
-
---
|
|
845
|
-
|
|
846
|
-
## Phase 13: DOCUMENTATION
|
|
847
|
-
|
|
848
|
-
**Goal:** Complete all documentation
|
|
849
|
-
|
|
850
|
-
### Storybook Autodocs
|
|
851
|
-
|
|
852
|
-
Ensure `tags: ['autodocs']` is set in story meta.
|
|
853
|
-
|
|
854
|
-
### JSDoc Comments
|
|
855
|
-
|
|
856
|
-
Add to component file:
|
|
857
|
-
|
|
858
|
-
````typescript
|
|
859
|
-
/**
|
|
860
|
-
* [Name] component - [Brief description]
|
|
861
|
-
*
|
|
862
|
-
* @example
|
|
863
|
-
* ```tsx
|
|
864
|
-
* <[Name] variant="primary" size="md">
|
|
865
|
-
* Click me
|
|
866
|
-
* </[Name]>
|
|
867
|
-
* ```
|
|
868
|
-
*/
|
|
869
|
-
````
|
|
870
|
-
|
|
871
|
-
### Registry Entry
|
|
872
|
-
|
|
873
|
-
Update `.claude/registry.json`:
|
|
874
|
-
|
|
875
|
-
```json
|
|
876
|
-
{
|
|
877
|
-
"components": {
|
|
878
|
-
"[name]": {
|
|
879
|
-
"name": "[Name]",
|
|
880
|
-
"description": "[From interview]",
|
|
881
|
-
"file": "src/components/[Name]/[Name].tsx",
|
|
882
|
-
"story": "src/components/[Name]/[Name].stories.tsx",
|
|
883
|
-
"tests": "src/components/[Name]/__tests__/",
|
|
884
|
-
"props_interface": "[Name]Props",
|
|
885
|
-
"variants": ["primary", "secondary"],
|
|
886
|
-
"accessibility": "wcag2aa",
|
|
887
|
-
"responsive": true,
|
|
888
|
-
"status": "complete",
|
|
889
|
-
"created_at": "[date]"
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
}
|
|
893
|
-
```
|
|
894
|
-
|
|
895
|
-
Present checklist:
|
|
896
|
-
|
|
897
|
-
```
|
|
898
|
-
Phase 12: DOCUMENTATION
|
|
899
|
-
|
|
900
|
-
Storybook autodocs: [Complete]
|
|
901
|
-
JSDoc comments: [Complete]
|
|
902
|
-
Types exported: [Complete]
|
|
903
|
-
Registry updated: [Complete]
|
|
904
|
-
|
|
905
|
-
Documentation complete?
|
|
906
|
-
A) Yes, proceed to completion
|
|
907
|
-
B) No, need changes
|
|
908
|
-
```
|
|
909
|
-
|
|
910
|
-
---
|
|
911
|
-
|
|
912
|
-
## Phase 14: COMPLETION
|
|
913
|
-
|
|
914
|
-
**Goal:** Final output and continuation prompt
|
|
915
|
-
|
|
916
|
-
### Update UI Showcase
|
|
917
|
-
|
|
918
|
-
If first component, create showcase page. Otherwise, component is auto-added via registry.
|
|
919
|
-
|
|
920
|
-
### Final Output
|
|
921
|
-
|
|
922
|
-
```
|
|
923
|
-
[Name] component complete!
|
|
924
|
-
|
|
925
|
-
Created Files:
|
|
926
|
-
- src/components/[Name]/[Name].tsx
|
|
927
|
-
- src/components/[Name]/[Name].types.ts
|
|
928
|
-
- src/components/[Name]/[Name].stories.tsx
|
|
929
|
-
- src/components/[Name]/__tests__/[Name].test.tsx
|
|
930
|
-
- src/components/[Name]/__tests__/[Name].visual.spec.ts
|
|
931
|
-
- src/components/[Name]/index.ts
|
|
932
|
-
|
|
933
|
-
Tests: All passed (ran during Phase 8-9)
|
|
934
|
-
Visual: Playwright screenshots captured (Phase 10)
|
|
935
|
-
A11y: WCAG 2.1 AA compliant
|
|
936
|
-
Brand: Matches .claude/BRAND_GUIDE.md
|
|
937
|
-
|
|
938
|
-
Registry: Added to .claude/registry.json
|
|
939
|
-
|
|
940
|
-
Would you like to create another component or page?
|
|
941
|
-
```
|
|
942
|
-
|
|
943
|
-
### Showcase Redirect
|
|
944
|
-
|
|
945
|
-
After successful component/page creation, output:
|
|
946
|
-
|
|
947
|
-
```
|
|
948
|
-
Your [component|page] has been added to the showcase!
|
|
949
|
-
|
|
950
|
-
View it at: http://localhost:3000/ui-showcase
|
|
951
|
-
|
|
952
|
-
Or run `pnpm dev` and navigate to /ui-showcase to:
|
|
953
|
-
- Preview your component with live editing (Sandpack)
|
|
954
|
-
- Test different variants and props
|
|
955
|
-
- View at different viewport sizes
|
|
956
|
-
```
|
|
957
|
-
|
|
958
|
-
For Sandpack live editing, install: `pnpm add @codesandbox/sandpack-react`
|
|
959
|
-
|
|
960
|
-
Update state: `phases.completion.status = "complete"`
|
|
961
|
-
|
|
962
|
-
### End-of-Workflow Summary
|
|
963
|
-
|
|
964
|
-
After successful component creation, display:
|
|
965
|
-
|
|
966
|
-
```
|
|
967
|
-
═══════════════════════════════════════════════════════════════
|
|
968
|
-
✅ COMPONENT CREATED: [ComponentName]
|
|
969
|
-
|
|
970
|
-
📍 Quick Links:
|
|
971
|
-
• Preview it: /ui-showcase
|
|
972
|
-
• Storybook: http://localhost:6006
|
|
973
|
-
• Run tests: pnpm test src/components/[ComponentName]
|
|
974
|
-
• Visual tests: pnpm playwright test --grep "[ComponentName]"
|
|
975
|
-
|
|
976
|
-
📊 Dashboard: /hustle-dev-dashboard
|
|
977
|
-
|
|
978
|
-
Next Steps:
|
|
979
|
-
• /hustle-ui-create-page - Create a page using this component
|
|
980
|
-
• /commit - Commit your changes
|
|
981
|
-
═══════════════════════════════════════════════════════════════
|
|
982
|
-
```
|
|
983
|
-
|
|
984
|
-
---
|
|
985
|
-
|
|
986
|
-
# Page Mode (14 Phases)
|
|
987
|
-
|
|
988
|
-
Similar flow with these differences:
|
|
989
|
-
|
|
990
|
-
- **Phase 5:** Select components FROM registry instead of checking ShadCN
|
|
991
|
-
- **Phase 6:** Create page data schema (API responses, form data)
|
|
992
|
-
- **Phase 7:** Check API routes and auth configuration
|
|
993
|
-
- **Phase 8:** Write Playwright E2E tests instead of Storybook stories
|
|
994
|
-
- **Phase 9:** Create page in `src/app/[name]/page.tsx`
|
|
995
|
-
- **Phase 10:** Run full Playwright E2E tests
|
|
996
|
-
|
|
997
|
-
See full page mode documentation in `/hustle-ui-create-page.md` (if implementing page mode).
|
|
998
|
-
|
|
999
|
-
---
|
|
1000
|
-
|
|
1001
|
-
## State File Structure
|
|
1002
|
-
|
|
1003
|
-
```json
|
|
1004
|
-
{
|
|
1005
|
-
"version": "3.9.0",
|
|
1006
|
-
"workflow": "ui-create-component",
|
|
1007
|
-
"active_element": "[name]",
|
|
1008
|
-
"elements": {
|
|
1009
|
-
"[name]": {
|
|
1010
|
-
"type": "component",
|
|
1011
|
-
"status": "in_progress",
|
|
1012
|
-
"started_at": "2025-12-12T15:30:00Z",
|
|
1013
|
-
"ui_config": {
|
|
1014
|
-
"mode": "component",
|
|
1015
|
-
"component_type": "atom",
|
|
1016
|
-
"design_system": "shadcn",
|
|
1017
|
-
"variants": ["size", "color"],
|
|
1018
|
-
"accessibility_level": "wcag2aa",
|
|
1019
|
-
"use_brand_guide": true
|
|
1020
|
-
},
|
|
1021
|
-
"phases": {
|
|
1022
|
-
"disambiguation": { "status": "complete" },
|
|
1023
|
-
"scope": { "status": "complete" },
|
|
1024
|
-
"design_research": {
|
|
1025
|
-
"status": "complete",
|
|
1026
|
-
"brand_guide_applied": true
|
|
1027
|
-
},
|
|
1028
|
-
"interview": { "status": "complete", "decisions": {} },
|
|
1029
|
-
"component_analysis": { "status": "complete", "dependencies": [] },
|
|
1030
|
-
"props_schema": { "status": "complete", "schema_file": "..." },
|
|
1031
|
-
"environment_check": { "status": "complete" },
|
|
1032
|
-
"tdd_red": { "status": "complete", "tests_failed": true },
|
|
1033
|
-
"tdd_green": { "status": "complete", "tests_passed": true },
|
|
1034
|
-
"verify": { "status": "complete", "four_step_passed": true },
|
|
1035
|
-
"tdd_refactor": { "status": "complete" },
|
|
1036
|
-
"documentation": { "status": "complete" },
|
|
1037
|
-
"completion": { "status": "complete" }
|
|
1038
|
-
}
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1042
|
-
```
|
|
1043
|
-
|
|
1044
|
-
---
|
|
1045
|
-
|
|
1046
|
-
## Key Principles
|
|
1047
|
-
|
|
1048
|
-
1. **ALWAYS ask user** - Never proceed without explicit response
|
|
1049
|
-
2. **Brand guide first** - Check and apply before implementation
|
|
1050
|
-
3. **ShadCN detection** - Reuse existing components when available
|
|
1051
|
-
4. **4-Step verification** - All 4 checks MUST pass
|
|
1052
|
-
5. **Tests run automatically** - LLM executes tests, user sees results
|
|
1053
|
-
6. **Showcase link guaranteed** - Always output at completion
|
|
1054
|
-
|
|
1055
|
-
---
|
|
1056
|
-
|
|
1057
|
-
**Version:** 4.0.0
|
|
1058
|
-
**Last Updated:** 2025-12-28
|