@champpaba/claude-agent-kit 3.6.0 → 3.6.2
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/package.json +1 -1
- package/skills/design-extract/CLAUDE.md +1 -0
- package/skills/design-extract/SKILL.md +6 -0
- package/skills/design-setup/CLAUDE.md +1 -0
- package/skills/design-setup/SKILL.md +6 -0
- package/skills/page-planner/SKILL.md +6 -0
- package/.claude/commands/designsetup.md +0 -1405
- package/.claude/commands/extract.md +0 -733
- package/.claude/commands/pageplan.md +0 -862
|
@@ -1,733 +0,0 @@
|
|
|
1
|
-
# /extract - Extract Design System from Website
|
|
2
|
-
|
|
3
|
-
You are an expert design systems engineer with deep knowledge of CSS, animations, and UX patterns.
|
|
4
|
-
|
|
5
|
-
Your task is to extract comprehensive design data from a website and save it as a complete YAML file with psychology analysis.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 📖 Usage
|
|
10
|
-
|
|
11
|
-
```bash
|
|
12
|
-
/extract <URL>
|
|
13
|
-
|
|
14
|
-
Arguments:
|
|
15
|
-
URL Required. Website URL to extract from
|
|
16
|
-
|
|
17
|
-
Examples:
|
|
18
|
-
/extract https://airbnb.com
|
|
19
|
-
/extract https://linear.app
|
|
20
|
-
/extract https://stripe.com
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## 🎯 Mission
|
|
26
|
-
|
|
27
|
-
Extract ALL design data from a website and save to `design-system/extracted/{site-name}/`:
|
|
28
|
-
- `data.yaml` - Complete 17-section design data + psychology analysis + animations
|
|
29
|
-
- `screenshots/` - Component screenshots (default + hover/focus states)
|
|
30
|
-
|
|
31
|
-
**Key Principles:**
|
|
32
|
-
1. **17 Sections Complete**: Colors with usage, typography with sizes, components with animations
|
|
33
|
-
2. **Psychology Included**: Target audience, emotions evoked, why it works
|
|
34
|
-
3. **Component-Level Detail**: Every component type with all states
|
|
35
|
-
4. **Animation Capture**: Before/after for all interactive states
|
|
36
|
-
|
|
37
|
-
---
|
|
38
|
-
|
|
39
|
-
## 🔍 STEP 0: Parse Input & Setup
|
|
40
|
-
|
|
41
|
-
### 0.1: Validate and Normalize URL
|
|
42
|
-
|
|
43
|
-
1. Check if URL argument is provided
|
|
44
|
-
- If missing, return error: "URL required. Usage: /extract https://airbnb.com"
|
|
45
|
-
2. Trim whitespace from URL
|
|
46
|
-
3. Add "https://" prefix if URL doesn't start with "http://" or "https://"
|
|
47
|
-
4. Parse hostname and auto-detect site name:
|
|
48
|
-
- Remove "www." prefix if present
|
|
49
|
-
- Remove top-level domain (TLD) to get clean site name
|
|
50
|
-
- Example: "www.airbnb.com" → "airbnb"
|
|
51
|
-
|
|
52
|
-
### 0.2: Check for Existing Extraction
|
|
53
|
-
|
|
54
|
-
1. Build path: `design-system/extracted/{siteName}/data.yaml`
|
|
55
|
-
2. If file exists:
|
|
56
|
-
- Read existing YAML file
|
|
57
|
-
- Extract `meta.extracted_at` field
|
|
58
|
-
- Ask user via AskUserQuestion:
|
|
59
|
-
- Question: "Site '{siteName}' was already extracted on {extractedDate}. Re-extract?"
|
|
60
|
-
- Options: "Yes, re-extract" (overwrite) or "No, cancel" (keep existing)
|
|
61
|
-
- If user chooses "No, cancel", exit with message: "Extraction cancelled. Existing data preserved."
|
|
62
|
-
|
|
63
|
-
### 0.3: Create Output Directories
|
|
64
|
-
|
|
65
|
-
Use Bash to create directory structure:
|
|
66
|
-
```bash
|
|
67
|
-
mkdir -p design-system/extracted/{siteName}/screenshots
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
**Report:**
|
|
71
|
-
```
|
|
72
|
-
🚀 Extraction Started
|
|
73
|
-
|
|
74
|
-
📍 URL: ${url}
|
|
75
|
-
📁 Site: ${siteName}
|
|
76
|
-
📂 Output: design-system/extracted/${siteName}/
|
|
77
|
-
|
|
78
|
-
⏳ Navigating to site...
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
---
|
|
82
|
-
|
|
83
|
-
## STEP 1: Navigate & Wait
|
|
84
|
-
|
|
85
|
-
### 1.1: Navigate to URL
|
|
86
|
-
|
|
87
|
-
Use agent-browser to navigate to the target URL:
|
|
88
|
-
```bash
|
|
89
|
-
agent-browser open {url}
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
### 1.2: Smart Wait for Page Load
|
|
93
|
-
|
|
94
|
-
1. Take DOM snapshot (verbose: false) to analyze page structure
|
|
95
|
-
2. From snapshot, find heading elements (filter lines containing `[heading]`)
|
|
96
|
-
3. If headings found:
|
|
97
|
-
- Extract text from first heading
|
|
98
|
-
- Use agent-browser wait_for to wait for that text (timeout: 15000ms)
|
|
99
|
-
- This ensures the main content is loaded
|
|
100
|
-
4. If no headings found or wait fails:
|
|
101
|
-
- Fallback to sleep 5000ms
|
|
102
|
-
|
|
103
|
-
### 1.3: Verify Document Ready
|
|
104
|
-
|
|
105
|
-
1. Evaluate script to check document.readyState
|
|
106
|
-
2. If not "complete", sleep additional 3000ms to ensure full page load
|
|
107
|
-
|
|
108
|
-
**Report:**
|
|
109
|
-
```
|
|
110
|
-
✅ Page loaded successfully
|
|
111
|
-
|
|
112
|
-
🔄 Extracting CSS data (17 sections)...
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
---
|
|
116
|
-
|
|
117
|
-
## STEP 2: Extract CSS Data (17 Sections in Parallel)
|
|
118
|
-
|
|
119
|
-
Run all extraction evaluations in parallel for speed. Use agent-browser `evaluate_script` for each extraction function below.
|
|
120
|
-
|
|
121
|
-
**Parallel Execution Strategy:**
|
|
122
|
-
- Execute all 8 extraction functions concurrently
|
|
123
|
-
- Collect results: colors, typography, shadows, spacing, buttons, cards, inputs, animations
|
|
124
|
-
- Non-critical failures should not block other extractions (use fallback empty arrays)
|
|
125
|
-
|
|
126
|
-
### 2.1: Extract Colors
|
|
127
|
-
|
|
128
|
-
Use agent-browser to evaluate script that:
|
|
129
|
-
|
|
130
|
-
1. **Query all elements**: `document.querySelectorAll('*')`
|
|
131
|
-
2. **For each element**, extract using `window.getComputedStyle()`:
|
|
132
|
-
- Background color (skip transparent: `rgba(0, 0, 0, 0)`)
|
|
133
|
-
- Text color
|
|
134
|
-
- Border color (skip transparent)
|
|
135
|
-
3. **Convert RGB to HEX**: Parse RGB values and convert to uppercase hex format
|
|
136
|
-
4. **Detect usage context** based on element tag/class:
|
|
137
|
-
- Background usage: button-bg, nav-bg, card-bg, hero-bg, page-bg, surface
|
|
138
|
-
- Text usage: heading, link, button-text, muted-text, body-text
|
|
139
|
-
- Border usage: input-border, card-border, divider
|
|
140
|
-
5. **Count frequency** of each color (how many times used)
|
|
141
|
-
6. **Sort by count** (most used first) and take top 20 per category
|
|
142
|
-
|
|
143
|
-
**Output format:**
|
|
144
|
-
```yaml
|
|
145
|
-
colors:
|
|
146
|
-
backgrounds:
|
|
147
|
-
- hex: "#FFFFFF"
|
|
148
|
-
rgb: "rgb(255, 255, 255)"
|
|
149
|
-
usage: "page-bg"
|
|
150
|
-
count: 45
|
|
151
|
-
texts:
|
|
152
|
-
- hex: "#000000"
|
|
153
|
-
usage: "body-text"
|
|
154
|
-
count: 32
|
|
155
|
-
borders:
|
|
156
|
-
- hex: "#E5E7EB"
|
|
157
|
-
usage: "divider"
|
|
158
|
-
count: 12
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
### 2.2: Extract Typography
|
|
162
|
-
|
|
163
|
-
Use agent-browser to evaluate script that:
|
|
164
|
-
|
|
165
|
-
1. **Extract heading styles** (h1, h2, h3):
|
|
166
|
-
- Query first 3 instances of each heading tag
|
|
167
|
-
- For each, extract using `window.getComputedStyle()`:
|
|
168
|
-
- Sample text (first 50 characters)
|
|
169
|
-
- fontSize, fontWeight, fontFamily
|
|
170
|
-
- lineHeight, letterSpacing, textTransform
|
|
171
|
-
- color
|
|
172
|
-
2. **Extract body text styles** (p, div, span):
|
|
173
|
-
- Query first 20 elements with text content > 20 characters
|
|
174
|
-
- Extract: fontSize, fontWeight, lineHeight, fontFamily, color
|
|
175
|
-
3. **Collect unique values**:
|
|
176
|
-
- All font families used
|
|
177
|
-
- All font weights (sorted numerically)
|
|
178
|
-
- All font sizes (sorted by value)
|
|
179
|
-
|
|
180
|
-
**Output format:**
|
|
181
|
-
```yaml
|
|
182
|
-
typography:
|
|
183
|
-
h1:
|
|
184
|
-
- text: "Welcome to our site"
|
|
185
|
-
fontSize: "48px"
|
|
186
|
-
fontWeight: "700"
|
|
187
|
-
fontFamily: "Inter, sans-serif"
|
|
188
|
-
h2:
|
|
189
|
-
- fontSize: "32px"
|
|
190
|
-
fontWeight: "600"
|
|
191
|
-
body:
|
|
192
|
-
- fontSize: "16px"
|
|
193
|
-
fontWeight: "400"
|
|
194
|
-
lineHeight: "1.5"
|
|
195
|
-
allFonts: ["Inter", "Roboto"]
|
|
196
|
-
allWeights: ["400", "500", "600", "700"]
|
|
197
|
-
allSizes: ["14px", "16px", "24px", "32px", "48px"]
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### 2.3: Extract Shadows & Effects
|
|
201
|
-
|
|
202
|
-
Use agent-browser to evaluate script that:
|
|
203
|
-
|
|
204
|
-
1. **Query all elements**: `document.querySelectorAll('*')`
|
|
205
|
-
2. **For each element**, extract using `window.getComputedStyle()`:
|
|
206
|
-
- boxShadow (skip "none")
|
|
207
|
-
- borderRadius (skip "0px")
|
|
208
|
-
- borderWidth (skip "0px")
|
|
209
|
-
3. **Collect unique values** using Set to avoid duplicates
|
|
210
|
-
4. **Limit results**:
|
|
211
|
-
- Top 15 unique box shadows
|
|
212
|
-
- Top 15 unique border radii
|
|
213
|
-
- Top 10 unique border widths
|
|
214
|
-
|
|
215
|
-
**Output format:**
|
|
216
|
-
```yaml
|
|
217
|
-
shadows:
|
|
218
|
-
- "0 1px 3px rgba(0, 0, 0, 0.1)"
|
|
219
|
-
- "0 4px 6px rgba(0, 0, 0, 0.1)"
|
|
220
|
-
borderRadii:
|
|
221
|
-
- "4px"
|
|
222
|
-
- "8px"
|
|
223
|
-
- "12px"
|
|
224
|
-
borderWidths:
|
|
225
|
-
- "1px"
|
|
226
|
-
- "2px"
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
### 2.4: Extract Spacing
|
|
230
|
-
|
|
231
|
-
Use agent-browser to evaluate script that:
|
|
232
|
-
|
|
233
|
-
1. **Query first 100 elements** for spacing analysis
|
|
234
|
-
2. **For each element**, extract using `window.getComputedStyle()`:
|
|
235
|
-
- Padding (all sides: top, right, bottom, left, shorthand) - skip "0px"
|
|
236
|
-
- Margin (top, bottom only) - skip "0px" and "auto"
|
|
237
|
-
- Gap (flexbox/grid) - skip "normal" and "0px"
|
|
238
|
-
3. **Detect spacing grid pattern**:
|
|
239
|
-
- Parse all spacing values to numbers
|
|
240
|
-
- Calculate Greatest Common Divisor (GCD) to find base unit
|
|
241
|
-
- Common pattern: 4px or 8px base grid
|
|
242
|
-
- Fallback to 8px if pattern unclear
|
|
243
|
-
4. **Limit results**:
|
|
244
|
-
- Top 20 unique padding values
|
|
245
|
-
- Top 20 unique margin values
|
|
246
|
-
- Top 10 unique gap values
|
|
247
|
-
- Top 15 most common spacing values overall
|
|
248
|
-
|
|
249
|
-
**Output format:**
|
|
250
|
-
```yaml
|
|
251
|
-
spacing:
|
|
252
|
-
detectedGrid: 8
|
|
253
|
-
paddings: ["8px", "16px", "24px", "32px"]
|
|
254
|
-
margins: ["8px", "16px", "24px"]
|
|
255
|
-
gaps: ["8px", "16px"]
|
|
256
|
-
commonValues: [8, 16, 24, 32, 40, 48]
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
### 2.5: Extract Buttons
|
|
260
|
-
|
|
261
|
-
Use agent-browser to evaluate script that:
|
|
262
|
-
|
|
263
|
-
1. **Query button elements** with selectors:
|
|
264
|
-
- `button`, `a[role="button"]`
|
|
265
|
-
- `.btn`, `[class*="button"]`, `[class*="Button"]`
|
|
266
|
-
2. **Take first 10 buttons** found
|
|
267
|
-
3. **For each button**:
|
|
268
|
-
- Add `data-extract-id` attribute (e.g., "button-0", "button-1")
|
|
269
|
-
- Extract using `window.getComputedStyle()`:
|
|
270
|
-
- Text content (first 30 characters)
|
|
271
|
-
- backgroundColor, color, padding
|
|
272
|
-
- border, borderRadius
|
|
273
|
-
- fontSize, fontWeight
|
|
274
|
-
- boxShadow, transition
|
|
275
|
-
|
|
276
|
-
**Why add data-extract-id**: Enables later re-querying for hover/focus state extraction.
|
|
277
|
-
|
|
278
|
-
### 2.6: Extract Cards
|
|
279
|
-
|
|
280
|
-
Use agent-browser to evaluate script that:
|
|
281
|
-
|
|
282
|
-
1. **Query card-like elements** with selectors:
|
|
283
|
-
- `[class*="card"]`, `[class*="Card"]`
|
|
284
|
-
- `article`, `section`
|
|
285
|
-
- `[class*="box"]`, `[class*="Box"]`
|
|
286
|
-
2. **Take first 10 cards** found
|
|
287
|
-
3. **For each card**:
|
|
288
|
-
- Add `data-extract-id` attribute (e.g., "card-0", "card-1")
|
|
289
|
-
- Extract className for reference
|
|
290
|
-
- Extract using `window.getComputedStyle()`:
|
|
291
|
-
- backgroundColor, padding
|
|
292
|
-
- border, borderRadius
|
|
293
|
-
- boxShadow, transition
|
|
294
|
-
|
|
295
|
-
### 2.7: Extract Input Fields
|
|
296
|
-
|
|
297
|
-
Use agent-browser to evaluate script that:
|
|
298
|
-
|
|
299
|
-
1. **Query input elements** with selectors:
|
|
300
|
-
- `input[type="text"]`, `input[type="email"]`, `input[type="password"]`
|
|
301
|
-
- `textarea`
|
|
302
|
-
2. **Take first 5 inputs** found
|
|
303
|
-
3. **For each input**:
|
|
304
|
-
- Add `data-extract-id` attribute (e.g., "input-0", "input-1")
|
|
305
|
-
- Extract type (text/email/password/textarea)
|
|
306
|
-
- Extract using `window.getComputedStyle()`:
|
|
307
|
-
- height, padding
|
|
308
|
-
- border, borderRadius
|
|
309
|
-
- fontSize, backgroundColor
|
|
310
|
-
- transition
|
|
311
|
-
|
|
312
|
-
### 2.8: Extract Animations
|
|
313
|
-
|
|
314
|
-
Use agent-browser to evaluate script that:
|
|
315
|
-
|
|
316
|
-
1. **Extract CSS @keyframes animations**:
|
|
317
|
-
- Loop through all document.styleSheets
|
|
318
|
-
- For each stylesheet, check cssRules
|
|
319
|
-
- Find rules with type `CSSRule.KEYFRAMES_RULE`
|
|
320
|
-
- Extract: animation name and full CSS text
|
|
321
|
-
- Handle CORS errors gracefully (skip external stylesheets)
|
|
322
|
-
|
|
323
|
-
2. **Extract CSS transitions**:
|
|
324
|
-
- Query first 50 elements
|
|
325
|
-
- For each, extract using `window.getComputedStyle()`:
|
|
326
|
-
- transition property
|
|
327
|
-
- transitionDuration
|
|
328
|
-
- transitionTimingFunction
|
|
329
|
-
- Skip default value: "all 0s ease 0s"
|
|
330
|
-
- Record element className or tagName for reference
|
|
331
|
-
|
|
332
|
-
**Output format:**
|
|
333
|
-
```yaml
|
|
334
|
-
animations:
|
|
335
|
-
keyframes:
|
|
336
|
-
- name: "fadeIn"
|
|
337
|
-
css: "@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }"
|
|
338
|
-
transitions:
|
|
339
|
-
- selector: "button"
|
|
340
|
-
transition: "all 0.3s ease"
|
|
341
|
-
transitionDuration: "0.3s"
|
|
342
|
-
transitionTimingFunction: "ease"
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
**Report:**
|
|
346
|
-
```
|
|
347
|
-
✅ CSS Data Extracted!
|
|
348
|
-
|
|
349
|
-
📊 Summary:
|
|
350
|
-
- Colors: ${colors.backgrounds.length} backgrounds, ${colors.texts.length} texts
|
|
351
|
-
- Typography: ${typography.allFonts.length} fonts, ${typography.allWeights.length} weights
|
|
352
|
-
- Shadows: ${shadows.shadows.length} unique values
|
|
353
|
-
- Spacing: ${spacing.detectedGrid}px grid detected
|
|
354
|
-
- Buttons: ${buttons.length} extracted
|
|
355
|
-
- Cards: ${cards.length} extracted
|
|
356
|
-
- Inputs: ${inputs.length} extracted
|
|
357
|
-
- Animations: ${animations.keyframes.length} @keyframes
|
|
358
|
-
|
|
359
|
-
🔄 Extracting component animations (hover/focus states)...
|
|
360
|
-
```
|
|
361
|
-
|
|
362
|
-
---
|
|
363
|
-
|
|
364
|
-
## STEP 3: Extract Component Animations (Interactive States)
|
|
365
|
-
|
|
366
|
-
For each component type, capture default and hover states to understand animations.
|
|
367
|
-
|
|
368
|
-
### 3.1: Button Hover States
|
|
369
|
-
|
|
370
|
-
For the **first 3 buttons** (to limit execution time):
|
|
371
|
-
|
|
372
|
-
1. **Find element by data-extract-id** (e.g., "button-0")
|
|
373
|
-
2. **Scroll element into view** (block: center) for visibility
|
|
374
|
-
3. **Wait 500ms** for scroll animation
|
|
375
|
-
4. **Take screenshot** of default state
|
|
376
|
-
- Save to: `design-system/extracted/{siteName}/screenshots/{btnId}-default.png`
|
|
377
|
-
5. **Capture default computed styles**:
|
|
378
|
-
- backgroundColor, color, boxShadow, transform
|
|
379
|
-
6. **Trigger hover state**:
|
|
380
|
-
- Dispatch `MouseEvent('mouseenter', { bubbles: true })` to element
|
|
381
|
-
7. **Wait 500ms** for transition to complete
|
|
382
|
-
8. **Take screenshot** of hover state
|
|
383
|
-
- Save to: `design-system/extracted/{siteName}/screenshots/{btnId}-hover.png`
|
|
384
|
-
9. **Capture hover computed styles**:
|
|
385
|
-
- backgroundColor, color, boxShadow, transform
|
|
386
|
-
10. **Remove hover state**:
|
|
387
|
-
- Dispatch `MouseEvent('mouseleave')` to element
|
|
388
|
-
11. **Compare states** and generate description:
|
|
389
|
-
- If boxShadow changed → "Shadow changes"
|
|
390
|
-
- If transform changed → "Transform changes"
|
|
391
|
-
- If background changed → "Background changes"
|
|
392
|
-
- Join changes with " + " or return "No visible changes"
|
|
393
|
-
|
|
394
|
-
### 3.2: Card Hover States
|
|
395
|
-
|
|
396
|
-
Repeat same process for **first 3 cards** with `data-extract-id="card-{i}"`.
|
|
397
|
-
|
|
398
|
-
### 3.3: Input Focus States
|
|
399
|
-
|
|
400
|
-
Similar process for **first 3 inputs** but use:
|
|
401
|
-
- Focus event instead of hover: `dispatchEvent(new FocusEvent('focus'))`
|
|
402
|
-
- Blur event to remove: `dispatchEvent(new FocusEvent('blur'))`
|
|
403
|
-
- Screenshot names: `{inputId}-default.png`, `{inputId}-focus.png`
|
|
404
|
-
|
|
405
|
-
**Store results** in componentAnimations object with structure:
|
|
406
|
-
```yaml
|
|
407
|
-
componentAnimations:
|
|
408
|
-
button-0:
|
|
409
|
-
type: "button"
|
|
410
|
-
description: "Shadow changes + Background changes"
|
|
411
|
-
transition: "all 0.3s ease"
|
|
412
|
-
states:
|
|
413
|
-
default:
|
|
414
|
-
background: "rgb(59, 130, 246)"
|
|
415
|
-
boxShadow: "none"
|
|
416
|
-
hover:
|
|
417
|
-
background: "rgb(37, 99, 235)"
|
|
418
|
-
boxShadow: "0 4px 6px rgba(0, 0, 0, 0.1)"
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
---
|
|
422
|
-
|
|
423
|
-
## STEP 4: Full-Page Screenshot
|
|
424
|
-
|
|
425
|
-
### 4.1: Ensure Screenshot Directory Exists
|
|
426
|
-
|
|
427
|
-
```bash
|
|
428
|
-
mkdir -p design-system/extracted/{siteName}/screenshots
|
|
429
|
-
```
|
|
430
|
-
|
|
431
|
-
### 4.2: Capture Full-Page Screenshot
|
|
432
|
-
|
|
433
|
-
Use agent-browser to take screenshot:
|
|
434
|
-
|
|
435
|
-
1. **First attempt**: Full-page screenshot
|
|
436
|
-
```bash
|
|
437
|
-
agent-browser screenshot --full design-system/extracted/{siteName}/screenshots/full-page.png
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
2. **If full-page fails**: Fallback to viewport-only
|
|
441
|
-
- Parameters: `fullPage: false`, `format: 'png'`
|
|
442
|
-
- Save to: `design-system/extracted/{siteName}/screenshots/viewport.png`
|
|
443
|
-
|
|
444
|
-
**Why fallback**: Some sites have infinite scroll or very long pages that cause full-page screenshots to fail.
|
|
445
|
-
|
|
446
|
-
---
|
|
447
|
-
|
|
448
|
-
## STEP 5: AI Psychology Analysis
|
|
449
|
-
|
|
450
|
-
### 5.1: Determine Screenshot Path
|
|
451
|
-
|
|
452
|
-
Check which screenshot exists:
|
|
453
|
-
- Prefer: `design-system/extracted/{siteName}/screenshots/full-page.png`
|
|
454
|
-
- Fallback: `design-system/extracted/{siteName}/screenshots/viewport.png`
|
|
455
|
-
|
|
456
|
-
### 5.2: Read Screenshot
|
|
457
|
-
|
|
458
|
-
Use Read tool to load the screenshot image for visual analysis.
|
|
459
|
-
|
|
460
|
-
### 5.3: Generate Psychology Analysis Prompt
|
|
461
|
-
|
|
462
|
-
Create analysis request with:
|
|
463
|
-
|
|
464
|
-
**Context provided:**
|
|
465
|
-
- The screenshot (visual attachment)
|
|
466
|
-
- Extracted CSS colors data (JSON formatted)
|
|
467
|
-
- Extracted typography fonts (JSON formatted)
|
|
468
|
-
|
|
469
|
-
**Request UX/UI psychology insights in YAML format covering:**
|
|
470
|
-
|
|
471
|
-
1. **style_classification**: Design style (Neo-Brutalism, Minimalist, Glassmorphism, Modern SaaS, etc.)
|
|
472
|
-
|
|
473
|
-
2. **emotions_evoked**: List of emotions with reasons
|
|
474
|
-
- emotion: What feeling the design triggers
|
|
475
|
-
- reason: Specific design elements causing this emotion
|
|
476
|
-
|
|
477
|
-
3. **target_audience**: Who this design appeals to
|
|
478
|
-
- primary: Main user demographic (description, age_range, tech_savvy)
|
|
479
|
-
- secondary: Secondary users (if applicable)
|
|
480
|
-
|
|
481
|
-
4. **visual_principles**: Key design patterns observed
|
|
482
|
-
- name: Principle name
|
|
483
|
-
- description: How it's applied
|
|
484
|
-
|
|
485
|
-
5. **why_it_works**: Strategic design decisions
|
|
486
|
-
- List of business/psychological reasons the design is effective
|
|
487
|
-
|
|
488
|
-
6. **design_philosophy**: Underlying beliefs
|
|
489
|
-
- core_belief: Central design philosophy
|
|
490
|
-
- key_principles: List of guiding principles
|
|
491
|
-
|
|
492
|
-
**Instruction**: Be specific with examples from the visual.
|
|
493
|
-
|
|
494
|
-
### 5.4: Extract YAML Response
|
|
495
|
-
|
|
496
|
-
Parse the LLM response to extract the YAML block (between triple backticks).
|
|
497
|
-
|
|
498
|
-
---
|
|
499
|
-
|
|
500
|
-
## STEP 6: Generate data.yaml (17 Sections + Psychology)
|
|
501
|
-
|
|
502
|
-
### 6.1: Calculate Coverage Metrics
|
|
503
|
-
|
|
504
|
-
Count how many of the 17 standard sections were successfully detected:
|
|
505
|
-
- Overview, Color Palette, Typography, Spacing System, Component Styles
|
|
506
|
-
- Shadows/Elevation, Animations/Transitions, Border Radius, Border Styles
|
|
507
|
-
- Layout Patterns, etc.
|
|
508
|
-
|
|
509
|
-
Calculate percentage: `(detectedSections / 17) * 100`
|
|
510
|
-
|
|
511
|
-
### 6.2: Build YAML Structure
|
|
512
|
-
|
|
513
|
-
Construct comprehensive YAML file with these sections:
|
|
514
|
-
|
|
515
|
-
**Header Comments:**
|
|
516
|
-
```yaml
|
|
517
|
-
# Design Extraction: {siteName}
|
|
518
|
-
# Extracted: {ISO timestamp}
|
|
519
|
-
# URL: {url}
|
|
520
|
-
```
|
|
521
|
-
|
|
522
|
-
**Meta Section:**
|
|
523
|
-
```yaml
|
|
524
|
-
meta:
|
|
525
|
-
site_name: {siteName}
|
|
526
|
-
url: {url}
|
|
527
|
-
extracted_at: {ISO timestamp}
|
|
528
|
-
extractor_version: "2.1.0"
|
|
529
|
-
coverage:
|
|
530
|
-
total_sections: 17
|
|
531
|
-
detected_sections: {count}
|
|
532
|
-
percentage: {percentage}
|
|
533
|
-
```
|
|
534
|
-
|
|
535
|
-
**Psychology Section:**
|
|
536
|
-
Insert the psychology YAML from Step 5.4
|
|
537
|
-
|
|
538
|
-
**Design Tokens Sections:**
|
|
539
|
-
```yaml
|
|
540
|
-
sections:
|
|
541
|
-
overview:
|
|
542
|
-
detected: true
|
|
543
|
-
style: {from psychology.style_classification}
|
|
544
|
-
tech_stack: Framework-agnostic
|
|
545
|
-
|
|
546
|
-
color_palette:
|
|
547
|
-
detected: true
|
|
548
|
-
primary:
|
|
549
|
-
- hex: {top 5 background colors}
|
|
550
|
-
rgb: {rgb value}
|
|
551
|
-
usage: {usage context}
|
|
552
|
-
text_colors:
|
|
553
|
-
- hex: {top 5 text colors}
|
|
554
|
-
usage: {usage context}
|
|
555
|
-
border_colors:
|
|
556
|
-
- hex: {top 3 border colors}
|
|
557
|
-
usage: {usage context}
|
|
558
|
-
|
|
559
|
-
typography:
|
|
560
|
-
detected: true
|
|
561
|
-
fonts: [{top 3 font families}]
|
|
562
|
-
weights: [{all weights, sorted}]
|
|
563
|
-
sizes: [{all sizes, sorted}]
|
|
564
|
-
|
|
565
|
-
spacing_system:
|
|
566
|
-
detected: true
|
|
567
|
-
grid_base: {detectedGrid}
|
|
568
|
-
common_values: [{spacing values}]
|
|
569
|
-
|
|
570
|
-
component_styles:
|
|
571
|
-
detected: true
|
|
572
|
-
buttons:
|
|
573
|
-
- id: {button-0}
|
|
574
|
-
text: {button text}
|
|
575
|
-
backgroundColor: {color}
|
|
576
|
-
color: {text color}
|
|
577
|
-
padding: {padding}
|
|
578
|
-
borderRadius: {radius}
|
|
579
|
-
transition: {transition}
|
|
580
|
-
hover_animation: {description from Step 3}
|
|
581
|
-
cards:
|
|
582
|
-
- {similar structure}
|
|
583
|
-
inputs:
|
|
584
|
-
- {similar structure}
|
|
585
|
-
|
|
586
|
-
shadows_elevation:
|
|
587
|
-
detected: true
|
|
588
|
-
values: [{top 5 shadow values}]
|
|
589
|
-
|
|
590
|
-
animations_transitions:
|
|
591
|
-
detected: true
|
|
592
|
-
keyframes:
|
|
593
|
-
- name: {animation name}
|
|
594
|
-
transitions:
|
|
595
|
-
- duration: {duration}
|
|
596
|
-
timing: {timing function}
|
|
597
|
-
|
|
598
|
-
border_radius:
|
|
599
|
-
detected: true
|
|
600
|
-
values: [{top 8 radius values}]
|
|
601
|
-
|
|
602
|
-
border_styles:
|
|
603
|
-
detected: true
|
|
604
|
-
widths: [{border widths}]
|
|
605
|
-
|
|
606
|
-
layout_patterns:
|
|
607
|
-
detected: true
|
|
608
|
-
container_width: "1280px"
|
|
609
|
-
grid_columns: 12
|
|
610
|
-
```
|
|
611
|
-
|
|
612
|
-
**Component Animations (Detailed):**
|
|
613
|
-
```yaml
|
|
614
|
-
animations:
|
|
615
|
-
button-0:
|
|
616
|
-
type: "button"
|
|
617
|
-
description: {from Step 3}
|
|
618
|
-
transition: {transition value}
|
|
619
|
-
states:
|
|
620
|
-
default:
|
|
621
|
-
background: {color}
|
|
622
|
-
boxShadow: {shadow}
|
|
623
|
-
hover:
|
|
624
|
-
background: {color}
|
|
625
|
-
boxShadow: {shadow}
|
|
626
|
-
card-0:
|
|
627
|
-
{similar structure}
|
|
628
|
-
```
|
|
629
|
-
|
|
630
|
-
### 6.3: Write File
|
|
631
|
-
|
|
632
|
-
Use Write tool to save the YAML content to:
|
|
633
|
-
```
|
|
634
|
-
design-system/extracted/{siteName}/data.yaml
|
|
635
|
-
```
|
|
636
|
-
|
|
637
|
-
---
|
|
638
|
-
|
|
639
|
-
## STEP 7: Final Report
|
|
640
|
-
|
|
641
|
-
```
|
|
642
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
643
|
-
✅ EXTRACTION COMPLETE: ${siteName}
|
|
644
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
645
|
-
|
|
646
|
-
📊 Coverage: ${countDetectedSections()}/17 sections
|
|
647
|
-
|
|
648
|
-
🎨 Design Tokens:
|
|
649
|
-
✅ Colors: ${colors.backgrounds.length} backgrounds (with usage)
|
|
650
|
-
✅ Typography: ${typography.allFonts.length} fonts
|
|
651
|
-
✅ Spacing: ${spacing.detectedGrid}px grid detected
|
|
652
|
-
✅ Components: ${buttons.length} buttons, ${cards.length} cards
|
|
653
|
-
✅ Shadows: ${shadows.shadows.length} unique values
|
|
654
|
-
✅ Animations: ${animations.keyframes.length} @keyframes
|
|
655
|
-
|
|
656
|
-
🧠 Psychology Analysis:
|
|
657
|
-
✅ Style classification
|
|
658
|
-
✅ Emotions evoked
|
|
659
|
-
✅ Target audience
|
|
660
|
-
✅ Visual principles
|
|
661
|
-
✅ Why it works
|
|
662
|
-
|
|
663
|
-
📸 Screenshots: ${Object.keys(componentAnimations).length * 2 + 1} captured
|
|
664
|
-
|
|
665
|
-
📁 Output:
|
|
666
|
-
✓ design-system/extracted/${siteName}/data.yaml
|
|
667
|
-
✓ design-system/extracted/${siteName}/screenshots/
|
|
668
|
-
|
|
669
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
670
|
-
|
|
671
|
-
🚀 Next Steps:
|
|
672
|
-
|
|
673
|
-
1. Extract more references (optional):
|
|
674
|
-
/extract https://linear.app
|
|
675
|
-
|
|
676
|
-
2. Generate design system:
|
|
677
|
-
/designsetup @prd.md
|
|
678
|
-
|
|
679
|
-
→ Will read: design-system/extracted/*/data.yaml
|
|
680
|
-
→ Will merge: Psychology + Tokens + Animations
|
|
681
|
-
→ Will output: design-system/data.yaml (final)
|
|
682
|
-
|
|
683
|
-
3. Review extracted data:
|
|
684
|
-
cat design-system/extracted/${siteName}/data.yaml
|
|
685
|
-
|
|
686
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
687
|
-
```
|
|
688
|
-
|
|
689
|
-
---
|
|
690
|
-
|
|
691
|
-
## Error Handling
|
|
692
|
-
|
|
693
|
-
### Critical Errors (Stop Execution)
|
|
694
|
-
|
|
695
|
-
**Navigation failures** - If agent-browser navigation fails:
|
|
696
|
-
1. Catch the error from `agent-browser open`
|
|
697
|
-
2. Return error message:
|
|
698
|
-
```
|
|
699
|
-
❌ Failed to load URL: {url}
|
|
700
|
-
|
|
701
|
-
Error: {error.message}
|
|
702
|
-
|
|
703
|
-
Check:
|
|
704
|
-
- Is the URL accessible?
|
|
705
|
-
- Is agent-browser installed? (npm install -g agent-browser)
|
|
706
|
-
- Did you run `agent-browser install` to get Chromium?
|
|
707
|
-
```
|
|
708
|
-
3. Stop execution (cannot proceed without page loaded)
|
|
709
|
-
|
|
710
|
-
### Non-Critical Errors (Continue with Fallbacks)
|
|
711
|
-
|
|
712
|
-
**Extraction failures** - If individual extraction steps fail:
|
|
713
|
-
1. Log warning message (e.g., "Color extraction failed: {error.message}")
|
|
714
|
-
2. Use fallback empty data:
|
|
715
|
-
- Colors: `{ backgrounds: [], texts: [], borders: [] }`
|
|
716
|
-
- Typography: `{ h1: [], h2: [], h3: [], body: [], allFonts: [], allWeights: [], allSizes: [] }`
|
|
717
|
-
- Shadows: `{ shadows: [], borderRadii: [], borderWidths: [] }`
|
|
718
|
-
- Components: `[]` (empty array)
|
|
719
|
-
3. Continue with other extractions (parallel execution means one failure doesn't block others)
|
|
720
|
-
4. Final YAML will mark section as `detected: false` if no data extracted
|
|
721
|
-
|
|
722
|
-
**Screenshot failures**:
|
|
723
|
-
- Full-page screenshot fails → Fallback to viewport screenshot
|
|
724
|
-
- Component screenshot fails → Skip that component, continue with others
|
|
725
|
-
- Psychology analysis screenshot missing → Use viewport screenshot as fallback
|
|
726
|
-
|
|
727
|
-
**YAML generation**:
|
|
728
|
-
- Missing data sections → Mark `detected: false` in YAML
|
|
729
|
-
- Invalid data → Use empty defaults, note in coverage percentage
|
|
730
|
-
|
|
731
|
-
---
|
|
732
|
-
|
|
733
|
-
**Now execute the extraction.**
|