mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-12 02:37:45 +08:00
Refactor layout and style extraction workflows for multi-selection capabilities
- Updated `layout-extract` command to support user multi-selection of layout concepts, allowing for multiple layout templates to be generated based on user preferences. - Revised argument hints and output structures to reflect changes in selection handling and output file formats. - Enhanced user interaction by enabling multi-select options in both layout and style extraction phases. - Streamlined the generation of layout templates and design systems to accommodate multiple selected variants, improving flexibility and user experience. - Adjusted validation and output verification processes to ensure consistency with new multi-selection features.
This commit is contained in:
@@ -70,31 +70,24 @@ IF exists({base_path}/.intermediates/style-analysis/design-space-analysis.json):
|
|||||||
|
|
||||||
**Output**: `design_tokens_valid`, `design_space_analysis`
|
**Output**: `design_tokens_valid`, `design_space_analysis`
|
||||||
|
|
||||||
### Step 3: Gather Layout Inspiration (Reuse or Create)
|
### Step 3: Gather Layout Inspiration (Direct MCP Search)
|
||||||
```bash
|
```bash
|
||||||
# Check if layout inspirations already exist from layout-extract phase
|
# Gather layout inspiration via MCP for each target
|
||||||
inspiration_source = "{base_path}/.intermediates/layout-analysis/inspirations"
|
layout_inspiration_map = {}
|
||||||
|
|
||||||
FOR target IN target_list:
|
FOR target IN target_list:
|
||||||
# Priority 1: Reuse existing inspiration from layout-extract
|
search_query = "{target} {target_type} layout patterns variations"
|
||||||
IF exists({inspiration_source}/{target}-layout-ideas.txt):
|
search_results = mcp__exa__web_search_exa(query=search_query, numResults=5)
|
||||||
# Reuse existing inspiration (no action needed)
|
|
||||||
REPORT: "Using existing layout inspiration for {target}"
|
|
||||||
ELSE:
|
|
||||||
# Priority 2: Generate new inspiration via MCP
|
|
||||||
bash(mkdir -p {inspiration_source})
|
|
||||||
search_query = "{target} {target_type} layout patterns variations"
|
|
||||||
mcp__exa__web_search_exa(query=search_query, numResults=5)
|
|
||||||
|
|
||||||
# Extract context from prompt for this target
|
# Extract context from prompt for this target
|
||||||
target_requirements = extract_relevant_context_from_prompt(prompt_text, target)
|
target_requirements = extract_relevant_context_from_prompt(prompt_text, target)
|
||||||
|
|
||||||
# Write inspiration file to centralized location
|
# Store inspiration in memory (no file write needed)
|
||||||
Write({inspiration_source}/{target}-layout-ideas.txt, inspiration_content)
|
layout_inspiration_map[target] = format_inspiration_from_search(search_results, target_requirements)
|
||||||
REPORT: "Created new layout inspiration for {target}"
|
REPORT: "Gathered layout inspiration for {target}"
|
||||||
```
|
```
|
||||||
|
|
||||||
**Output**: `T` inspiration text files (reused or created in `.intermediates/layout-analysis/inspirations/`)
|
**Output**: `layout_inspiration_map` (in-memory, passed to agents)
|
||||||
|
|
||||||
## Phase 2: Target-Style-Centric Batch Generation (Agent)
|
## Phase 2: Target-Style-Centric Batch Generation (Agent)
|
||||||
|
|
||||||
@@ -132,7 +125,7 @@ Task(ui-design-agent): `
|
|||||||
${design_attributes ? "DESIGN_ATTRIBUTES: " + JSON.stringify(design_attributes) : ""}
|
${design_attributes ? "DESIGN_ATTRIBUTES: " + JSON.stringify(design_attributes) : ""}
|
||||||
|
|
||||||
## Reference
|
## Reference
|
||||||
- Layout inspiration: Read("{base_path}/.intermediates/layout-analysis/inspirations/{target}-layout-ideas.txt")
|
- Layout inspiration: {layout_inspiration_map[target]}
|
||||||
- Design tokens: Read("{base_path}/style-extraction/style-{style_id}/design-tokens.json")
|
- Design tokens: Read("{base_path}/style-extraction/style-{style_id}/design-tokens.json")
|
||||||
Parse ALL token values including:
|
Parse ALL token values including:
|
||||||
* colors, typography (with combinations), spacing, opacity
|
* colors, typography (with combinations), spacing, opacity
|
||||||
@@ -315,8 +308,6 @@ bash(~/.claude/scripts/ui-generate-preview.sh "{base_path}/prototypes")
|
|||||||
{base_path}/
|
{base_path}/
|
||||||
├── .intermediates/
|
├── .intermediates/
|
||||||
│ └── layout-analysis/
|
│ └── layout-analysis/
|
||||||
│ └── inspirations/
|
|
||||||
│ └── {target}-layout-ideas.txt # Layout inspiration (reused or created)
|
|
||||||
├── prototypes/
|
├── prototypes/
|
||||||
│ ├── {target}-style-{s}-layout-{l}.html # Final prototypes
|
│ ├── {target}-style-{s}-layout-{l}.html # Final prototypes
|
||||||
│ ├── {target}-style-{s}-layout-{l}.css
|
│ ├── {target}-style-{s}-layout-{l}.css
|
||||||
|
|||||||
@@ -207,7 +207,8 @@ run_id = "run-$(date +%Y%m%d)-$RANDOM"
|
|||||||
relative_base_path = --session ? ".workflow/WFS-{session}/design-${run_id}" : ".workflow/.design/design-${run_id}"
|
relative_base_path = --session ? ".workflow/WFS-{session}/design-${run_id}" : ".workflow/.design/design-${run_id}"
|
||||||
|
|
||||||
# Create directory and convert to absolute path
|
# Create directory and convert to absolute path
|
||||||
Bash(mkdir -p "${relative_base_path}/{style-extraction,prototypes}")
|
Bash(mkdir -p "${relative_base_path}/style-extraction")
|
||||||
|
Bash(mkdir -p "${relative_base_path}/prototypes")
|
||||||
base_path=$(cd "${relative_base_path}" && pwd)
|
base_path=$(cd "${relative_base_path}" && pwd)
|
||||||
|
|
||||||
Write({base_path}/.run-metadata.json): {
|
Write({base_path}/.run-metadata.json): {
|
||||||
@@ -315,7 +316,8 @@ IF design_source IN ["code_only", "hybrid"]:
|
|||||||
# Check file existence and assess completeness
|
# Check file existence and assess completeness
|
||||||
style_exists = exists("{base_path}/style-extraction/style-1/design-tokens.json")
|
style_exists = exists("{base_path}/style-extraction/style-1/design-tokens.json")
|
||||||
animation_exists = exists("{base_path}/animation-extraction/animation-tokens.json")
|
animation_exists = exists("{base_path}/animation-extraction/animation-tokens.json")
|
||||||
layout_exists = exists("{base_path}/layout-extraction/layout-templates.json")
|
layout_count = bash(ls {base_path}/layout-extraction/layout-*.json 2>/dev/null | wc -l)
|
||||||
|
layout_exists = (layout_count > 0)
|
||||||
|
|
||||||
style_complete = false
|
style_complete = false
|
||||||
animation_complete = false
|
animation_complete = false
|
||||||
@@ -351,14 +353,16 @@ IF design_source IN ["code_only", "hybrid"]:
|
|||||||
|
|
||||||
# Layout completeness check
|
# Layout completeness check
|
||||||
IF layout_exists:
|
IF layout_exists:
|
||||||
layouts = Read("{base_path}/layout-extraction/layout-templates.json")
|
# Read first layout file to verify structure
|
||||||
|
first_layout = bash(ls {base_path}/layout-extraction/layout-*.json 2>/dev/null | head -1)
|
||||||
|
layout_data = Read(first_layout)
|
||||||
layout_complete = (
|
layout_complete = (
|
||||||
layouts.layout_templates?.length >= 3 &&
|
layout_count >= 1 &&
|
||||||
layouts.extraction_metadata?.layout_system?.type &&
|
layout_data.template?.dom_structure &&
|
||||||
layouts.extraction_metadata?.responsive?.breakpoints
|
layout_data.template?.css_layout_rules
|
||||||
)
|
)
|
||||||
IF NOT layout_complete AND layouts.extraction_metadata?.completeness?.missing_items:
|
IF NOT layout_complete:
|
||||||
missing_categories.extend(layouts.extraction_metadata.completeness.missing_items)
|
missing_categories.push("complete layout structure")
|
||||||
ELSE:
|
ELSE:
|
||||||
missing_categories.push("layout templates")
|
missing_categories.push("layout templates")
|
||||||
|
|
||||||
@@ -386,7 +390,7 @@ IF design_source == "visual_only" OR needs_visual_supplement:
|
|||||||
command = "/workflow:ui-design:style-extract --base-path \"{base_path}\" " +
|
command = "/workflow:ui-design:style-extract --base-path \"{base_path}\" " +
|
||||||
(--images ? "--images \"{images}\" " : "") +
|
(--images ? "--images \"{images}\" " : "") +
|
||||||
(--prompt ? "--prompt \"{prompt}\" " : "") +
|
(--prompt ? "--prompt \"{prompt}\" " : "") +
|
||||||
"--mode explore --variants {style_variants}"
|
"--variants {style_variants}"
|
||||||
SlashCommand(command)
|
SlashCommand(command)
|
||||||
ELSE:
|
ELSE:
|
||||||
REPORT: "✅ Phase 1: Style (Using Code Import)"
|
REPORT: "✅ Phase 1: Style (Using Code Import)"
|
||||||
@@ -415,7 +419,7 @@ IF (design_source == "visual_only" OR needs_visual_supplement) OR (NOT layout_co
|
|||||||
command = "/workflow:ui-design:layout-extract --base-path \"{base_path}\" " +
|
command = "/workflow:ui-design:layout-extract --base-path \"{base_path}\" " +
|
||||||
(--images ? "--images \"{images}\" " : "") +
|
(--images ? "--images \"{images}\" " : "") +
|
||||||
(--prompt ? "--prompt \"{prompt}\" " : "") +
|
(--prompt ? "--prompt \"{prompt}\" " : "") +
|
||||||
"--targets \"{targets_string}\" --mode explore --variants {layout_variants} --device-type \"{device_type}\""
|
"--targets \"{targets_string}\" --variants {layout_variants} --device-type \"{device_type}\""
|
||||||
SlashCommand(command)
|
SlashCommand(command)
|
||||||
ELSE:
|
ELSE:
|
||||||
REPORT: "✅ Phase 2.5: Layout (Using Code Import)"
|
REPORT: "✅ Phase 2.5: Layout (Using Code Import)"
|
||||||
@@ -549,10 +553,11 @@ Architecture: Style-Centric Batch Generation
|
|||||||
Run ID: {run_id} | Session: {session_id or "standalone"}
|
Run ID: {run_id} | Session: {session_id or "standalone"}
|
||||||
Type: {icon} {target_type} | Device: {device_type} | Matrix: {s}×{l}×{n} = {total} prototypes
|
Type: {icon} {target_type} | Device: {device_type} | Matrix: {s}×{l}×{n} = {total} prototypes
|
||||||
|
|
||||||
Phase 1: {s} complete design systems (style-extract)
|
Phase 1: {s} complete design systems (style-extract with multi-select)
|
||||||
Phase 2: {n×l} layout templates (layout-extract explore mode)
|
Phase 2: {n×l} layout templates (layout-extract with multi-select)
|
||||||
- Device: {device_type} layouts
|
- Device: {device_type} layouts
|
||||||
- {n} targets × {l} layout variants = {n×l} structural templates
|
- {n} targets × {l} layout variants = {n×l} structural templates
|
||||||
|
- User-selected concepts generated in parallel
|
||||||
Phase 3: UI Assembly (generate)
|
Phase 3: UI Assembly (generate)
|
||||||
- Pure assembly: layout templates + design tokens
|
- Pure assembly: layout templates + design tokens
|
||||||
- {s}×{l}×{n} = {total} final prototypes
|
- {s}×{l}×{n} = {total} final prototypes
|
||||||
@@ -562,21 +567,22 @@ Phase 4: Brainstorming artifacts updated
|
|||||||
Assembly Process:
|
Assembly Process:
|
||||||
✅ Separation of Concerns: Layout (structure) + Style (tokens) kept separate
|
✅ Separation of Concerns: Layout (structure) + Style (tokens) kept separate
|
||||||
✅ Layout Extraction: {n×l} reusable structural templates
|
✅ Layout Extraction: {n×l} reusable structural templates
|
||||||
|
✅ Multi-Selection Workflow: User selects multiple variants from generated options
|
||||||
✅ Pure Assembly: No design decisions in generate phase
|
✅ Pure Assembly: No design decisions in generate phase
|
||||||
✅ Device-Optimized: Layouts designed for {device_type}
|
✅ Device-Optimized: Layouts designed for {device_type}
|
||||||
|
|
||||||
Design Quality:
|
Design Quality:
|
||||||
✅ Token-Driven Styling: 100% var() usage
|
✅ Token-Driven Styling: 100% var() usage
|
||||||
✅ Structural Variety: {l} distinct layouts per target
|
✅ Structural Variety: {l} distinct layouts per target (user-selected)
|
||||||
✅ Style Variety: {s} independent design systems
|
✅ Style Variety: {s} independent design systems (user-selected)
|
||||||
✅ Device-Optimized: Layouts designed for {device_type}
|
✅ Device-Optimized: Layouts designed for {device_type}
|
||||||
|
|
||||||
📂 {base_path}/
|
📂 {base_path}/
|
||||||
├── .intermediates/ (Intermediate analysis files)
|
├── .intermediates/ (Intermediate analysis files)
|
||||||
│ ├── style-analysis/ (computed-styles.json, design-space-analysis.json)
|
│ ├── style-analysis/ (computed-styles.json, design-space-analysis.json)
|
||||||
│ └── layout-analysis/ (dom-structure-*.json, inspirations/*.txt)
|
│ └── layout-analysis/ (analysis-options.json, user-selection.json, dom-structure-*.json)
|
||||||
├── style-extraction/ ({s} complete design systems)
|
├── style-extraction/ ({s} complete design systems)
|
||||||
├── layout-extraction/ ({n×l} layout templates + layout-space-analysis.json)
|
├── layout-extraction/ ({n×l} layout template files: layout-{target}-{variant}.json)
|
||||||
├── prototypes/ ({total} assembled prototypes)
|
├── prototypes/ ({total} assembled prototypes)
|
||||||
└── .run-metadata.json (includes device type)
|
└── .run-metadata.json (includes device type)
|
||||||
|
|
||||||
|
|||||||
@@ -225,8 +225,8 @@ IF design_source == "hybrid":
|
|||||||
REPORT: " → Source: {code_base_path}"
|
REPORT: " → Source: {code_base_path}"
|
||||||
REPORT: " → Mode: Hybrid (Web + Code)"
|
REPORT: " → Mode: Hybrid (Web + Code)"
|
||||||
|
|
||||||
command = "/workflow:ui-design:import-from-code --base-path \"{base_path}\" " +
|
command = "/workflow:ui-design:import-from-code --output-path \"{base_path}\" " +
|
||||||
"--base-path \"{code_base_path}\""
|
"--source-path \"{code_base_path}\""
|
||||||
|
|
||||||
TRY:
|
TRY:
|
||||||
SlashCommand(command)
|
SlashCommand(command)
|
||||||
@@ -239,7 +239,8 @@ IF design_source == "hybrid":
|
|||||||
# Check file existence and assess completeness
|
# Check file existence and assess completeness
|
||||||
style_exists = exists("{base_path}/style-extraction/style-1/design-tokens.json")
|
style_exists = exists("{base_path}/style-extraction/style-1/design-tokens.json")
|
||||||
animation_exists = exists("{base_path}/animation-extraction/animation-tokens.json")
|
animation_exists = exists("{base_path}/animation-extraction/animation-tokens.json")
|
||||||
layout_exists = exists("{base_path}/layout-extraction/layout-templates.json")
|
layout_count = bash(ls {base_path}/layout-extraction/layout-*.json 2>/dev/null | wc -l)
|
||||||
|
layout_exists = (layout_count > 0)
|
||||||
|
|
||||||
style_complete = false
|
style_complete = false
|
||||||
animation_complete = false
|
animation_complete = false
|
||||||
@@ -275,14 +276,16 @@ IF design_source == "hybrid":
|
|||||||
|
|
||||||
# Layout completeness check
|
# Layout completeness check
|
||||||
IF layout_exists:
|
IF layout_exists:
|
||||||
layouts = Read("{base_path}/layout-extraction/layout-templates.json")
|
# Read first layout file to verify structure
|
||||||
|
first_layout = bash(ls {base_path}/layout-extraction/layout-*.json 2>/dev/null | head -1)
|
||||||
|
layout_data = Read(first_layout)
|
||||||
layout_complete = (
|
layout_complete = (
|
||||||
layouts.layout_templates?.length >= 3 &&
|
layout_count >= 1 &&
|
||||||
layouts.extraction_metadata?.layout_system?.type &&
|
layout_data.template?.dom_structure &&
|
||||||
layouts.extraction_metadata?.responsive?.breakpoints
|
layout_data.template?.css_layout_rules
|
||||||
)
|
)
|
||||||
IF NOT layout_complete AND layouts.extraction_metadata?.completeness?.missing_items:
|
IF NOT layout_complete:
|
||||||
missing_categories.extend(layouts.extraction_metadata.completeness.missing_items)
|
missing_categories.push("complete layout structure")
|
||||||
ELSE:
|
ELSE:
|
||||||
missing_categories.push("layout templates")
|
missing_categories.push("layout templates")
|
||||||
|
|
||||||
@@ -405,7 +408,7 @@ ELSE:
|
|||||||
extraction_prompt = f"Extract visual style tokens from '{primary_target}' with consistency across all pages."
|
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()])
|
url_map_for_extract = ",".join([f"{name}:{url}" for name, url in url_map.items()])
|
||||||
extract_command = f"/workflow:ui-design:style-extract --base-path \"{base_path}\" --images \"{images_glob}\" --urls \"{url_map_for_extract}\" --prompt \"{extraction_prompt}\" --mode imitate"
|
extract_command = f"/workflow:ui-design:style-extract --base-path \"{base_path}\" --images \"{images_glob}\" --urls \"{url_map_for_extract}\" --prompt \"{extraction_prompt}\" --variants 1"
|
||||||
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")
|
||||||
@@ -436,7 +439,7 @@ IF skip_layout:
|
|||||||
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()])
|
url_map_for_layout = ",".join([f"{target}:{url}" for target, url in url_map.items()])
|
||||||
layout_extract_command = f"/workflow:ui-design:layout-extract --base-path \"{base_path}\" --images \"{images_glob}\" --urls \"{url_map_for_layout}\" --targets \"{','.join(target_names)}\" --mode imitate"
|
layout_extract_command = f"/workflow:ui-design:layout-extract --base-path \"{base_path}\" --images \"{images_glob}\" --urls \"{url_map_for_layout}\" --targets \"{','.join(target_names)}\" --variants 1"
|
||||||
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")
|
||||||
@@ -546,7 +549,7 @@ ELSE:
|
|||||||
│ ├── animation-tokens.json
|
│ ├── animation-tokens.json
|
||||||
│ └── animation-guide.md
|
│ └── animation-guide.md
|
||||||
├── layout-extraction/ # Structure templates
|
├── layout-extraction/ # Structure templates
|
||||||
│ └── layout-templates.json
|
│ └── layout-{target}-1.json # One file per target
|
||||||
└── prototypes/ # {generated_count} HTML/CSS files
|
└── prototypes/ # {generated_count} HTML/CSS files
|
||||||
├── {target1}-style-1-layout-1.html + .css
|
├── {target1}-style-1-layout-1.html + .css
|
||||||
├── {target2}-style-1-layout-1.html + .css
|
├── {target2}-style-1-layout-1.html + .css
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
name: workflow:ui-design:import-from-code
|
name: workflow:ui-design:import-from-code
|
||||||
description: Import design system from code files (CSS/JS/HTML/SCSS) using parallel agent analysis with final synthesis
|
description: Import design system from code files (CSS/JS/HTML/SCSS) using parallel agent analysis with final synthesis
|
||||||
argument-hint: "[--base-path <path>] [--css \"<glob>\"] [--js \"<glob>\"] [--scss \"<glob>\"] [--html \"<glob>\"] [--style-files \"<glob>\"] [--session <id>]"
|
argument-hint: "[--source-path <path>] [--output-path <path>] [--css \"<glob>\"] [--js \"<glob>\"] [--scss \"<glob>\"] [--html \"<glob>\"] [--style-files \"<glob>\"] [--session <id>]"
|
||||||
allowed-tools: Read,Write,Bash,Glob,Grep,Task,TodoWrite
|
allowed-tools: Read,Write,Bash,Glob,Grep,Task,TodoWrite
|
||||||
auto-continue: true
|
auto-continue: true
|
||||||
---
|
---
|
||||||
@@ -34,7 +34,8 @@ Extract design system tokens from source code files (CSS/SCSS/JS/TS/HTML) using
|
|||||||
/workflow:ui-design:import-from-code [FLAGS]
|
/workflow:ui-design:import-from-code [FLAGS]
|
||||||
|
|
||||||
# Flags
|
# Flags
|
||||||
--base-path <path> Base directory for analysis (default: current directory)
|
--source-path <path> Source code directory to analyze (default: current directory)
|
||||||
|
--output-path <path> Output directory for extracted design tokens (default: current directory)
|
||||||
--css "<glob>" CSS file glob pattern (e.g., "theme/*.css")
|
--css "<glob>" CSS file glob pattern (e.g., "theme/*.css")
|
||||||
--scss "<glob>" SCSS file glob pattern (e.g., "styles/*.scss")
|
--scss "<glob>" SCSS file glob pattern (e.g., "styles/*.scss")
|
||||||
--js "<glob>" JavaScript file glob pattern (e.g., "theme/*.js")
|
--js "<glob>" JavaScript file glob pattern (e.g., "theme/*.js")
|
||||||
@@ -47,19 +48,19 @@ Extract design system tokens from source code files (CSS/SCSS/JS/TS/HTML) using
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Basic usage - auto-discover all files
|
# Basic usage - auto-discover all files
|
||||||
/workflow:ui-design:import-from-code --base-path ./
|
/workflow:ui-design:import-from-code --source-path ./src --output-path ./design-system
|
||||||
|
|
||||||
# Target specific directories
|
# Target specific directories
|
||||||
/workflow:ui-design:import-from-code --base-path ./src --css "theme/*.css" --js "theme/*.js"
|
/workflow:ui-design:import-from-code --source-path ./src --output-path ./design-system --css "theme/*.css" --js "theme/*.js"
|
||||||
|
|
||||||
# Tailwind config only
|
# Tailwind config only (output to current directory)
|
||||||
/workflow:ui-design:import-from-code --js "tailwind.config.js"
|
/workflow:ui-design:import-from-code --source-path ./ --js "tailwind.config.js"
|
||||||
|
|
||||||
# CSS framework import
|
# CSS framework import
|
||||||
/workflow:ui-design:import-from-code --css "styles/**/*.scss" --html "components/**/*.html"
|
/workflow:ui-design:import-from-code --source-path ./src --output-path ./design-system --css "styles/**/*.scss" --html "components/**/*.html"
|
||||||
|
|
||||||
# Universal style files
|
# Universal style files
|
||||||
/workflow:ui-design:import-from-code --style-files "**/theme.*"
|
/workflow:ui-design:import-from-code --source-path ./src --output-path ./design-system --style-files "**/theme.*"
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -74,11 +75,12 @@ Extract design system tokens from source code files (CSS/SCSS/JS/TS/HTML) using
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 1. Initialize directories
|
# 1. Initialize directories
|
||||||
base_path="${base_path:-.}"
|
source_path="${source_path:-.}"
|
||||||
intermediates_dir="${base_path}/.intermediates/import-analysis"
|
output_path="${output_path:-.}"
|
||||||
|
intermediates_dir="${output_path}/.intermediates/import-analysis"
|
||||||
mkdir -p "$intermediates_dir"
|
mkdir -p "$intermediates_dir"
|
||||||
|
|
||||||
echo "[Phase 0] File Discovery Started"
|
echo "[Phase 0] File Discovery Started (source: $source_path, output: $output_path)"
|
||||||
```
|
```
|
||||||
|
|
||||||
<!-- TodoWrite: Initialize todo list -->
|
<!-- TodoWrite: Initialize todo list -->
|
||||||
@@ -95,7 +97,7 @@ echo "[Phase 0] File Discovery Started"
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 2. Discover files by type
|
# 2. Discover files by type
|
||||||
cd "$base_path" || exit 1
|
cd "$source_path" || exit 1
|
||||||
|
|
||||||
# CSS files
|
# CSS files
|
||||||
if [ -n "$css" ]; then
|
if [ -n "$css" ]; then
|
||||||
@@ -181,7 +183,7 @@ Task(ui-design-agent): `
|
|||||||
[STYLE_TOKENS_EXTRACTION]
|
[STYLE_TOKENS_EXTRACTION]
|
||||||
Extract visual design tokens (colors, typography, spacing, shadows, borders) from ALL file types
|
Extract visual design tokens (colors, typography, spacing, shadows, borders) from ALL file types
|
||||||
|
|
||||||
MODE: style-extraction | BASE_PATH: ${base_path}
|
MODE: style-extraction | SOURCE_PATH: ${source_path} | OUTPUT_PATH: ${output_path}
|
||||||
|
|
||||||
## Input Files (Can reference ANY file type)
|
## Input Files (Can reference ANY file type)
|
||||||
|
|
||||||
@@ -208,7 +210,7 @@ Task(ui-design-agent): `
|
|||||||
|
|
||||||
## Output Requirements
|
## Output Requirements
|
||||||
|
|
||||||
Generate 2 files in ${base_path}/style-extraction/style-1/:
|
Generate 2 files in ${output_path}/style-extraction/style-1/:
|
||||||
1. design-tokens.json (production-ready design tokens)
|
1. design-tokens.json (production-ready design tokens)
|
||||||
2. style-guide.md (design philosophy and usage guide)
|
2. style-guide.md (design philosophy and usage guide)
|
||||||
|
|
||||||
@@ -357,13 +359,13 @@ Task(ui-design-agent): `
|
|||||||
|
|
||||||
## Critical Requirements
|
## Critical Requirements
|
||||||
- ✅ Can read ANY file type (CSS/SCSS/JS/TS/HTML) - not restricted to CSS only
|
- ✅ Can read ANY file type (CSS/SCSS/JS/TS/HTML) - not restricted to CSS only
|
||||||
- ✅ Use Read() tool for each file you want to analyze
|
- ✅ Use Read() tool for each file you want to analyze (files are in SOURCE_PATH: ${source_path})
|
||||||
- ✅ Cross-reference between file types for better extraction
|
- ✅ Cross-reference between file types for better extraction
|
||||||
- ✅ Extract all visual token types systematically
|
- ✅ Extract all visual token types systematically
|
||||||
- ✅ Create style-extraction/style-1/ directory first: Bash(mkdir -p "${base_path}/style-extraction/style-1")
|
- ✅ Create style-extraction/style-1/ directory first: Bash(mkdir -p "${output_path}/style-extraction/style-1")
|
||||||
- ✅ Use Write() to save both files:
|
- ✅ Use Write() to save both files:
|
||||||
- ${base_path}/style-extraction/style-1/design-tokens.json
|
- ${output_path}/style-extraction/style-1/design-tokens.json
|
||||||
- ${base_path}/style-extraction/style-1/style-guide.md
|
- ${output_path}/style-extraction/style-1/style-guide.md
|
||||||
- ✅ Include _metadata.completeness field to track missing content
|
- ✅ Include _metadata.completeness field to track missing content
|
||||||
- ❌ NO external research or MCP calls
|
- ❌ NO external research or MCP calls
|
||||||
`
|
`
|
||||||
@@ -378,7 +380,7 @@ Task(ui-design-agent): `
|
|||||||
[ANIMATION_TOKENS_EXTRACTION]
|
[ANIMATION_TOKENS_EXTRACTION]
|
||||||
Extract animation/transition tokens from ALL file types
|
Extract animation/transition tokens from ALL file types
|
||||||
|
|
||||||
MODE: animation-extraction | BASE_PATH: ${base_path}
|
MODE: animation-extraction | SOURCE_PATH: ${source_path} | OUTPUT_PATH: ${output_path}
|
||||||
|
|
||||||
## Input Files (Can reference ANY file type)
|
## Input Files (Can reference ANY file type)
|
||||||
|
|
||||||
@@ -405,7 +407,7 @@ Task(ui-design-agent): `
|
|||||||
|
|
||||||
## Output Requirements
|
## Output Requirements
|
||||||
|
|
||||||
Generate 2 files in ${base_path}/animation-extraction/:
|
Generate 2 files in ${output_path}/animation-extraction/:
|
||||||
1. animation-tokens.json (production-ready animation tokens)
|
1. animation-tokens.json (production-ready animation tokens)
|
||||||
2. animation-guide.md (animation usage guide)
|
2. animation-guide.md (animation usage guide)
|
||||||
|
|
||||||
@@ -530,13 +532,13 @@ Task(ui-design-agent): `
|
|||||||
|
|
||||||
## Critical Requirements
|
## Critical Requirements
|
||||||
- ✅ Can read ANY file type (CSS/SCSS/JS/TS/HTML)
|
- ✅ Can read ANY file type (CSS/SCSS/JS/TS/HTML)
|
||||||
- ✅ Use Read() tool for each file you want to analyze
|
- ✅ Use Read() tool for each file you want to analyze (files are in SOURCE_PATH: ${source_path})
|
||||||
- ✅ Detect animation framework if used
|
- ✅ Detect animation framework if used
|
||||||
- ✅ Extract all animation-related tokens
|
- ✅ Extract all animation-related tokens
|
||||||
- ✅ Create animation-extraction/ directory first: Bash(mkdir -p "${base_path}/animation-extraction")
|
- ✅ Create animation-extraction/ directory first: Bash(mkdir -p "${output_path}/animation-extraction")
|
||||||
- ✅ Use Write() to save both files:
|
- ✅ Use Write() to save both files:
|
||||||
- ${base_path}/animation-extraction/animation-tokens.json
|
- ${output_path}/animation-extraction/animation-tokens.json
|
||||||
- ${base_path}/animation-extraction/animation-guide.md
|
- ${output_path}/animation-extraction/animation-guide.md
|
||||||
- ✅ Include _metadata.completeness field to track missing content
|
- ✅ Include _metadata.completeness field to track missing content
|
||||||
- ❌ NO external research or MCP calls
|
- ❌ NO external research or MCP calls
|
||||||
`
|
`
|
||||||
@@ -551,7 +553,7 @@ Task(ui-design-agent): `
|
|||||||
[LAYOUT_PATTERNS_EXTRACTION]
|
[LAYOUT_PATTERNS_EXTRACTION]
|
||||||
Extract layout patterns and component structures from ALL file types
|
Extract layout patterns and component structures from ALL file types
|
||||||
|
|
||||||
MODE: layout-extraction | BASE_PATH: ${base_path}
|
MODE: layout-extraction | SOURCE_PATH: ${source_path} | OUTPUT_PATH: ${output_path}
|
||||||
|
|
||||||
## Input Files (Can reference ANY file type)
|
## Input Files (Can reference ANY file type)
|
||||||
|
|
||||||
@@ -578,7 +580,7 @@ Task(ui-design-agent): `
|
|||||||
|
|
||||||
## Output Requirements
|
## Output Requirements
|
||||||
|
|
||||||
Generate 1 file: ${base_path}/layout-extraction/layout-templates.json
|
Generate 1 file: ${output_path}/layout-extraction/layout-templates.json
|
||||||
|
|
||||||
### layout-templates.json Structure:
|
### layout-templates.json Structure:
|
||||||
{
|
{
|
||||||
@@ -675,11 +677,11 @@ Task(ui-design-agent): `
|
|||||||
|
|
||||||
## Critical Requirements
|
## Critical Requirements
|
||||||
- ✅ Can read ANY file type (CSS/SCSS/JS/TS/HTML)
|
- ✅ Can read ANY file type (CSS/SCSS/JS/TS/HTML)
|
||||||
- ✅ Use Read() tool for each file you want to analyze
|
- ✅ Use Read() tool for each file you want to analyze (files are in SOURCE_PATH: ${source_path})
|
||||||
- ✅ Identify naming conventions and layout systems
|
- ✅ Identify naming conventions and layout systems
|
||||||
- ✅ Extract component patterns with variants and states
|
- ✅ Extract component patterns with variants and states
|
||||||
- ✅ Create layout-extraction/ directory first: Bash(mkdir -p "${base_path}/layout-extraction")
|
- ✅ Create layout-extraction/ directory first: Bash(mkdir -p "${output_path}/layout-extraction")
|
||||||
- ✅ Use Write() to save: ${base_path}/layout-extraction/layout-templates.json
|
- ✅ Use Write() to save: ${output_path}/layout-extraction/layout-templates.json
|
||||||
- ✅ Include extraction_metadata.completeness field to track missing content
|
- ✅ Include extraction_metadata.completeness field to track missing content
|
||||||
- ❌ NO external research or MCP calls
|
- ❌ NO external research or MCP calls
|
||||||
`
|
`
|
||||||
@@ -710,11 +712,11 @@ echo "[Phase 1] Parallel agent analysis complete"
|
|||||||
|
|
||||||
### Generated Files
|
### Generated Files
|
||||||
|
|
||||||
**Location**: `${base_path}/`
|
**Location**: `${output_path}/`
|
||||||
|
|
||||||
**Directory Structure**:
|
**Directory Structure**:
|
||||||
```
|
```
|
||||||
${base_path}/
|
${output_path}/
|
||||||
├── style-extraction/
|
├── style-extraction/
|
||||||
│ └── style-1/
|
│ └── style-1/
|
||||||
│ ├── design-tokens.json # Production-ready design tokens
|
│ ├── design-tokens.json # Production-ready design tokens
|
||||||
@@ -769,7 +771,7 @@ ${base_path}/
|
|||||||
|
|
||||||
| Error | Cause | Resolution |
|
| Error | Cause | Resolution |
|
||||||
|-------|-------|------------|
|
|-------|-------|------------|
|
||||||
| No files discovered | Glob patterns too restrictive or wrong base-path | Check glob patterns and base-path, verify file locations |
|
| No files discovered | Glob patterns too restrictive or wrong source-path | Check glob patterns and source-path, verify file locations |
|
||||||
| Agent reports "failed" status | No tokens found in any file | Review file content, check if files contain design tokens |
|
| Agent reports "failed" status | No tokens found in any file | Review file content, check if files contain design tokens |
|
||||||
| Empty completeness reports | Files exist but contain no extractable tokens | Manually verify token definitions in source files |
|
| Empty completeness reports | Files exist but contain no extractable tokens | Manually verify token definitions in source files |
|
||||||
| Missing file type | Specific file type not discovered | Use explicit glob flags (--css, --js, --html, --scss) |
|
| Missing file type | Specific file type not discovered | Use explicit glob flags (--css, --js, --html, --scss) |
|
||||||
@@ -779,7 +781,8 @@ ${base_path}/
|
|||||||
## Best Practices
|
## Best Practices
|
||||||
|
|
||||||
1. **Use auto-discovery for full projects**: Omit glob flags to discover all files automatically
|
1. **Use auto-discovery for full projects**: Omit glob flags to discover all files automatically
|
||||||
2. **Target specific directories for speed**: Use `--base-path` + specific globs for focused analysis
|
2. **Target specific directories for speed**: Use `--source-path` to target source code and `--output-path` for extracted tokens, combined with specific globs for focused analysis
|
||||||
3. **Cross-reference agent reports**: Compare all three completeness reports to identify gaps
|
3. **Separate source and output**: Always use distinct `--source-path` (where source code lives) and `--output-path` (where design tokens are generated) to avoid polluting source code directory
|
||||||
4. **Review missing content**: Check `missing` field in reports for actionable improvements
|
4. **Cross-reference agent reports**: Compare all three completeness reports to identify gaps
|
||||||
5. **Verify file discovery**: Check `.intermediates/import-analysis/*-files.txt` if agents report no data
|
5. **Review missing content**: Check `missing` field in reports for actionable improvements
|
||||||
|
6. **Verify file discovery**: Check `${output_path}/.intermediates/import-analysis/*-files.txt` if agents report no data
|
||||||
|
|||||||
@@ -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
|
||||||
argument-hint: [--base-path <path>] [--session <id>] [--images "<glob>"] [--urls "<list>"] [--prompt "<desc>"] [--targets "<list>"] [--mode <imitate|explore>] [--variants <count>] [--device-type <desktop|mobile|tablet|responsive>]
|
argument-hint: [--base-path <path>] [--session <id>] [--images "<glob>"] [--urls "<list>"] [--prompt "<desc>"] [--targets "<list>"] [--variants <count>] [--device-type <desktop|mobile|tablet|responsive>]
|
||||||
allowed-tools: TodoWrite(*), Read(*), Write(*), Glob(*), Bash(*), Task(ui-design-agent), mcp__exa__web_search_exa(*)
|
allowed-tools: TodoWrite(*), Read(*), Write(*), Glob(*), Bash(*), Task(ui-design-agent), mcp__exa__web_search_exa(*)
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -14,10 +14,8 @@ Extract structural layout information from reference images, URLs, or text promp
|
|||||||
**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
|
||||||
- **Dual-Mode**:
|
- **Behavior**: Generate N layout concepts → User multi-select → Generate selected templates
|
||||||
- `imitate`: High-fidelity replication of single layout structure
|
- **Output**: `layout-templates.json` with DOM structure, component hierarchy, and CSS layout rules
|
||||||
- `explore`: Multiple structurally distinct layout variations
|
|
||||||
- **Single 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
|
||||||
|
|
||||||
@@ -45,15 +43,10 @@ ELSE:
|
|||||||
has_urls = false
|
has_urls = false
|
||||||
url_list = []
|
url_list = []
|
||||||
|
|
||||||
# Determine extraction mode
|
# Set variants count (default: 3, range: 1-5)
|
||||||
extraction_mode = --mode OR "imitate" # "imitate" or "explore"
|
# Behavior: Generate N layout concepts per target → User multi-select → Generate selected templates
|
||||||
|
variants_count = --variants OR 3
|
||||||
# Set variants count based on mode
|
VALIDATE: 1 <= variants_count <= 5
|
||||||
IF extraction_mode == "imitate":
|
|
||||||
variants_count = 1 # Force single variant (ignore --variants)
|
|
||||||
ELSE IF extraction_mode == "explore":
|
|
||||||
variants_count = --variants OR 3 # Default to 3
|
|
||||||
VALIDATE: 1 <= variants_count <= 5
|
|
||||||
|
|
||||||
# Resolve targets
|
# Resolve targets
|
||||||
# Priority: --targets → url_list targets → prompt analysis → default ["page"]
|
# Priority: --targets → url_list targets → prompt analysis → default ["page"]
|
||||||
@@ -62,6 +55,9 @@ IF --targets:
|
|||||||
ELSE IF has_urls:
|
ELSE IF has_urls:
|
||||||
targets = [url_info.target for url_info in url_list]
|
targets = [url_info.target for url_info in url_list]
|
||||||
ELSE IF --prompt:
|
ELSE IF --prompt:
|
||||||
|
# Extract targets from prompt using pattern matching
|
||||||
|
# Looks for keywords: "page names", target descriptors (login, dashboard, etc.)
|
||||||
|
# Returns lowercase, hyphenated strings (e.g., ["login", "dashboard"])
|
||||||
targets = extract_from_prompt(--prompt)
|
targets = extract_from_prompt(--prompt)
|
||||||
ELSE:
|
ELSE:
|
||||||
targets = ["page"]
|
targets = ["page"]
|
||||||
@@ -190,36 +186,17 @@ IF result.exploration?.triggered:
|
|||||||
IF session_has_inputs: SKIP Step 2 file reading
|
IF session_has_inputs: SKIP Step 2 file reading
|
||||||
|
|
||||||
# 2. Check if output already exists
|
# 2. Check if output already exists
|
||||||
bash(test -f {base_path}/layout-extraction/layout-templates.json && echo "exists")
|
bash(find {base_path}/layout-extraction -name "layout-*.json" -print -quit | grep -q . && echo "exists")
|
||||||
IF exists: SKIP to completion
|
IF exists: SKIP to completion
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Phase 0 Output**: `input_mode`, `base_path`, `extraction_mode`, `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 (Explore Mode Only)
|
## Phase 1: Layout Concept Generation
|
||||||
|
|
||||||
### Step 1: Check Extraction Mode
|
### Step 1: Generate Layout Concept Options (Agent Task 1)
|
||||||
```bash
|
|
||||||
# extraction_mode == "imitate" → skip this phase
|
|
||||||
# extraction_mode == "explore" → execute this phase
|
|
||||||
```
|
|
||||||
|
|
||||||
**If imitate mode**: Skip to Phase 2
|
|
||||||
|
|
||||||
### Step 2: Gather Layout Inspiration (Explore Mode)
|
|
||||||
```bash
|
|
||||||
bash(mkdir -p {base_path}/.intermediates/layout-analysis/inspirations)
|
|
||||||
|
|
||||||
# For each target: Research via MCP
|
|
||||||
# mcp__exa__web_search_exa(query="{target} layout patterns {device_type}", numResults=5)
|
|
||||||
|
|
||||||
# Write inspiration file
|
|
||||||
Write({base_path}/.intermediates/layout-analysis/inspirations/{target}-layout-ideas.txt, inspiration_content)
|
|
||||||
```
|
|
||||||
|
|
||||||
### Step 3: Generate Layout Concept Options (Agent Task 1)
|
|
||||||
**Executor**: `Task(ui-design-agent)`
|
**Executor**: `Task(ui-design-agent)`
|
||||||
|
|
||||||
Launch agent to generate `variants_count` layout concept options for each target:
|
Launch agent to generate `variants_count` layout concept options for each target:
|
||||||
@@ -235,7 +212,6 @@ Task(ui-design-agent): `
|
|||||||
## Input Analysis
|
## Input Analysis
|
||||||
- Targets: {targets.join(", ")}
|
- Targets: {targets.join(", ")}
|
||||||
- Device type: {device_type}
|
- Device type: {device_type}
|
||||||
- Layout inspiration: Read inspirations from {base_path}/.intermediates/layout-analysis/inspirations/
|
|
||||||
- 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" : ""}
|
||||||
|
|
||||||
@@ -272,7 +248,7 @@ Task(ui-design-agent): `
|
|||||||
`
|
`
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 4: Verify Options File Created
|
### Step 2: Verify Options File Created
|
||||||
```bash
|
```bash
|
||||||
bash(test -f {base_path}/.intermediates/layout-analysis/analysis-options.json && echo "created")
|
bash(test -f {base_path}/.intermediates/layout-analysis/analysis-options.json && echo "created")
|
||||||
|
|
||||||
@@ -333,13 +309,13 @@ Please select your preferred concept for this target.
|
|||||||
|
|
||||||
### Step 3: Capture User Selection (Per Target)
|
### Step 3: Capture User Selection (Per Target)
|
||||||
```javascript
|
```javascript
|
||||||
// Use AskUserQuestion tool for each target
|
// Use AskUserQuestion tool for each target (multi-select enabled)
|
||||||
FOR each target:
|
FOR each target:
|
||||||
AskUserQuestion({
|
AskUserQuestion({
|
||||||
questions: [{
|
questions: [{
|
||||||
question: "Which layout concept do you prefer for '{target}'?",
|
question: "Which layout concept(s) do you prefer for '{target}'?",
|
||||||
header: "Layout for " + target,
|
header: "Layout for " + target,
|
||||||
multiSelect: false,
|
multiSelect: true, // Multi-selection enabled (default behavior)
|
||||||
options: [
|
options: [
|
||||||
{FOR each concept in layout_concepts[target]:
|
{FOR each concept in layout_concepts[target]:
|
||||||
label: "Concept {concept.index}: {concept.concept_name}",
|
label: "Concept {concept.index}: {concept.concept_name}",
|
||||||
@@ -349,39 +325,47 @@ FOR each target:
|
|||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
|
|
||||||
// Parse user response
|
// Parse user response (array of selections)
|
||||||
selected_option_text = user_answer
|
selected_options = user_answer
|
||||||
|
|
||||||
// Check for user cancellation
|
// Check for user cancellation
|
||||||
IF selected_option_text == null OR selected_option_text == "":
|
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 concept index from response format "Concept N: Name"
|
// Extract concept indices from array
|
||||||
match = selected_option_text.match(/Concept (\d+):/)
|
selected_indices = []
|
||||||
IF match:
|
FOR each selected_option_text IN selected_options:
|
||||||
selected_index = parseInt(match[1])
|
match = selected_option_text.match(/Concept (\d+):/)
|
||||||
ELSE:
|
IF match:
|
||||||
ERROR: "Invalid selection format. Expected 'Concept N: ...' format"
|
selected_indices.push(parseInt(match[1]))
|
||||||
EXIT workflow
|
ELSE:
|
||||||
|
ERROR: "Invalid selection format. Expected 'Concept N: ...' format"
|
||||||
|
EXIT workflow
|
||||||
|
|
||||||
// Store selection for this target
|
// Store selections for this target (array of indices)
|
||||||
selections[target] = {
|
selections[target] = {
|
||||||
selected_index: selected_index,
|
selected_indices: selected_indices, // Array of selected indices
|
||||||
concept_name: layout_concepts[target][selected_index-1].concept_name
|
concept_names: selected_indices.map(i => layout_concepts[target][i-1].concept_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
REPORT: "✅ Selected {selected_indices.length} layout(s) for {target}"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 4: Write User Selection File
|
### Step 4: Write User Selection File
|
||||||
```bash
|
```bash
|
||||||
|
# Calculate total selections across all targets
|
||||||
|
total_selections = sum([len(selections[t].selected_indices) for t in targets])
|
||||||
|
|
||||||
# Create user selection JSON
|
# Create user selection JSON
|
||||||
selection_data = {
|
selection_data = {
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"selected_at": "{current_timestamp}",
|
"selected_at": "{current_timestamp}",
|
||||||
"selection_type": "per_target",
|
"selection_type": "per_target_multi",
|
||||||
"session_id": "{session_id}"
|
"session_id": "{session_id}",
|
||||||
|
"total_selections": total_selections
|
||||||
},
|
},
|
||||||
"selections": selections // {target: {selected_index, concept_name}}
|
"selections": selections // {target: {selected_indices: [...], concept_names: [...]}}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Write to file
|
# Write to file
|
||||||
@@ -393,149 +377,155 @@ bash(test -f {base_path}/.intermediates/layout-analysis/user-selection.json && e
|
|||||||
|
|
||||||
### Step 5: Confirmation Message
|
### Step 5: Confirmation Message
|
||||||
```
|
```
|
||||||
✅ Selections recorded!
|
✅ Selections recorded! Total: {total_selections} layout(s)
|
||||||
|
|
||||||
{FOR each target, selection in selections:
|
{FOR each target, selection in selections:
|
||||||
• {target}: Concept {selection.selected_index} - {selection.concept_name}
|
• {target}: {selection.selected_indices.length} layout(s) selected
|
||||||
|
{FOR each index IN selection.selected_indices:
|
||||||
|
- Concept {index}: {layout_concepts[target][index-1].concept_name}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Proceeding to generate detailed layout templates based on your selections...
|
Proceeding to generate {total_selections} detailed layout template(s)...
|
||||||
```
|
```
|
||||||
|
|
||||||
**Output**: `user-selection.json` with user's choices for all targets
|
**Output**: `user-selection.json` with user's multi-selections for all targets
|
||||||
|
|
||||||
## Phase 2: Layout Template Generation (Agent Task 2)
|
## Phase 2: Layout Template Generation (Agent Task 2)
|
||||||
|
|
||||||
**Executor**: `Task(ui-design-agent)` for selected concept(s)
|
**Executor**: `Task(ui-design-agent)` × `Total_Selected_Templates` in **parallel**
|
||||||
|
|
||||||
### Step 1: Load User Selection (Explore Mode)
|
### Step 1: Load User Selections and Build Task List
|
||||||
```bash
|
```bash
|
||||||
# For explore mode, read user selection
|
# Read user selections
|
||||||
IF extraction_mode == "explore":
|
selection = Read({base_path}/.intermediates/layout-analysis/user-selection.json)
|
||||||
selection = Read({base_path}/.intermediates/layout-analysis/user-selection.json)
|
selections_per_target = selection.selections
|
||||||
selections_per_target = selection.selections
|
|
||||||
|
|
||||||
# Also read the selected concept details from options
|
# Read concept details
|
||||||
options = Read({base_path}/.intermediates/layout-analysis/analysis-options.json)
|
options = Read({base_path}/.intermediates/layout-analysis/analysis-options.json)
|
||||||
layout_concepts = options.layout_concepts
|
layout_concepts = options.layout_concepts
|
||||||
|
|
||||||
# Build selected concepts map
|
# Build task list for all selected concepts across all targets
|
||||||
selected_concepts = {}
|
task_list = []
|
||||||
FOR each target in targets:
|
FOR each target in targets:
|
||||||
selected_index = selections_per_target[target].selected_index
|
selected_indices = selections_per_target[target].selected_indices # Array
|
||||||
selected_concepts[target] = layout_concepts[target][selected_index-1] # 0-indexed
|
concept_names = selections_per_target[target].concept_names # Array
|
||||||
ELSE:
|
|
||||||
# Imitate mode - no selection needed
|
FOR i in range(len(selected_indices)):
|
||||||
selected_concepts = null
|
idx = selected_indices[i]
|
||||||
|
concept = layout_concepts[target][idx - 1] # 0-indexed array
|
||||||
|
variant_id = i + 1 # 1-based variant numbering
|
||||||
|
|
||||||
|
task_list.push({
|
||||||
|
target: target,
|
||||||
|
variant_id: variant_id,
|
||||||
|
concept: concept,
|
||||||
|
output_file: "{base_path}/layout-extraction/layout-{target}-{variant_id}.json"
|
||||||
|
})
|
||||||
|
|
||||||
|
total_tasks = task_list.length
|
||||||
|
REPORT: "Generating {total_tasks} layout templates across {targets.length} targets"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: Launch Agent Task
|
### Step 2: Launch Parallel Agent Tasks
|
||||||
Generate layout templates for selected concepts:
|
Generate layout templates for ALL selected concepts in parallel:
|
||||||
```javascript
|
```javascript
|
||||||
Task(ui-design-agent): `
|
FOR each task in task_list:
|
||||||
[LAYOUT_TEMPLATE_GENERATION_TASK]
|
Task(ui-design-agent): `
|
||||||
Generate detailed layout templates based on user-selected concepts.
|
[LAYOUT_TEMPLATE_GENERATION_TASK #{task.variant_id} for {task.target}]
|
||||||
Focus ONLY on structure and layout. DO NOT concern with visual style (colors, fonts, etc.).
|
Generate detailed layout template based on user-selected concept.
|
||||||
|
Focus ONLY on structure and layout. DO NOT concern with visual style (colors, fonts, etc.).
|
||||||
|
|
||||||
SESSION: {session_id} | MODE: {extraction_mode} | BASE_PATH: {base_path}
|
SESSION: {session_id} | BASE_PATH: {base_path}
|
||||||
DEVICE_TYPE: {device_type}
|
TARGET: {task.target} | VARIANT: {task.variant_id}
|
||||||
|
DEVICE_TYPE: {device_type}
|
||||||
|
|
||||||
${extraction_mode == "explore" ? `
|
USER SELECTION:
|
||||||
USER SELECTIONS:
|
- Selected Concept: {task.concept.concept_name}
|
||||||
${targets.map(target => `
|
- Philosophy: {task.concept.design_philosophy}
|
||||||
Target: ${target}
|
- Pattern: {task.concept.layout_pattern}
|
||||||
- Selected Concept: ${selected_concepts[target].concept_name}
|
- Key Components: {task.concept.key_components.join(", ")}
|
||||||
- Philosophy: ${selected_concepts[target].design_philosophy}
|
- Structural Features: {task.concept.structural_features.join(", ")}
|
||||||
- Pattern: ${selected_concepts[target].layout_pattern}
|
|
||||||
- Key Components: ${selected_concepts[target].key_components.join(", ")}
|
|
||||||
- Structural Features: ${selected_concepts[target].structural_features.join(", ")}
|
|
||||||
`).join("\n")}
|
|
||||||
` : `
|
|
||||||
MODE: Imitate - High-fidelity replication of reference layout structure
|
|
||||||
TARGETS: ${targets.join(", ")}
|
|
||||||
`}
|
|
||||||
|
|
||||||
## Input Analysis
|
## Input Analysis
|
||||||
- Targets: {targets.join(", ")}
|
- Target: {task.target}
|
||||||
- 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 Data: Read from .intermediates/layout-analysis/dom-structure-*.json - USE THIS for accurate layout properties" : ""}
|
${dom_structure_available ? "- DOM Structure Data: Read from .intermediates/layout-analysis/dom-structure-{task.target}.json - USE THIS for accurate layout properties" : ""}
|
||||||
|
|
||||||
## Generation Rules
|
## Generation Rules
|
||||||
${extraction_mode == "explore" ? `
|
- Develop the user-selected layout concept into a detailed template
|
||||||
- **Explore Mode**: Develop each user-selected layout concept into a detailed template
|
- Use the selected concept's key_components as foundation
|
||||||
- Use the selected concept's key_components as foundation
|
- Apply the selected layout_pattern (grid-3col, flex-row, etc.)
|
||||||
- Apply the selected layout_pattern (grid-3col, flex-row, etc.)
|
- Honor the structural_features defined in the concept
|
||||||
- Honor the structural_features defined in the concept
|
- Expand the concept with complete DOM structure and CSS layout rules
|
||||||
- Expand the concept with complete DOM structure and CSS layout rules
|
${dom_structure_available ? `
|
||||||
` : `
|
- IMPORTANT: You have access to real DOM structure data with accurate flex/grid properties
|
||||||
- **Imitate Mode**: High-fidelity replication of reference layout structure
|
- Use DOM data as primary source for layout properties
|
||||||
${dom_structure_available ? "- Use DOM structure data as ground truth" : "- Use visual inference"}
|
- Extract real flex/grid configurations (display, flexDirection, justifyContent, alignItems, gap)
|
||||||
`}
|
- Use actual element bounds for responsive breakpoint decisions
|
||||||
${dom_structure_available ? `
|
- Preserve identified patterns from DOM structure
|
||||||
- IMPORTANT: You have access to real DOM structure data with accurate flex/grid properties
|
` : ""}
|
||||||
- Use DOM data as primary source for layout properties
|
|
||||||
- Extract real flex/grid configurations (display, flexDirection, justifyContent, alignItems, gap)
|
|
||||||
- Use actual element bounds for responsive breakpoint decisions
|
|
||||||
- Preserve identified patterns from DOM structure
|
|
||||||
` : ""}
|
|
||||||
|
|
||||||
## Generate for EACH Target
|
## Template Generation
|
||||||
For target in {targets}:
|
|
||||||
${extraction_mode == "explore" ? "Based on user-selected concept:" : "Based on reference:"}
|
|
||||||
|
|
||||||
1. **DOM Structure**:
|
1. **DOM Structure**:
|
||||||
- Semantic HTML5 tags: <header>, <nav>, <main>, <aside>, <section>, <footer>
|
- Semantic HTML5 tags: <header>, <nav>, <main>, <aside>, <section>, <footer>
|
||||||
- ARIA roles and accessibility attributes
|
- ARIA roles and accessibility attributes
|
||||||
${extraction_mode == "explore" ? "- Use key_components from selected concept" : ""}
|
- Use key_components from selected concept
|
||||||
${dom_structure_available ? "- Base on extracted DOM tree from .intermediates" : "- Infer from visual analysis"}
|
${dom_structure_available ? "- Base on extracted DOM tree from .intermediates" : "- Infer from visual analysis"}
|
||||||
- Device-specific optimizations for {device_type}
|
- Device-specific optimizations for {device_type}
|
||||||
|
|
||||||
2. **Component Hierarchy**:
|
2. **Component Hierarchy**:
|
||||||
- Array of main layout regions
|
- Array of main layout regions
|
||||||
${extraction_mode == "explore" ? "- Derived from selected concept's key_components" : ""}
|
- Derived from selected concept's key_components
|
||||||
|
|
||||||
3. **CSS Layout Rules**:
|
3. **CSS Layout Rules**:
|
||||||
${extraction_mode == "explore" ? "- Implement selected layout_pattern" : ""}
|
- Implement selected layout_pattern
|
||||||
${dom_structure_available ? "- Use real layout properties from DOM structure data" : "- Focus on Grid, Flexbox, position, alignment"}
|
${dom_structure_available ? "- Use real layout properties from DOM structure data" : "- Focus on Grid, Flexbox, position, alignment"}
|
||||||
- Use CSS Custom Properties: var(--spacing-*), var(--breakpoint-*)
|
- Use CSS Custom Properties: var(--spacing-*), var(--breakpoint-*)
|
||||||
- Device-specific styles (mobile-first @media for responsive)
|
- Device-specific styles (mobile-first @media for responsive)
|
||||||
- NO colors, NO fonts, NO shadows - layout structure only
|
- NO colors, NO fonts, NO shadows - layout structure only
|
||||||
|
|
||||||
## Output Format
|
## Output Format
|
||||||
Write complete layout-templates.json with layout_templates array.
|
Write single-template JSON object with:
|
||||||
Each template must include:
|
- target: "{task.target}"
|
||||||
- target (string)
|
- variant_id: "layout-{task.variant_id}"
|
||||||
- variant_id: "layout-1" (always 1 since only selected concept is generated)
|
- source_image_path (string): Reference image path
|
||||||
- source_image_path (string): Reference image path
|
- device_type: "{device_type}"
|
||||||
- device_type (string)
|
- design_philosophy (string from selected concept)
|
||||||
- design_philosophy (string ${extraction_mode == "explore" ? "- from selected concept" : ""})
|
- dom_structure (JSON object)
|
||||||
- dom_structure (JSON object)
|
- component_hierarchy (array of strings)
|
||||||
- component_hierarchy (array of strings)
|
- css_layout_rules (string)
|
||||||
- css_layout_rules (string)
|
|
||||||
|
|
||||||
## Critical Requirements
|
## Critical Requirements
|
||||||
- ✅ Use Write() tool for layout-templates.json
|
- ✅ Use Write() tool for {task.output_file}
|
||||||
- ✅ One template per target (only selected concept)
|
- ✅ Single template for {task.target} variant {task.variant_id}
|
||||||
- ✅ Structure only, no visual styling
|
- ✅ Structure only, no visual styling
|
||||||
- ✅ Token-based CSS (var())
|
- ✅ Token-based CSS (var())
|
||||||
${extraction_mode == "explore" ? "- ✅ Maintain consistency with selected concepts" : ""}
|
- ✅ Maintain consistency with selected concept
|
||||||
`
|
`
|
||||||
```
|
```
|
||||||
|
|
||||||
**Output**: Agent generates `layout-templates.json` with one template per target
|
**Output**: Agent generates multiple layout template files (one per selected concept)
|
||||||
|
|
||||||
### Step 2: Write Output File
|
### Step 3: Verify Output Files
|
||||||
```bash
|
```bash
|
||||||
# Take JSON output from agent
|
# Count generated files
|
||||||
bash(echo '{agent_json_output}' > {base_path}/layout-extraction/layout-templates.json)
|
expected_count = total_tasks
|
||||||
|
actual_count = bash(ls {base_path}/layout-extraction/layout-*.json | wc -l)
|
||||||
|
|
||||||
# Verify output
|
# Verify all files were created
|
||||||
bash(test -f {base_path}/layout-extraction/layout-templates.json && echo "exists")
|
IF actual_count == expected_count:
|
||||||
bash(cat {base_path}/layout-extraction/layout-templates.json | grep -q "layout_templates" && echo "valid")
|
REPORT: "✓ All {expected_count} layout template files generated"
|
||||||
|
ELSE:
|
||||||
|
ERROR: "Expected {expected_count} files, found {actual_count}"
|
||||||
|
|
||||||
|
# Verify file structure (sample check)
|
||||||
|
bash(cat {base_path}/layout-extraction/layout-{first_target}-1.json | grep -q "variant_id" && echo "valid structure")
|
||||||
```
|
```
|
||||||
|
|
||||||
**Output**: `layout-templates.json` created and verified
|
**Output**: All layout template files created and verified (one file per selected concept)
|
||||||
|
|
||||||
## Completion
|
## Completion
|
||||||
|
|
||||||
@@ -543,9 +533,10 @@ bash(cat {base_path}/layout-extraction/layout-templates.json | grep -q "layout_t
|
|||||||
```javascript
|
```javascript
|
||||||
TodoWrite({todos: [
|
TodoWrite({todos: [
|
||||||
{content: "Setup and input validation", status: "completed", activeForm: "Validating inputs"},
|
{content: "Setup and input validation", status: "completed", activeForm: "Validating inputs"},
|
||||||
{content: "Layout research (explore mode)", status: "completed", activeForm: "Researching layout patterns"},
|
{content: "Layout concept analysis (agent)", status: "completed", activeForm: "Analyzing layout patterns"},
|
||||||
{content: "Layout analysis and synthesis (agent)", status: "completed", activeForm: "Generating layout templates"},
|
{content: "User selection confirmation", status: "completed", activeForm: "Confirming selections"},
|
||||||
{content: "Write layout-templates.json", status: "completed", activeForm: "Saving templates"}
|
{content: "Generate layout templates (parallel)", status: "completed", activeForm: "Generating templates"},
|
||||||
|
{content: "Verify output files", status: "completed", activeForm: "Verifying files"}
|
||||||
]});
|
]});
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -555,11 +546,9 @@ TodoWrite({todos: [
|
|||||||
|
|
||||||
Configuration:
|
Configuration:
|
||||||
- Session: {session_id}
|
- Session: {session_id}
|
||||||
- Extraction Mode: {extraction_mode} (imitate/explore)
|
|
||||||
- Device Type: {device_type}
|
- Device Type: {device_type}
|
||||||
- Targets: {targets}
|
- Targets: {targets.join(", ")}
|
||||||
- Variants per Target: {variants_count}
|
- Total Templates: {total_tasks} ({targets.length} targets with multi-selection)
|
||||||
- Total Templates: {targets.length × variants_count}
|
|
||||||
{IF has_urls AND dom_structure_available:
|
{IF has_urls AND dom_structure_available:
|
||||||
- 🔍 URL Mode: DOM structure extracted from {len(url_list)} URL(s)
|
- 🔍 URL Mode: DOM structure extracted from {len(url_list)} URL(s)
|
||||||
- Accuracy: Real flex/grid properties from live pages
|
- Accuracy: Real flex/grid properties from live pages
|
||||||
@@ -568,22 +557,28 @@ Configuration:
|
|||||||
- ⚠️ URL Mode: Chrome DevTools unavailable, used visual analysis fallback
|
- ⚠️ URL Mode: Chrome DevTools unavailable, used visual analysis fallback
|
||||||
}
|
}
|
||||||
|
|
||||||
{IF extraction_mode == "explore":
|
User Selections:
|
||||||
Layout Research:
|
{FOR each target in targets:
|
||||||
- {targets.length} inspiration files generated
|
- {target}: {selections_per_target[target].concept_names.join(", ")} ({selections_per_target[target].selected_indices.length} variants)
|
||||||
- Pattern search focused on {device_type} layouts
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Generated Templates:
|
Generated Templates:
|
||||||
{FOR each template: - Target: {template.target} | Variant: {template.variant_id} | Philosophy: {template.design_philosophy}}
|
{base_path}/layout-extraction/
|
||||||
|
{FOR each target in targets:
|
||||||
Output File:
|
{FOR each variant_id in range(1, selections_per_target[target].selected_indices.length + 1):
|
||||||
- {base_path}/layout-extraction/layout-templates.json
|
├── layout-{target}-{variant_id}.json
|
||||||
{IF dom_structure_available:
|
}
|
||||||
- {base_path}/.intermediates/layout-analysis/dom-structure-*.json ({len(url_list)} files)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Next: /workflow:ui-design:generate will combine these structural templates with style systems to produce final prototypes.
|
Intermediate Files:
|
||||||
|
- {base_path}/.intermediates/layout-analysis/
|
||||||
|
├── analysis-options.json (concept proposals)
|
||||||
|
├── user-selection.json (multi-selections per target)
|
||||||
|
{IF dom_structure_available:
|
||||||
|
├── dom-structure-*.json ({len(url_list)} DOM extracts)
|
||||||
|
}
|
||||||
|
|
||||||
|
Next: /workflow:ui-design:generate or /workflow:ui-design:batch-generate will combine these structural templates with design systems to produce final prototypes.
|
||||||
```
|
```
|
||||||
|
|
||||||
## Simple Bash Commands
|
## Simple Bash Commands
|
||||||
@@ -595,19 +590,18 @@ bash(find .workflow -type d -name "design-run-*" | head -1)
|
|||||||
|
|
||||||
# Create output directories
|
# Create output directories
|
||||||
bash(mkdir -p {base_path}/layout-extraction)
|
bash(mkdir -p {base_path}/layout-extraction)
|
||||||
bash(mkdir -p {base_path}/.intermediates/layout-analysis/inspirations) # explore mode only
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Validation Commands
|
### Validation Commands
|
||||||
```bash
|
```bash
|
||||||
# Check if already extracted
|
# Check if already extracted
|
||||||
bash(test -f {base_path}/layout-extraction/layout-templates.json && echo "exists")
|
bash(find {base_path}/layout-extraction -name "layout-*.json" -print -quit | grep -q . && echo "exists")
|
||||||
|
|
||||||
# Validate JSON structure
|
# Count generated files
|
||||||
bash(cat layout-templates.json | grep -q "layout_templates" && echo "valid")
|
bash(ls {base_path}/layout-extraction/layout-*.json | wc -l)
|
||||||
|
|
||||||
# Count templates
|
# Validate JSON structure (sample check)
|
||||||
bash(cat layout-templates.json | grep -c "\"target\":")
|
bash(cat {base_path}/layout-extraction/layout-{first_target}-1.json | grep -q "variant_id" && echo "valid")
|
||||||
```
|
```
|
||||||
|
|
||||||
### File Operations
|
### File Operations
|
||||||
@@ -616,9 +610,6 @@ bash(cat layout-templates.json | grep -c "\"target\":")
|
|||||||
bash(ls {images_pattern})
|
bash(ls {images_pattern})
|
||||||
Read({image_path})
|
Read({image_path})
|
||||||
|
|
||||||
# Write inspiration files (explore mode)
|
|
||||||
Write({base_path}/.intermediates/layout-analysis/inspirations/{target}-layout-ideas.txt, content)
|
|
||||||
|
|
||||||
# Write layout templates
|
# Write layout templates
|
||||||
bash(echo '{json}' > {base_path}/layout-extraction/layout-templates.json)
|
bash(echo '{json}' > {base_path}/layout-extraction/layout-templates.json)
|
||||||
```
|
```
|
||||||
@@ -629,28 +620,28 @@ bash(echo '{json}' > {base_path}/layout-extraction/layout-templates.json)
|
|||||||
{base_path}/
|
{base_path}/
|
||||||
├── .intermediates/ # Intermediate analysis files
|
├── .intermediates/ # Intermediate analysis files
|
||||||
│ └── layout-analysis/
|
│ └── layout-analysis/
|
||||||
│ ├── dom-structure-{target}.json # Extracted DOM structure (URL mode only)
|
│ ├── analysis-options.json # Generated layout concepts
|
||||||
│ └── inspirations/ # Explore mode only
|
│ ├── user-selection.json # User's multi-selections per target
|
||||||
│ └── {target}-layout-ideas.txt # Layout inspiration research
|
│ └── dom-structure-{target}.json # Extracted DOM structure (URL mode only)
|
||||||
└── layout-extraction/ # Final layout templates
|
└── layout-extraction/ # Final layout templates
|
||||||
├── layout-templates.json # Structural layout templates
|
└── layout-{target}-{variant}.json # Structural layout templates (one per selected concept)
|
||||||
└── layout-space-analysis.json # Layout directions (explore mode only)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## layout-templates.json Format
|
## Layout Template File Format
|
||||||
|
|
||||||
|
Each `layout-{target}-{variant}.json` file contains a single template:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"extraction_metadata": {
|
"extraction_metadata": {
|
||||||
"session_id": "...",
|
"session_id": "...",
|
||||||
"input_mode": "image|url|prompt|hybrid",
|
"input_mode": "image|url|prompt|hybrid",
|
||||||
"extraction_mode": "imitate|explore",
|
|
||||||
"device_type": "desktop|mobile|tablet|responsive",
|
"device_type": "desktop|mobile|tablet|responsive",
|
||||||
"timestamp": "...",
|
"timestamp": "...",
|
||||||
"variants_count": 3,
|
"target": "home",
|
||||||
"targets": ["home", "dashboard"]
|
"variant_id": "layout-1"
|
||||||
},
|
},
|
||||||
"layout_templates": [
|
"template":
|
||||||
{
|
{
|
||||||
"target": "home",
|
"target": "home",
|
||||||
"variant_id": "layout-1",
|
"variant_id": "layout-1",
|
||||||
@@ -705,8 +696,8 @@ ERROR: Invalid target name
|
|||||||
ERROR: Agent task failed
|
ERROR: Agent task failed
|
||||||
→ Check agent output, retry with simplified prompt
|
→ Check agent output, retry with simplified prompt
|
||||||
|
|
||||||
ERROR: MCP search failed (explore mode)
|
ERROR: MCP search failed
|
||||||
→ Check network, retry
|
→ Check network connection, retry command
|
||||||
```
|
```
|
||||||
|
|
||||||
### Recovery Strategies
|
### Recovery Strategies
|
||||||
@@ -720,11 +711,12 @@ ERROR: MCP search failed (explore mode)
|
|||||||
- **Hybrid Extraction Strategy** - Combines real DOM structure data with AI visual analysis
|
- **Hybrid Extraction Strategy** - Combines real DOM structure data with AI visual analysis
|
||||||
- **Accurate Layout Properties** - Chrome DevTools extracts real flex/grid configurations, bounds, and hierarchy
|
- **Accurate Layout Properties** - Chrome DevTools extracts real flex/grid configurations, bounds, and hierarchy
|
||||||
- **Separation of Concerns** - Decouples layout (structure) from style (visuals)
|
- **Separation of Concerns** - Decouples layout (structure) from style (visuals)
|
||||||
- **Structural Exploration** - Explore mode enables A/B testing of different layouts
|
- **Multi-Selection Workflow** - Generate N concepts → User selects multiple → Parallel template generation
|
||||||
|
- **Structural Exploration** - Enables A/B testing of different layouts through multi-selection
|
||||||
- **Token-Based Layout** - CSS uses `var()` placeholders for instant design system adaptation
|
- **Token-Based Layout** - CSS uses `var()` placeholders for instant design system adaptation
|
||||||
- **Device-Specific** - Tailored structures for different screen sizes
|
- **Device-Specific** - Tailored structures for different screen sizes
|
||||||
- **Graceful Fallback** - Falls back to visual analysis if Chrome DevTools unavailable
|
- **Graceful Fallback** - Falls back to visual analysis if Chrome DevTools unavailable
|
||||||
- **Foundation for Assembly** - Provides structural blueprint for refactored `generate` command
|
- **Foundation for Assembly** - Provides structural blueprint for prototype generation
|
||||||
- **Agent-Powered** - Deep structural analysis with AI
|
- **Agent-Powered** - Deep structural analysis with AI
|
||||||
|
|
||||||
## Integration
|
## Integration
|
||||||
@@ -732,17 +724,17 @@ ERROR: MCP search failed (explore mode)
|
|||||||
**Workflow Position**: Between style extraction and prototype generation
|
**Workflow Position**: Between style extraction and prototype generation
|
||||||
|
|
||||||
**New Workflow**:
|
**New Workflow**:
|
||||||
1. `/workflow:ui-design:style-extract` → `design-tokens.json` + `style-guide.md` (Complete design systems)
|
1. `/workflow:ui-design:style-extract` → Multiple `style-N/design-tokens.json` files (Complete design systems)
|
||||||
2. `/workflow:ui-design:layout-extract` → `layout-templates.json` (Structural templates)
|
2. `/workflow:ui-design:layout-extract` → Multiple `layout-{target}-{variant}.json` files (Structural templates)
|
||||||
3. `/workflow:ui-design:generate` (Pure assembler):
|
3. `/workflow:ui-design:generate` or `/workflow:ui-design:batch-generate` (Assembler):
|
||||||
- **Reads**: `design-tokens.json` + `layout-templates.json`
|
- **Reads**: All `design-tokens.json` files + all `layout-{target}-{variant}.json` files
|
||||||
- **Action**: For each style × layout combination:
|
- **Action**: For each style × layout combination:
|
||||||
1. Build HTML from `dom_structure`
|
1. Build HTML from `dom_structure`
|
||||||
2. Create layout CSS from `css_layout_rules`
|
2. Create layout CSS from `css_layout_rules`
|
||||||
3. Link design tokens CSS
|
3. Apply design tokens to CSS
|
||||||
4. Inject placeholder content
|
4. Generate complete prototypes
|
||||||
- **Output**: Complete token-driven HTML/CSS prototypes
|
- **Output**: Complete token-driven HTML/CSS prototypes
|
||||||
|
|
||||||
**Input**: Reference images, URLs, or text prompts
|
**Input**: Reference images, URLs, or text prompts
|
||||||
**Output**: `layout-templates.json` for `/workflow:ui-design:generate`
|
**Output**: `layout-{target}-{variant}.json` files for downstream generation commands
|
||||||
**Next**: `/workflow:ui-design:generate --session {session_id}`
|
**Next**: `/workflow:ui-design:generate` or `/workflow:ui-design:batch-generate`
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
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
|
||||||
argument-hint: "[--base-path <path>] [--session <id>] [--images "<glob>"] [--urls "<list>"] [--prompt "<desc>"] [--mode <imitate|explore>] [--variants <count>]"
|
argument-hint: "[--base-path <path>] [--session <id>] [--images "<glob>"] [--urls "<list>"] [--prompt "<desc>"] [--variants <count>]"
|
||||||
allowed-tools: TodoWrite(*), Read(*), Write(*), Glob(*), mcp__chrome-devtools__navigate_page(*), mcp__chrome-devtools__evaluate_script(*)
|
allowed-tools: TodoWrite(*), Read(*), Write(*), Glob(*), mcp__chrome-devtools__navigate_page(*), mcp__chrome-devtools__evaluate_script(*)
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -40,16 +40,10 @@ IF --urls:
|
|||||||
ELSE:
|
ELSE:
|
||||||
has_urls = false
|
has_urls = false
|
||||||
|
|
||||||
# Determine extraction mode
|
# Set variants count (default: 3, range: 1-5)
|
||||||
# Priority: --mode parameter → default "imitate"
|
# Behavior: Generate N design directions → User multi-select → Generate selected variants
|
||||||
extraction_mode = --mode OR "imitate" # "imitate" or "explore"
|
variants_count = --variants OR 3
|
||||||
|
VALIDATE: 1 <= variants_count <= 5
|
||||||
# Set variants count based on mode
|
|
||||||
IF extraction_mode == "imitate":
|
|
||||||
variants_count = 1 # Force single variant for imitate mode (ignore --variants)
|
|
||||||
ELSE IF extraction_mode == "explore":
|
|
||||||
variants_count = --variants OR 3 # Default to 3 for explore mode
|
|
||||||
VALIDATE: 1 <= variants_count <= 5
|
|
||||||
|
|
||||||
# Determine base path (auto-detect and convert to absolute)
|
# Determine base path (auto-detect and convert to absolute)
|
||||||
relative_path=$(find .workflow -type d -name "design-run-*" | head -1)
|
relative_path=$(find .workflow -type d -name "design-run-*" | head -1)
|
||||||
@@ -142,24 +136,15 @@ 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 (Explore Mode Only)
|
## Phase 1: Design Direction Generation
|
||||||
|
|
||||||
### Step 1: Check Extraction Mode
|
### Step 1: Load Project Context
|
||||||
```bash
|
|
||||||
# Check extraction mode
|
|
||||||
# extraction_mode == "imitate" → skip this phase
|
|
||||||
# extraction_mode == "explore" → execute this phase
|
|
||||||
```
|
|
||||||
|
|
||||||
**If imitate mode**: Skip to Phase 2
|
|
||||||
|
|
||||||
### Step 2: Load Project Context (Explore Mode)
|
|
||||||
```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)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 3: Generate Design Direction Options (Agent Task 1)
|
### Step 2: Generate Design Direction Options (Agent Task 1)
|
||||||
**Executor**: `Task(ui-design-agent)`
|
**Executor**: `Task(ui-design-agent)`
|
||||||
|
|
||||||
Launch agent to generate `variants_count` design direction options with previews:
|
Launch agent to generate `variants_count` design direction options with previews:
|
||||||
@@ -207,7 +192,7 @@ Task(ui-design-agent): `
|
|||||||
`
|
`
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 4: Verify Options File Created
|
### Step 3: Verify Options File Created
|
||||||
```bash
|
```bash
|
||||||
bash(test -f {base_path}/.intermediates/style-analysis/analysis-options.json && echo "created")
|
bash(test -f {base_path}/.intermediates/style-analysis/analysis-options.json && echo "created")
|
||||||
|
|
||||||
@@ -267,12 +252,12 @@ Please select the direction(s) you'd like to develop into complete design system
|
|||||||
|
|
||||||
### Step 3: Capture User Selection
|
### Step 3: Capture User Selection
|
||||||
```javascript
|
```javascript
|
||||||
// Use AskUserQuestion tool for selection
|
// Use AskUserQuestion tool for multi-selection
|
||||||
AskUserQuestion({
|
AskUserQuestion({
|
||||||
questions: [{
|
questions: [{
|
||||||
question: "Which design direction would you like to develop into a complete design system?",
|
question: "Which design direction(s) would you like to develop into complete design systems?",
|
||||||
header: "Style Choice",
|
header: "Style Choice",
|
||||||
multiSelect: false, // Single selection for Phase 1
|
multiSelect: true, // Multi-selection enabled (default behavior)
|
||||||
options: [
|
options: [
|
||||||
{FOR each direction:
|
{FOR each direction:
|
||||||
label: "Option {direction.index}: {direction.philosophy_name}",
|
label: "Option {direction.index}: {direction.philosophy_name}",
|
||||||
@@ -282,21 +267,25 @@ AskUserQuestion({
|
|||||||
}]
|
}]
|
||||||
})
|
})
|
||||||
|
|
||||||
// Parse user response (e.g., "Option 1: Minimalist & Airy")
|
// Parse user response (array of selections, e.g., ["Option 1: ...", "Option 3: ..."])
|
||||||
selected_option_text = user_answer
|
selected_options = user_answer
|
||||||
|
|
||||||
// Check for user cancellation
|
// Check for user cancellation
|
||||||
IF selected_option_text == null OR selected_option_text == "":
|
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 index from response format "Option N: Name"
|
// Extract option indices from array
|
||||||
match = selected_option_text.match(/Option (\d+):/)
|
selected_indices = []
|
||||||
IF match:
|
FOR each selected_option_text IN selected_options:
|
||||||
selected_index = parseInt(match[1])
|
match = selected_option_text.match(/Option (\d+):/)
|
||||||
ELSE:
|
IF match:
|
||||||
ERROR: "Invalid selection format. Expected 'Option N: ...' format"
|
selected_indices.push(parseInt(match[1]))
|
||||||
EXIT workflow
|
ELSE:
|
||||||
|
ERROR: "Invalid selection format. Expected 'Option N: ...' format"
|
||||||
|
EXIT workflow
|
||||||
|
|
||||||
|
REPORT: "✅ Selected {selected_indices.length} design direction(s)"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 4: Write User Selection File
|
### Step 4: Write User Selection File
|
||||||
@@ -305,10 +294,11 @@ ELSE:
|
|||||||
selection_data = {
|
selection_data = {
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"selected_at": "{current_timestamp}",
|
"selected_at": "{current_timestamp}",
|
||||||
"selection_type": "single",
|
"selection_type": "multi",
|
||||||
"session_id": "{session_id}"
|
"session_id": "{session_id}",
|
||||||
|
"selection_count": selected_indices.length
|
||||||
},
|
},
|
||||||
"selected_indices": [selected_index],
|
"selected_indices": selected_indices, // Array of selected indices
|
||||||
"refinements": {
|
"refinements": {
|
||||||
"enabled": false
|
"enabled": false
|
||||||
}
|
}
|
||||||
@@ -325,99 +315,87 @@ bash(test -f {base_path}/.intermediates/style-analysis/user-selection.json && ec
|
|||||||
```
|
```
|
||||||
✅ Selection recorded!
|
✅ Selection recorded!
|
||||||
|
|
||||||
You selected: Option {selected_index} - {selected_direction.philosophy_name}
|
You selected {selected_indices.length} design direction(s):
|
||||||
|
{FOR each index IN selected_indices:
|
||||||
|
• Option {index} - {design_directions[index-1].philosophy_name}
|
||||||
|
}
|
||||||
|
|
||||||
Proceeding to generate complete design system based on your selection...
|
Proceeding to generate {selected_indices.length} complete design system(s)...
|
||||||
```
|
```
|
||||||
|
|
||||||
**Output**: `user-selection.json` with user's choice
|
**Output**: `user-selection.json` with user's multi-selection
|
||||||
|
|
||||||
## Phase 2: Design System Generation (Agent Task 2)
|
## Phase 2: Design System Generation (Agent Task 2)
|
||||||
|
|
||||||
**Executor**: `Task(ui-design-agent)` for selected variant(s)
|
**Executor**: `Task(ui-design-agent)` for selected variant(s)
|
||||||
|
|
||||||
### Step 1: Load User Selection (Explore Mode)
|
### Step 1: Load User Selection
|
||||||
```bash
|
```bash
|
||||||
# For explore mode, read user selection
|
# Read user selection
|
||||||
IF extraction_mode == "explore":
|
selection = Read({base_path}/.intermediates/style-analysis/user-selection.json)
|
||||||
selection = Read({base_path}/.intermediates/style-analysis/user-selection.json)
|
selected_indices = selection.selected_indices # Array of selected indices
|
||||||
selected_indices = selection.selected_indices
|
|
||||||
refinements = selection.refinements
|
|
||||||
|
|
||||||
# Also read the selected direction details from options
|
# Read the selected direction details from options
|
||||||
options = Read({base_path}/.intermediates/style-analysis/analysis-options.json)
|
options = Read({base_path}/.intermediates/style-analysis/analysis-options.json)
|
||||||
selected_directions = [options.design_directions[i-1] for i in selected_indices] # 0-indexed
|
selected_directions = [options.design_directions[i-1] for i in selected_indices] # 0-indexed array
|
||||||
|
|
||||||
# For Phase 1, we only allow single selection
|
actual_variants_count = selected_indices.length
|
||||||
selected_direction = selected_directions[0]
|
REPORT: "📦 Generating {actual_variants_count} design system(s)..."
|
||||||
actual_variants_count = 1
|
|
||||||
ELSE:
|
|
||||||
# Imitate mode - generate single variant without selection
|
|
||||||
selected_direction = null
|
|
||||||
actual_variants_count = 1
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: Create Output Directory
|
### Step 2: Create Output Directories
|
||||||
```bash
|
```bash
|
||||||
# Create directory for selected variant only
|
# Create directories for each selected variant
|
||||||
bash(mkdir -p {base_path}/style-extraction/style-1)
|
FOR index IN 1..actual_variants_count:
|
||||||
|
bash(mkdir -p {base_path}/style-extraction/style-{index})
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 3: Launch Agent Task
|
### Step 3: Launch Agent Tasks (Parallel)
|
||||||
Generate design system for selected direction:
|
Generate design systems for ALL selected directions in parallel (max 5 concurrent):
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
Task(ui-design-agent): `
|
// Launch parallel tasks, one for each selected direction
|
||||||
[DESIGN_SYSTEM_GENERATION_TASK]
|
FOR variant_index IN 1..actual_variants_count:
|
||||||
Generate production-ready design system based on user-selected direction
|
selected_direction = selected_directions[variant_index - 1] // 0-indexed
|
||||||
|
|
||||||
SESSION: {session_id} | MODE: {extraction_mode} | BASE_PATH: {base_path}
|
Task(ui-design-agent): `
|
||||||
|
[DESIGN_SYSTEM_GENERATION_TASK #{variant_index}/{actual_variants_count}]
|
||||||
|
Generate production-ready design system based on user-selected direction
|
||||||
|
|
||||||
${extraction_mode == "explore" ? `
|
SESSION: {session_id} | VARIANT: {variant_index}/{actual_variants_count} | BASE_PATH: {base_path}
|
||||||
USER SELECTION:
|
|
||||||
- Selected Direction: ${selected_direction.philosophy_name}
|
|
||||||
- Design Attributes: ${JSON.stringify(selected_direction.design_attributes)}
|
|
||||||
- Search Keywords: ${selected_direction.search_keywords.join(", ")}
|
|
||||||
- Anti-keywords: ${selected_direction.anti_keywords.join(", ")}
|
|
||||||
- Rationale: ${selected_direction.rationale}
|
|
||||||
- Preview Colors: Primary=${selected_direction.preview.primary_color}, Accent=${selected_direction.preview.accent_color}
|
|
||||||
- Preview Typography: Heading=${selected_direction.preview.font_family_heading}, Body=${selected_direction.preview.font_family_body}
|
|
||||||
- Preview Border Radius: ${selected_direction.preview.border_radius_base}
|
|
||||||
|
|
||||||
${refinements.enabled ? `
|
USER SELECTION:
|
||||||
USER REFINEMENTS:
|
- Selected Direction: ${selected_direction.philosophy_name}
|
||||||
${refinements.primary_color ? "- Primary Color Override: " + refinements.primary_color : ""}
|
- Design Attributes: ${JSON.stringify(selected_direction.design_attributes)}
|
||||||
${refinements.font_family_heading ? "- Heading Font Override: " + refinements.font_family_heading : ""}
|
- Search Keywords: ${selected_direction.search_keywords.join(", ")}
|
||||||
${refinements.font_family_body ? "- Body Font Override: " + refinements.font_family_body : ""}
|
- Anti-keywords: ${selected_direction.anti_keywords.join(", ")}
|
||||||
` : ""}
|
- Rationale: ${selected_direction.rationale}
|
||||||
` : ""}
|
- Preview Colors: Primary=${selected_direction.preview.primary_color}, Accent=${selected_direction.preview.accent_color}
|
||||||
|
- Preview Typography: Heading=${selected_direction.preview.font_family_heading}, Body=${selected_direction.preview.font_family_body}
|
||||||
|
- Preview Border Radius: ${selected_direction.preview.border_radius_base}
|
||||||
|
|
||||||
## Input Analysis
|
## Input Analysis
|
||||||
- Input mode: {input_mode} (image/text/hybrid${has_urls ? "/url" : ""})
|
- Input mode: {input_mode} (image/text/hybrid${has_urls ? "/url" : ""})
|
||||||
- Visual references: {loaded_images OR prompt_guidance}
|
- Visual references: {loaded_images OR prompt_guidance}
|
||||||
${computed_styles_available ? "- Computed styles: Use as ground truth (Read from .intermediates/style-analysis/computed-styles.json)" : ""}
|
${computed_styles_available ? "- Computed styles: Use as ground truth (Read from .intermediates/style-analysis/computed-styles.json)" : ""}
|
||||||
|
|
||||||
## Generation Rules
|
## Generation Rules
|
||||||
${extraction_mode == "explore" ? `
|
- Develop the selected design direction into a complete design system
|
||||||
- **Explore Mode**: Develop the selected design direction into a complete design system
|
- Use preview elements as foundation and expand with full token coverage
|
||||||
- Use preview elements as foundation and expand with full token coverage
|
- Apply design_attributes to all token values:
|
||||||
- Apply design_attributes to all token values:
|
* color_saturation → OKLCH chroma values
|
||||||
* color_saturation → OKLCH chroma values
|
* visual_weight → font weights, shadow depths
|
||||||
* visual_weight → font weights, shadow depths
|
* density → spacing scale compression/expansion
|
||||||
* density → spacing scale compression/expansion
|
* formality → typography choices, border radius
|
||||||
* formality → typography choices, border radius
|
* organic_geometric → border radius, shape patterns
|
||||||
* organic_geometric → border radius, shape patterns
|
* innovation → token naming, experimental values
|
||||||
* innovation → token naming, experimental values
|
- Honor search_keywords for design inspiration
|
||||||
- Honor search_keywords for design inspiration
|
- Avoid anti_keywords patterns
|
||||||
- Avoid anti_keywords patterns
|
- All colors in OKLCH format ${computed_styles_available ? "(convert from computed RGB)" : ""}
|
||||||
` : `
|
- WCAG AA compliance: 4.5:1 text contrast, 3:1 UI contrast
|
||||||
- **Imitate Mode**: High-fidelity replication of reference design
|
|
||||||
${computed_styles_available ? "- Use computed styles as ground truth for all measurements" : "- Use visual inference for measurements"}
|
|
||||||
`}
|
|
||||||
- All colors in OKLCH format ${computed_styles_available ? "(convert from computed RGB)" : ""}
|
|
||||||
- WCAG AA compliance: 4.5:1 text contrast, 3:1 UI contrast
|
|
||||||
|
|
||||||
## Generate
|
## Generate
|
||||||
Create complete design system in {base_path}/style-extraction/style-1/
|
Create complete design system in {base_path}/style-extraction/style-{variant_index}/
|
||||||
|
|
||||||
1. **design-tokens.json**:
|
1. **design-tokens.json**:
|
||||||
- Complete token structure with ALL fields:
|
- Complete token structure with ALL fields:
|
||||||
@@ -450,14 +428,13 @@ Task(ui-design-agent): `
|
|||||||
|
|
||||||
## Critical Requirements
|
## Critical Requirements
|
||||||
- ✅ Use Write() tool immediately for each file
|
- ✅ Use Write() tool immediately for each file
|
||||||
- ✅ Write to style-1/ directory (single output)
|
- ✅ Write to style-{variant_index}/ directory
|
||||||
- ❌ NO external research or MCP calls (pure AI generation)
|
- ❌ NO external research or MCP calls (pure AI generation)
|
||||||
- ✅ Maintain consistency with user-selected direction
|
- ✅ Maintain consistency with user-selected direction
|
||||||
${refinements.enabled ? "- ✅ Apply user refinements precisely" : ""}
|
`
|
||||||
`
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**Output**: Agent generates 2 files (design-tokens.json, style-guide.md) for selected direction
|
**Output**: {actual_variants_count} parallel agent tasks generate 2 files each (design-tokens.json, style-guide.md)
|
||||||
|
|
||||||
## Phase 3: Verify Output
|
## Phase 3: Verify Output
|
||||||
|
|
||||||
@@ -561,8 +538,10 @@ bash(cat {base_path}/style-extraction/style-1/design-tokens.json | grep -q "colo
|
|||||||
# Load brainstorming context
|
# Load brainstorming context
|
||||||
bash(test -f .brainstorming/role analysis documents && cat it)
|
bash(test -f .brainstorming/role analysis documents && cat it)
|
||||||
|
|
||||||
# Create directories
|
# Create directories (example for multiple variants)
|
||||||
bash(mkdir -p {base_path}/style-extraction/style-{{1..3}})
|
bash(mkdir -p {base_path}/style-extraction/style-1)
|
||||||
|
bash(mkdir -p {base_path}/style-extraction/style-2)
|
||||||
|
bash(mkdir -p {base_path}/style-extraction/style-3)
|
||||||
|
|
||||||
# Verify output
|
# Verify output
|
||||||
bash(ls {base_path}/style-extraction/style-1/)
|
bash(ls {base_path}/style-extraction/style-1/)
|
||||||
|
|||||||
Reference in New Issue
Block a user