mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-11 02:33:51 +08:00
Enhance layout and style extraction commands with dual mode support for exploration and refinement.
- 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.
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: animation-extract
|
name: animation-extract
|
||||||
description: Extract animation and transition patterns from URLs, CSS, or interactive questioning for design system documentation
|
description: Extract animation and transition patterns from URLs, CSS, or interactive questioning for design system documentation
|
||||||
argument-hint: "[--design-id <id>] [--session <id>] [--urls "<list>"] [--focus "<types>"] [--interactive]"
|
argument-hint: "[--design-id <id>] [--session <id>] [--urls "<list>"] [--focus "<types>"] [--interactive] [--refine]"
|
||||||
allowed-tools: TodoWrite(*), Read(*), Write(*), Glob(*), Bash(*), AskUserQuestion(*), Task(ui-design-agent), mcp__chrome-devtools__navigate_page(*), mcp__chrome-devtools__evaluate_script(*)
|
allowed-tools: TodoWrite(*), Read(*), Write(*), Glob(*), Bash(*), AskUserQuestion(*), Task(ui-design-agent), mcp__chrome-devtools__navigate_page(*), mcp__chrome-devtools__evaluate_script(*)
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -13,8 +13,10 @@ Extract animation and transition patterns from URLs or interactive questioning u
|
|||||||
|
|
||||||
**Strategy**: AI-Driven Animation Specification with Visual Previews
|
**Strategy**: AI-Driven Animation Specification with Visual Previews
|
||||||
|
|
||||||
|
- **Dual Modes**: Exploration mode (generate from scratch) or Refinement mode (fine-tune existing)
|
||||||
- **CSS Extraction**: Automatic CSS animation/transition extraction from URLs via Chrome DevTools
|
- **CSS Extraction**: Automatic CSS animation/transition extraction from URLs via Chrome DevTools
|
||||||
- **Question Generation**: Agent generates context-aware specification questions with visual previews
|
- **Question Generation**: Agent generates context-aware specification questions with visual previews
|
||||||
|
- **Refinement Options**: Fine-tune timing, easing, context variations, and interaction intensity
|
||||||
- **Visual Previews**: Timeline representations, easing curve ASCII art, and animation sequence diagrams
|
- **Visual Previews**: Timeline representations, easing curve ASCII art, and animation sequence diagrams
|
||||||
- **Flexible Input**: URLs for CSS extraction, or standalone question-based specification
|
- **Flexible Input**: URLs for CSS extraction, or standalone question-based specification
|
||||||
- **Optional Interaction**: User answers questions only when `--interactive` flag present
|
- **Optional Interaction**: User answers questions only when `--interactive` flag present
|
||||||
@@ -54,6 +56,14 @@ ELSE:
|
|||||||
# Check interactive mode flag
|
# Check interactive mode flag
|
||||||
interactive_mode = --interactive OR false
|
interactive_mode = --interactive OR false
|
||||||
|
|
||||||
|
# Check refinement mode flag
|
||||||
|
refine_mode = --refine OR false
|
||||||
|
|
||||||
|
IF refine_mode:
|
||||||
|
REPORT: "🔧 Refinement mode enabled: Will refine existing animation system"
|
||||||
|
ELSE:
|
||||||
|
REPORT: "✨ Exploration mode: Will generate animation system from scratch"
|
||||||
|
|
||||||
# Determine base path with priority: --design-id > --session > auto-detect
|
# Determine base path with priority: --design-id > --session > auto-detect
|
||||||
if [ -n "$DESIGN_ID" ]; then
|
if [ -n "$DESIGN_ID" ]; then
|
||||||
# Exact match by design ID
|
# Exact match by design ID
|
||||||
@@ -164,7 +174,7 @@ IF exists: SKIP to completion
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Phase 0 Output**: `input_mode`, `base_path`, `has_urls`, `url_list[]`, `focus_types[]`, `has_design_context`, `interactive_mode`, `animations_extracted`
|
**Phase 0 Output**: `input_mode`, `base_path`, `has_urls`, `url_list[]`, `focus_types[]`, `has_design_context`, `interactive_mode`, `refine_mode`, `animations_extracted`
|
||||||
|
|
||||||
## Phase 1: Animation Specification Generation
|
## Phase 1: Animation Specification Generation
|
||||||
|
|
||||||
@@ -184,14 +194,16 @@ IF animations_extracted:
|
|||||||
|
|
||||||
**Executor**: `Task(ui-design-agent)`
|
**Executor**: `Task(ui-design-agent)`
|
||||||
|
|
||||||
Launch agent to generate animation specification options with previews:
|
**Conditional Logic**: Branch based on `refine_mode` flag
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
Task(ui-design-agent): `
|
IF NOT refine_mode:
|
||||||
[ANIMATION_SPECIFICATION_GENERATION_TASK]
|
// EXPLORATION MODE (default)
|
||||||
Generate context-aware animation specification questions
|
Task(ui-design-agent): `
|
||||||
|
[ANIMATION_SPECIFICATION_GENERATION_TASK]
|
||||||
|
Generate context-aware animation specification questions
|
||||||
|
|
||||||
SESSION: {session_id} | MODE: explore | BASE_PATH: {base_path}
|
SESSION: {session_id} | MODE: explore | BASE_PATH: {base_path}
|
||||||
|
|
||||||
## Input Analysis
|
## Input Analysis
|
||||||
- Focus types: {focus_types.join(", ")}
|
- Focus types: {focus_types.join(", ")}
|
||||||
@@ -277,27 +289,120 @@ Task(ui-design-agent): `
|
|||||||
}
|
}
|
||||||
|
|
||||||
CRITICAL: Use Write() tool immediately after generating complete JSON
|
CRITICAL: Use Write() tool immediately after generating complete JSON
|
||||||
`
|
`
|
||||||
|
|
||||||
|
ELSE:
|
||||||
|
// REFINEMENT MODE
|
||||||
|
Task(ui-design-agent): `
|
||||||
|
[ANIMATION_REFINEMENT_OPTIONS_TASK]
|
||||||
|
Generate refinement options for existing animation system
|
||||||
|
|
||||||
|
SESSION: {session_id} | MODE: refine | BASE_PATH: {base_path}
|
||||||
|
|
||||||
|
## Load Existing Animation System
|
||||||
|
- Existing tokens: Read from {base_path}/animation-extraction/animation-tokens.json
|
||||||
|
- Focus types: {focus_types.join(", ")}
|
||||||
|
- Design context: {has_design_context ? "Available" : "None"}
|
||||||
|
${animations_extracted ? "- CSS Data: Read from .intermediates/animation-analysis/animations-*.json" : ""}
|
||||||
|
|
||||||
|
## Refinement Categories
|
||||||
|
Generate 8-12 refinement options across these categories:
|
||||||
|
|
||||||
|
1. **Timing Adjustments** (2-3 options):
|
||||||
|
- Duration scale: Faster timing across the board ↔ Slower, more deliberate timing
|
||||||
|
- Specific categories: Accelerate interactions only ↔ Extend page transitions
|
||||||
|
- Micro-timing: Adjust stagger delays ↔ Sequential animation gaps
|
||||||
|
|
||||||
|
2. **Easing Fine-Tuning** (2-3 options):
|
||||||
|
- Curve intensity: Sharper, snappier curves ↔ Softer, smoother curves
|
||||||
|
- Category-specific: Bouncier interactions ↔ Linear state changes
|
||||||
|
- Spring physics: Adjust bounce/damping parameters
|
||||||
|
|
||||||
|
3. **Context-Specific Variations** (2-3 options):
|
||||||
|
- Reduced motion: Adjust reduced-motion fallbacks
|
||||||
|
- Mobile optimization: Shorter durations for touch interactions
|
||||||
|
- Component-specific: Different hover styles for buttons vs cards
|
||||||
|
|
||||||
|
4. **Interaction Intensity** (1-2 options):
|
||||||
|
- Transform magnitude: Subtle movements (2-4px) ↔ Dramatic movements (8-12px)
|
||||||
|
- Scale adjustments: Minimal scale changes ↔ Bold scale emphasis
|
||||||
|
- Opacity ranges: Partial fades ↔ Full visibility transitions
|
||||||
|
|
||||||
|
## Generate Refinement Options
|
||||||
|
For each category, create option with:
|
||||||
|
1. **Option ID** (sequential number)
|
||||||
|
2. **Category** (timing_adjustments, easing_tuning, context_variations, interaction_intensity)
|
||||||
|
3. **Label** (brief Chinese description, e.g., "加快整体节奏")
|
||||||
|
4. **Description** (detailed explanation of changes)
|
||||||
|
5. **Impact Scope** (which tokens will be modified)
|
||||||
|
6. **Technical Changes** (specific value adjustments)
|
||||||
|
7. **Before/After Preview** (show current vs proposed values)
|
||||||
|
|
||||||
|
## Output
|
||||||
|
Write single JSON file: {base_path}/.intermediates/animation-analysis/refinement-options.json
|
||||||
|
|
||||||
|
Use schema:
|
||||||
|
{
|
||||||
|
"metadata": {
|
||||||
|
"generated_at": "<timestamp>",
|
||||||
|
"mode": "refinement",
|
||||||
|
"existing_tokens_loaded": true,
|
||||||
|
"total_refinements": <count>
|
||||||
|
},
|
||||||
|
"current_animation_system": {
|
||||||
|
// Copy from animation-tokens.json for reference
|
||||||
|
},
|
||||||
|
"refinement_options": [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"category": "timing_adjustments",
|
||||||
|
"label": "加快整体动画节奏",
|
||||||
|
"description": "将所有 duration 值减少 30%,使界面响应更快速",
|
||||||
|
"impact_scope": "duration.fast, duration.normal, duration.slow",
|
||||||
|
"technical_changes": {
|
||||||
|
"duration.fast": {"from": "150ms", "to": "105ms"},
|
||||||
|
"duration.normal": {"from": "300ms", "to": "210ms"},
|
||||||
|
"duration.slow": {"from": "500ms", "to": "350ms"}
|
||||||
|
},
|
||||||
|
"preview": {
|
||||||
|
"before": "Normal button hover: 150ms",
|
||||||
|
"after": "Faster button hover: 105ms"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
...
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
CRITICAL: Use Write() tool immediately after generating complete JSON
|
||||||
|
`
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 3: Verify Options File Created
|
### Step 3: Verify Options File Created
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash(test -f {base_path}/.intermediates/animation-analysis/analysis-options.json && echo "created")
|
IF NOT refine_mode:
|
||||||
|
# Exploration mode: Check for analysis-options.json
|
||||||
# Quick validation
|
bash(test -f {base_path}/.intermediates/animation-analysis/analysis-options.json && echo "created")
|
||||||
bash(cat {base_path}/.intermediates/animation-analysis/analysis-options.json | grep -q "specification_options" && echo "valid")
|
bash(cat {base_path}/.intermediates/animation-analysis/analysis-options.json | grep -q "specification_options" && echo "valid")
|
||||||
|
ELSE:
|
||||||
|
# Refinement mode: Check for refinement-options.json
|
||||||
|
bash(test -f {base_path}/.intermediates/animation-analysis/refinement-options.json && echo "created")
|
||||||
|
bash(cat {base_path}/.intermediates/animation-analysis/refinement-options.json | grep -q "refinement_options" && echo "valid")
|
||||||
```
|
```
|
||||||
|
|
||||||
**Output**: `analysis-options.json` with animation specification questions
|
**Output**:
|
||||||
|
- Exploration mode: `analysis-options.json` with animation specification questions
|
||||||
|
- Refinement mode: `refinement-options.json` with refinement options
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Phase 1 Output**: `analysis-options.json` with generated specification questions
|
**Phase 1 Output**:
|
||||||
|
- Exploration mode: `analysis-options.json` with generated specification questions
|
||||||
|
- Refinement mode: `refinement-options.json` with refinement options
|
||||||
|
|
||||||
## Phase 1.5: User Confirmation (Optional - Triggered by --interactive)
|
## Phase 1.5: User Confirmation (Optional - Triggered by --interactive)
|
||||||
|
|
||||||
**Purpose**: Allow user to answer animation specification questions before generating tokens
|
**Purpose**: Allow user to answer animation specification questions (exploration) or select refinement options (refinement) before generating tokens
|
||||||
|
|
||||||
**Trigger Condition**: Execute this phase ONLY if `--interactive` flag is present
|
**Trigger Condition**: Execute this phase ONLY if `--interactive` flag is present
|
||||||
|
|
||||||
@@ -315,135 +420,224 @@ REPORT: "🎯 Interactive mode enabled: User answers required"
|
|||||||
### Step 2: Load and Present Options
|
### Step 2: Load and Present Options
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Read options file
|
# Read options file based on mode
|
||||||
options = Read({base_path}/.intermediates/animation-analysis/analysis-options.json)
|
IF NOT refine_mode:
|
||||||
|
# Exploration mode
|
||||||
# Parse specification questions
|
options = Read({base_path}/.intermediates/animation-analysis/analysis-options.json)
|
||||||
specification_options = options.specification_options
|
specification_options = options.specification_options
|
||||||
|
ELSE:
|
||||||
|
# Refinement mode
|
||||||
|
options = Read({base_path}/.intermediates/animation-analysis/refinement-options.json)
|
||||||
|
refinement_options = options.refinement_options
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 3: Present Options to User
|
### Step 3: Present Options to User
|
||||||
|
|
||||||
|
**Conditional Display**: Branch based on `refine_mode` flag
|
||||||
|
|
||||||
```
|
```
|
||||||
📋 Animation Specification Questions
|
IF NOT refine_mode:
|
||||||
|
// EXPLORATION MODE
|
||||||
|
📋 Animation Specification Questions
|
||||||
|
|
||||||
We've generated {options.metadata.total_questions} questions to define your animation system.
|
We've generated {options.metadata.total_questions} questions to define your animation system.
|
||||||
Please answer each question to customize the animation behavior.
|
Please answer each question to customize the animation behavior.
|
||||||
|
|
||||||
{FOR each question in specification_options:
|
{FOR each question in specification_options:
|
||||||
═══════════════════════════════════════════════════
|
═══════════════════════════════════════════════════
|
||||||
Question {question.id}: {question.question}
|
Question {question.id}: {question.question}
|
||||||
Category: {question.category}
|
Category: {question.category}
|
||||||
═══════════════════════════════════════════════════
|
═══════════════════════════════════════════════════
|
||||||
|
|
||||||
{FOR each option in question.options:
|
{FOR each option in question.options:
|
||||||
{option.key}) {option.label}
|
{option.key}) {option.label}
|
||||||
{option.details}
|
{option.details}
|
||||||
|
|
||||||
${option.visual_preview ? "Preview:\n " + option.visual_preview.timeline || option.visual_preview.curve_art || option.visual_preview.animation_sequence : ""}
|
${option.visual_preview ? "Preview:\n " + option.visual_preview.timeline || option.visual_preview.curve_art || option.visual_preview.animation_sequence : ""}
|
||||||
${option.visual_preview ? " " + option.visual_preview.description : ""}
|
${option.visual_preview ? " " + option.visual_preview.description : ""}
|
||||||
|
|
||||||
${option.duration_values ? "Durations: " + JSON.stringify(option.duration_values) : ""}
|
${option.duration_values ? "Durations: " + JSON.stringify(option.duration_values) : ""}
|
||||||
${option.easing_curves ? "Easing: " + JSON.stringify(option.easing_curves) : ""}
|
${option.easing_curves ? "Easing: " + JSON.stringify(option.easing_curves) : ""}
|
||||||
${option.transform_value ? "Transform: " + option.transform_value : ""}
|
${option.transform_value ? "Transform: " + option.transform_value : ""}
|
||||||
}
|
}
|
||||||
|
|
||||||
═══════════════════════════════════════════════════
|
═══════════════════════════════════════════════════
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ELSE:
|
||||||
|
// REFINEMENT MODE
|
||||||
|
🔧 Animation System Refinement Options
|
||||||
|
|
||||||
|
We've generated {options.metadata.total_refinements} refinement options to fine-tune your animation system.
|
||||||
|
Select which refinements to apply (can select multiple).
|
||||||
|
|
||||||
|
{FOR each refinement in refinement_options:
|
||||||
|
═══════════════════════════════════════════════════
|
||||||
|
Option {refinement.id}: {refinement.label}
|
||||||
|
Category: {refinement.category}
|
||||||
|
═══════════════════════════════════════════════════
|
||||||
|
|
||||||
|
Description: {refinement.description}
|
||||||
|
Impact Scope: {refinement.impact_scope}
|
||||||
|
|
||||||
|
Technical Changes:
|
||||||
|
{FOR each token, changes IN refinement.technical_changes:
|
||||||
|
• {token}:
|
||||||
|
Before: {changes.from}
|
||||||
|
After: {changes.to}
|
||||||
|
}
|
||||||
|
|
||||||
|
Preview:
|
||||||
|
{refinement.preview.before} → {refinement.preview.after}
|
||||||
|
|
||||||
|
═══════════════════════════════════════════════════
|
||||||
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 4: Capture User Selection
|
### Step 4: Capture User Selection
|
||||||
|
|
||||||
**Interaction Strategy**: If questions > 4 OR any question has > 3 options, use batch text format:
|
**Conditional Interaction**: Branch based on `refine_mode` flag
|
||||||
|
|
||||||
```
|
|
||||||
【问题[N] - [category]】[question_text]
|
|
||||||
[key]) [label]
|
|
||||||
[details]
|
|
||||||
[key]) [label]
|
|
||||||
[details]
|
|
||||||
...
|
|
||||||
请回答 (格式: 1a 2b 3c...):
|
|
||||||
|
|
||||||
User input: "[N][key] [N][key] ..." → Parse answer pairs (single selection per question)
|
|
||||||
```
|
|
||||||
|
|
||||||
Otherwise, use `AskUserQuestion` below.
|
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// Use AskUserQuestion tool for each question (single selection)
|
IF NOT refine_mode:
|
||||||
user_answers = {}
|
// EXPLORATION MODE - Single selection per question
|
||||||
|
user_answers = {}
|
||||||
|
|
||||||
FOR each question IN specification_options:
|
FOR each question IN specification_options:
|
||||||
AskUserQuestion({
|
AskUserQuestion({
|
||||||
questions: [{
|
questions: [{
|
||||||
question: question.question,
|
question: question.question,
|
||||||
header: question.category,
|
header: question.category,
|
||||||
multiSelect: false, // Single selection per question
|
multiSelect: false, // Single selection per question
|
||||||
options: [
|
options: [
|
||||||
{FOR each option IN question.options:
|
{FOR each option IN question.options:
|
||||||
label: "{option.key}) {option.label}",
|
label: "{option.key}) {option.label}",
|
||||||
description: option.details
|
description: option.details
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
|
|
||||||
// Parse user response (single selection, e.g., "a) Fast & Snappy")
|
// Parse user response (single selection, e.g., "a) Fast & Snappy")
|
||||||
selected_option_text = user_answer
|
selected_option_text = user_answer
|
||||||
|
|
||||||
// Check for user cancellation
|
// Check for user cancellation
|
||||||
IF selected_option_text == null:
|
IF selected_option_text == null:
|
||||||
REPORT: "⚠️ User canceled selection. Using default animation preferences."
|
REPORT: "⚠️ User canceled selection. Using default animation preferences."
|
||||||
EXIT Phase 1.5
|
EXIT Phase 1.5
|
||||||
|
|
||||||
// Extract option key from selection text
|
// Extract option key from selection text
|
||||||
match = selected_option_text.match(/^([a-e])\)/)
|
match = selected_option_text.match(/^([a-e])\)/)
|
||||||
IF match:
|
IF match:
|
||||||
selected_key = match[1]
|
selected_key = match[1]
|
||||||
user_answers[question.category] = selected_key
|
user_answers[question.category] = selected_key
|
||||||
REPORT: "✅ {question.category}: Selected option {selected_key}"
|
REPORT: "✅ {question.category}: Selected option {selected_key}"
|
||||||
ELSE:
|
ELSE:
|
||||||
ERROR: "Invalid selection format. Expected 'a) ...' format"
|
ERROR: "Invalid selection format. Expected 'a) ...' format"
|
||||||
EXIT workflow
|
EXIT workflow
|
||||||
|
|
||||||
REPORT: "✅ Collected {Object.keys(user_answers).length} animation preferences"
|
REPORT: "✅ Collected {Object.keys(user_answers).length} animation preferences"
|
||||||
|
|
||||||
|
ELSE:
|
||||||
|
// REFINEMENT MODE - Multi-selection of refinements
|
||||||
|
AskUserQuestion({
|
||||||
|
questions: [{
|
||||||
|
question: "Which refinement(s) would you like to apply to your animation system?",
|
||||||
|
header: "Refinements",
|
||||||
|
multiSelect: true, // Can select multiple refinements
|
||||||
|
options: [
|
||||||
|
{FOR each refinement IN refinement_options:
|
||||||
|
label: "{refinement.id}. {refinement.label}",
|
||||||
|
description: "{refinement.description} (Affects: {refinement.impact_scope})"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
|
// Parse user response (multi-selection)
|
||||||
|
selected_refinements = user_answer
|
||||||
|
|
||||||
|
// Check for user cancellation
|
||||||
|
IF selected_refinements == null:
|
||||||
|
REPORT: "⚠️ User canceled selection. No refinements will be applied."
|
||||||
|
EXIT Phase 1.5
|
||||||
|
|
||||||
|
// Extract refinement IDs
|
||||||
|
selected_ids = []
|
||||||
|
FOR each selection IN selected_refinements:
|
||||||
|
match = selection.match(/^(\d+)\./)
|
||||||
|
IF match:
|
||||||
|
selected_ids.push(parseInt(match[1]))
|
||||||
|
|
||||||
|
REPORT: "✅ Selected {selected_ids.length} refinement(s) to apply"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 5: Update Options File with User Selection
|
### Step 5: Update Options File with User Selection
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Update analysis-options.json with user selection (embedded)
|
IF NOT refine_mode:
|
||||||
options.user_selection = {
|
# EXPLORATION MODE - Update analysis-options.json
|
||||||
"selected_at": "{current_timestamp}",
|
options.user_selection = {
|
||||||
"session_id": "{session_id}",
|
"selected_at": "{current_timestamp}",
|
||||||
"answers": user_answers // {category: selected_key}
|
"session_id": "{session_id}",
|
||||||
}
|
"answers": user_answers // {category: selected_key}
|
||||||
|
}
|
||||||
|
|
||||||
# Write updated file back
|
# Write updated file back
|
||||||
Write({base_path}/.intermediates/animation-analysis/analysis-options.json, JSON.stringify(options, indent=2))
|
Write({base_path}/.intermediates/animation-analysis/analysis-options.json, JSON.stringify(options, indent=2))
|
||||||
|
|
||||||
# Verify
|
# Verify
|
||||||
bash(test -f {base_path}/.intermediates/animation-analysis/analysis-options.json && echo "saved")
|
bash(test -f {base_path}/.intermediates/animation-analysis/analysis-options.json && echo "saved")
|
||||||
|
|
||||||
|
ELSE:
|
||||||
|
# REFINEMENT MODE - Update refinement-options.json
|
||||||
|
options.user_selection = {
|
||||||
|
"selected_at": "{current_timestamp}",
|
||||||
|
"session_id": "{session_id}",
|
||||||
|
"selected_refinements": selected_ids // Array of refinement IDs
|
||||||
|
}
|
||||||
|
|
||||||
|
# Write updated file back
|
||||||
|
Write({base_path}/.intermediates/animation-analysis/refinement-options.json, JSON.stringify(options, indent=2))
|
||||||
|
|
||||||
|
# Verify
|
||||||
|
bash(test -f {base_path}/.intermediates/animation-analysis/refinement-options.json && echo "saved")
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 6: Confirmation Message
|
### Step 6: Confirmation Message
|
||||||
|
|
||||||
```
|
```
|
||||||
✅ Animation preferences recorded!
|
IF NOT refine_mode:
|
||||||
|
// EXPLORATION MODE
|
||||||
|
✅ Animation preferences recorded!
|
||||||
|
|
||||||
You selected:
|
You selected:
|
||||||
{FOR each category, selected_key IN user_answers:
|
{FOR each category, selected_key IN user_answers:
|
||||||
question = find(specification_options, q => q.category == category)
|
question = find(specification_options, q => q.category == category)
|
||||||
option = find(question.options, o => o.key == selected_key)
|
option = find(question.options, o => o.key == selected_key)
|
||||||
• {category}: {option.label}
|
• {category}: {option.label}
|
||||||
({option.details})
|
({option.details})
|
||||||
}
|
}
|
||||||
|
|
||||||
Proceeding to generate animation system with your preferences...
|
Proceeding to generate animation system with your preferences...
|
||||||
|
|
||||||
|
ELSE:
|
||||||
|
// REFINEMENT MODE
|
||||||
|
✅ Refinement selections recorded!
|
||||||
|
|
||||||
|
You selected {selected_ids.length} refinement(s):
|
||||||
|
{FOR each id IN selected_ids:
|
||||||
|
refinement = find(refinement_options, r => r.id == id)
|
||||||
|
• {refinement.label} ({refinement.category})
|
||||||
|
Impact: {refinement.impact_scope}
|
||||||
|
}
|
||||||
|
|
||||||
|
Proceeding to apply refinements to animation system...
|
||||||
```
|
```
|
||||||
|
|
||||||
**Output**: Updated `analysis-options.json` with embedded `user_selection` field
|
**Output**:
|
||||||
|
- Exploration mode: Updated `analysis-options.json` with embedded `user_selection` field
|
||||||
|
- Refinement mode: Updated `refinement-options.json` with `user_selection.selected_refinements` array
|
||||||
|
|
||||||
## Phase 2: Animation System Generation (Agent Task 2)
|
## Phase 2: Animation System Generation (Agent Task 2)
|
||||||
|
|
||||||
@@ -452,21 +646,35 @@ Proceeding to generate animation system with your preferences...
|
|||||||
### Step 1: Load User Selection or Use Defaults
|
### Step 1: Load User Selection or Use Defaults
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Read analysis-options.json which may contain user_selection
|
IF NOT refine_mode:
|
||||||
options = Read({base_path}/.intermediates/animation-analysis/analysis-options.json)
|
# EXPLORATION MODE - Read analysis-options.json
|
||||||
specification_options = options.specification_options
|
options = Read({base_path}/.intermediates/animation-analysis/analysis-options.json)
|
||||||
|
specification_options = options.specification_options
|
||||||
|
|
||||||
# Check if user_selection field exists (interactive mode)
|
# Check if user_selection field exists (interactive mode)
|
||||||
IF options.user_selection AND options.user_selection.answers:
|
IF options.user_selection AND options.user_selection.answers:
|
||||||
# Interactive mode: Use user-selected preferences
|
# Interactive mode: Use user-selected preferences
|
||||||
user_answers = options.user_selection.answers
|
user_answers = options.user_selection.answers
|
||||||
|
REPORT: "🎯 Interactive mode: Using user-selected animation preferences"
|
||||||
|
ELSE:
|
||||||
|
# Non-interactive mode: Use defaults (first option for each question)
|
||||||
|
user_answers = null
|
||||||
|
REPORT: "ℹ️ Non-interactive mode: Using default animation preferences"
|
||||||
|
|
||||||
REPORT: "🎯 Interactive mode: Using user-selected animation preferences"
|
|
||||||
ELSE:
|
ELSE:
|
||||||
# Non-interactive mode: Use defaults (first option for each question)
|
# REFINEMENT MODE - Read refinement-options.json
|
||||||
user_answers = null
|
options = Read({base_path}/.intermediates/animation-analysis/refinement-options.json)
|
||||||
|
refinement_options = options.refinement_options
|
||||||
|
|
||||||
REPORT: "ℹ️ Non-interactive mode: Using default animation preferences"
|
# Check if user_selection field exists (interactive mode)
|
||||||
|
IF options.user_selection AND options.user_selection.selected_refinements:
|
||||||
|
# Interactive mode: Use user-selected refinements
|
||||||
|
selected_refinements = options.user_selection.selected_refinements
|
||||||
|
REPORT: "🎯 Interactive mode: Applying {selected_refinements.length} selected refinement(s)"
|
||||||
|
ELSE:
|
||||||
|
# Non-interactive mode: Apply all refinements
|
||||||
|
selected_refinements = null
|
||||||
|
REPORT: "ℹ️ Non-interactive mode: Applying all refinements"
|
||||||
|
|
||||||
# Load extracted animations if available
|
# Load extracted animations if available
|
||||||
extracted_animations = []
|
extracted_animations = []
|
||||||
@@ -487,14 +695,16 @@ bash(mkdir -p {base_path}/animation-extraction)
|
|||||||
|
|
||||||
### Step 3: Launch Animation Generation Task
|
### Step 3: Launch Animation Generation Task
|
||||||
|
|
||||||
Generate animation system based on user preferences (or defaults) + CSS extraction:
|
**Conditional Task**: Branch based on `refine_mode` flag
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
Task(ui-design-agent): `
|
IF NOT refine_mode:
|
||||||
[ANIMATION_SYSTEM_GENERATION_TASK]
|
// EXPLORATION MODE
|
||||||
Generate production-ready animation system based on user preferences and CSS extraction
|
Task(ui-design-agent): `
|
||||||
|
[ANIMATION_SYSTEM_GENERATION_TASK]
|
||||||
|
Generate production-ready animation system based on user preferences and CSS extraction
|
||||||
|
|
||||||
SESSION: {session_id} | BASE_PATH: {base_path}
|
SESSION: {session_id} | MODE: explore | BASE_PATH: {base_path}
|
||||||
|
|
||||||
USER PREFERENCES:
|
USER PREFERENCES:
|
||||||
${user_answers ? "- User Selection: " + JSON.stringify(user_answers) : "- Using Defaults: First option for each category"}
|
${user_answers ? "- User Selection: " + JSON.stringify(user_answers) : "- Using Defaults: First option for each category"}
|
||||||
@@ -659,10 +869,98 @@ Task(ui-design-agent): `
|
|||||||
- ${user_answers ? "✅ READ analysis-options.json for user_selection field" : "✅ Use first option from each question as default"}
|
- ${user_answers ? "✅ READ analysis-options.json for user_selection field" : "✅ Use first option from each question as default"}
|
||||||
- ❌ NO user questions or interaction in this phase
|
- ❌ NO user questions or interaction in this phase
|
||||||
- ❌ NO external research or MCP calls
|
- ❌ NO external research or MCP calls
|
||||||
`
|
`
|
||||||
|
|
||||||
|
ELSE:
|
||||||
|
// REFINEMENT MODE
|
||||||
|
Task(ui-design-agent): `
|
||||||
|
[ANIMATION_SYSTEM_REFINEMENT_TASK]
|
||||||
|
Apply selected refinements to existing animation system
|
||||||
|
|
||||||
|
SESSION: {session_id} | MODE: refine | BASE_PATH: {base_path}
|
||||||
|
|
||||||
|
## Load Existing Animation System
|
||||||
|
- Current tokens: Read from {base_path}/animation-extraction/animation-tokens.json
|
||||||
|
- Refinement options: Read from .intermediates/animation-analysis/refinement-options.json
|
||||||
|
|
||||||
|
REFINEMENT SELECTION:
|
||||||
|
${selected_refinements ? `
|
||||||
|
- Interactive mode: Apply selected refinements
|
||||||
|
- Selected IDs: ${JSON.stringify(selected_refinements)}
|
||||||
|
- For each ID in selected_refinements:
|
||||||
|
* Find refinement in refinement_options by id
|
||||||
|
* Apply technical_changes to corresponding tokens
|
||||||
|
` : `
|
||||||
|
- Non-interactive mode: Apply ALL refinements
|
||||||
|
- For each refinement in refinement_options:
|
||||||
|
* Apply technical_changes to corresponding tokens
|
||||||
|
`}
|
||||||
|
|
||||||
|
## Input Analysis
|
||||||
|
- CSS extraction: {extracted_animations.length > 0 ? "Available" : "None"}
|
||||||
|
${extracted_animations.length > 0 ? "- CSS Data: " + JSON.stringify(extracted_animations) : ""}
|
||||||
|
- Design context: {has_design_context ? "Available" : "None"}
|
||||||
|
${has_design_context ? "- Design Tokens: Read from style-extraction/style-1/design-tokens.json" : ""}
|
||||||
|
|
||||||
|
## Refinement Application Rules
|
||||||
|
${selected_refinements ? `
|
||||||
|
- ONLY apply refinements with IDs in selected_refinements array
|
||||||
|
- Skip refinements not selected by user
|
||||||
|
` : `
|
||||||
|
- Apply ALL refinements from refinement_options
|
||||||
|
- Combine multiple refinements that affect same token
|
||||||
|
`}
|
||||||
|
- Load current animation-tokens.json
|
||||||
|
- For each applicable refinement:
|
||||||
|
* Parse technical_changes field
|
||||||
|
* Apply "to" values to replace "from" values in tokens
|
||||||
|
* Preserve structure and var() references
|
||||||
|
- If multiple refinements affect same token, apply in sequence
|
||||||
|
- Maintain WCAG compliance and semantic naming
|
||||||
|
- All tokens use CSS Custom Property format: var(--duration-fast)
|
||||||
|
|
||||||
|
## Conflict Resolution
|
||||||
|
- If multiple selected refinements modify same token:
|
||||||
|
* Apply refinements in ID order (lowest first)
|
||||||
|
* Later refinements override earlier ones
|
||||||
|
* Document conflicts in animation-guide.md
|
||||||
|
|
||||||
|
## Generate Updated Files
|
||||||
|
|
||||||
|
### 1. animation-tokens.json
|
||||||
|
Updated animation token structure with refinements applied:
|
||||||
|
- Load existing structure
|
||||||
|
- Apply technical_changes from selected/all refinements
|
||||||
|
- Maintain var() references and semantic naming
|
||||||
|
- Validate all cubic-bezier values
|
||||||
|
|
||||||
|
### 2. animation-guide.md
|
||||||
|
Updated usage guide with refinement documentation:
|
||||||
|
- Original sections (Animation Philosophy, Duration Scale, etc.)
|
||||||
|
- **NEW: Refinement History** section:
|
||||||
|
* Applied refinements list
|
||||||
|
* Before/after comparisons
|
||||||
|
* Rationale for changes
|
||||||
|
* Migration notes if needed
|
||||||
|
|
||||||
|
## Output File Paths
|
||||||
|
- animation-tokens.json: {base_path}/animation-extraction/animation-tokens.json (OVERWRITE)
|
||||||
|
- animation-guide.md: {base_path}/animation-extraction/animation-guide.md (UPDATE with refinement history)
|
||||||
|
|
||||||
|
## Critical Requirements
|
||||||
|
- ✅ Use Write() tool immediately for both files
|
||||||
|
- ✅ OVERWRITE existing animation-tokens.json with refined version
|
||||||
|
- ✅ UPDATE animation-guide.md (don't overwrite, add refinement history section)
|
||||||
|
- ✅ All tokens use CSS Custom Property format: var(--duration-fast)
|
||||||
|
- ✅ Include prefers-reduced-motion media query guidance
|
||||||
|
- ✅ Validate all cubic-bezier values are valid (4 numbers between 0-1)
|
||||||
|
- ${selected_refinements ? "✅ READ refinement-options.json for user_selection.selected_refinements" : "✅ Apply ALL refinements from refinement_options"}
|
||||||
|
- ❌ NO user questions or interaction in this phase
|
||||||
|
- ❌ NO external research or MCP calls
|
||||||
|
`
|
||||||
```
|
```
|
||||||
|
|
||||||
**Output**: Agent generates 2 files (animation-tokens.json, animation-guide.md)
|
**Output**: Agent generates/updates 2 files (animation-tokens.json, animation-guide.md)
|
||||||
|
|
||||||
## Phase 3: Verify Output
|
## Phase 3: Verify Output
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: imitate-auto
|
name: imitate-auto
|
||||||
description: High-speed multi-page UI replication with batch screenshot capture and design token extraction
|
description: UI design workflow with direct code/image input for design token extraction and prototype generation
|
||||||
argument-hint: --url-map "<map>" [--capture-mode <batch|deep>] [--depth <1-5>] [--session <id>] [--prompt "<desc>"]
|
argument-hint: "[--images "<glob>"] [--prompt "<desc>"] [--session <id>]"
|
||||||
allowed-tools: SlashCommand(*), TodoWrite(*), Read(*), Write(*), Bash(*)
|
allowed-tools: SlashCommand(*), TodoWrite(*), Read(*), Write(*), Bash(*)
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -9,79 +9,72 @@ allowed-tools: SlashCommand(*), TodoWrite(*), Read(*), Write(*), Bash(*)
|
|||||||
|
|
||||||
## Overview & Execution Model
|
## Overview & Execution Model
|
||||||
|
|
||||||
**Fully autonomous replication orchestrator**: Efficiently replicate multiple web pages through sequential execution from screenshot capture to design integration.
|
**Fully autonomous design orchestrator**: Efficiently create UI prototypes through sequential execution from design token extraction to system integration.
|
||||||
|
|
||||||
**Dual Capture Strategy**: Supports two capture modes for different use cases:
|
**Direct Input Strategy**: Accepts local code files and images:
|
||||||
- **Batch Mode** (default): Fast multi-URL screenshot capture via `/workflow:ui-design:capture`
|
- **Code Files**: Detect file paths in `--prompt` parameter
|
||||||
- **Deep Mode**: Interactive layer exploration for single URL via `/workflow:ui-design:explore-layers`
|
- **Images**: Reference images via `--images` glob pattern
|
||||||
|
- **Hybrid**: Combine both code and visual inputs
|
||||||
|
|
||||||
**Autonomous Flow** (⚠️ CONTINUOUS EXECUTION - DO NOT STOP):
|
**Autonomous Flow** (⚠️ CONTINUOUS EXECUTION - DO NOT STOP):
|
||||||
1. User triggers: `/workflow:ui-design:imitate-auto --url-map "..."`
|
1. User triggers: `/workflow:ui-design:imitate-auto [--images "..."] [--prompt "..."]`
|
||||||
2. Phase 0: Initialize and parse parameters
|
2. Phase 0: Initialize and detect input sources
|
||||||
3. Phase 1: Screenshot capture (batch or deep mode) → **Execute phase (blocks until finished)** → Auto-continues
|
3. Phase 2: Style extraction (complete design systems) → **Execute phase (blocks until finished)** → Auto-continues
|
||||||
4. Phase 2: Style extraction (complete design systems) → **Execute phase (blocks until finished)** → Auto-continues
|
4. Phase 2.3: Animation extraction (CSS auto mode) → **Execute phase (blocks until finished)** → Auto-continues
|
||||||
5. Phase 2.3: Animation extraction (CSS auto mode) → **Execute phase (blocks until finished)** → Auto-continues
|
5. Phase 2.5: Layout extraction (structure templates) → **Execute phase (blocks until finished)** → Auto-continues
|
||||||
6. Phase 2.5: Layout extraction (structure templates) → **Execute phase (blocks until finished)** → Auto-continues
|
6. Phase 3: Batch UI assembly → **Execute phase (blocks until finished)** → Auto-continues
|
||||||
7. Phase 3: Batch UI assembly → **Execute phase (blocks until finished)** → Auto-continues
|
7. Phase 4: Design system integration → Reports completion
|
||||||
8. Phase 4: Design system integration → Reports completion
|
|
||||||
|
|
||||||
**Phase Transition Mechanism**:
|
**Phase Transition Mechanism**:
|
||||||
- `SlashCommand` is BLOCKING - execution pauses until the command finishes
|
- `SlashCommand` is BLOCKING - execution pauses until the command finishes
|
||||||
- When each phase finishes executing: Automatically process output and execute next phase
|
- When each phase finishes executing: Automatically process output and execute next phase
|
||||||
- No user interaction required after initial parameter parsing
|
- No user interaction required after initial parameter parsing
|
||||||
|
|
||||||
**Auto-Continue Mechanism**: TodoWrite tracks phase status. When each phase finishes executing, you MUST immediately construct and execute the next phase command. No user intervention required. The workflow is NOT complete until reaching Phase 5.
|
**Auto-Continue Mechanism**: TodoWrite tracks phase status. When each phase finishes executing, you MUST immediately construct and execute the next phase command. No user intervention required. The workflow is NOT complete until reaching Phase 4.
|
||||||
|
|
||||||
## Core Rules
|
## Core Rules
|
||||||
|
|
||||||
1. **Start Immediately**: TodoWrite initialization → Phase 1 execution
|
1. **Start Immediately**: TodoWrite initialization → Phase 2 execution
|
||||||
2. **No Preliminary Validation**: Sub-commands handle their own validation
|
2. **No Preliminary Validation**: Sub-commands handle their own validation
|
||||||
3. **Parse & Pass**: Extract data from each output for next phase
|
3. **Parse & Pass**: Extract data from each output for next phase
|
||||||
4. **Track Progress**: Update TodoWrite after each phase
|
4. **Track Progress**: Update TodoWrite after each phase
|
||||||
5. **⚠️ CRITICAL: DO NOT STOP** - This is a continuous multi-phase workflow. Each SlashCommand execution blocks until finished, then you MUST immediately execute the next phase. Workflow is NOT complete until Phase 5.
|
5. **⚠️ CRITICAL: DO NOT STOP** - This is a continuous multi-phase workflow. Each SlashCommand execution blocks until finished, then you MUST immediately execute the next phase. Workflow is NOT complete until Phase 4.
|
||||||
|
|
||||||
## Parameter Requirements
|
## Parameter Requirements
|
||||||
|
|
||||||
**Required Parameters**:
|
**Optional Parameters** (at least one of --images or --prompt required):
|
||||||
- `--url-map "<map>"`: Target page mapping
|
- `--images "<glob>"`: Reference image paths (e.g., `"design-refs/*"`, `"screenshots/*.png"`)
|
||||||
- Format: `"target1:url1, target2:url2, ..."`
|
- Glob patterns supported
|
||||||
- Example: `"home:https://linear.app, pricing:https://linear.app/pricing"`
|
- Multiple images can be matched
|
||||||
- First target serves as primary style source
|
|
||||||
|
|
||||||
**Optional Parameters**:
|
- `--prompt "<desc>"`: Design description or file path
|
||||||
- `--capture-mode <batch|deep>` (Optional, default: batch): Screenshot capture strategy
|
- Can contain file paths (automatically detected)
|
||||||
- `batch` (default): Multi-URL fast batch capture via `/workflow:ui-design:capture`
|
- Influences extract command analysis focus
|
||||||
- `deep`: Single-URL interactive depth exploration via `/workflow:ui-design:explore-layers`
|
- Example: `"Focus on dark mode"`, `"Emphasize minimalist design"`
|
||||||
- **Note**: `deep` mode only uses first URL from url-map
|
- Example with path: `"Use design from ./src/components"`
|
||||||
|
|
||||||
- `--depth <1-5>` (Optional, default: 3): Capture depth for deep mode
|
|
||||||
- `1`: Page level (full-page screenshot)
|
|
||||||
- `2`: Element level (+ key components)
|
|
||||||
- `3`: Interaction level (+ modals, dropdowns)
|
|
||||||
- `4`: Embedded level (+ iframes)
|
|
||||||
- `5`: Shadow DOM (+ web components)
|
|
||||||
- **Only applies when** `--capture-mode deep`
|
|
||||||
|
|
||||||
- `--session <id>` (Optional): Workflow session ID
|
- `--session <id>` (Optional): Workflow session ID
|
||||||
- Integrate into existing session (`.workflow/WFS-{session}/`)
|
- Integrate into existing session (`.workflow/WFS-{session}/`)
|
||||||
- Enable automatic design system integration (Phase 5)
|
- Enable automatic design system integration (Phase 4)
|
||||||
- If not provided: standalone mode (`.workflow/.design/`)
|
- If not provided: standalone mode (`.workflow/.design/`)
|
||||||
|
|
||||||
- `--prompt "<desc>"` (Optional): Style extraction guidance
|
**Input Rules**:
|
||||||
- Influences extract command analysis focus
|
- Must provide at least one: `--images` or `--prompt`
|
||||||
- Example: `"Focus on dark mode"`, `"Emphasize minimalist design"`
|
- Multiple parameters can be combined for guided analysis
|
||||||
- **Note**: Design systems are now production-ready by default (no separate consolidate step)
|
- File paths in `--prompt` are automatically detected and imported
|
||||||
|
|
||||||
## Execution Modes
|
## Execution Modes
|
||||||
|
|
||||||
**Capture Modes**:
|
**Input Sources**:
|
||||||
- **Batch Mode** (default): Multi-URL screenshot capture for fast replication
|
- **Code Files**: Automatically detected from `--prompt` file paths
|
||||||
- Uses `/workflow:ui-design:capture` for parallel screenshot capture
|
- Triggers `/workflow:ui-design:import-from-code` for token extraction
|
||||||
- Optimized for replicating multiple pages efficiently
|
- Analyzes existing CSS/JS/HTML files
|
||||||
- **Deep Mode**: Single-URL layer exploration for detailed analysis
|
- **Visual Input**: Images via `--images` glob pattern
|
||||||
- Uses `/workflow:ui-design:explore-layers` for interactive depth traversal
|
- Reference images for style extraction
|
||||||
- Captures page layers at different depths (1-5)
|
- Screenshots or design mockups
|
||||||
- Only processes first URL from url-map
|
- **Hybrid Mode**: Combines code import with visual supplements
|
||||||
|
- Code provides base tokens
|
||||||
|
- Images supplement missing design elements
|
||||||
|
|
||||||
**Token Processing**:
|
**Token Processing**:
|
||||||
- **Direct Generation**: Complete design systems generated in style-extract phase
|
- **Direct Generation**: Complete design systems generated in style-extract phase
|
||||||
@@ -94,15 +87,47 @@ allowed-tools: SlashCommand(*), TodoWrite(*), Read(*), Write(*), Bash(*)
|
|||||||
- Integrated: Design system automatically added to session artifacts
|
- Integrated: Design system automatically added to session artifacts
|
||||||
- Standalone: Output in `.workflow/.design/{run_id}/`
|
- Standalone: Output in `.workflow/.design/{run_id}/`
|
||||||
|
|
||||||
## 6-Phase Execution
|
## 5-Phase Execution
|
||||||
|
|
||||||
### Phase 0: Initialization and Target Parsing
|
### Phase 0: Intelligent Path Detection & Initialization
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Generate design ID (ID = directory name)
|
# Step 1: Detect design source from inputs
|
||||||
|
code_files_detected = false
|
||||||
|
code_base_path = null
|
||||||
|
has_visual_input = false
|
||||||
|
|
||||||
|
IF --prompt:
|
||||||
|
# Extract potential file paths from prompt
|
||||||
|
potential_paths = extract_paths_from_text(--prompt)
|
||||||
|
FOR path IN potential_paths:
|
||||||
|
IF file_or_directory_exists(path):
|
||||||
|
code_files_detected = true
|
||||||
|
code_base_path = path
|
||||||
|
BREAK
|
||||||
|
|
||||||
|
IF --images:
|
||||||
|
# Check if images parameter points to existing files
|
||||||
|
IF glob_matches_files(--images):
|
||||||
|
has_visual_input = true
|
||||||
|
|
||||||
|
# Step 2: Determine design source strategy
|
||||||
|
design_source = "unknown"
|
||||||
|
IF code_files_detected AND has_visual_input:
|
||||||
|
design_source = "hybrid" # Both code and visual
|
||||||
|
ELSE IF code_files_detected:
|
||||||
|
design_source = "code_only" # Only code files
|
||||||
|
ELSE IF has_visual_input OR --prompt:
|
||||||
|
design_source = "visual_only" # Only visual/prompt
|
||||||
|
ELSE:
|
||||||
|
ERROR: "No design source provided (code files, images, or prompt required)"
|
||||||
|
EXIT 1
|
||||||
|
|
||||||
|
STORE: design_source, code_base_path, has_visual_input
|
||||||
|
|
||||||
|
# Step 3: Initialize directories
|
||||||
design_id = "design-run-$(date +%Y%m%d)-$RANDOM"
|
design_id = "design-run-$(date +%Y%m%d)-$RANDOM"
|
||||||
|
|
||||||
# Determine base path and session mode
|
|
||||||
IF --session:
|
IF --session:
|
||||||
session_id = {provided_session}
|
session_id = {provided_session}
|
||||||
relative_base_path = ".workflow/WFS-{session_id}/{design_id}"
|
relative_base_path = ".workflow/WFS-{session_id}/{design_id}"
|
||||||
@@ -116,100 +141,36 @@ ELSE:
|
|||||||
Bash(mkdir -p "{relative_base_path}")
|
Bash(mkdir -p "{relative_base_path}")
|
||||||
base_path=$(cd "{relative_base_path}" && pwd)
|
base_path=$(cd "{relative_base_path}" && pwd)
|
||||||
|
|
||||||
# Step 0.1: Intelligent Path Detection
|
|
||||||
code_files_detected = false
|
|
||||||
code_base_path = null
|
|
||||||
design_source = "web" # Default for imitate-auto
|
|
||||||
|
|
||||||
IF --prompt:
|
|
||||||
# Extract potential file paths from prompt
|
|
||||||
potential_paths = extract_paths_from_text(--prompt)
|
|
||||||
FOR path IN potential_paths:
|
|
||||||
IF file_or_directory_exists(path):
|
|
||||||
code_files_detected = true
|
|
||||||
code_base_path = path
|
|
||||||
design_source = "hybrid" # Web + Code
|
|
||||||
BREAK
|
|
||||||
|
|
||||||
STORE: design_source, code_base_path
|
|
||||||
|
|
||||||
# Parse url-map
|
|
||||||
url_map_string = {--url-map}
|
|
||||||
VALIDATE: url_map_string is not empty, "--url-map parameter is required"
|
|
||||||
|
|
||||||
# Parse target:url pairs
|
|
||||||
url_map = {} # {target_name: url}
|
|
||||||
target_names = []
|
|
||||||
|
|
||||||
FOR pair IN split(url_map_string, ","):
|
|
||||||
pair = pair.strip()
|
|
||||||
|
|
||||||
IF ":" NOT IN pair:
|
|
||||||
ERROR: "Invalid url-map format: '{pair}'"
|
|
||||||
ERROR: "Expected format: 'target:url'"
|
|
||||||
ERROR: "Example: 'home:https://example.com, pricing:https://example.com/pricing'"
|
|
||||||
EXIT 1
|
|
||||||
|
|
||||||
target, url = pair.split(":", 1)
|
|
||||||
target = target.strip().lower().replace(" ", "-")
|
|
||||||
url = url.strip()
|
|
||||||
|
|
||||||
url_map[target] = url
|
|
||||||
target_names.append(target)
|
|
||||||
|
|
||||||
VALIDATE: len(target_names) > 0, "url-map must contain at least one target:url pair"
|
|
||||||
|
|
||||||
primary_target = target_names[0] # First target as primary style source
|
|
||||||
|
|
||||||
# Parse capture mode
|
|
||||||
capture_mode = --capture-mode OR "batch"
|
|
||||||
depth = int(--depth OR 3)
|
|
||||||
|
|
||||||
# Validate capture mode
|
|
||||||
IF capture_mode NOT IN ["batch", "deep"]:
|
|
||||||
ERROR: "Invalid --capture-mode: {capture_mode}"
|
|
||||||
ERROR: "Valid options: batch, deep"
|
|
||||||
EXIT 1
|
|
||||||
|
|
||||||
# Validate depth (only for deep mode)
|
|
||||||
IF capture_mode == "deep":
|
|
||||||
IF depth NOT IN [1, 2, 3, 4, 5]:
|
|
||||||
ERROR: "Invalid --depth: {depth}"
|
|
||||||
ERROR: "Valid range: 1-5"
|
|
||||||
EXIT 1
|
|
||||||
|
|
||||||
# Warn if multiple URLs in deep mode
|
|
||||||
IF len(target_names) > 1:
|
|
||||||
WARN: "⚠️ Deep mode only uses first URL: '{primary_target}'"
|
|
||||||
WARN: " Other URLs will be ignored: {', '.join(target_names[1:])}"
|
|
||||||
WARN: " For multi-URL, use --capture-mode batch"
|
|
||||||
|
|
||||||
# Write metadata
|
# Write metadata
|
||||||
metadata = {
|
metadata = {
|
||||||
"workflow": "imitate-auto",
|
"workflow": "imitate-auto",
|
||||||
"run_id": run_id,
|
"run_id": design_id,
|
||||||
"session_id": session_id,
|
"session_id": session_id,
|
||||||
"timestamp": current_timestamp(),
|
"timestamp": current_timestamp(),
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"url_map": url_map,
|
"design_source": design_source,
|
||||||
"capture_mode": capture_mode,
|
"code_base_path": code_base_path,
|
||||||
"depth": depth IF capture_mode == "deep" ELSE null,
|
"images": --images OR null,
|
||||||
"prompt": --prompt OR null
|
"prompt": --prompt OR null
|
||||||
},
|
},
|
||||||
"targets": target_names,
|
|
||||||
"status": "in_progress"
|
"status": "in_progress"
|
||||||
}
|
}
|
||||||
|
|
||||||
Write("{base_path}/.run-metadata.json", JSON.stringify(metadata, null, 2))
|
Write("{base_path}/.run-metadata.json", JSON.stringify(metadata, null, 2))
|
||||||
|
|
||||||
|
# Initialize default flags
|
||||||
|
animation_complete = false
|
||||||
|
needs_visual_supplement = false
|
||||||
|
style_complete = false
|
||||||
|
layout_complete = false
|
||||||
|
|
||||||
# Initialize TodoWrite
|
# Initialize TodoWrite
|
||||||
TodoWrite({todos: [
|
TodoWrite({todos: [
|
||||||
{content: "Initialize and parse url-map", status: "completed", activeForm: "Initializing"},
|
{content: "Initialize and detect design source", status: "completed", activeForm: "Initializing"},
|
||||||
{content: capture_mode == "batch" ? f"Batch screenshot capture ({len(target_names)} targets)" : f"Deep exploration (depth {depth})", status: "pending", activeForm: "Capturing screenshots"},
|
|
||||||
{content: "Extract style (complete design systems)", status: "pending", activeForm: "Extracting style"},
|
{content: "Extract style (complete design systems)", status: "pending", activeForm: "Extracting style"},
|
||||||
{content: "Extract animation (CSS auto mode)", status: "pending", activeForm: "Extracting animation"},
|
{content: "Extract animation (CSS auto mode)", status: "pending", activeForm: "Extracting animation"},
|
||||||
{content: "Extract layout (structure templates)", status: "pending", activeForm: "Extracting layout"},
|
{content: "Extract layout (structure templates)", status: "pending", activeForm: "Extracting layout"},
|
||||||
{content: f"Assemble UI for {len(target_names)} targets", status: "pending", activeForm: "Assembling UI"},
|
{content: "Assemble UI prototypes", status: "pending", activeForm: "Assembling UI"},
|
||||||
{content: session_id ? "Integrate design system" : "Standalone completion", status: "pending", activeForm: "Completing"}
|
{content: session_id ? "Integrate design system" : "Standalone completion", status: "pending", activeForm: "Completing"}
|
||||||
]})
|
]})
|
||||||
```
|
```
|
||||||
@@ -310,105 +271,36 @@ IF design_source == "hybrid":
|
|||||||
|
|
||||||
STORE: style_complete, animation_complete, layout_complete
|
STORE: style_complete, animation_complete, layout_complete
|
||||||
|
|
||||||
TodoWrite(mark_completed: "Initialize and parse url-map",
|
TodoWrite(mark_completed: "Initialize and detect design source",
|
||||||
mark_in_progress: capture_mode == "batch" ? f"Batch screenshot capture ({len(target_names)} targets)" : f"Deep exploration (depth {depth})")
|
mark_in_progress: "Extract style (complete design systems)")
|
||||||
```
|
|
||||||
|
|
||||||
### Phase 1: Screenshot Capture (Dual Mode)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
REPORT: "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
||||||
REPORT: "🚀 Phase 1: Screenshot Capture"
|
|
||||||
IF design_source == "hybrid":
|
|
||||||
REPORT: " → Purpose: Verify and supplement code analysis"
|
|
||||||
REPORT: "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
|
||||||
|
|
||||||
IF capture_mode == "batch":
|
|
||||||
# Mode A: Batch Multi-URL Capture
|
|
||||||
url_map_command_string = ",".join([f"{name}:{url}" for name, url in url_map.items()])
|
|
||||||
capture_command = f"/workflow:ui-design:capture --design-id \"{design_id}\" --url-map \"{url_map_command_string}\""
|
|
||||||
|
|
||||||
TRY:
|
|
||||||
SlashCommand(capture_command)
|
|
||||||
CATCH error:
|
|
||||||
ERROR: "Batch capture failed: {error}"
|
|
||||||
ERROR: "Cannot proceed without screenshots"
|
|
||||||
EXIT 1
|
|
||||||
|
|
||||||
# Verify batch capture results
|
|
||||||
screenshot_metadata_path = "{base_path}/screenshots/capture-metadata.json"
|
|
||||||
|
|
||||||
IF NOT exists(screenshot_metadata_path):
|
|
||||||
ERROR: "capture command did not generate metadata file"
|
|
||||||
ERROR: "Expected: {screenshot_metadata_path}"
|
|
||||||
EXIT 1
|
|
||||||
|
|
||||||
screenshot_metadata = Read(screenshot_metadata_path)
|
|
||||||
captured_count = screenshot_metadata.total_captured
|
|
||||||
total_requested = screenshot_metadata.total_requested
|
|
||||||
missing_count = total_requested - captured_count
|
|
||||||
|
|
||||||
IF missing_count > 0:
|
|
||||||
missing_targets = [s.target for s in screenshot_metadata.screenshots if not s.captured]
|
|
||||||
WARN: "⚠️ Missing {missing_count} screenshots: {', '.join(missing_targets)}"
|
|
||||||
|
|
||||||
IF captured_count == 0:
|
|
||||||
ERROR: "No screenshots captured - cannot proceed"
|
|
||||||
EXIT 1
|
|
||||||
|
|
||||||
ELSE: # capture_mode == "deep"
|
|
||||||
# Mode B: Deep Interactive Layer Exploration
|
|
||||||
primary_url = url_map[primary_target]
|
|
||||||
explore_command = f"/workflow:ui-design:explore-layers --url \"{primary_url}\" --depth {depth} --design-id \"{design_id}\""
|
|
||||||
|
|
||||||
TRY:
|
|
||||||
SlashCommand(explore_command)
|
|
||||||
CATCH error:
|
|
||||||
ERROR: "Deep exploration failed: {error}"
|
|
||||||
ERROR: "Cannot proceed without screenshots"
|
|
||||||
EXIT 1
|
|
||||||
|
|
||||||
# Verify deep exploration results
|
|
||||||
layer_map_path = "{base_path}/screenshots/layer-map.json"
|
|
||||||
|
|
||||||
IF NOT exists(layer_map_path):
|
|
||||||
ERROR: "explore-layers did not generate layer-map.json"
|
|
||||||
ERROR: "Expected: {layer_map_path}"
|
|
||||||
EXIT 1
|
|
||||||
|
|
||||||
layer_map = Read(layer_map_path)
|
|
||||||
captured_count = layer_map.summary.total_captures
|
|
||||||
total_requested = captured_count # For consistency with batch mode
|
|
||||||
|
|
||||||
TodoWrite(mark_completed: f"Batch screenshot capture ({len(target_names)} targets)" IF capture_mode == "batch" ELSE f"Deep exploration (depth {depth})",
|
|
||||||
mark_in_progress: "Extract style (visual tokens)")
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Phase 2: Style Extraction
|
### Phase 2: Style Extraction
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Determine if style extraction needed
|
# Determine if style extraction needed
|
||||||
skip_style = (design_source == "hybrid" AND style_complete)
|
skip_style = (design_source == "code_only" AND style_complete)
|
||||||
|
|
||||||
IF skip_style:
|
IF skip_style:
|
||||||
REPORT: "✅ Phase 2: Style (Using Code Import)"
|
REPORT: "✅ Phase 2: Style (Using Code Import)"
|
||||||
ELSE:
|
ELSE:
|
||||||
REPORT: "🚀 Phase 2: Style Extraction"
|
REPORT: "🚀 Phase 2: Style Extraction"
|
||||||
IF capture_mode == "batch":
|
|
||||||
images_glob = f"{base_path}/screenshots/*.{{png,jpg,jpeg,webp}}"
|
# Build command with available inputs
|
||||||
ELSE:
|
command_parts = [f"/workflow:ui-design:style-extract --design-id \"{design_id}\""]
|
||||||
images_glob = f"{base_path}/screenshots/**/*.{{png,jpg,jpeg,webp}}"
|
|
||||||
|
IF --images:
|
||||||
|
command_parts.append(f"--images \"{--images}\"")
|
||||||
|
|
||||||
IF --prompt:
|
IF --prompt:
|
||||||
extraction_prompt = f"Extract visual style tokens from '{primary_target}'. {--prompt}"
|
extraction_prompt = --prompt
|
||||||
ELSE:
|
|
||||||
IF design_source == "hybrid":
|
IF design_source == "hybrid":
|
||||||
extraction_prompt = f"Extract visual style tokens from '{primary_target}' to supplement code-imported design tokens."
|
extraction_prompt = f"{--prompt} (supplement code-imported tokens)"
|
||||||
ELSE:
|
command_parts.append(f"--prompt \"{extraction_prompt}\"")
|
||||||
extraction_prompt = f"Extract visual style tokens from '{primary_target}' with consistency across all pages."
|
|
||||||
|
|
||||||
url_map_for_extract = ",".join([f"{name}:{url}" for name, url in url_map.items()])
|
command_parts.extend(["--variants 1", "--interactive"])
|
||||||
extract_command = f"/workflow:ui-design:style-extract --design-id \"{design_id}\" --images \"{images_glob}\" --urls \"{url_map_for_extract}\" --prompt \"{extraction_prompt}\" --variants 1 --interactive"
|
|
||||||
|
extract_command = " ".join(command_parts)
|
||||||
SlashCommand(extract_command)
|
SlashCommand(extract_command)
|
||||||
|
|
||||||
TodoWrite(mark_completed: "Extract style", mark_in_progress: "Extract animation")
|
TodoWrite(mark_completed: "Extract style", mark_in_progress: "Extract animation")
|
||||||
@@ -417,29 +309,42 @@ TodoWrite(mark_completed: "Extract style", mark_in_progress: "Extract animation"
|
|||||||
### Phase 2.3: Animation Extraction
|
### Phase 2.3: Animation Extraction
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
skip_animation = (design_source == "hybrid" AND animation_complete)
|
skip_animation = (design_source == "code_only" AND animation_complete)
|
||||||
|
|
||||||
IF skip_animation:
|
IF skip_animation:
|
||||||
REPORT: "✅ Phase 2.3: Animation (Using Code Import)"
|
REPORT: "✅ Phase 2.3: Animation (Using Code Import)"
|
||||||
ELSE:
|
ELSE:
|
||||||
REPORT: "🚀 Phase 2.3: Animation Extraction"
|
REPORT: "🚀 Phase 2.3: Animation Extraction"
|
||||||
url_map_for_animation = ",".join([f"{target}:{url}" for target, url in url_map.items()])
|
animation_extract_command = f"/workflow:ui-design:animation-extract --design-id \"{design_id}\" --interactive"
|
||||||
animation_extract_command = f"/workflow:ui-design:animation-extract --design-id \"{design_id}\" --urls \"{url_map_for_animation}\" --mode auto"
|
|
||||||
SlashCommand(animation_extract_command)
|
SlashCommand(animation_extract_command)
|
||||||
|
|
||||||
|
TodoWrite(mark_completed: "Extract animation", mark_in_progress: "Extract layout")
|
||||||
```
|
```
|
||||||
|
|
||||||
### Phase 2.5: Layout Extraction
|
### Phase 2.5: Layout Extraction
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
skip_layout = (design_source == "hybrid" AND layout_complete)
|
skip_layout = (design_source == "code_only" AND layout_complete)
|
||||||
|
|
||||||
IF skip_layout:
|
IF skip_layout:
|
||||||
REPORT: "✅ Phase 2.5: Layout (Using Code Import)"
|
REPORT: "✅ Phase 2.5: Layout (Using Code Import)"
|
||||||
ELSE:
|
ELSE:
|
||||||
REPORT: "🚀 Phase 2.5: Layout Extraction"
|
REPORT: "🚀 Phase 2.5: Layout Extraction"
|
||||||
url_map_for_layout = ",".join([f"{target}:{url}" for target, url in url_map.items()])
|
|
||||||
layout_extract_command = f"/workflow:ui-design:layout-extract --design-id \"{design_id}\" --images \"{images_glob}\" --urls \"{url_map_for_layout}\" --targets \"{','.join(target_names)}\" --variants 1 --interactive"
|
# Build command with available inputs
|
||||||
|
command_parts = [f"/workflow:ui-design:layout-extract --design-id \"{design_id}\""]
|
||||||
|
|
||||||
|
IF --images:
|
||||||
|
command_parts.append(f"--images \"{--images}\"")
|
||||||
|
|
||||||
|
IF --prompt:
|
||||||
|
command_parts.append(f"--prompt \"{--prompt}\"")
|
||||||
|
|
||||||
|
# Default target if not specified
|
||||||
|
command_parts.append("--targets \"home\"")
|
||||||
|
command_parts.extend(["--variants 1", "--interactive"])
|
||||||
|
|
||||||
|
layout_extract_command = " ".join(command_parts)
|
||||||
SlashCommand(layout_extract_command)
|
SlashCommand(layout_extract_command)
|
||||||
|
|
||||||
TodoWrite(mark_completed: "Extract layout", mark_in_progress: "Assemble UI")
|
TodoWrite(mark_completed: "Extract layout", mark_in_progress: "Assemble UI")
|
||||||
@@ -490,7 +395,7 @@ TodoWrite({todos: [
|
|||||||
]})
|
]})
|
||||||
```
|
```
|
||||||
|
|
||||||
### Phase 6: Completion Report
|
### Phase 4: Completion Report
|
||||||
|
|
||||||
**Completion Message**:
|
**Completion Message**:
|
||||||
```
|
```
|
||||||
@@ -500,26 +405,24 @@ TodoWrite({todos: [
|
|||||||
|
|
||||||
━━━ 📊 Workflow Summary ━━━
|
━━━ 📊 Workflow Summary ━━━
|
||||||
|
|
||||||
Mode: {capture_mode == "batch" ? "Batch Multi-Page Replication" : f"Deep Interactive Exploration (depth {depth})"}
|
Mode: Direct Input ({design_source})
|
||||||
Session: {session_id or "standalone"}
|
Session: {session_id or "standalone"}
|
||||||
Run ID: {run_id}
|
Run ID: {run_id}
|
||||||
|
|
||||||
Phase 1 - Screenshot Capture: ✅ {IF capture_mode == "batch": f"{captured_count}/{total_requested} screenshots" ELSE: f"{captured_count} screenshots ({total_layers} layers)"}
|
Phase 0 - Input Detection: ✅ {design_source} mode
|
||||||
{IF capture_mode == "batch" AND captured_count < total_requested: f"⚠️ {total_requested - captured_count} missing" ELSE: "All targets captured"}
|
{IF design_source == "code_only": "Code files imported" ELSE IF design_source == "hybrid": "Code + visual inputs" ELSE: "Visual inputs"}
|
||||||
|
|
||||||
Phase 2 - Style Extraction: ✅ Production-ready design systems
|
Phase 2 - Style Extraction: ✅ Production-ready design systems
|
||||||
Output: style-extraction/style-1/ (design-tokens.json + style-guide.md)
|
Output: style-extraction/style-1/ (design-tokens.json + style-guide.md)
|
||||||
Quality: WCAG AA compliant, OKLCH colors
|
Quality: WCAG AA compliant, OKLCH colors
|
||||||
|
|
||||||
Phase 2.3 - Animation Extraction: ✅ CSS animations and transitions
|
Phase 2.3 - Animation Extraction: ✅ Animation tokens
|
||||||
Output: animation-extraction/ (animation-tokens.json + animation-guide.md)
|
Output: animation-extraction/ (animation-tokens.json + animation-guide.md)
|
||||||
Method: Auto-extracted from live URLs via Chrome DevTools
|
|
||||||
|
|
||||||
Phase 2.5 - Layout Extraction: ✅ Structure templates
|
Phase 2.5 - Layout Extraction: ✅ Structure templates
|
||||||
Templates: {template_count} layout structures
|
Templates: {template_count} layout structures
|
||||||
|
|
||||||
Phase 3 - UI Assembly: ✅ {generated_count} pages assembled
|
Phase 3 - UI Assembly: ✅ {generated_count} prototypes assembled
|
||||||
Targets: {', '.join(target_names)}
|
|
||||||
Configuration: 1 style × 1 layout × {generated_count} pages
|
Configuration: 1 style × 1 layout × {generated_count} pages
|
||||||
|
|
||||||
Phase 4 - Integration: {IF session_id: "✅ Integrated into session" ELSE: "⏭️ Standalone mode"}
|
Phase 4 - Integration: {IF session_id: "✅ Integrated into session" ELSE: "⏭️ Standalone mode"}
|
||||||
@@ -527,20 +430,6 @@ Phase 4 - Integration: {IF session_id: "✅ Integrated into session" ELSE: "⏭
|
|||||||
━━━ 📂 Output Structure ━━━
|
━━━ 📂 Output Structure ━━━
|
||||||
|
|
||||||
{base_path}/
|
{base_path}/
|
||||||
├── screenshots/ # {captured_count} screenshots
|
|
||||||
{IF capture_mode == "batch":
|
|
||||||
│ ├── {target1}.png
|
|
||||||
│ ├── {target2}.png
|
|
||||||
│ └── capture-metadata.json
|
|
||||||
ELSE:
|
|
||||||
│ ├── depth-1/
|
|
||||||
│ │ └── full-page.png
|
|
||||||
│ ├── depth-2/
|
|
||||||
│ │ └── {elements}.png
|
|
||||||
│ ├── depth-{depth}/
|
|
||||||
│ │ └── {layers}.png
|
|
||||||
│ └── layer-map.json
|
|
||||||
}
|
|
||||||
├── style-extraction/ # Production-ready design systems
|
├── style-extraction/ # Production-ready design systems
|
||||||
│ └── style-1/
|
│ └── style-1/
|
||||||
│ ├── design-tokens.json
|
│ ├── design-tokens.json
|
||||||
@@ -549,19 +438,18 @@ ELSE:
|
|||||||
│ ├── animation-tokens.json
|
│ ├── animation-tokens.json
|
||||||
│ └── animation-guide.md
|
│ └── animation-guide.md
|
||||||
├── layout-extraction/ # Structure templates
|
├── layout-extraction/ # Structure templates
|
||||||
│ └── layout-{target}-1.json # One file per target
|
│ └── layout-home-1.json # Layout templates
|
||||||
└── prototypes/ # {generated_count} HTML/CSS files
|
└── prototypes/ # {generated_count} HTML/CSS files
|
||||||
├── {target1}-style-1-layout-1.html + .css
|
├── home-style-1-layout-1.html + .css
|
||||||
├── {target2}-style-1-layout-1.html + .css
|
|
||||||
├── compare.html # Interactive preview
|
├── compare.html # Interactive preview
|
||||||
└── index.html # Quick navigation
|
└── index.html # Quick navigation
|
||||||
|
|
||||||
━━━ ⚡ Performance ━━━
|
━━━ ⚡ Performance ━━━
|
||||||
|
|
||||||
Total workflow time: ~{estimate_total_time()} minutes
|
Total workflow time: ~{estimate_total_time()} minutes
|
||||||
Screenshot capture: ~{capture_time}
|
|
||||||
Style extraction: ~{extract_time}
|
Style extraction: ~{extract_time}
|
||||||
Token processing: ~{token_processing_time}
|
Animation extraction: ~{animation_time}
|
||||||
|
Layout extraction: ~{layout_time}
|
||||||
UI generation: ~{generate_time}
|
UI generation: ~{generate_time}
|
||||||
|
|
||||||
━━━ 🌐 Next Steps ━━━
|
━━━ 🌐 Next Steps ━━━
|
||||||
@@ -592,15 +480,15 @@ ELSE:
|
|||||||
```javascript
|
```javascript
|
||||||
// Initialize IMMEDIATELY at start of Phase 0 to track multi-phase execution
|
// Initialize IMMEDIATELY at start of Phase 0 to track multi-phase execution
|
||||||
TodoWrite({todos: [
|
TodoWrite({todos: [
|
||||||
{content: "Initialize and parse url-map", status: "in_progress", activeForm: "Initializing"},
|
{content: "Initialize and detect design source", status: "in_progress", activeForm: "Initializing"},
|
||||||
{content: "Batch screenshot capture", status: "pending", activeForm: "Capturing screenshots"},
|
|
||||||
{content: "Extract style (complete design systems)", status: "pending", activeForm: "Extracting style"},
|
{content: "Extract style (complete design systems)", status: "pending", activeForm: "Extracting style"},
|
||||||
|
{content: "Extract animation (CSS auto mode)", status: "pending", activeForm: "Extracting animation"},
|
||||||
{content: "Extract layout (structure templates)", status: "pending", activeForm: "Extracting layout"},
|
{content: "Extract layout (structure templates)", status: "pending", activeForm: "Extracting layout"},
|
||||||
{content: "Assemble UI for all targets", status: "pending", activeForm: "Assembling UI"},
|
{content: "Assemble UI prototypes", status: "pending", activeForm: "Assembling UI"},
|
||||||
{content: "Integrate design system", status: "pending", activeForm: "Integrating"}
|
{content: "Integrate design system", status: "pending", activeForm: "Integrating"}
|
||||||
]})
|
]})
|
||||||
|
|
||||||
// ⚠️ CRITICAL: When each SlashCommand execution finishes (Phase 1-5), you MUST:
|
// ⚠️ CRITICAL: When each SlashCommand execution finishes (Phase 2-4), you MUST:
|
||||||
// 1. SlashCommand blocks and returns when phase finishes executing
|
// 1. SlashCommand blocks and returns when phase finishes executing
|
||||||
// 2. Update current phase: status → "completed"
|
// 2. Update current phase: status → "completed"
|
||||||
// 3. Update next phase: status → "in_progress"
|
// 3. Update next phase: status → "in_progress"
|
||||||
@@ -611,46 +499,48 @@ TodoWrite({todos: [
|
|||||||
## Error Handling
|
## Error Handling
|
||||||
|
|
||||||
### Pre-execution Checks
|
### Pre-execution Checks
|
||||||
- **url-map format validation**: Clear error message with format example
|
- **Input validation**: Must provide at least one of --images or --prompt
|
||||||
- **Empty url-map**: Error and exit
|
- **Design source detection**: Error if no valid inputs found
|
||||||
- **Invalid target names**: Regex validation with suggestions
|
- **Code import failure**: Fallback to visual-only mode in hybrid, error in code-only mode
|
||||||
|
|
||||||
### Phase-Specific Errors
|
### Phase-Specific Errors
|
||||||
- **Screenshot capture failure (Phase 1)**:
|
- **Code import failure (Phase 0.5)**:
|
||||||
- If total_captured == 0: Terminate workflow
|
- code_only mode: Terminate with clear error
|
||||||
- If partial failure: Warn but continue with available screenshots
|
- hybrid mode: Warn and fallback to visual-only mode
|
||||||
|
|
||||||
- **Style extraction failure (Phase 2)**:
|
- **Style extraction failure (Phase 2)**:
|
||||||
- If extract fails: Terminate with clear error
|
- If extract fails: Terminate with clear error
|
||||||
- If style-cards.json missing: Terminate with debugging info
|
- If design-tokens.json missing: Terminate with debugging info
|
||||||
|
|
||||||
- **Token processing failure (Phase 3)**:
|
- **Animation extraction failure (Phase 2.3)**:
|
||||||
- Consolidate mode: Terminate if consolidate fails
|
- Non-critical: Warn but continue
|
||||||
- Fast mode: Validate proposed_tokens exist before copying
|
- Can proceed without animation tokens
|
||||||
|
|
||||||
- **UI generation failure (Phase 4)**:
|
- **Layout extraction failure (Phase 2.5)**:
|
||||||
|
- If extract fails: Terminate with error
|
||||||
|
- Need layout templates for assembly
|
||||||
|
|
||||||
|
- **UI generation failure (Phase 3)**:
|
||||||
- If generate fails: Terminate with error
|
- If generate fails: Terminate with error
|
||||||
- If generated_count < target_count: Warn but proceed
|
- If generated_count < expected: Warn but proceed
|
||||||
|
|
||||||
- **Integration failure (Phase 5)**:
|
- **Integration failure (Phase 4)**:
|
||||||
- Non-blocking: Warn but don't terminate
|
- Non-blocking: Warn but don't terminate
|
||||||
- Prototypes already available
|
- Prototypes already available
|
||||||
|
|
||||||
### Recovery Strategies
|
### Recovery Strategies
|
||||||
- **Partial screenshot failure**: Continue with available screenshots, list missing in warning
|
- **Code import failure**: Automatic fallback to visual-only in hybrid mode
|
||||||
- **Generate failure**: Report specific target failures, user can re-generate individually
|
- **Generate failure**: Report specific failures, user can re-generate individually
|
||||||
- **Integration failure**: Prototypes still usable, can integrate manually
|
- **Integration failure**: Prototypes still usable, can integrate manually
|
||||||
|
|
||||||
## Integration Points
|
## Integration Points
|
||||||
|
|
||||||
- **Input**: `--url-map` (multiple target:url pairs) + optional `--capture-mode`, `--depth`, `--session`, `--prompt`
|
- **Input**: `--images` (glob pattern) and/or `--prompt` (text/file paths) + optional `--session`
|
||||||
- **Output**: Complete design system in `{base_path}/` (screenshots, style-extraction, layout-extraction, prototypes)
|
- **Output**: Complete design system in `{base_path}/` (style-extraction, layout-extraction, prototypes)
|
||||||
- **Sub-commands Called**:
|
- **Sub-commands Called**:
|
||||||
1. Phase 1 (conditional):
|
1. `/workflow:ui-design:import-from-code` (Phase 0.5, conditional - if code files detected)
|
||||||
- `--capture-mode batch`: `/workflow:ui-design:capture` (multi-URL batch)
|
|
||||||
- `--capture-mode deep`: `/workflow:ui-design:explore-layers` (single-URL depth exploration)
|
|
||||||
2. `/workflow:ui-design:style-extract` (Phase 2 - complete design systems)
|
2. `/workflow:ui-design:style-extract` (Phase 2 - complete design systems)
|
||||||
3. `/workflow:ui-design:animation-extract` (Phase 2.3 - CSS animations and transitions)
|
3. `/workflow:ui-design:animation-extract` (Phase 2.3 - animation tokens)
|
||||||
4. `/workflow:ui-design:layout-extract` (Phase 2.5 - structure templates)
|
4. `/workflow:ui-design:layout-extract` (Phase 2.5 - structure templates)
|
||||||
5. `/workflow:ui-design:generate` (Phase 3 - pure assembly)
|
5. `/workflow:ui-design:generate` (Phase 3 - pure assembly)
|
||||||
6. `/workflow:ui-design:update` (Phase 4, if --session)
|
6. `/workflow:ui-design:update` (Phase 4, if --session)
|
||||||
@@ -660,30 +550,31 @@ TodoWrite({todos: [
|
|||||||
```
|
```
|
||||||
✅ UI Design Imitate-Auto Workflow Complete!
|
✅ UI Design Imitate-Auto Workflow Complete!
|
||||||
|
|
||||||
Mode: {capture_mode} | Session: {session_id or "standalone"}
|
Mode: Direct Input ({design_source}) | Session: {session_id or "standalone"}
|
||||||
Run ID: {run_id}
|
Run ID: {run_id}
|
||||||
|
|
||||||
Phase 1 - Screenshot Capture: ✅ {captured_count} screenshots
|
Phase 0 - Input Detection: ✅ {design_source} mode
|
||||||
Phase 2 - Style Extraction: ✅ Production-ready design systems
|
Phase 2 - Style Extraction: ✅ Production-ready design systems
|
||||||
|
Phase 2.3 - Animation Extraction: ✅ Animation tokens
|
||||||
Phase 2.5 - Layout Extraction: ✅ Structure templates
|
Phase 2.5 - Layout Extraction: ✅ Structure templates
|
||||||
Phase 3 - UI Assembly: ✅ {generated_count} pages assembled
|
Phase 3 - UI Assembly: ✅ {generated_count} prototypes assembled
|
||||||
Phase 4 - Integration: {IF session_id: "✅ Integrated" ELSE: "⏭️ Standalone"}
|
Phase 4 - Integration: {IF session_id: "✅ Integrated" ELSE: "⏭️ Standalone"}
|
||||||
|
|
||||||
Design Quality:
|
Design Quality:
|
||||||
✅ High-Fidelity Replication: Accurate style from primary target
|
|
||||||
✅ Token-Driven Styling: 100% var() usage
|
✅ Token-Driven Styling: 100% var() usage
|
||||||
✅ Production-Ready: WCAG AA compliant, OKLCH colors
|
✅ Production-Ready: WCAG AA compliant, OKLCH colors
|
||||||
|
✅ Multi-Source: Code import + visual extraction
|
||||||
|
|
||||||
📂 {base_path}/
|
📂 {base_path}/
|
||||||
├── screenshots/ # {captured_count} screenshots
|
|
||||||
├── style-extraction/style-1/ # Production-ready design system
|
├── style-extraction/style-1/ # Production-ready design system
|
||||||
|
├── animation-extraction/ # Animation tokens
|
||||||
├── layout-extraction/ # Structure templates
|
├── layout-extraction/ # Structure templates
|
||||||
└── prototypes/ # {generated_count} HTML/CSS files
|
└── prototypes/ # {generated_count} HTML/CSS files
|
||||||
|
|
||||||
🌐 Preview: {base_path}/prototypes/compare.html
|
🌐 Preview: {base_path}/prototypes/compare.html
|
||||||
- Interactive preview
|
- Interactive preview
|
||||||
- Side-by-side comparison
|
- Design token driven
|
||||||
- {generated_count} replicated pages
|
- {generated_count} assembled prototypes
|
||||||
|
|
||||||
Next: [/workflow:execute] OR [Open compare.html → /workflow:plan]
|
Next: [/workflow:execute] OR [Open compare.html → /workflow:plan]
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: layout-extract
|
name: layout-extract
|
||||||
description: Extract structural layout information from reference images, URLs, or text prompts using Claude analysis
|
description: Extract structural layout information from reference images, URLs, or text prompts using Claude analysis with variant generation or refinement mode
|
||||||
argument-hint: [--design-id <id>] [--session <id>] [--images "<glob>"] [--urls "<list>"] [--prompt "<desc>"] [--targets "<list>"] [--variants <count>] [--device-type <desktop|mobile|tablet|responsive>] [--interactive]
|
argument-hint: [--design-id <id>] [--session <id>] [--images "<glob>"] [--urls "<list>"] [--prompt "<desc>"] [--targets "<list>"] [--variants <count>] [--device-type <desktop|mobile|tablet|responsive>] [--interactive] [--refine]
|
||||||
allowed-tools: TodoWrite(*), Read(*), Write(*), Glob(*), Bash(*), AskUserQuestion(*), Task(ui-design-agent), mcp__exa__web_search_exa(*)
|
allowed-tools: TodoWrite(*), Read(*), Write(*), Glob(*), Bash(*), AskUserQuestion(*), Task(ui-design-agent), mcp__exa__web_search_exa(*)
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -9,12 +9,16 @@ allowed-tools: TodoWrite(*), Read(*), Write(*), Glob(*), Bash(*), AskUserQuestio
|
|||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
Extract structural layout information from reference images, URLs, or text prompts using AI analysis. This command separates the "scaffolding" (HTML structure and CSS layout) from the "paint" (visual tokens handled by `style-extract`).
|
Extract structural layout information from reference images, URLs, or text prompts using AI analysis. Supports two modes:
|
||||||
|
1. **Exploration Mode** (default): Generate multiple contrasting layout variants
|
||||||
|
2. **Refinement Mode** (`--refine`): Refine a single existing layout through detailed adjustments
|
||||||
|
|
||||||
|
This command separates the "scaffolding" (HTML structure and CSS layout) from the "paint" (visual tokens handled by `style-extract`).
|
||||||
|
|
||||||
**Strategy**: AI-Driven Structural Analysis
|
**Strategy**: AI-Driven Structural Analysis
|
||||||
|
|
||||||
- **Agent-Powered**: Uses `ui-design-agent` for deep structural analysis
|
- **Agent-Powered**: Uses `ui-design-agent` for deep structural analysis
|
||||||
- **Behavior**: Generate N layout concepts → User multi-select → Generate selected templates
|
- **Dual Mode**: Exploration (multiple contrasting variants) or Refinement (single layout fine-tuning)
|
||||||
- **Output**: `layout-templates.json` with DOM structure, component hierarchy, and CSS layout rules
|
- **Output**: `layout-templates.json` with DOM structure, component hierarchy, and CSS layout rules
|
||||||
- **Device-Aware**: Optimized for specific device types (desktop, mobile, tablet, responsive)
|
- **Device-Aware**: Optimized for specific device types (desktop, mobile, tablet, responsive)
|
||||||
- **Token-Based**: CSS uses `var()` placeholders for spacing and breakpoints
|
- **Token-Based**: CSS uses `var()` placeholders for spacing and breakpoints
|
||||||
@@ -43,10 +47,19 @@ ELSE:
|
|||||||
has_urls = false
|
has_urls = false
|
||||||
url_list = []
|
url_list = []
|
||||||
|
|
||||||
# Set variants count (default: 3, range: 1-5)
|
# Detect refinement mode
|
||||||
# Behavior: Generate N layout concepts per target → User multi-select → Generate selected templates
|
refine_mode = --refine OR false
|
||||||
variants_count = --variants OR 3
|
|
||||||
VALIDATE: 1 <= variants_count <= 5
|
# 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 layout per target"
|
||||||
|
ELSE:
|
||||||
|
variants_count = --variants OR 3
|
||||||
|
VALIDATE: 1 <= variants_count <= 5
|
||||||
|
REPORT: "🔍 Exploration mode: Will generate {variants_count} contrasting layout concepts per target"
|
||||||
|
|
||||||
# Resolve targets
|
# Resolve targets
|
||||||
# Priority: --targets → url_list targets → prompt analysis → default ["page"]
|
# Priority: --targets → url_list targets → prompt analysis → default ["page"]
|
||||||
@@ -210,30 +223,46 @@ IF exists: SKIP to completion
|
|||||||
|
|
||||||
**Phase 0 Output**: `input_mode`, `base_path`, `variants_count`, `targets[]`, `device_type`, loaded inputs
|
**Phase 0 Output**: `input_mode`, `base_path`, `variants_count`, `targets[]`, `device_type`, loaded inputs
|
||||||
|
|
||||||
## Phase 1: Layout Concept Generation
|
## Phase 1: Layout Concept or Refinement Options Generation
|
||||||
|
|
||||||
### Step 1: Generate Layout Concept Options (Agent Task 1)
|
### Step 0.5: Load Existing Layout (Refinement Mode)
|
||||||
|
```bash
|
||||||
|
IF refine_mode:
|
||||||
|
# Load existing layout for refinement
|
||||||
|
existing_layouts = {}
|
||||||
|
FOR target IN targets:
|
||||||
|
layout_files = bash(find {base_path}/layout-extraction -name "layout-{target}-*.json" -print)
|
||||||
|
IF layout_files:
|
||||||
|
# Use first/latest layout file for this target
|
||||||
|
existing_layouts[target] = Read(first_layout_file)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 1: Generate Options (Agent Task 1 - Mode-Specific)
|
||||||
**Executor**: `Task(ui-design-agent)`
|
**Executor**: `Task(ui-design-agent)`
|
||||||
|
|
||||||
Launch agent to generate `variants_count` layout concept options for each target:
|
**Exploration Mode** (default): Generate contrasting layout concepts
|
||||||
|
**Refinement Mode** (`--refine`): Generate refinement options for existing layouts
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
Task(ui-design-agent): `
|
// Conditional agent task based on refine_mode
|
||||||
[LAYOUT_CONCEPT_GENERATION_TASK]
|
IF NOT refine_mode:
|
||||||
Generate {variants_count} structurally distinct layout concepts for each target
|
// EXPLORATION MODE
|
||||||
|
Task(ui-design-agent): `
|
||||||
|
[LAYOUT_CONCEPT_GENERATION_TASK]
|
||||||
|
Generate {variants_count} structurally distinct layout concepts for each target
|
||||||
|
|
||||||
SESSION: {session_id} | MODE: explore | BASE_PATH: {base_path}
|
SESSION: {session_id} | MODE: explore | BASE_PATH: {base_path}
|
||||||
TARGETS: {targets} | DEVICE_TYPE: {device_type}
|
TARGETS: {targets} | DEVICE_TYPE: {device_type}
|
||||||
|
|
||||||
## Input Analysis
|
## Input Analysis
|
||||||
- Targets: {targets.join(", ")}
|
- Targets: {targets.join(", ")}
|
||||||
- Device type: {device_type}
|
- Device type: {device_type}
|
||||||
- Visual references: {loaded_images if available}
|
- Visual references: {loaded_images if available}
|
||||||
${dom_structure_available ? "- DOM Structure: Read from .intermediates/layout-analysis/dom-structure-*.json" : ""}
|
${dom_structure_available ? "- DOM Structure: Read from .intermediates/layout-analysis/dom-structure-*.json" : ""}
|
||||||
|
|
||||||
## Analysis Rules
|
## Analysis Rules
|
||||||
- For EACH target, generate {variants_count} structurally DIFFERENT layout concepts
|
- For EACH target, generate {variants_count} structurally DIFFERENT layout concepts
|
||||||
- Concepts must differ in: grid structure, component arrangement, visual hierarchy
|
- Concepts must differ in: grid structure, component arrangement, visual hierarchy
|
||||||
- Each concept should have distinct navigation pattern, content flow, and responsive behavior
|
- Each concept should have distinct navigation pattern, content flow, and responsive behavior
|
||||||
|
|
||||||
## Generate for EACH Target
|
## Generate for EACH Target
|
||||||
@@ -261,7 +290,71 @@ Task(ui-design-agent): `
|
|||||||
Use schema from INTERACTIVE-DATA-SPEC.md (Layout Extract: analysis-options.json)
|
Use schema from INTERACTIVE-DATA-SPEC.md (Layout Extract: analysis-options.json)
|
||||||
|
|
||||||
CRITICAL: Use Write() tool immediately after generating complete JSON
|
CRITICAL: Use Write() tool immediately after generating complete JSON
|
||||||
`
|
`
|
||||||
|
ELSE:
|
||||||
|
// REFINEMENT MODE
|
||||||
|
Task(ui-design-agent): `
|
||||||
|
[LAYOUT_REFINEMENT_OPTIONS_TASK]
|
||||||
|
Generate refinement options for existing layout(s)
|
||||||
|
|
||||||
|
SESSION: {session_id} | MODE: refine | BASE_PATH: {base_path}
|
||||||
|
TARGETS: {targets} | DEVICE_TYPE: {device_type}
|
||||||
|
|
||||||
|
## Existing Layouts
|
||||||
|
${FOR target IN targets: "- {target}: {existing_layouts[target]}"}
|
||||||
|
|
||||||
|
## Input Guidance
|
||||||
|
- User prompt: {prompt_guidance if available}
|
||||||
|
- Visual references: {loaded_images if available}
|
||||||
|
|
||||||
|
## Refinement Categories
|
||||||
|
Generate 8-12 refinement options per target across these categories:
|
||||||
|
|
||||||
|
1. **Density Adjustments** (2-3 options per target):
|
||||||
|
- More compact: Tighter spacing, reduced whitespace
|
||||||
|
- More spacious: Increased margins, breathing room
|
||||||
|
- Balanced: Moderate adjustments
|
||||||
|
|
||||||
|
2. **Responsiveness Tuning** (2-3 options per target):
|
||||||
|
- Breakpoint behavior: Earlier/later column stacking
|
||||||
|
- Mobile layout: Different navigation/content priority
|
||||||
|
- Tablet optimization: Hybrid desktop/mobile approach
|
||||||
|
|
||||||
|
3. **Grid/Flex Specifics** (2-3 options per target):
|
||||||
|
- Column counts: 2-col ↔ 3-col ↔ 4-col
|
||||||
|
- Gap sizes: Tighter ↔ wider gutters
|
||||||
|
- Alignment: Different flex/grid justification
|
||||||
|
|
||||||
|
4. **Component Arrangement** (1-2 options per target):
|
||||||
|
- Navigation placement: Top ↔ side ↔ bottom
|
||||||
|
- Sidebar position: Left ↔ right ↔ none
|
||||||
|
- Content hierarchy: Different section ordering
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
Each option (per target):
|
||||||
|
- target: Which target this refinement applies to
|
||||||
|
- category: "density|responsiveness|grid|arrangement"
|
||||||
|
- option_id: unique identifier
|
||||||
|
- label: Short descriptive name (e.g., "More Compact Spacing")
|
||||||
|
- description: What changes (2-3 sentences)
|
||||||
|
- preview_changes: Key structural adjustments
|
||||||
|
- impact_scope: Which layout regions affected
|
||||||
|
|
||||||
|
## Output
|
||||||
|
Write single JSON file: {base_path}/.intermediates/layout-analysis/analysis-options.json
|
||||||
|
|
||||||
|
Use refinement schema:
|
||||||
|
{
|
||||||
|
"mode": "refinement",
|
||||||
|
"device_type": "{device_type}",
|
||||||
|
"refinement_options": {
|
||||||
|
"{target1}": [array of refinement options],
|
||||||
|
"{target2}": [array of refinement options]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CRITICAL: Use Write() tool immediately after generating complete JSON
|
||||||
|
`
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: Verify Options File Created
|
### Step 2: Verify Options File Created
|
||||||
@@ -278,7 +371,9 @@ bash(cat {base_path}/.intermediates/layout-analysis/analysis-options.json | grep
|
|||||||
|
|
||||||
## Phase 1.5: User Confirmation (Optional - Triggered by --interactive)
|
## Phase 1.5: User Confirmation (Optional - Triggered by --interactive)
|
||||||
|
|
||||||
**Purpose**: Allow user to select preferred layout concept(s) for each target before generating detailed templates
|
**Purpose**:
|
||||||
|
- **Exploration Mode**: Allow user to select preferred layout concept(s) per target
|
||||||
|
- **Refinement Mode**: Allow user to select refinement options to apply per target
|
||||||
|
|
||||||
**Trigger Condition**: Execute this phase ONLY if `--interactive` flag is present
|
**Trigger Condition**: Execute this phase ONLY if `--interactive` flag is present
|
||||||
|
|
||||||
@@ -287,18 +382,27 @@ bash(cat {base_path}/.intermediates/layout-analysis/analysis-options.json | grep
|
|||||||
# Skip this entire phase if --interactive flag is not present
|
# Skip this entire phase if --interactive flag is not present
|
||||||
IF NOT --interactive:
|
IF NOT --interactive:
|
||||||
SKIP to Phase 2
|
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 per target"
|
||||||
|
|
||||||
# Interactive mode enabled
|
# Interactive mode enabled
|
||||||
REPORT: "🎯 Interactive mode: User selection required for {targets.length} target(s)"
|
REPORT: "🎯 Interactive mode: User selection required for {targets.length} target(s)"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: Load and Present Options
|
### Step 2: Load and Present Options (Mode-Specific)
|
||||||
```bash
|
```bash
|
||||||
# Read options file
|
# Read options file
|
||||||
options = Read({base_path}/.intermediates/layout-analysis/analysis-options.json)
|
options = Read({base_path}/.intermediates/layout-analysis/analysis-options.json)
|
||||||
|
|
||||||
# Parse layout concepts
|
# Branch based on mode
|
||||||
layout_concepts = options.layout_concepts
|
IF NOT refine_mode:
|
||||||
|
# EXPLORATION MODE
|
||||||
|
layout_concepts = options.layout_concepts
|
||||||
|
ELSE:
|
||||||
|
# REFINEMENT MODE
|
||||||
|
refinement_options = options.refinement_options
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: Present Options to User (Per Target)
|
### Step 2: Present Options to User (Per Target)
|
||||||
|
|||||||
@@ -1,20 +1,22 @@
|
|||||||
---
|
---
|
||||||
name: style-extract
|
name: style-extract
|
||||||
description: Extract design style from reference images or text prompts using Claude analysis with variant generation
|
description: Extract design style from reference images or text prompts using Claude analysis with variant generation or refinement mode
|
||||||
argument-hint: "[--design-id <id>] [--session <id>] [--images "<glob>"] [--urls "<list>"] [--prompt "<desc>"] [--variants <count>] [--interactive]"
|
argument-hint: "[--design-id <id>] [--session <id>] [--images "<glob>"] [--urls "<list>"] [--prompt "<desc>"] [--variants <count>] [--interactive] [--refine]"
|
||||||
allowed-tools: TodoWrite(*), Read(*), Write(*), Glob(*), AskUserQuestion(*), mcp__chrome-devtools__navigate_page(*), mcp__chrome-devtools__evaluate_script(*)
|
allowed-tools: TodoWrite(*), Read(*), Write(*), Glob(*), AskUserQuestion(*), mcp__chrome-devtools__navigate_page(*), mcp__chrome-devtools__evaluate_script(*)
|
||||||
---
|
---
|
||||||
|
|
||||||
# Style Extraction Command
|
# Style Extraction Command
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
Extract design style from reference images or text prompts using Claude's built-in analysis. Directly generates production-ready design systems with complete `design-tokens.json` and `style-guide.md` for each variant.
|
Extract design style from reference images or text prompts using Claude's built-in analysis. Supports two modes:
|
||||||
|
1. **Exploration Mode** (default): Generate multiple contrasting design variants
|
||||||
|
2. **Refinement Mode** (`--refine`): Refine a single existing design through detailed adjustments
|
||||||
|
|
||||||
**Strategy**: AI-Driven Design Space Exploration
|
**Strategy**: AI-Driven Design Space Exploration
|
||||||
- **Claude-Native**: 100% Claude analysis, no external tools
|
- **Claude-Native**: 100% Claude analysis, no external tools
|
||||||
- **Direct Output**: Complete design systems (design-tokens.json + style-guide.md)
|
- **Direct Output**: Complete design systems (design-tokens.json + style-guide.md)
|
||||||
- **Flexible Input**: Images, text prompts, or both (hybrid mode)
|
- **Flexible Input**: Images, text prompts, or both (hybrid mode)
|
||||||
- **Maximum Contrast**: AI generates maximally divergent design directions
|
- **Dual Mode**: Exploration (multiple contrasting variants) or Refinement (single design fine-tuning)
|
||||||
- **Production-Ready**: WCAG AA compliant, OKLCH colors, semantic naming
|
- **Production-Ready**: WCAG AA compliant, OKLCH colors, semantic naming
|
||||||
|
|
||||||
## Phase 0: Setup & Input Validation
|
## Phase 0: Setup & Input Validation
|
||||||
@@ -40,10 +42,19 @@ IF --urls:
|
|||||||
ELSE:
|
ELSE:
|
||||||
has_urls = false
|
has_urls = false
|
||||||
|
|
||||||
# Set variants count (default: 3, range: 1-5)
|
# Detect refinement mode
|
||||||
# Behavior: Generate N design directions → User multi-select → Generate selected variants
|
refine_mode = --refine OR false
|
||||||
variants_count = --variants OR 3
|
|
||||||
VALIDATE: 1 <= variants_count <= 5
|
# 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
|
# Determine base path with priority: --design-id > --session > auto-detect
|
||||||
if [ -n "$DESIGN_ID" ]; then
|
if [ -n "$DESIGN_ID" ]; then
|
||||||
@@ -152,60 +163,130 @@ 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 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 Generation
|
## Phase 1: Design Direction or Refinement Options Generation
|
||||||
|
|
||||||
### Step 1: Load Project Context
|
### Step 1: Load Project Context
|
||||||
```bash
|
```bash
|
||||||
# Load brainstorming context if available
|
# Load brainstorming context if available
|
||||||
bash(test -f {base_path}/.brainstorming/role analysis documents && cat it)
|
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 Design Direction Options (Agent Task 1)
|
### Step 2: Generate Options (Agent Task 1 - Mode-Specific)
|
||||||
**Executor**: `Task(ui-design-agent)`
|
**Executor**: `Task(ui-design-agent)`
|
||||||
|
|
||||||
Launch agent to generate `variants_count` design direction options with previews:
|
**Exploration Mode** (default): Generate contrasting design directions
|
||||||
|
**Refinement Mode** (`--refine`): Generate refinement options for existing design
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
Task(ui-design-agent): `
|
// Conditional agent task based on refine_mode
|
||||||
[DESIGN_DIRECTION_GENERATION_TASK]
|
IF NOT refine_mode:
|
||||||
Generate {variants_count} maximally contrasting design directions with visual previews
|
// 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}
|
SESSION: {session_id} | MODE: explore | BASE_PATH: {base_path}
|
||||||
|
|
||||||
## Input Analysis
|
## Input Analysis
|
||||||
- User prompt: {prompt_guidance}
|
- User prompt: {prompt_guidance}
|
||||||
- Visual references: {loaded_images if available}
|
- Visual references: {loaded_images if available}
|
||||||
- Project context: {brainstorming_context if available}
|
- Project context: {brainstorming_context if available}
|
||||||
|
|
||||||
## Analysis Rules
|
## Analysis Rules
|
||||||
- Analyze 6D attribute space: color saturation, visual weight, formality, organic/geometric, innovation, density
|
- Analyze 6D attribute space: color saturation, visual weight, formality, organic/geometric, innovation, density
|
||||||
- Generate {variants_count} directions with MAXIMUM contrast
|
- Generate {variants_count} directions with MAXIMUM contrast
|
||||||
- Each direction must be distinctly different (min distance score: 0.7)
|
- Each direction must be distinctly different (min distance score: 0.7)
|
||||||
|
|
||||||
## Generate for EACH Direction
|
## Generate for EACH Direction
|
||||||
1. **Core Philosophy**:
|
1. **Core Philosophy**:
|
||||||
- philosophy_name (2-3 words, e.g., "Minimalist & Airy")
|
- philosophy_name (2-3 words, e.g., "Minimalist & Airy")
|
||||||
- design_attributes (6D scores 0-1)
|
- design_attributes (6D scores 0-1)
|
||||||
- search_keywords (3-5 keywords)
|
- search_keywords (3-5 keywords)
|
||||||
- anti_keywords (2-3 keywords to avoid)
|
- anti_keywords (2-3 keywords to avoid)
|
||||||
- rationale (why this is distinct from others)
|
- rationale (why this is distinct from others)
|
||||||
|
|
||||||
2. **Visual Preview Elements**:
|
2. **Visual Preview Elements**:
|
||||||
- primary_color (OKLCH format)
|
- primary_color (OKLCH format)
|
||||||
- secondary_color (OKLCH format)
|
- secondary_color (OKLCH format)
|
||||||
- accent_color (OKLCH format)
|
- accent_color (OKLCH format)
|
||||||
- font_family_heading (specific font name)
|
- font_family_heading (specific font name)
|
||||||
- font_family_body (specific font name)
|
- font_family_body (specific font name)
|
||||||
- border_radius_base (e.g., "0.5rem")
|
- border_radius_base (e.g., "0.5rem")
|
||||||
- mood_description (1-2 sentences describing the feel)
|
- mood_description (1-2 sentences describing the feel)
|
||||||
|
|
||||||
## Output
|
## Output
|
||||||
Write single JSON file: {base_path}/.intermediates/style-analysis/analysis-options.json
|
Write single JSON file: {base_path}/.intermediates/style-analysis/analysis-options.json
|
||||||
|
|
||||||
Use schema from INTERACTIVE-DATA-SPEC.md (Style Extract: analysis-options.json)
|
Use schema from INTERACTIVE-DATA-SPEC.md (Style Extract: analysis-options.json)
|
||||||
|
|
||||||
CRITICAL: Use Write() tool immediately after generating complete 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
|
### Step 3: Verify Options File Created
|
||||||
@@ -222,7 +303,9 @@ bash(cat {base_path}/.intermediates/style-analysis/analysis-options.json | grep
|
|||||||
|
|
||||||
## Phase 1.5: User Confirmation (Optional - Triggered by --interactive)
|
## Phase 1.5: User Confirmation (Optional - Triggered by --interactive)
|
||||||
|
|
||||||
**Purpose**: Allow user to select preferred design direction(s) before generating full design systems
|
**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
|
**Trigger Condition**: Execute this phase ONLY if `--interactive` flag is present
|
||||||
|
|
||||||
@@ -231,21 +314,31 @@ bash(cat {base_path}/.intermediates/style-analysis/analysis-options.json | grep
|
|||||||
# Skip this entire phase if --interactive flag is not present
|
# Skip this entire phase if --interactive flag is not present
|
||||||
IF NOT --interactive:
|
IF NOT --interactive:
|
||||||
SKIP to Phase 2
|
SKIP to Phase 2
|
||||||
REPORT: "ℹ️ Non-interactive mode: Will generate all {variants_count} variants"
|
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"
|
REPORT: "🎯 Interactive mode enabled: User selection required"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: Load and Present Options
|
### Step 2: Load and Present Options (Mode-Specific)
|
||||||
```bash
|
```bash
|
||||||
# Read options file
|
# Read options file
|
||||||
options = Read({base_path}/.intermediates/style-analysis/analysis-options.json)
|
options = Read({base_path}/.intermediates/style-analysis/analysis-options.json)
|
||||||
|
|
||||||
# Parse design directions
|
# Branch based on mode
|
||||||
design_directions = options.design_directions
|
IF NOT refine_mode:
|
||||||
|
# EXPLORATION MODE
|
||||||
|
design_directions = options.design_directions
|
||||||
|
ELSE:
|
||||||
|
# REFINEMENT MODE
|
||||||
|
refinement_options = options.refinement_options
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: Present Options to User
|
### Step 3: Present Options to User (Mode-Specific)
|
||||||
|
|
||||||
|
**Exploration Mode**:
|
||||||
```
|
```
|
||||||
📋 Design Direction Options
|
📋 Design Direction Options
|
||||||
|
|
||||||
@@ -278,30 +371,39 @@ Please select the direction(s) you'd like to develop into complete design system
|
|||||||
═══════════════════════════════════════════════════
|
═══════════════════════════════════════════════════
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 3: Capture User Selection and Update Analysis JSON
|
**Refinement Mode**:
|
||||||
|
|
||||||
**Interaction Strategy**: If variants > 4, use batch text format:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
【选项[N]】[philosophy_name]
|
📋 Design Refinement Options
|
||||||
[rationale]
|
|
||||||
...
|
|
||||||
请选择 (格式: 1 2 3 多选,或 1 单选):
|
|
||||||
|
|
||||||
User input:
|
We've analyzed your existing design system and generated refinement options.
|
||||||
"[N1]" → Single selection
|
Please select the refinement(s) you'd like to apply.
|
||||||
"[N1] [N2] [N3] ..." → Multi-selection
|
|
||||||
|
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}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
═══════════════════════════════════════════════════
|
||||||
```
|
```
|
||||||
|
|
||||||
Otherwise, use `AskUserQuestion` below.
|
### Step 4: Capture User Selection and Update Analysis JSON
|
||||||
|
|
||||||
|
**Exploration Mode Interaction**:
|
||||||
```javascript
|
```javascript
|
||||||
// Use AskUserQuestion tool for multi-selection
|
// Use AskUserQuestion tool for multi-selection
|
||||||
AskUserQuestion({
|
AskUserQuestion({
|
||||||
questions: [{
|
questions: [{
|
||||||
question: "Which design direction(s) would you like to develop into complete design systems?",
|
question: "Which design direction(s) would you like to develop into complete design systems?",
|
||||||
header: "Style Choice",
|
header: "Style Choice",
|
||||||
multiSelect: true, // Multi-selection enabled (default behavior)
|
multiSelect: true, // Multi-selection enabled
|
||||||
options: [
|
options: [
|
||||||
{FOR each direction:
|
{FOR each direction:
|
||||||
label: "Option {direction.index}: {direction.philosophy_name}",
|
label: "Option {direction.index}: {direction.philosophy_name}",
|
||||||
@@ -311,7 +413,7 @@ AskUserQuestion({
|
|||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
|
|
||||||
// Parse user response (array of selections, e.g., ["Option 1: ...", "Option 3: ..."])
|
// Parse user response (array of selections)
|
||||||
selected_options = user_answer
|
selected_options = user_answer
|
||||||
|
|
||||||
// Check for user cancellation
|
// Check for user cancellation
|
||||||
@@ -319,33 +421,73 @@ IF selected_options == null OR selected_options.length == 0:
|
|||||||
REPORT: "⚠️ User canceled selection. Workflow terminated."
|
REPORT: "⚠️ User canceled selection. Workflow terminated."
|
||||||
EXIT workflow
|
EXIT workflow
|
||||||
|
|
||||||
// Extract option indices from array
|
// Extract option indices
|
||||||
selected_indices = []
|
selected_indices = []
|
||||||
FOR each selected_option_text IN selected_options:
|
FOR each selected_option_text IN selected_options:
|
||||||
match = selected_option_text.match(/Option (\d+):/)
|
match = selected_option_text.match(/Option (\d+):/)
|
||||||
IF match:
|
IF match:
|
||||||
selected_indices.push(parseInt(match[1]))
|
selected_indices.push(parseInt(match[1]))
|
||||||
ELSE:
|
|
||||||
ERROR: "Invalid selection format. Expected 'Option N: ...' format"
|
|
||||||
EXIT workflow
|
|
||||||
|
|
||||||
REPORT: "✅ Selected {selected_indices.length} design direction(s)"
|
REPORT: "✅ Selected {selected_indices.length} design direction(s)"
|
||||||
|
|
||||||
// Update analysis-options.json with user selection
|
// Update analysis-options.json
|
||||||
options_file = Read({base_path}/.intermediates/style-analysis/analysis-options.json)
|
options_file = Read({base_path}/.intermediates/style-analysis/analysis-options.json)
|
||||||
options_file.user_selection = {
|
options_file.user_selection = {
|
||||||
"selected_at": NOW(),
|
"selected_at": NOW(),
|
||||||
"selected_indices": selected_indices,
|
"selected_indices": selected_indices,
|
||||||
"selection_count": selected_indices.length
|
"selection_count": selected_indices.length
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write updated file back
|
|
||||||
Write({base_path}/.intermediates/style-analysis/analysis-options.json, JSON.stringify(options_file, indent=2))
|
Write({base_path}/.intermediates/style-analysis/analysis-options.json, JSON.stringify(options_file, indent=2))
|
||||||
|
|
||||||
REPORT: "✅ Updated analysis-options.json with user selection"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 4: Confirmation Message
|
**Refinement Mode Interaction**:
|
||||||
|
```javascript
|
||||||
|
// 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!
|
✅ Selection recorded!
|
||||||
|
|
||||||
@@ -357,7 +499,19 @@ You selected {selected_indices.length} design direction(s):
|
|||||||
Proceeding to generate {selected_indices.length} complete design system(s)...
|
Proceeding to generate {selected_indices.length} complete design system(s)...
|
||||||
```
|
```
|
||||||
|
|
||||||
**Output**: Updated `analysis-options.json` with user's multi-selection embedded
|
**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)
|
## Phase 2: Design System Generation (Agent Task 2)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user