- Updated `layout-extract` command to include a refinement mode (`--refine`) for generating single refined layouts, alongside exploration mode for multiple contrasting variants. - Added detailed reporting and validation for variants count based on the selected mode. - Implemented logic to load existing layouts for refinement and generate specific refinement options categorized by density, responsiveness, grid specifics, and component arrangement. - Updated `style-extract` command similarly to support refinement mode, allowing for detailed adjustments to existing design systems. - Enhanced user interaction phases to accommodate selection of refinements or design directions based on the active mode.
32 KiB
Style Extraction Command
Overview
Extract design style from reference images or text prompts using Claude's built-in analysis. Supports two modes:
- Exploration Mode (default): Generate multiple contrasting design variants
- Refinement Mode (
--refine): Refine a single existing design through detailed adjustments
Strategy: AI-Driven Design Space Exploration
- Claude-Native: 100% Claude analysis, no external tools
- Direct Output: Complete design systems (design-tokens.json + style-guide.md)
- Flexible Input: Images, text prompts, or both (hybrid mode)
- Dual Mode: Exploration (multiple contrasting variants) or Refinement (single design fine-tuning)
- Production-Ready: WCAG AA compliant, OKLCH colors, semantic naming
Phase 0: Setup & Input Validation
Step 1: Detect Input Mode, Extraction Mode & Base Path
# Detect input source
# Priority: --urls + --images + --prompt → hybrid-url | --urls + --images → url-image | --urls → url | --images + --prompt → hybrid | --images → image | --prompt → text
# Parse URLs if provided (format: "target:url,target:url,...")
IF --urls:
url_list = []
FOR pair IN split(--urls, ","):
IF ":" IN pair:
target, url = pair.split(":", 1)
url_list.append({target: target.strip(), url: url.strip()})
ELSE:
# Single URL without target
url_list.append({target: "page", url: pair.strip()})
has_urls = true
primary_url = url_list[0].url # First URL as primary source
ELSE:
has_urls = false
# Detect refinement mode
refine_mode = --refine OR false
# Set variants count
# Refinement mode: Force variants_count = 1 (ignore user-provided --variants)
# Exploration mode: Use --variants or default to 3 (range: 1-5)
IF refine_mode:
variants_count = 1
REPORT: "🔧 Refinement mode enabled: Will generate 1 refined design system"
ELSE:
variants_count = --variants OR 3
VALIDATE: 1 <= variants_count <= 5
REPORT: "🔍 Exploration mode: Will generate {variants_count} contrasting design directions"
# Determine base path with priority: --design-id > --session > auto-detect
if [ -n "$DESIGN_ID" ]; then
# Exact match by design ID
relative_path=$(find .workflow -name "${DESIGN_ID}" -type d -print -quit)
elif [ -n "$SESSION_ID" ]; then
# Latest in session
relative_path=$(find .workflow/WFS-$SESSION_ID -name "design-run-*" -type d -printf "%T@ %p\n" 2>/dev/null | sort -nr | head -1 | cut -d' ' -f2)
else
# Latest globally
relative_path=$(find .workflow -name "design-run-*" -type d -printf "%T@ %p\n" 2>/dev/null | sort -nr | head -1 | cut -d' ' -f2)
fi
# Validate and convert to absolute path
if [ -z "$relative_path" ] || [ ! -d "$relative_path" ]; then
echo "❌ ERROR: Design run not found"
echo "💡 HINT: Run '/workflow:ui-design:list' to see available design runs"
exit 1
fi
base_path=$(cd "$relative_path" && pwd)
bash(echo "✓ Base path: $base_path")
Step 2: Extract Computed Styles (URL Mode - Auto-Trigger)
# AUTO-TRIGGER: If URLs are available (from --urls parameter or capture metadata), automatically extract real CSS values
# This provides accurate design tokens to supplement visual analysis
# Priority 1: Check for --urls parameter
IF has_urls:
url_to_extract = primary_url
url_source = "--urls parameter"
# Priority 2: Check for URL metadata from capture phase
ELSE IF exists({base_path}/.metadata/capture-urls.json):
capture_urls = Read({base_path}/.metadata/capture-urls.json)
url_to_extract = capture_urls[0] # Use first URL
url_source = "capture metadata"
ELSE:
url_to_extract = null
# Execute extraction if URL available
IF url_to_extract AND mcp_chrome_devtools_available:
REPORT: "🔍 Auto-triggering URL mode: Extracting computed styles from {url_source}"
REPORT: " URL: {url_to_extract}"
# Read extraction script
script_content = Read(~/.claude/scripts/extract-computed-styles.js)
# Open page in Chrome DevTools
mcp__chrome-devtools__navigate_page(url=url_to_extract)
# Execute extraction script directly
result = mcp__chrome-devtools__evaluate_script(function=script_content)
# Save computed styles to intermediates directory
bash(mkdir -p {base_path}/.intermediates/style-analysis)
Write({base_path}/.intermediates/style-analysis/computed-styles.json, result)
computed_styles_available = true
REPORT: " ✅ Computed styles extracted and saved"
ELSE:
computed_styles_available = false
IF url_to_extract:
REPORT: "⚠️ Chrome DevTools MCP not available, falling back to visual analysis"
Extraction Script Reference: ~/.claude/scripts/extract-computed-styles.js
Usage: Read the script file and use content directly in mcp__chrome-devtools__evaluate_script()
Script returns:
metadata: Extraction timestamp, URL, methodtokens: Organized design tokens (colors, borderRadii, shadows, fontSizes, fontWeights, spacing)
Benefits:
- ✅ Pixel-perfect accuracy for border-radius, box-shadow, padding, etc.
- ✅ Eliminates guessing from visual analysis
- ✅ Provides ground truth for design tokens
Step 3: Load Inputs
# For image mode
bash(ls {images_pattern}) # Expand glob pattern
Read({image_path}) # Load each image
# For text mode
# Validate --prompt is non-empty
# Create output directory
bash(mkdir -p {base_path}/style-extraction/)
Step 3: Memory Check
# 1. Check if inputs cached in session memory
IF session_has_inputs: SKIP Step 2 file reading
# 2. Check if output already exists
bash(test -f {base_path}/style-extraction/style-1/design-tokens.json && echo "exists")
IF exists: SKIP to completion
Phase 0 Output: input_mode, base_path, extraction_mode, variants_count, loaded_images[] or prompt_guidance, has_urls, url_list[], computed_styles_available
Phase 1: Design Direction or Refinement Options Generation
Step 1: Load Project Context
# Load brainstorming context if available
bash(test -f {base_path}/.brainstorming/role analysis documents && cat it)
# Load existing design system if refinement mode
IF refine_mode:
existing_tokens = Read({base_path}/style-extraction/style-1/design-tokens.json)
existing_guide = Read({base_path}/style-extraction/style-1/style-guide.md)
Step 2: Generate Options (Agent Task 1 - Mode-Specific)
Executor: Task(ui-design-agent)
Exploration Mode (default): Generate contrasting design directions
Refinement Mode (--refine): Generate refinement options for existing design
// Conditional agent task based on refine_mode
IF NOT refine_mode:
// EXPLORATION MODE
Task(ui-design-agent): `
[DESIGN_DIRECTION_GENERATION_TASK]
Generate {variants_count} maximally contrasting design directions with visual previews
SESSION: {session_id} | MODE: explore | BASE_PATH: {base_path}
## Input Analysis
- User prompt: {prompt_guidance}
- Visual references: {loaded_images if available}
- Project context: {brainstorming_context if available}
## Analysis Rules
- Analyze 6D attribute space: color saturation, visual weight, formality, organic/geometric, innovation, density
- Generate {variants_count} directions with MAXIMUM contrast
- Each direction must be distinctly different (min distance score: 0.7)
## Generate for EACH Direction
1. **Core Philosophy**:
- philosophy_name (2-3 words, e.g., "Minimalist & Airy")
- design_attributes (6D scores 0-1)
- search_keywords (3-5 keywords)
- anti_keywords (2-3 keywords to avoid)
- rationale (why this is distinct from others)
2. **Visual Preview Elements**:
- primary_color (OKLCH format)
- secondary_color (OKLCH format)
- accent_color (OKLCH format)
- font_family_heading (specific font name)
- font_family_body (specific font name)
- border_radius_base (e.g., "0.5rem")
- mood_description (1-2 sentences describing the feel)
## Output
Write single JSON file: {base_path}/.intermediates/style-analysis/analysis-options.json
Use schema from INTERACTIVE-DATA-SPEC.md (Style Extract: analysis-options.json)
CRITICAL: Use Write() tool immediately after generating complete JSON
`
ELSE:
// REFINEMENT MODE
Task(ui-design-agent): `
[DESIGN_REFINEMENT_OPTIONS_TASK]
Generate refinement options for existing design system
SESSION: {session_id} | MODE: refine | BASE_PATH: {base_path}
## Existing Design System
- design-tokens.json: {existing_tokens}
- style-guide.md: {existing_guide}
## Input Guidance
- User prompt: {prompt_guidance}
- Visual references: {loaded_images if available}
## Refinement Categories
Generate 8-12 refinement options across these categories:
1. **Intensity/Degree Adjustments** (2-3 options):
- Color intensity: more vibrant ↔ more muted
- Visual weight: bolder ↔ lighter
- Density: more compact ↔ more spacious
2. **Specific Attribute Tuning** (3-4 options):
- Border radius: sharper corners ↔ rounder edges
- Shadow depth: subtler shadows ↔ deeper elevation
- Typography scale: tighter scale ↔ more contrast
- Spacing scale: tighter rhythm ↔ more breathing room
3. **Context-Specific Variations** (2-3 options):
- Dark mode optimization
- Mobile-specific adjustments
- High-contrast accessibility mode
4. **Component-Level Customization** (1-2 options):
- Button styling emphasis
- Card/container treatment
- Form input refinements
## Output Format
Each option:
- category: "intensity|attribute|context|component"
- option_id: unique identifier
- label: Short descriptive name (e.g., "More Vibrant Colors")
- description: What changes (2-3 sentences)
- preview_changes: Key token adjustments preview
- impact_scope: Which tokens affected
## Output
Write single JSON file: {base_path}/.intermediates/style-analysis/analysis-options.json
Use refinement schema:
{
"mode": "refinement",
"base_design": "style-1",
"refinement_options": [array of refinement options]
}
CRITICAL: Use Write() tool immediately after generating complete JSON
`
Step 3: Verify Options File Created
bash(test -f {base_path}/.intermediates/style-analysis/analysis-options.json && echo "created")
# Quick validation
bash(cat {base_path}/.intermediates/style-analysis/analysis-options.json | grep -q "design_directions" && echo "valid")
Output: analysis-options.json with design direction options
Phase 1.5: User Confirmation (Optional - Triggered by --interactive)
Purpose:
- Exploration Mode: Allow user to select preferred design direction(s)
- Refinement Mode: Allow user to select refinement options to apply
Trigger Condition: Execute this phase ONLY if --interactive flag is present
Step 1: Check Interactive Flag
# Skip this entire phase if --interactive flag is not present
IF NOT --interactive:
SKIP to Phase 2
IF refine_mode:
REPORT: "ℹ️ Non-interactive refinement mode: Will apply all suggested refinements"
ELSE:
REPORT: "ℹ️ Non-interactive mode: Will generate all {variants_count} variants"
REPORT: "🎯 Interactive mode enabled: User selection required"
Step 2: Load and Present Options (Mode-Specific)
# Read options file
options = Read({base_path}/.intermediates/style-analysis/analysis-options.json)
# Branch based on mode
IF NOT refine_mode:
# EXPLORATION MODE
design_directions = options.design_directions
ELSE:
# REFINEMENT MODE
refinement_options = options.refinement_options
Step 3: Present Options to User (Mode-Specific)
Exploration Mode:
📋 Design Direction Options
We've generated {variants_count} contrasting design directions for your review.
Please select the direction(s) you'd like to develop into complete design systems.
{FOR each direction in design_directions:
═══════════════════════════════════════════════════
Option {direction.index}: {direction.philosophy_name}
═══════════════════════════════════════════════════
Philosophy: {direction.rationale}
Visual Preview:
• Colors: {direction.preview.primary_color} (primary), {direction.preview.accent_color} (accent)
• Typography: {direction.preview.font_family_heading} (headings), {direction.preview.font_family_body} (body)
• Border Radius: {direction.preview.border_radius_base}
• Mood: {direction.preview.mood_description}
Design Attributes:
• Color Saturation: {direction.design_attributes.color_saturation * 100}%
• Visual Weight: {direction.design_attributes.visual_weight * 100}%
• Formality: {direction.design_attributes.formality * 100}%
• Innovation: {direction.design_attributes.innovation * 100}%
Keywords: {join(direction.search_keywords, ", ")}
Avoiding: {join(direction.anti_keywords, ", ")}
}
═══════════════════════════════════════════════════
Refinement Mode:
📋 Design Refinement Options
We've analyzed your existing design system and generated refinement options.
Please select the refinement(s) you'd like to apply.
Base Design: style-1
{FOR each option in refinement_options grouped by category:
━━━ {category_name} ━━━
{FOR each refinement in category_options:
[{refinement.option_id}] {refinement.label}
{refinement.description}
Preview: {refinement.preview_changes}
Affects: {refinement.impact_scope}
}
}
═══════════════════════════════════════════════════
Step 4: Capture User Selection and Update Analysis JSON
Exploration Mode Interaction:
// Use AskUserQuestion tool for multi-selection
AskUserQuestion({
questions: [{
question: "Which design direction(s) would you like to develop into complete design systems?",
header: "Style Choice",
multiSelect: true, // Multi-selection enabled
options: [
{FOR each direction:
label: "Option {direction.index}: {direction.philosophy_name}",
description: "{direction.mood_description}"
}
]
}]
})
// Parse user response (array of selections)
selected_options = user_answer
// Check for user cancellation
IF selected_options == null OR selected_options.length == 0:
REPORT: "⚠️ User canceled selection. Workflow terminated."
EXIT workflow
// Extract option indices
selected_indices = []
FOR each selected_option_text IN selected_options:
match = selected_option_text.match(/Option (\d+):/)
IF match:
selected_indices.push(parseInt(match[1]))
REPORT: "✅ Selected {selected_indices.length} design direction(s)"
// Update analysis-options.json
options_file = Read({base_path}/.intermediates/style-analysis/analysis-options.json)
options_file.user_selection = {
"selected_at": NOW(),
"selected_indices": selected_indices,
"selection_count": selected_indices.length
}
Write({base_path}/.intermediates/style-analysis/analysis-options.json, JSON.stringify(options_file, indent=2))
Refinement Mode Interaction:
// Use AskUserQuestion tool for multi-selection of refinements
AskUserQuestion({
questions: [{
question: "Which refinement(s) would you like to apply to your design system?",
header: "Refinements",
multiSelect: true, // Multi-selection enabled
options: [
{FOR each refinement:
label: "{refinement.label}",
description: "{refinement.description} (Affects: {refinement.impact_scope})"
}
]
}]
})
// Parse user response
selected_refinements = user_answer
// Check for user cancellation
IF selected_refinements == null OR selected_refinements.length == 0:
REPORT: "⚠️ User canceled selection. Workflow terminated."
EXIT workflow
// Extract refinement option_ids
selected_option_ids = []
FOR each selected_text IN selected_refinements:
# Match against refinement labels to find option_ids
FOR each refinement IN refinement_options:
IF refinement.label IN selected_text:
selected_option_ids.push(refinement.option_id)
REPORT: "✅ Selected {selected_option_ids.length} refinement(s)"
// Update analysis-options.json
options_file = Read({base_path}/.intermediates/style-analysis/analysis-options.json)
options_file.user_selection = {
"selected_at": NOW(),
"selected_option_ids": selected_option_ids,
"selection_count": selected_option_ids.length
}
Write({base_path}/.intermediates/style-analysis/analysis-options.json, JSON.stringify(options_file, indent=2))
Step 5: Confirmation Message (Mode-Specific)
Exploration Mode:
✅ Selection recorded!
You selected {selected_indices.length} design direction(s):
{FOR each index IN selected_indices:
• Option {index} - {design_directions[index-1].philosophy_name}
}
Proceeding to generate {selected_indices.length} complete design system(s)...
Refinement Mode:
✅ Selection recorded!
You selected {selected_option_ids.length} refinement(s):
{FOR each id IN selected_option_ids:
• {refinement_by_id[id].label} ({refinement_by_id[id].category})
}
Proceeding to apply refinements and generate updated design system...
Output: Updated analysis-options.json with user's selection embedded
Phase 2: Design System Generation (Agent Task 2)
Executor: Task(ui-design-agent) for selected variant(s)
Step 1: Load User Selection or Default to All
# Read analysis-options.json which may contain user_selection
options = Read({base_path}/.intermediates/style-analysis/analysis-options.json)
# Check if user_selection field exists (interactive mode)
IF options.user_selection AND options.user_selection.selected_indices:
# Interactive mode: Use user-selected variants
selected_indices = options.user_selection.selected_indices # Array of selected indices (e.g., [1, 3])
REPORT: "🎯 Interactive mode: Using {selected_indices.length} user-selected variant(s)"
ELSE:
# Non-interactive mode: Generate ALL variants (default behavior)
selected_indices = [1, 2, ..., variants_count] # All indices from 1 to variants_count
REPORT: "ℹ️ Non-interactive mode: Generating all {variants_count} variant(s)"
# Extract the selected direction details from options
selected_directions = [options.design_directions[i-1] for i in selected_indices] # 0-indexed array
actual_variants_count = selected_indices.length
REPORT: "📦 Generating {actual_variants_count} design system(s)..."
Step 2: Create Output Directories
# Create directories for each selected variant
FOR index IN 1..actual_variants_count:
bash(mkdir -p {base_path}/style-extraction/style-{index})
Step 3: Launch Agent Tasks (Parallel)
Generate design systems for ALL selected directions in parallel (max 5 concurrent):
// Launch parallel tasks, one for each selected direction
FOR variant_index IN 1..actual_variants_count:
selected_direction = selected_directions[variant_index - 1] // 0-indexed
Task(ui-design-agent): `
[DESIGN_SYSTEM_GENERATION_TASK #{variant_index}/{actual_variants_count}]
Generate production-ready design system based on user-selected direction
SESSION: {session_id} | VARIANT: {variant_index}/{actual_variants_count} | BASE_PATH: {base_path}
USER SELECTION:
- Selected Direction: ${selected_direction.philosophy_name}
- Design Attributes: ${JSON.stringify(selected_direction.design_attributes)}
- Search Keywords: ${selected_direction.search_keywords.join(", ")}
- Anti-keywords: ${selected_direction.anti_keywords.join(", ")}
- Rationale: ${selected_direction.rationale}
- Preview Colors: Primary=${selected_direction.preview.primary_color}, Accent=${selected_direction.preview.accent_color}
- Preview Typography: Heading=${selected_direction.preview.font_family_heading}, Body=${selected_direction.preview.font_family_body}
- Preview Border Radius: ${selected_direction.preview.border_radius_base}
## Input Analysis
- Input mode: {input_mode} (image/text/hybrid${has_urls ? "/url" : ""})
- Visual references: {loaded_images OR prompt_guidance}
${computed_styles_available ? "- Computed styles: Use as ground truth (Read from .intermediates/style-analysis/computed-styles.json)" : ""}
## Generation Rules
- Develop the selected design direction into a complete design system
- Use preview elements as foundation and expand with full token coverage
- Apply design_attributes to all token values:
* color_saturation → OKLCH chroma values
* visual_weight → font weights, shadow depths
* density → spacing scale compression/expansion
* formality → typography choices, border radius
* organic_geometric → border radius, shape patterns
* innovation → token naming, experimental values
- Honor search_keywords for design inspiration
- Avoid anti_keywords patterns
- All colors in OKLCH format ${computed_styles_available ? "(convert from computed RGB)" : ""}
- WCAG AA compliance: 4.5:1 text contrast, 3:1 UI contrast
## Generate
Create complete design system in {base_path}/style-extraction/style-{variant_index}/
1. **design-tokens.json**:
- Complete token structure with ALL fields:
* colors (brand, surface, semantic, text, border) - OKLCH format
* typography (families, sizes, weights, line heights, letter spacing, combinations)
* typography.combinations: Predefined typography presets (heading-primary, heading-secondary, body-regular, body-emphasis, caption, label) using var() references
* spacing (0-24 scale)
* opacity (0, 10, 20, 40, 60, 80, 90, 100)
* border_radius (none to full)
* shadows (sm to xl)
* component_styles (button, card, input variants) - component presets using var() references
* breakpoints (sm to 2xl)
- All colors in OKLCH format
${extraction_mode == "explore" ? "- Start from preview colors and expand to full palette" : ""}
${extraction_mode == "explore" && refinements.enabled ? "- Apply user refinements where specified" : ""}
- Common Tailwind CSS usage patterns in project (if extracting from existing project)
2. **style-guide.md**:
- Design philosophy (${extraction_mode == "explore" ? "expand on: " + selected_direction.philosophy_name : "describe the reference design"})
- Complete color system documentation with accessibility notes
- Typography scale and usage guidelines
- Typography Combinations section: Document each preset (heading-primary, heading-secondary, body-regular, body-emphasis, caption, label) with usage context and code examples
- Spacing system explanation
- Opacity & Transparency section: Opacity scale usage, common use cases (disabled states, overlays, hover effects), accessibility considerations
- Shadows & Elevation section: Shadow hierarchy and semantic usage
- Component Styles section: Document button, card, and input variants with code examples and visual descriptions
- Border Radius system and semantic usage
- Component examples and usage patterns
- Common Tailwind CSS patterns (if applicable)
## Critical Requirements
- ✅ Use Write() tool immediately for each file
- ✅ Write to style-{variant_index}/ directory
- ❌ NO external research or MCP calls (pure AI generation)
- ✅ Maintain consistency with user-selected direction
`
Output: {actual_variants_count} parallel agent tasks generate 2 files each (design-tokens.json, style-guide.md)
Phase 3: Verify Output
Step 1: Check Files Created
# Verify all design systems created
bash(ls {base_path}/style-extraction/style-*/design-tokens.json | wc -l)
# Validate structure
bash(cat {base_path}/style-extraction/style-1/design-tokens.json | grep -q "colors" && echo "valid")
Step 2: Verify File Sizes
bash(ls -lh {base_path}/style-extraction/style-1/)
Output: variants_count × 2 files verified
Completion
Todo Update
TodoWrite({todos: [
{content: "Setup and input validation", status: "completed", activeForm: "Validating inputs"},
{content: "Design space analysis (explore mode)", status: "completed", activeForm: "Analyzing design space"},
{content: "Design system generation (agent)", status: "completed", activeForm: "Generating design systems"},
{content: "Verify output files", status: "completed", activeForm: "Verifying files"}
]});
Output Message
✅ Style extraction complete!
Configuration:
- Session: {session_id}
- Extraction Mode: {extraction_mode} (imitate/explore)
- Input Mode: {input_mode} (image/text/hybrid{"/url" if has_urls else ""})
- Variants: {variants_count}
- Production-Ready: Complete design systems generated
{IF has_urls AND computed_styles_available:
- 🔍 URL Mode: Computed styles extracted from {len(url_list)} URL(s)
- Accuracy: Pixel-perfect design tokens from DOM
}
{IF has_urls AND NOT computed_styles_available:
- ⚠️ URL Mode: Chrome DevTools unavailable, used visual analysis fallback
}
{IF extraction_mode == "explore":
Design Direction Selection:
- You selected: Option {selected_index} - {selected_direction.philosophy_name}
- Generated from {variants_count} contrasting design direction options
}
Generated Files:
{base_path}/style-extraction/
└── style-1/ (design-tokens.json, style-guide.md)
{IF computed_styles_available:
Intermediate Analysis:
{base_path}/.intermediates/style-analysis/computed-styles.json (extracted from {primary_url})
}
{IF extraction_mode == "explore":
{base_path}/.intermediates/style-analysis/analysis-options.json (design direction options + user selection)
}
Next: /workflow:ui-design:layout-extract --session {session_id} --targets "..."
OR: /workflow:ui-design:generate --session {session_id}
Simple Bash Commands
Path Operations
# Find design directory
bash(find .workflow -type d -name "design-run-*" | head -1)
# Expand image pattern
bash(ls {images_pattern})
# Create output directory
bash(mkdir -p {base_path}/style-extraction/)
Validation Commands
# Check if already extracted
bash(test -f {base_path}/style-extraction/style-1/design-tokens.json && echo "exists")
# Count variants
bash(ls {base_path}/style-extraction/style-* -d | wc -l)
# Validate JSON structure
bash(cat {base_path}/style-extraction/style-1/design-tokens.json | grep -q "colors" && echo "valid")
File Operations
# Load brainstorming context
bash(test -f .brainstorming/role analysis documents && cat it)
# Create directories (example for multiple variants)
bash(mkdir -p {base_path}/style-extraction/style-1)
bash(mkdir -p {base_path}/style-extraction/style-2)
bash(mkdir -p {base_path}/style-extraction/style-3)
# Verify output
bash(ls {base_path}/style-extraction/style-1/)
bash(test -f {base_path}/.intermediates/style-analysis/analysis-options.json && echo "saved")
Output Structure
{base_path}/
├── .intermediates/ # Intermediate analysis files
│ └── style-analysis/
│ ├── computed-styles.json # Extracted CSS values from DOM (if URL available)
│ └── analysis-options.json # Design direction options + user selection (explore mode only)
└── style-extraction/ # Final design system
└── style-1/
├── design-tokens.json # Production-ready design tokens
└── style-guide.md # Design philosophy and usage guide
design-tokens.json Format
{
"colors": {
"brand": {"primary": "oklch(...)", "secondary": "oklch(...)", "accent": "oklch(...)"},
"surface": {"background": "oklch(...)", "elevated": "oklch(...)", "overlay": "oklch(...)"},
"semantic": {"success": "oklch(...)", "warning": "oklch(...)", "error": "oklch(...)", "info": "oklch(...)"},
"text": {"primary": "oklch(...)", "secondary": "oklch(...)", "tertiary": "oklch(...)", "inverse": "oklch(...)"},
"border": {"default": "oklch(...)", "strong": "oklch(...)", "subtle": "oklch(...)"}
},
"typography": {
"font_family": {...},
"font_size": {...},
"font_weight": {...},
"line_height": {...},
"letter_spacing": {...},
"combinations": {
"heading-primary": {"family": "var(--font-family-heading)", "size": "var(--font-size-3xl)", "weight": "var(--font-weight-bold)", "line_height": "var(--line-height-tight)", "letter_spacing": "var(--letter-spacing-tight)"},
"heading-secondary": {...},
"body-regular": {...},
"body-emphasis": {...},
"caption": {...},
"label": {...}
}
},
"spacing": {"0": "0", "1": "0.25rem", ..., "24": "6rem"},
"opacity": {"0": "0", "10": "0.1", "20": "0.2", "40": "0.4", "60": "0.6", "80": "0.8", "90": "0.9", "100": "1"},
"border_radius": {"none": "0", "sm": "0.25rem", ..., "full": "9999px"},
"shadows": {"sm": "...", "md": "...", "lg": "...", "xl": "..."},
"component_styles": {
"button": {
"primary": {"background": "var(--color-brand-primary)", "color": "var(--color-text-inverse)", "padding": "var(--spacing-3) var(--spacing-6)", "border_radius": "var(--border-radius-md)", "font_weight": "var(--font-weight-semibold)"},
"secondary": {...},
"tertiary": {...}
},
"card": {
"default": {"background": "var(--color-surface-elevated)", "padding": "var(--spacing-6)", "border_radius": "var(--border-radius-lg)", "shadow": "var(--shadow-md)"},
"interactive": {...}
},
"input": {
"default": {"border": "1px solid var(--color-border-default)", "padding": "var(--spacing-3)", "border_radius": "var(--border-radius-md)", "background": "var(--color-surface-background)"},
"focus": {...},
"error": {...}
}
},
"breakpoints": {"sm": "640px", ..., "2xl": "1536px"}
}
Requirements: OKLCH colors, complete coverage, semantic naming, WCAG AA compliance, typography combinations, component style presets, opacity scale
Error Handling
Common Errors
ERROR: No images found
→ Check glob pattern
ERROR: Invalid prompt
→ Provide non-empty string
ERROR: Claude JSON parsing error
→ Retry with stricter format
Key Features
- Auto-Trigger URL Mode - Automatically extracts computed styles when --urls provided (no manual flag needed)
- Direct Design System Generation - Complete design-tokens.json + style-guide.md in one step
- Hybrid Extraction Strategy - Combines computed CSS values (ground truth) with AI visual analysis
- Pixel-Perfect Accuracy - Chrome DevTools extracts exact border-radius, shadows, spacing values
- AI-Driven Design Space Exploration - 6D attribute space analysis for maximum contrast
- Variant-Specific Directions - Each variant has unique philosophy, keywords, anti-patterns
- Maximum Contrast Guarantee - Variants maximally distant in attribute space
- Flexible Input - Images, text, URLs, or hybrid mode
- Graceful Fallback - Falls back to pure visual inference if Chrome DevTools unavailable
- Production-Ready - OKLCH colors, WCAG AA compliance, semantic naming
- Agent-Driven - Autonomous multi-file generation with ui-design-agent