mirror of
https://github.com/catlog22/Claude-Code-Workflow.git
synced 2026-02-05 01:50:27 +08:00
feat: Add ui-generate-preview-v2.sh script for style-centric prototype preview generation
- Implemented a new script to generate compare.html and index.html for UI prototypes. - Auto-detects styles, layouts, and targets from HTML file patterns. - Generates an interactive comparison matrix and a simple index of prototypes. - Includes a detailed PREVIEW.md guide with usage instructions and file structure.
This commit is contained in:
377
.claude/commands/workflow/ui-design/explore-auto-v2.md
Normal file
377
.claude/commands/workflow/ui-design/explore-auto-v2.md
Normal file
@@ -0,0 +1,377 @@
|
||||
---
|
||||
name: explore-auto-v2
|
||||
description: Exploratory UI design workflow with style-centric batch generation
|
||||
usage: /workflow:ui-design:explore-auto-v2 [--prompt "<desc>"] [--images "<glob>"] [--targets "<list>"] [--target-type "page|component"] [--session <id>] [--style-variants <count>] [--layout-variants <count>] [--batch-plan]
|
||||
examples:
|
||||
- /workflow:ui-design:explore-auto-v2 --prompt "Generate 3 style variants for modern blog: home, article, author"
|
||||
- /workflow:ui-design:explore-auto-v2 --prompt "SaaS dashboard and settings with 2 layout options"
|
||||
- /workflow:ui-design:explore-auto-v2 --images "refs/*.png" --prompt "E-commerce: home, product, cart" --style-variants 3 --layout-variants 3
|
||||
- /workflow:ui-design:explore-auto-v2 --session WFS-auth --images "refs/*.png"
|
||||
- /workflow:ui-design:explore-auto-v2 --targets "navbar,hero" --target-type "component" --style-variants 3 --layout-variants 2
|
||||
allowed-tools: SlashCommand(*), TodoWrite(*), Read(*), Bash(*), Glob(*), Write(*), Task(conceptual-planning-agent)
|
||||
---
|
||||
|
||||
# UI Design Auto Workflow Command
|
||||
|
||||
## Overview & Execution Model
|
||||
|
||||
**Fully autonomous orchestrator**: Executes all design phases sequentially from style extraction to design integration, with optional batch planning.
|
||||
|
||||
**Unified Target System**: Generates `style_variants × layout_variants × targets` prototypes, where targets can be:
|
||||
- **Pages** (full-page layouts): home, dashboard, settings, etc.
|
||||
- **Components** (isolated UI elements): navbar, card, hero, form, etc.
|
||||
- **Mixed**: Can combine both in a single workflow
|
||||
|
||||
**Autonomous Flow** (⚠️ CONTINUOUS EXECUTION - DO NOT STOP):
|
||||
1. User triggers: `/workflow:ui-design:explore-auto-v2 [params]`
|
||||
2. Phase 1 (style-extract) → **WAIT for completion** → Auto-continues
|
||||
3. Phase 2 (style-consolidate) → **WAIT for completion** → Auto-continues
|
||||
4. **Phase 3 (ui-generate-v2)** → **WAIT for completion** → Auto-continues
|
||||
5. Phase 4 (design-update) → **WAIT for completion** → Auto-continues
|
||||
6. Phase 5 (batch-plan, optional) → Reports completion
|
||||
|
||||
**Auto-Continue Mechanism**: TodoWrite tracks phase status. Upon each phase completion, you MUST immediately construct and execute the next phase command. No user intervention required. The workflow is NOT complete until reaching Phase 4 (or Phase 5 if --batch-plan).
|
||||
|
||||
**Target Type Detection**: Automatically inferred from prompt/targets, or explicitly set via `--target-type`.
|
||||
|
||||
## Core Rules
|
||||
|
||||
1. **Start Immediately**: TodoWrite initialization → Phase 1 execution
|
||||
2. **No Preliminary Validation**: Sub-commands handle their own validation
|
||||
3. **Parse & Pass**: Extract data from each output for next phase
|
||||
4. **Default to All**: When selecting variants/prototypes, use ALL generated items
|
||||
5. **Track Progress**: Update TodoWrite after each phase
|
||||
6. **⚠️ CRITICAL: DO NOT STOP** - This is a continuous multi-phase workflow. After each SlashCommand completes, you MUST wait for completion, then immediately execute the next phase. Workflow is NOT complete until Phase 4 (or Phase 5 if --batch-plan).
|
||||
|
||||
## Parameter Requirements
|
||||
|
||||
**Optional Parameters** (all have smart defaults):
|
||||
- `--targets "<list>"`: Comma-separated targets (pages/components) to generate (inferred from prompt/session if omitted)
|
||||
- `--target-type "page|component|auto"`: Explicitly set target type (default: `auto` - intelligent detection)
|
||||
- `--session <id>`: Workflow session ID (standalone mode if omitted)
|
||||
- `--images "<glob>"`: Reference image paths (default: `design-refs/*`)
|
||||
- `--prompt "<description>"`: Design style and target description
|
||||
- `--style-variants <count>`: Style variants (default: inferred from prompt or 3, range: 1-5)
|
||||
- `--layout-variants <count>`: Layout variants per style (default: inferred or 3, range: 1-5)
|
||||
- `--batch-plan`: Auto-generate implementation tasks after design-update
|
||||
|
||||
**Legacy Parameters** (maintained for backward compatibility):
|
||||
- `--pages "<list>"`: Alias for `--targets` with `--target-type page`
|
||||
- `--components "<list>"`: Alias for `--targets` with `--target-type component`
|
||||
|
||||
**Input Rules**:
|
||||
- Must provide at least one: `--images` or `--prompt` or `--targets`
|
||||
- Multiple parameters can be combined for guided analysis
|
||||
- If `--targets` not provided, intelligently inferred from prompt/session
|
||||
|
||||
**Supported Target Types**:
|
||||
- **Pages** (full layouts): home, dashboard, settings, profile, login, etc.
|
||||
- **Components** (UI elements):
|
||||
- Navigation: navbar, header, menu, breadcrumb, tabs, sidebar
|
||||
- Content: hero, card, list, table, grid, timeline
|
||||
- Input: form, search, filter, input-group
|
||||
- Feedback: modal, alert, toast, badge, progress
|
||||
- Media: gallery, carousel, video-player, image-card
|
||||
- Other: footer, pagination, dropdown, tooltip, avatar
|
||||
|
||||
**Intelligent Prompt Parsing**: Extracts variant counts from natural language:
|
||||
- "Generate **3 style variants**" → `--style-variants 3`
|
||||
- "**2 layout options**" → `--layout-variants 2`
|
||||
- "Create **4 styles** with **2 layouts each**" → `--style-variants 4 --layout-variants 2`
|
||||
- Explicit flags override prompt inference
|
||||
|
||||
## Execution Modes
|
||||
|
||||
**Matrix Mode** (style-centric):
|
||||
- Generates `style_variants × layout_variants × targets` prototypes
|
||||
- **Phase 1**: `style_variants` style options with design_attributes (extract)
|
||||
- **Phase 2**: `style_variants` independent design systems (consolidate)
|
||||
- **Phase 3**: Style-centric batch generation (generate-v2)
|
||||
- Sub-phase 1: `targets × layout_variants` target-specific layout plans
|
||||
- **Sub-phase 2**: `S` style-centric agents (each handles `L×T` combinations)
|
||||
- Sub-phase 3: `style_variants × layout_variants × targets` final prototypes
|
||||
- Performance: Efficient parallel execution with S agents
|
||||
- Quality: HTML structure adapts to design_attributes
|
||||
- Pages: Full-page layouts with complete structure
|
||||
- Components: Isolated elements with minimal wrapper
|
||||
|
||||
**Integrated vs. Standalone**:
|
||||
- `--session` flag determines session integration or standalone execution
|
||||
|
||||
## 6-Phase Execution
|
||||
|
||||
### Phase 0a: Intelligent Prompt Parsing
|
||||
```bash
|
||||
# Parse variant counts from prompt or use explicit/default values
|
||||
IF --prompt AND (NOT --style-variants OR NOT --layout-variants):
|
||||
style_variants = regex_extract(prompt, r"(\d+)\s*style") OR --style-variants OR 3
|
||||
layout_variants = regex_extract(prompt, r"(\d+)\s*layout") OR --layout-variants OR 3
|
||||
ELSE:
|
||||
style_variants = --style-variants OR 3
|
||||
layout_variants = --layout-variants OR 3
|
||||
|
||||
VALIDATE: 1 <= style_variants <= 5, 1 <= layout_variants <= 5
|
||||
```
|
||||
|
||||
### Phase 0b: Run Initialization & Directory Setup
|
||||
```bash
|
||||
run_id = "run-$(date +%Y%m%d-%H%M%S)"
|
||||
base_path = --session ? ".workflow/WFS-{session}/design-${run_id}" : ".workflow/.design/${run_id}"
|
||||
|
||||
Bash(mkdir -p "${base_path}/{style-extraction,style-consolidation,prototypes}")
|
||||
|
||||
Write({base_path}/.run-metadata.json): {
|
||||
"run_id": "${run_id}", "session_id": "${session_id}", "timestamp": "...",
|
||||
"workflow": "ui-design:auto-v2",
|
||||
"version": "2.0",
|
||||
"architecture": "style-centric-batch-generation",
|
||||
"parameters": { "style_variants": ${style_variants}, "layout_variants": ${layout_variants},
|
||||
"targets": "${inferred_target_list}", "target_type": "${target_type}",
|
||||
"prompt": "${prompt_text}", "images": "${images_pattern}" },
|
||||
"status": "in_progress",
|
||||
"performance_mode": "optimized"
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 0c: Unified Target Inference with Intelligent Type Detection
|
||||
```bash
|
||||
# Priority: --pages/--components (legacy) → --targets → --prompt analysis → synthesis → default
|
||||
target_list = []; target_type = "auto"; target_source = "none"
|
||||
|
||||
# Step 1-2: Explicit parameters (legacy or unified)
|
||||
IF --pages: target_list = split(--pages); target_type = "page"; target_source = "explicit_legacy"
|
||||
ELSE IF --components: target_list = split(--components); target_type = "component"; target_source = "explicit_legacy"
|
||||
ELSE IF --targets:
|
||||
target_list = split(--targets); target_source = "explicit"
|
||||
target_type = --target-type != "auto" ? --target-type : detect_target_type(target_list)
|
||||
|
||||
# Step 3: Prompt analysis (Claude internal analysis)
|
||||
ELSE IF --prompt:
|
||||
analysis_result = analyze_prompt("{prompt_text}") # Extract targets, types, purpose
|
||||
target_list = analysis_result.targets
|
||||
target_type = analysis_result.primary_type OR detect_target_type(target_list)
|
||||
target_source = "prompt_analysis"
|
||||
|
||||
# Step 4: Session synthesis
|
||||
ELSE IF --session AND exists(synthesis-specification.md):
|
||||
target_list = extract_targets_from_synthesis(); target_type = "page"; target_source = "synthesis"
|
||||
|
||||
# Step 5: Fallback
|
||||
IF NOT target_list: target_list = ["home"]; target_type = "page"; target_source = "default"
|
||||
|
||||
# Validate and clean
|
||||
validated_targets = [normalize(t) for t in target_list if is_valid(t)]
|
||||
IF NOT validated_targets: validated_targets = ["home"]; target_type = "page"
|
||||
IF --target-type != "auto": target_type = --target-type
|
||||
|
||||
# Interactive confirmation
|
||||
DISPLAY_CONFIRMATION(target_type, target_source, validated_targets):
|
||||
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
"{emoji} {LABEL} CONFIRMATION (v2.0 Style-Centric)"
|
||||
"Type: {target_type} | Source: {target_source}"
|
||||
"Targets ({count}): {', '.join(validated_targets)}"
|
||||
"Performance: {style_variants} agent calls (vs {layout_variants * len(validated_targets)} in v1.0)"
|
||||
"Options: 'continue/yes' | 'targets: a,b' | 'skip: x' | 'add: y' | 'type: page|component'"
|
||||
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
user_input = WAIT_FOR_USER_INPUT()
|
||||
|
||||
# Process user modifications
|
||||
MATCH user_input:
|
||||
"continue|yes|ok" → proceed
|
||||
"targets: ..." → validated_targets = parse_new_list()
|
||||
"skip: ..." → validated_targets = remove_items()
|
||||
"add: ..." → validated_targets = add_items()
|
||||
"type: ..." → target_type = extract_type()
|
||||
default → proceed with current list
|
||||
|
||||
STORE: inferred_target_list, target_type, target_inference_source
|
||||
```
|
||||
|
||||
**Helper Function: detect_target_type()**
|
||||
```bash
|
||||
detect_target_type(target_list):
|
||||
page_keywords = ["home", "dashboard", "settings", "profile", "login", "signup", "auth", ...]
|
||||
component_keywords = ["navbar", "header", "footer", "hero", "card", "button", "form", ...]
|
||||
|
||||
page_matches = count_matches(target_list, page_keywords + ["page", "screen", "view"])
|
||||
component_matches = count_matches(target_list, component_keywords + ["component", "widget"])
|
||||
|
||||
RETURN "component" IF component_matches > page_matches ELSE "page"
|
||||
```
|
||||
|
||||
### Phase 1: Style Extraction
|
||||
```bash
|
||||
command = "/workflow:ui-design:extract --base-path \"{base_path}\" " +
|
||||
(--images ? "--images \"{images}\" " : "") +
|
||||
(--prompt ? "--prompt \"{prompt}\" " : "") +
|
||||
"--variants {style_variants} --mode explore"
|
||||
SlashCommand(command)
|
||||
|
||||
# Output: {style_variants} style cards with design_attributes
|
||||
# WAIT for extract command to complete, then IMMEDIATELY continue to Phase 2
|
||||
# DO NOT STOP - Phase 2 must execute automatically
|
||||
```
|
||||
|
||||
### Phase 2: Style Consolidation
|
||||
```bash
|
||||
command = "/workflow:ui-design:consolidate --base-path \"{base_path}\" " +
|
||||
"--variants {style_variants}"
|
||||
SlashCommand(command)
|
||||
|
||||
# Output: {style_variants} independent design systems with tokens.css
|
||||
# WAIT for consolidate command to complete, then IMMEDIATELY continue to Phase 3
|
||||
# DO NOT STOP - Phase 3 must execute automatically
|
||||
```
|
||||
|
||||
### Phase 3: Style-Centric Matrix UI Generation
|
||||
```bash
|
||||
targets_string = ",".join(inferred_target_list)
|
||||
command = "/workflow:ui-design:generate-v2 --base-path \"{base_path}\" " +
|
||||
"--targets \"{targets_string}\" --target-type \"{target_type}\" " +
|
||||
"--style-variants {style_variants} --layout-variants {layout_variants}"
|
||||
|
||||
total = style_variants × layout_variants × len(inferred_target_list)
|
||||
agent_calls = style_variants
|
||||
|
||||
REPORT: "🚀 Phase 3: {type_icon} {targets_string} | Matrix: {s}×{l}×{n} = {total} prototypes"
|
||||
REPORT: " → Agent calls: {agent_calls} style-centric agents"
|
||||
REPORT: " → Layout planning: {len(inferred_target_list)}×{layout_variants} target-specific layouts"
|
||||
REPORT: " → Style-centric generation: Each of {style_variants} agents handles {layout_variants}×{len(inferred_target_list)} combinations"
|
||||
|
||||
SlashCommand(command)
|
||||
|
||||
# WAIT for generate-v2 command to complete, then IMMEDIATELY continue to Phase 4
|
||||
# DO NOT STOP - Phase 4 must execute automatically
|
||||
# Output:
|
||||
# - {target}-layout-{l}.json (target-specific layout plans)
|
||||
# - {target}-style-{s}-layout-{l}.html (final prototypes with style-aware structure)
|
||||
# - compare.html (interactive matrix view)
|
||||
# - PREVIEW.md (usage instructions)
|
||||
```
|
||||
|
||||
### Phase 4: Design System Integration
|
||||
```bash
|
||||
command = "/workflow:ui-design:update" + (--session ? " --session {session_id}" : "")
|
||||
SlashCommand(command)
|
||||
|
||||
# WAIT for update command to complete
|
||||
# If --batch-plan flag present: IMMEDIATELY continue to Phase 5
|
||||
# If no --batch-plan: Workflow complete, display final report
|
||||
```
|
||||
|
||||
### Phase 5: Batch Task Generation (Optional)
|
||||
```bash
|
||||
IF --batch-plan:
|
||||
FOR target IN inferred_target_list:
|
||||
task_desc = "Implement {target} {target_type} based on design system"
|
||||
SlashCommand("/workflow:plan --agent \"{task_desc}\"")
|
||||
```
|
||||
|
||||
## TodoWrite Pattern
|
||||
```javascript
|
||||
// Initialize at workflow start to track multi-phase execution
|
||||
TodoWrite({todos: [
|
||||
{"content": "Execute style extraction", "status": "in_progress", "activeForm": "Executing..."},
|
||||
{"content": "Execute style consolidation", "status": "pending", "activeForm": "Executing..."},
|
||||
{"content": "Execute style-centric UI generation", "status": "pending", "activeForm": "Executing..."},
|
||||
{"content": "Execute design integration", "status": "pending", "activeForm": "Executing..."}
|
||||
]})
|
||||
|
||||
// ⚠️ CRITICAL: After EACH phase completion, you MUST:
|
||||
// 1. Update current phase: status → "completed"
|
||||
// 2. Update next phase: status → "in_progress"
|
||||
// 3. Continue to execute next phase immediately
|
||||
// This ensures continuous workflow tracking and prevents premature stopping
|
||||
```
|
||||
|
||||
## Key Features
|
||||
|
||||
- **🚀 Performance**: Style-centric batch generation with S agent calls
|
||||
- **🎨 Style-Aware**: HTML structure adapts to design_attributes
|
||||
- **✅ Perfect Consistency**: Each style by single agent
|
||||
- **📦 Autonomous**: No user intervention required between phases
|
||||
- **🧠 Intelligent**: Parses natural language, infers targets/types
|
||||
- **🔄 Reproducible**: Deterministic flow with isolated run directories
|
||||
- **🎯 Flexible**: Supports pages, components, or mixed targets
|
||||
|
||||
## Examples
|
||||
|
||||
### 1. Page Mode (Prompt Inference)
|
||||
```bash
|
||||
/workflow:ui-design:explore-auto-v2 --prompt "Modern blog: home, article, author"
|
||||
# Result: 27 prototypes (3×3×3)
|
||||
```
|
||||
|
||||
### 2. Custom Matrix with Session
|
||||
```bash
|
||||
/workflow:ui-design:explore-auto-v2 --session WFS-ecommerce --images "refs/*.png" --style-variants 2 --layout-variants 2
|
||||
# Result: 2×2×N prototypes
|
||||
```
|
||||
|
||||
### 3. Component Mode
|
||||
```bash
|
||||
/workflow:ui-design:explore-auto-v2 --targets "navbar,hero" --target-type "component" --style-variants 3 --layout-variants 2
|
||||
# Result: 12 prototypes (3×2×2) - components with minimal wrapper
|
||||
```
|
||||
|
||||
### 4. Intelligent Parsing + Batch Planning
|
||||
```bash
|
||||
/workflow:ui-design:explore-auto-v2 --prompt "Create 4 styles with 2 layouts for dashboard and settings" --batch-plan
|
||||
# Result: 16 prototypes (4×2×2) + auto-generated tasks
|
||||
```
|
||||
|
||||
### 5. Large Scale
|
||||
```bash
|
||||
/workflow:ui-design:explore-auto-v2 --targets "home,dashboard,settings,profile" --style-variants 3 --layout-variants 3
|
||||
# Result: 36 prototypes (3×3×4)
|
||||
```
|
||||
|
||||
## Completion Output
|
||||
```
|
||||
✅ UI Design Explore-Auto Workflow Complete!
|
||||
|
||||
Architecture: Style-Centric Batch Generation
|
||||
Run ID: {run_id} | Session: {session_id or "standalone"}
|
||||
Type: {icon} {target_type} | Matrix: {s}×{l}×{n} = {total} prototypes
|
||||
|
||||
Phase 1: {s} style variants with design_attributes (extract)
|
||||
Phase 2: {s} design systems with tokens.css (consolidate)
|
||||
Phase 3: Style-centric batch generation (generate-v2)
|
||||
- {n}×{l} target-specific layout plans
|
||||
- {s} style-centric agents (each handled {l}×{n} combinations)
|
||||
- {s}×{l}×{n} = {total} final prototypes with style-aware structure
|
||||
Phase 4: Brainstorming artifacts updated
|
||||
[Phase 5: {n} implementation tasks created] # if --batch-plan
|
||||
|
||||
Agent Execution:
|
||||
✅ Style-centric agents: {s} agents total
|
||||
✅ Each agent handles: {l}×{n} combinations
|
||||
|
||||
Design Quality:
|
||||
✅ Style-Aware Structure: HTML adapts to design_attributes
|
||||
✅ Style Consistency: PERFECT (each style by single agent)
|
||||
✅ Token-Driven Styling: 100% var() usage
|
||||
|
||||
📂 {base_path}/
|
||||
├── style-extraction/ ({s} style cards + design-space-analysis.json)
|
||||
├── style-consolidation/ ({s} design systems with tokens.css)
|
||||
├── prototypes/
|
||||
│ ├── _templates/ ({n}×{l} layout JSON files)
|
||||
│ └── ... ({total} final prototypes)
|
||||
└── .run-metadata.json
|
||||
|
||||
🌐 Preview: {base_path}/prototypes/compare.html
|
||||
- Interactive {s}×{l} matrix view
|
||||
- Side-by-side comparison
|
||||
- Target-specific layouts with style-aware structure
|
||||
- Toggle between {n} targets
|
||||
|
||||
{icon} Targets: {', '.join(targets)} (type: {target_type})
|
||||
- Each target has {l} custom-designed layouts
|
||||
- Each style × target × layout has unique HTML structure (not just CSS!)
|
||||
- Layout plans stored as structured JSON
|
||||
|
||||
Next: [/workflow:execute] OR [Open compare.html → Select → /workflow:plan]
|
||||
```
|
||||
|
||||
741
.claude/commands/workflow/ui-design/generate-v2.md
Normal file
741
.claude/commands/workflow/ui-design/generate-v2.md
Normal file
@@ -0,0 +1,741 @@
|
||||
---
|
||||
name: generate-v2
|
||||
description: Generate UI prototypes using style-centric batch generation
|
||||
usage: /workflow:ui-design:generate-v2 [--targets "<list>"] [--target-type "page|component"] [--base-path <path>] [--session <id>] [--style-variants <count>] [--layout-variants <count>]
|
||||
examples:
|
||||
- /workflow:ui-design:generate-v2 --session WFS-auth --targets "dashboard,settings" --style-variants 3 --layout-variants 3
|
||||
- /workflow:ui-design:generate-v2 --base-path ".workflow/WFS-auth/design-run-20250109-143022" --targets "home,pricing"
|
||||
- /workflow:ui-design:generate-v2 --targets "navbar,hero,card" --target-type "component" --style-variants 2 --layout-variants 2
|
||||
allowed-tools: TodoWrite(*), Read(*), Write(*), Task(ui-design-agent), Bash(*)
|
||||
---
|
||||
|
||||
# UI Generation Command (Style-Centric Architecture)
|
||||
|
||||
**Executor**: → @ui-design-agent
|
||||
**Parallel Generation**: Phase 2 → @ui-design-agent (S tasks, each handling L×T combinations)
|
||||
|
||||
## Overview
|
||||
Generate production-ready UI prototypes (HTML/CSS) using **style-centric batch generation**. Each agent handles all layout × target combinations for one style, ensuring maximum style consistency and optimal performance.
|
||||
|
||||
## Core Philosophy
|
||||
- **Style-Centric Batching**: Each of S agents generates ALL L×T prototypes for one style
|
||||
- **Style-Aware Structure**: HTML DOM adapts based on design_attributes (density, visual_weight, etc.)
|
||||
- **Performance Optimized**: S agent calls for efficient generation
|
||||
- **Perfect Style Consistency**: All layouts for a style generated by single agent with full context
|
||||
- **Token-Driven Styling**: All styles reference design-tokens.json via tokens.css
|
||||
- **Production-Ready**: Semantic HTML5, ARIA attributes, responsive design
|
||||
|
||||
## Execution Protocol
|
||||
|
||||
### Phase 1: Path Resolution & Context Loading
|
||||
```bash
|
||||
# 1. Determine base path
|
||||
IF --base-path: base_path = {provided_base_path}
|
||||
ELSE IF --session: base_path = find_latest_path_matching(".workflow/WFS-{session}/design-*")
|
||||
ELSE: base_path = find_latest_path_matching(".workflow/.design/*")
|
||||
|
||||
# 2. Determine style variant count and layout variant count
|
||||
style_variants = --style-variants OR auto_detect_from_consolidation()
|
||||
layout_variants = --layout-variants OR 3
|
||||
VALIDATE: 1 <= style_variants <= 5
|
||||
VALIDATE: 1 <= layout_variants <= 5
|
||||
|
||||
# Validate against actual style directories
|
||||
actual_style_count = count_directories({base_path}/style-consolidation/style-*)
|
||||
|
||||
IF actual_style_count == 0:
|
||||
ERROR: "No style directories found"; SUGGEST: "Run /workflow:ui-design:consolidate first"; EXIT 1
|
||||
|
||||
IF style_variants > actual_style_count:
|
||||
WARN: "⚠️ Requested {style_variants}, but only {actual_style_count} exist"
|
||||
REPORT: " Available styles: {list_directories}"; style_variants = actual_style_count
|
||||
|
||||
REPORT: "✅ Validated style variants: {style_variants}"
|
||||
|
||||
# 3. Enhanced target list parsing with type detection
|
||||
target_list = []; target_type = "page" # Default
|
||||
|
||||
# Priority 1: Unified --targets parameter
|
||||
IF --targets:
|
||||
raw_targets = {--targets value}
|
||||
target_list = split_and_clean(raw_targets, delimiters=[",", ";", "、"])
|
||||
target_list = [t.strip().lower().replace(" ", "-") for t in target_list if t.strip()]
|
||||
|
||||
target_type = --target-type provided ? {--target-type} : detect_target_type(target_list)
|
||||
REPORT: "🎯 Using provided targets ({target_type}): {', '.join(target_list)}"
|
||||
|
||||
# Priority 2: Legacy --pages parameter
|
||||
ELSE IF --pages:
|
||||
raw_targets = {--pages value}
|
||||
target_list = split_and_clean(raw_targets, delimiters=[",", ";", "、"])
|
||||
target_list = [t.strip().lower().replace(" ", "-") for t in target_list if t.strip()]
|
||||
target_type = "page"
|
||||
REPORT: "📋 Using provided pages (legacy): {', '.join(target_list)}"
|
||||
|
||||
# Priority 3: Extract from synthesis-specification.md
|
||||
ELSE IF --session:
|
||||
synthesis_spec = Read(.workflow/WFS-{session}/.brainstorming/synthesis-specification.md)
|
||||
target_list = extract_targets_from_synthesis(synthesis_spec); target_type = "page"
|
||||
REPORT: "📋 Extracted from synthesis: {', '.join(target_list)}"
|
||||
|
||||
# Priority 4: Detect from existing prototypes or default
|
||||
ELSE:
|
||||
target_list = detect_from_prototypes({base_path}/prototypes/) OR ["home"]; target_type = "page"
|
||||
REPORT: "📋 Detected/default targets: {', '.join(target_list)}"
|
||||
|
||||
# 4. Validate target names
|
||||
validated_targets = [t for t in target_list if regex_match(t, r"^[a-z0-9][a-z0-9_-]*$")]
|
||||
invalid_targets = [t for t in target_list if t not in validated_targets]
|
||||
|
||||
IF invalid_targets: REPORT: "⚠️ Skipped invalid target names: {', '.join(invalid_targets)}"
|
||||
VALIDATE: validated_targets not empty, "No valid targets found"
|
||||
target_list = validated_targets
|
||||
|
||||
STORE: target_list, target_type
|
||||
|
||||
# 5. Verify design systems exist
|
||||
FOR style_id IN range(1, style_variants + 1):
|
||||
VERIFY: exists({base_path}/style-consolidation/style-{style_id}/design-tokens.json)
|
||||
VERIFY: exists({base_path}/style-consolidation/style-{style_id}/tokens.css)
|
||||
|
||||
# 6. Load design space analysis (for style-aware generation)
|
||||
design_space_path = "{base_path}/style-extraction/design-space-analysis.json"
|
||||
IF exists(design_space_path):
|
||||
design_space_analysis = Read(design_space_path)
|
||||
REPORT: "📊 Loaded design space analysis with style attributes"
|
||||
ELSE:
|
||||
WARN: "⚠️ No design space analysis found - will use basic style generation"
|
||||
design_space_analysis = null
|
||||
|
||||
# 7. Load requirements (if integrated mode)
|
||||
IF --session:
|
||||
synthesis_spec = Read(.workflow/WFS-{session}/.brainstorming/synthesis-specification.md)
|
||||
ELSE:
|
||||
synthesis_spec = null
|
||||
```
|
||||
|
||||
### Phase 1.5: Target-Specific Layout Planning
|
||||
```bash
|
||||
REPORT: "📐 Planning {layout_variants} layout strategies for each target..."
|
||||
|
||||
CREATE: {base_path}/prototypes/_templates/
|
||||
|
||||
# For each target, plan its specific layouts
|
||||
FOR target IN target_list:
|
||||
REPORT: " Planning layouts for '{target}' ({target_type})..."
|
||||
|
||||
FOR layout_id IN range(1, layout_variants + 1):
|
||||
Task(ui-design-agent): "
|
||||
[TARGET_LAYOUT_PLANNING]
|
||||
|
||||
TARGET: {target} | TARGET_TYPE: {target_type} | LAYOUT_ID: {layout_id}
|
||||
BASE_PATH: {base_path}
|
||||
{IF synthesis_spec: PROJECT_REQUIREMENTS: {synthesis_spec}}
|
||||
|
||||
## Task
|
||||
Research and generate layout plan JSON for '{target}' ({target_type}).
|
||||
|
||||
## Research (MCP Required)
|
||||
mcp__exa__get_code_context_exa(
|
||||
query=\"modern {target} {target_type} layout patterns 2024 2025\",
|
||||
tokensNum=\"dynamic\"
|
||||
)
|
||||
|
||||
## Output File
|
||||
Write(\"{base_path}/prototypes/_templates/{target}-layout-{layout_id}.json\", layout_plan_json)
|
||||
|
||||
## JSON Structure (Required Fields)
|
||||
```json
|
||||
{{
|
||||
\"id\": \"layout-{layout_id}\",
|
||||
\"target\": \"{target}\",
|
||||
\"target_type\": \"{target_type}\",
|
||||
\"name\": \"Descriptive name (2-4 words)\",
|
||||
\"description\": \"2-3 sentences\",
|
||||
\"structure\": {{
|
||||
// IF page: type, regions, grid, sidebar, responsive
|
||||
// IF component: arrangement, alignment, spacing, element_order
|
||||
}},
|
||||
\"semantic_hints\": [...],
|
||||
\"accessibility_features\": [...],
|
||||
\"research_references\": [...]
|
||||
}}
|
||||
```
|
||||
|
||||
## Requirements
|
||||
- Research-informed, target-specific, meaningfully different from other layout IDs
|
||||
- Write file directly (not text output)
|
||||
"
|
||||
|
||||
# Wait for all agent tasks to complete
|
||||
REPORT: "⏳ Waiting for layout planning agents to complete..."
|
||||
|
||||
# Verify agent created layout JSON files
|
||||
REPORT: "📝 Verifying agent file creation..."
|
||||
|
||||
FOR target IN target_list:
|
||||
FOR layout_id IN range(1, layout_variants + 1):
|
||||
layout_json_label = f"{target}-layout-{layout_id}.json"
|
||||
json_path = f"{base_path}/prototypes/_templates/{layout_json_label}"
|
||||
|
||||
# Verify file exists
|
||||
VERIFY: exists(json_path), f"Layout JSON not created by agent: {layout_json_label}"
|
||||
|
||||
# Validate JSON structure
|
||||
TRY:
|
||||
layout_json_content = Read(json_path)
|
||||
layout_plan = JSON.parse(layout_json_content)
|
||||
|
||||
# Validate required fields
|
||||
VALIDATE: layout_plan.id == f"layout-{layout_id}", f"Invalid layout ID in {layout_json_label}"
|
||||
VALIDATE: layout_plan.target == target, f"Invalid target in {layout_json_label}"
|
||||
VALIDATE: layout_plan.target_type == target_type, f"Invalid target_type in {layout_json_label}"
|
||||
VALIDATE: layout_plan.name exists, f"Missing 'name' field in {layout_json_label}"
|
||||
VALIDATE: layout_plan.structure exists, f"Missing 'structure' field in {layout_json_label}"
|
||||
|
||||
file_size = get_file_size(json_path)
|
||||
REPORT: f" ✓ Verified: {layout_json_label} - {layout_plan.name} ({file_size} KB)"
|
||||
CATCH error:
|
||||
ERROR: f"Validation failed for {layout_json_label}: {error}"
|
||||
REPORT: f" ⚠️ File exists but validation failed - review agent output"
|
||||
|
||||
REPORT: f"✅ Phase 1.5 complete: Verified {len(target_list) × layout_variants} target-specific layout files"
|
||||
```
|
||||
|
||||
### Phase 1.6: Convert Design Tokens to CSS
|
||||
```bash
|
||||
REPORT: "🎨 Converting design tokens to CSS variables..."
|
||||
|
||||
# Check for jq dependency
|
||||
IF NOT command_exists("jq"):
|
||||
ERROR: "jq is not installed or not in PATH. The conversion script requires jq."
|
||||
REPORT: "Please install jq: macOS: brew install jq | Linux: apt-get install jq | Windows: https://stedolan.github.io/jq/download/"
|
||||
EXIT 1
|
||||
|
||||
# Convert design tokens to CSS for each style variant
|
||||
FOR style_id IN range(1, style_variants + 1):
|
||||
tokens_json_path = "{base_path}/style-consolidation/style-${style_id}/design-tokens.json"
|
||||
tokens_css_path = "{base_path}/style-consolidation/style-${style_id}/tokens.css"
|
||||
script_path = "~/.claude/scripts/convert_tokens_to_css.sh"
|
||||
|
||||
# Verify input file exists
|
||||
VERIFY: exists(tokens_json_path), f"Design tokens not found for style-{style_id}"
|
||||
|
||||
# Execute conversion: cat input.json | script.sh > output.css
|
||||
Bash(cat "${tokens_json_path}" | "${script_path}" > "${tokens_css_path}")
|
||||
|
||||
# Verify output was generated
|
||||
IF exit_code == 0 AND exists(tokens_css_path):
|
||||
file_size = get_file_size(tokens_css_path)
|
||||
REPORT: f" ✓ Generated tokens.css for style-{style_id} ({file_size} KB)"
|
||||
ELSE:
|
||||
ERROR: f"Failed to generate tokens.css for style-{style_id}"
|
||||
EXIT 1
|
||||
|
||||
REPORT: f"✅ Phase 1.6 complete: Converted {style_variants} design token files to CSS"
|
||||
```
|
||||
|
||||
### Phase 1.7: Extract Token Variable Names from CSS
|
||||
```bash
|
||||
REPORT: "📋 Extracting actual CSS variable names from tokens.css..."
|
||||
tokens_css_path = "{base_path}/style-consolidation/style-1/tokens.css"
|
||||
VERIFY: exists(tokens_css_path), "tokens.css not found. Phase 1.6 may have failed."
|
||||
|
||||
tokens_css_content = Read(tokens_css_path)
|
||||
|
||||
# Extract all CSS variable names from the generated file
|
||||
# Pattern: --variable-name: value;
|
||||
all_token_vars = extract_css_variables(tokens_css_content) # Regex: r'--([a-z0-9-_]+):'
|
||||
|
||||
# Categorize variables for better Agent understanding
|
||||
color_vars = [v for v in all_token_vars if v.startswith('--color-')]
|
||||
typography_vars = [v for v in all_token_vars if v.startswith(('--font-', '--line-height-', '--letter-spacing-'))]
|
||||
spacing_vars = [v for v in all_token_vars if v.startswith('--spacing-')]
|
||||
radius_vars = [v for v in all_token_vars if v.startswith('--border-radius-')]
|
||||
shadow_vars = [v for v in all_token_vars if v.startswith('--shadow-')]
|
||||
breakpoint_vars = [v for v in all_token_vars if v.startswith('--breakpoint-')]
|
||||
|
||||
REPORT: f"✅ Extracted {len(all_token_vars)} actual CSS variables from tokens.css"
|
||||
REPORT: f" Colors: {len(color_vars)} | Typography: {len(typography_vars)} | Spacing: {len(spacing_vars)}"
|
||||
```
|
||||
|
||||
### Phase 2: Style-Centric Batch Generation
|
||||
|
||||
**Strategy**: S style-centric agents, each generating L×T prototypes for one style.
|
||||
**Performance**: S agent calls for parallel execution
|
||||
|
||||
```bash
|
||||
REPORT: "🎨 Phase 2: Launching {style_variants} style-centric agents..."
|
||||
REPORT: " Each agent generates {layout_variants}×{len(target_list)}={layout_variants * len(target_list)} prototypes"
|
||||
|
||||
CREATE: {base_path}/prototypes/
|
||||
|
||||
# Launch ONE agent task PER STYLE (parallel execution)
|
||||
FOR style_id IN range(1, style_variants + 1):
|
||||
# Load style-specific context
|
||||
style_tokens_path = "{base_path}/style-consolidation/style-{style_id}/design-tokens.json"
|
||||
style_css_path = "{base_path}/style-consolidation/style-{style_id}/tokens.css"
|
||||
style_guide_path = "{base_path}/style-consolidation/style-{style_id}/style-guide.md"
|
||||
|
||||
# Extract design attributes for this style (if available)
|
||||
IF design_space_analysis AND style_id <= len(design_space_analysis.divergent_directions):
|
||||
design_attributes = design_space_analysis.divergent_directions[style_id - 1]
|
||||
philosophy_name = design_attributes.philosophy_name
|
||||
attributes_summary = JSON.stringify({
|
||||
density: design_attributes.design_attributes.density,
|
||||
visual_weight: design_attributes.design_attributes.visual_weight,
|
||||
formality: design_attributes.design_attributes.formality,
|
||||
organic_vs_geometric: design_attributes.design_attributes.organic_vs_geometric,
|
||||
innovation: design_attributes.design_attributes.innovation
|
||||
})
|
||||
ELSE:
|
||||
design_attributes = null
|
||||
philosophy_name = f"Style {style_id}"
|
||||
attributes_summary = "No design attributes available"
|
||||
|
||||
Task(ui-design-agent): """
|
||||
[STYLE_CENTRIC_UI_BATCH_GENERATION]
|
||||
|
||||
## 🎯 Mission
|
||||
Generate COMPLETE set of UI prototypes for Style-{style_id} across ALL targets and layouts.
|
||||
Total files to create: {layout_variants × len(target_list) × 2} (HTML + CSS pairs)
|
||||
|
||||
## 🎨 Style Context (Your Design Identity)
|
||||
STYLE_ID: {style_id}
|
||||
PHILOSOPHY: {philosophy_name}
|
||||
|
||||
{IF design_attributes:
|
||||
DESIGN_ATTRIBUTES: {attributes_summary}
|
||||
- density: {design_attributes.design_attributes.density} → Affects spacing, container usage
|
||||
- visual_weight: {design_attributes.design_attributes.visual_weight} → Affects borders, shadows, nesting
|
||||
- formality: {design_attributes.design_attributes.formality} → Affects font choices, structure formality
|
||||
- organic_vs_geometric: {design_attributes.design_attributes.organic_vs_geometric} → Affects border-radius, alignment
|
||||
- innovation: {design_attributes.design_attributes.innovation} → Affects layout adventurousness
|
||||
}
|
||||
|
||||
STYLE_FILES:
|
||||
- Design Tokens: {style_tokens_path}
|
||||
- CSS Variables: {style_css_path}
|
||||
- Style Guide: {style_guide_path}
|
||||
|
||||
## 📋 Batch Generation Matrix
|
||||
TARGETS: {target_list} # Example: [dashboard, settings]
|
||||
LAYOUTS: 1 to {layout_variants} # Example: [1, 2, 3]
|
||||
TOTAL_COMBINATIONS: {layout_variants × len(target_list)}
|
||||
TARGET_TYPE: {target_type}
|
||||
|
||||
## 🔄 Required Execution Loop
|
||||
|
||||
You MUST implement this nested loop to generate all combinations:
|
||||
|
||||
```pseudocode
|
||||
FOR target IN {target_list}:
|
||||
FOR layout_id IN [1..{layout_variants}]:
|
||||
# Step 1: Load layout plan
|
||||
layout_plan_path = "{base_path}/prototypes/_templates/{target}-layout-{layout_id}.json"
|
||||
layout_plan = Read(layout_plan_path)
|
||||
|
||||
# Step 2: Load CSS variables (to know what tokens exist)
|
||||
tokens_css = Read("{style_css_path}")
|
||||
available_vars = extract_all_css_variables(tokens_css) # Pattern: --variable-name:
|
||||
|
||||
# Step 3: Generate STYLE-AWARE HTML structure
|
||||
# ⚠️ CRITICAL: Structure must adapt based on design_attributes!
|
||||
|
||||
html_structure = generate_html_with_style_awareness(
|
||||
target=target,
|
||||
layout_plan=layout_plan,
|
||||
target_type="{target_type}",
|
||||
design_attributes={design_attributes if design_attributes else "null"}
|
||||
)
|
||||
|
||||
## Style-Aware Structure Rules:
|
||||
{IF design_attributes:
|
||||
# Apply design_attributes to HTML structure:
|
||||
IF density == 'spacious':
|
||||
→ Use FEWER containers, flatter DOM hierarchy
|
||||
→ Example: <main><section class="card"></section></main>
|
||||
IF density == 'compact':
|
||||
→ Use MORE containers, allow nesting
|
||||
→ Example: <main><div class="grid"><div class="card-wrapper"><section></section></div></div></main>
|
||||
|
||||
IF visual_weight == 'heavy':
|
||||
→ Add extra wrapper divs for border effects
|
||||
→ Example: <div class="border-container"><div class="content-wrapper">...</div></div>
|
||||
IF visual_weight == 'minimal' or 'light':
|
||||
→ Minimal wrappers, direct structure
|
||||
→ Example: <section class="card">...</section>
|
||||
|
||||
IF organic_vs_geometric == 'brutalist':
|
||||
→ Hard edges, overlapping allowed, structural honesty
|
||||
IF organic_vs_geometric == 'organic':
|
||||
→ Flowing, natural hierarchy
|
||||
}
|
||||
|
||||
# Step 4: Generate structural CSS using ONLY extracted variables
|
||||
# ⚠️ CRITICAL: Use var() for ALL styling, NO hardcoded values
|
||||
|
||||
css_content = generate_structural_css(
|
||||
layout_plan=layout_plan,
|
||||
available_vars=available_vars, # ⚠️ Only use these!
|
||||
design_attributes={design_attributes if design_attributes else "null"}
|
||||
)
|
||||
|
||||
## CSS Requirements:
|
||||
- ALL colors use: var(--color-*)
|
||||
- ALL fonts use: var(--font-*)
|
||||
- ALL spacing use: var(--spacing-*)
|
||||
- ALL radius use: var(--border-radius-*)
|
||||
- ALL shadows use: var(--shadow-*)
|
||||
- Responsive: Use var(--breakpoint-*) for media queries
|
||||
|
||||
{IF design_attributes:
|
||||
# Apply design_attributes to CSS properties:
|
||||
IF density == 'spacious':
|
||||
→ Use larger spacing values: var(--spacing-8) instead of var(--spacing-4)
|
||||
IF density == 'compact':
|
||||
→ Use smaller spacing values: var(--spacing-2) instead of var(--spacing-4)
|
||||
|
||||
IF visual_weight == 'heavy':
|
||||
→ Use stronger shadows: var(--shadow-lg) instead of var(--shadow-md)
|
||||
→ Add border declarations
|
||||
IF visual_weight == 'minimal':
|
||||
→ Use subtle shadows: var(--shadow-sm) or none
|
||||
→ Minimal borders
|
||||
}
|
||||
|
||||
# Step 5: HTML must include CSS placeholders
|
||||
html_content = html_structure.replace("</head>", \"\"\"
|
||||
<link rel="stylesheet" href="{{STRUCTURAL_CSS}}">
|
||||
<link rel="stylesheet" href="{{TOKEN_CSS}}">
|
||||
</head>
|
||||
\"\"\")
|
||||
|
||||
# Step 6: Write files IMMEDIATELY (don't accumulate)
|
||||
output_html = "{base_path}/prototypes/{target}-style-{style_id}-layout-{layout_id}.html"
|
||||
output_css = "{base_path}/prototypes/{target}-style-{style_id}-layout-{layout_id}.css"
|
||||
|
||||
Write(output_html, html_content)
|
||||
Write(output_css, css_content)
|
||||
|
||||
REPORT: f" ✓ Generated: {target}-style-{style_id}-layout-{layout_id}"
|
||||
```
|
||||
|
||||
## ⚠️ Critical Requirements
|
||||
|
||||
### 1. HTML Generation Rules
|
||||
- **Complete HTML5 document**: <!DOCTYPE html>, <html>, <head>, <body>
|
||||
- **Semantic elements**: Use <header>, <nav>, <main>, <section>, <article>, <aside>, <footer>
|
||||
- **ARIA attributes**: aria-label, role, aria-labelledby for accessibility
|
||||
- **Responsive meta**: <meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
- **CSS placeholders**: MUST include {{STRUCTURAL_CSS}} and {{TOKEN_CSS}} placeholders
|
||||
|
||||
### 2. Style-Aware Structure Adaptation
|
||||
{IF design_attributes:
|
||||
**You have design_attributes - USE THEM to vary DOM structure:**
|
||||
- Same target+layout with different styles = DIFFERENT HTML structures
|
||||
- Example: Minimalist dashboard (density=spacious) has fewer divs than Brutalist dashboard (visual_weight=heavy)
|
||||
- This is NOT just CSS differences - the HTML tree itself must adapt!
|
||||
}
|
||||
{ELSE:
|
||||
**No design_attributes available - generate clean, semantic structure**
|
||||
- Focus on layout_plan requirements
|
||||
- Use best practices for {target_type} structure
|
||||
}
|
||||
|
||||
### 3. CSS Generation Rules
|
||||
- **Token-driven**: 100% var() usage, ZERO hardcoded values
|
||||
- **Structural only**: Layout, positioning, spacing, structure
|
||||
- **NO styling**: No colors, fonts in structural CSS (handled by tokens.css)
|
||||
- **Responsive**: Mobile-first, use var(--breakpoint-*) for media queries
|
||||
|
||||
### 4. Layout Differentiation
|
||||
- layout-1 vs layout-2 vs layout-3 must be STRUCTURALLY DIFFERENT
|
||||
- Not just CSS tweaks - different grid systems, different regions
|
||||
- Refer to layout_plan.structure for each layout's unique requirements
|
||||
|
||||
### 5. Write Operations (MANDATORY)
|
||||
- Write() IMMEDIATELY after generating each prototype
|
||||
- Do NOT accumulate all content and write at end
|
||||
- Do NOT return file contents as text output
|
||||
- Each Write() creates one HTML or CSS file
|
||||
|
||||
## ✅ Completion Report
|
||||
|
||||
After generating ALL {layout_variants × len(target_list)} combinations, report:
|
||||
|
||||
```
|
||||
✅ Style-{style_id} ({philosophy_name}) Batch Generation Complete
|
||||
Files Created: {layout_variants × len(target_list) × 2} ({layout_variants × len(target_list)} HTML + {layout_variants × len(target_list)} CSS)
|
||||
|
||||
{FOR target IN target_list:
|
||||
{target.capitalize()}:
|
||||
{FOR layout_id IN range(1, layout_variants + 1):
|
||||
- {target}-style-{style_id}-layout-{layout_id}.html/css ({file_size_kb} KB each)
|
||||
}
|
||||
}
|
||||
|
||||
Summary: All prototypes generated with {IF design_attributes: 'style-aware structure' ELSE: 'semantic structure'}
|
||||
```
|
||||
|
||||
## 🔑 Key Success Criteria
|
||||
- [ ] Generated exactly {layout_variants × len(target_list) × 2} files
|
||||
- [ ] All HTML files include CSS placeholders
|
||||
- [ ] All CSS files use var() exclusively (no hardcoded values)
|
||||
- [ ] {IF design_attributes: '[ ] HTML structure varies based on design_attributes' ELSE: '[ ] HTML structure follows layout_plan'}
|
||||
- [ ] Layout-1, Layout-2, Layout-3 are structurally distinct
|
||||
- [ ] All files written directly to filesystem (not returned as text)
|
||||
"""
|
||||
|
||||
REPORT: "⏳ Phase 2: Waiting for {style_variants} style-centric agents to complete..."
|
||||
REPORT: " Expected total files: {style_variants × layout_variants × len(target_list) × 2}"
|
||||
```
|
||||
|
||||
### Phase 2.5: Verify Agent File Creation
|
||||
```bash
|
||||
REPORT: "📝 Phase 2.5: Verifying style-centric generation..."
|
||||
|
||||
total_expected = style_variants × layout_variants × len(target_list) × 2
|
||||
total_found = 0
|
||||
|
||||
FOR style_id IN range(1, style_variants + 1):
|
||||
style_files_found = 0
|
||||
|
||||
FOR layout_id IN range(1, layout_variants + 1):
|
||||
FOR target IN target_list:
|
||||
html_file = f"{target}-style-{style_id}-layout-{layout_id}.html"
|
||||
css_file = f"{target}-style-{style_id}-layout-{layout_id}.css"
|
||||
|
||||
html_path = f"{base_path}/prototypes/{html_file}"
|
||||
css_path = f"{base_path}/prototypes/{css_file}"
|
||||
|
||||
# Verify files exist
|
||||
IF exists(html_path) AND exists(css_path):
|
||||
# Validate content
|
||||
html_content = Read(html_path)
|
||||
css_content = Read(css_path)
|
||||
|
||||
# Basic validation
|
||||
VALIDATE: "<!DOCTYPE html>" in html_content, f"Invalid HTML: {html_file}"
|
||||
VALIDATE: "{{STRUCTURAL_CSS}}" in html_content, f"Missing CSS placeholder: {html_file}"
|
||||
VALIDATE: "var(--" in css_content, f"Missing CSS variables: {css_file}"
|
||||
|
||||
html_size = get_file_size(html_path)
|
||||
css_size = get_file_size(css_path)
|
||||
|
||||
style_files_found += 2
|
||||
total_found += 2
|
||||
|
||||
REPORT: f" ✓ {html_file} ({html_size} KB) + {css_file} ({css_size} KB)"
|
||||
ELSE:
|
||||
ERROR: f" ✗ Missing files: {target}-style-{style_id}-layout-{layout_id}.*"
|
||||
|
||||
REPORT: f" Style-{style_id}: {style_files_found}/{layout_variants * len(target_list) * 2} files verified"
|
||||
|
||||
IF total_found == total_expected:
|
||||
REPORT: f"✅ Phase 2.5 complete: Verified all {total_expected} files"
|
||||
ELSE:
|
||||
ERROR: f"⚠️ Only {total_found}/{total_expected} files found - some agents may have failed"
|
||||
```
|
||||
|
||||
### Phase 3: Generate Preview Files
|
||||
|
||||
```bash
|
||||
REPORT: "🌐 Phase 3: Generating preview files..."
|
||||
|
||||
# Phase 3a: Replace CSS placeholders in HTML files
|
||||
FOR style_id IN range(1, style_variants + 1):
|
||||
tokens_css_rel_path = f"../style-consolidation/style-{style_id}/tokens.css"
|
||||
|
||||
FOR layout_id IN range(1, layout_variants + 1):
|
||||
FOR target IN target_list:
|
||||
html_path = f"{base_path}/prototypes/{target}-style-{style_id}-layout-{layout_id}.html"
|
||||
css_path = f"{target}-style-{style_id}-layout-{layout_id}.css" # Relative path
|
||||
|
||||
IF exists(html_path):
|
||||
html_content = Read(html_path)
|
||||
|
||||
# Replace placeholders
|
||||
html_content = html_content.replace("{{STRUCTURAL_CSS}}", css_path)
|
||||
html_content = html_content.replace("{{TOKEN_CSS}}", tokens_css_rel_path)
|
||||
|
||||
# Write updated HTML
|
||||
Write(html_path, html_content)
|
||||
|
||||
REPORT: " ✓ Updated CSS links in all HTML files"
|
||||
|
||||
# Phase 3b: Generate compare.html and index.html using simplified preview script
|
||||
prototypes_dir = f"{base_path}/prototypes"
|
||||
|
||||
# Simple preview generation (no template substitution)
|
||||
Bash(~/.claude/scripts/ui-generate-preview-v2.sh "{prototypes_dir}")
|
||||
|
||||
# The script auto-detects: S, L, T from file patterns
|
||||
# The script generates: compare.html, index.html, PREVIEW.md
|
||||
|
||||
# Verify preview files generated
|
||||
preview_files = [
|
||||
f"{base_path}/prototypes/compare.html",
|
||||
f"{base_path}/prototypes/index.html",
|
||||
f"{base_path}/prototypes/PREVIEW.md"
|
||||
]
|
||||
|
||||
all_present = True
|
||||
FOR file_path IN preview_files:
|
||||
IF exists(file_path):
|
||||
REPORT: f" ✓ Generated: {basename(file_path)}"
|
||||
ELSE:
|
||||
WARN: f" ✗ Missing: {basename(file_path)}"
|
||||
all_present = False
|
||||
|
||||
IF all_present:
|
||||
REPORT: "✅ Phase 3 complete: All preview files generated"
|
||||
ELSE:
|
||||
WARN: "⚠️ Some preview files missing - script may need attention"
|
||||
```
|
||||
|
||||
### Phase 4: Completion
|
||||
|
||||
```javascript
|
||||
TodoWrite({todos: [
|
||||
{content: "Resolve paths and load design systems", status: "completed", activeForm: "Loading design systems"},
|
||||
{content: `Plan ${target_list.length}×${layout_variants} target-specific layouts`, status: "completed", activeForm: "Planning layouts"},
|
||||
{content: `Convert ${style_variants} design token files to CSS`, status: "completed", activeForm: "Converting tokens to CSS"},
|
||||
{content: "Extract CSS variable names from tokens.css", status: "completed", activeForm: "Extracting variable names"},
|
||||
{content: `Launch ${style_variants} style-centric agents (each handling ${layout_variants}×${target_list.length} combinations)`, status: "completed", activeForm: "Running style-centric generation"},
|
||||
{content: `Verify ${style_variants * layout_variants * target_list.length * 2} generated files`, status: "completed", activeForm: "Verifying files"},
|
||||
{content: "Generate preview files (compare.html, index.html)", status: "completed", activeForm: "Generating previews"}
|
||||
]});
|
||||
```
|
||||
|
||||
**Completion Message**:
|
||||
```
|
||||
✅ Style-Centric UI Generation Complete!
|
||||
|
||||
Architecture: Style-Centric Batch Generation
|
||||
|
||||
Configuration:
|
||||
- Style Variants: {style_variants}
|
||||
- Layout Variants: {layout_variants} (target-specific planning)
|
||||
- Target Type: {target_type_icon} {target_type}
|
||||
- Targets: {target_list}
|
||||
- Total Prototypes: {style_variants * layout_variants * len(target_list)}
|
||||
|
||||
Agent Execution:
|
||||
✅ Style-centric agents: S = {style_variants} agents
|
||||
✅ Each agent handles: L×T = {layout_variants}×{len(target_list)} combinations
|
||||
|
||||
Design Quality:
|
||||
✅ Style-Aware Structure: {IF design_space_analysis: 'YES - HTML adapts to design_attributes' ELSE: 'Standard semantic structure'}
|
||||
✅ Style Consistency: PERFECT (each style by single agent)
|
||||
✅ Token-Driven Styling: 100% var() usage
|
||||
|
||||
Output Files:
|
||||
- Layout Plans: {len(target_list) × layout_variants} JSON files
|
||||
- HTML Prototypes: {style_variants * layout_variants * len(target_list)} files
|
||||
- CSS Files: {style_variants * layout_variants * len(target_list)} files
|
||||
- Preview Files: compare.html, index.html, PREVIEW.md
|
||||
|
||||
Generated Structure:
|
||||
📂 {base_path}/prototypes/
|
||||
├── _templates/
|
||||
│ └── {target}-layout-{l}.json ({len(target_list) × layout_variants} layout plans)
|
||||
├── {target}-style-{s}-layout-{l}.html ({style_variants * layout_variants * len(target_list)} prototypes)
|
||||
├── {target}-style-{s}-layout-{l}.css
|
||||
├── compare.html (interactive S×L×T matrix)
|
||||
├── index.html (quick navigation)
|
||||
└── PREVIEW.md (usage instructions)
|
||||
|
||||
🌐 Interactive Preview:
|
||||
1. Matrix View: Open compare.html (recommended)
|
||||
2. Quick Index: Open index.html
|
||||
3. Instructions: See PREVIEW.md
|
||||
|
||||
{IF design_space_analysis:
|
||||
🎨 Style-Aware Generation Active:
|
||||
Each style's prototypes use structure adapted to design_attributes:
|
||||
- Density affects container nesting and whitespace
|
||||
- Visual weight affects wrapper layers and border structure
|
||||
- Same layout × same target × different style = DIFFERENT HTML trees!
|
||||
}
|
||||
|
||||
Next: /workflow:ui-design:update {--session flag if applicable}
|
||||
|
||||
Note: When called from /workflow:ui-design:explore-auto, design-update is triggered automatically.
|
||||
|
||||
**Dynamic Values**: target_type_icon: "📄" for page, "🧩" for component
|
||||
```
|
||||
|
||||
## Output Structure
|
||||
|
||||
```
|
||||
{base_path}/prototypes/
|
||||
├── _templates/ # Layout planning only
|
||||
│ └── {target}-layout-1.json # Layout plan JSON
|
||||
├── {target}-style-{s}-layout-{l}.html # Final prototypes (S×L×T)
|
||||
├── {target}-style-{s}-layout-{l}.css
|
||||
├── compare.html # Interactive matrix
|
||||
├── index.html # Navigation page
|
||||
└── PREVIEW.md # Instructions
|
||||
|
||||
{base_path}/style-consolidation/
|
||||
├── style-1/ (design-tokens.json, tokens.css, style-guide.md)
|
||||
├── style-2/ (same structure)
|
||||
└── style-{S}/ (same structure)
|
||||
```
|
||||
|
||||
## Error Handling
|
||||
|
||||
### Pre-execution Checks
|
||||
- **No design systems found**: Error - Run `/workflow:ui-design:consolidate` first
|
||||
- **Invalid target names**: Extract from synthesis-specification.md or error with validation message
|
||||
- **Missing design-space-analysis.json**: WARN only - generation continues with basic structure
|
||||
- **Unsupported target type**: Error if target_type not in ["page", "component"]
|
||||
|
||||
### Phase-Specific Errors
|
||||
- **Agent execution errors (Phase 2)**: Report details, identify which style agent failed
|
||||
- **Token conversion errors (Phase 1.6)**: Check design-tokens.json format
|
||||
- **Missing files (Phase 2.5)**: Indicates agent failed to write - review agent output logs
|
||||
- **Preview generation errors (Phase 3)**: Check script exists, permissions
|
||||
|
||||
### Recovery Strategies
|
||||
- **Partial generation**: If some style agents succeed, you still have those prototypes
|
||||
- **Retry single style**: Can re-run targeting failed style directory
|
||||
- **Missing design_attributes**: Generation works without them - just less style-aware
|
||||
- **Permission errors**: Run `chmod +x ~/.claude/scripts/ui-generate-preview-v2.sh`
|
||||
|
||||
## Key Features
|
||||
|
||||
1. **🚀 Style-Centric Batch Generation**
|
||||
Each agent handles ALL L×T combinations for one style with efficient parallel execution
|
||||
|
||||
2. **🎨 Style-Aware Structure Adaptation**
|
||||
HTML DOM adapts based on design_attributes (density, visual_weight, organic_vs_geometric)
|
||||
|
||||
3. **📦 Intelligent Context Batching**
|
||||
Each agent receives full style context + all layout plans + all targets
|
||||
|
||||
4. **⚡ Performance Optimized**
|
||||
Parallel execution of S agents for efficient generation
|
||||
|
||||
5. **🔒 Guaranteed Style Consistency**
|
||||
All layouts for a style by single agent; Maintains philosophy throughout
|
||||
|
||||
6. **📐 Target-Specific Layout Planning**
|
||||
Each target gets custom-designed layouts via MCP research
|
||||
|
||||
7. **🎯 Token-Driven Styling**
|
||||
100% var() usage; Each style has own tokens.css
|
||||
|
||||
8. **🌐 Interactive Visualization**
|
||||
Full-featured compare.html with matrix grid
|
||||
|
||||
9. **✅ Production-Ready Output**
|
||||
Semantic HTML5, ARIA attributes, WCAG 2.2 compliant
|
||||
|
||||
## Integration Points
|
||||
|
||||
- **Input**: Per-style design-tokens.json + tokens.css; design-space-analysis.json (optional); targets + layout-variants
|
||||
- **Output**: S×L×T HTML/CSS prototypes for `/workflow:ui-design:update`
|
||||
- **Auto Integration**: Triggered by `/workflow:ui-design:explore-auto`
|
||||
- **Backward Compatibility**: Works without design-space-analysis.json
|
||||
550
.claude/scripts/ui-generate-preview-v2.sh
Normal file
550
.claude/scripts/ui-generate-preview-v2.sh
Normal file
@@ -0,0 +1,550 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# UI Generate Preview v2.0 - Simplified Preview Generation
|
||||
# Purpose: Generate compare.html and index.html for style-centric prototypes
|
||||
# No template substitution - just preview generation
|
||||
#
|
||||
# Usage: ui-generate-preview-v2.sh <prototypes_dir>
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
# Color output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
prototypes_dir="${1:-.}"
|
||||
|
||||
if [[ ! -d "$prototypes_dir" ]]; then
|
||||
echo -e "${RED}Error: Directory not found: $prototypes_dir${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$prototypes_dir" || exit 1
|
||||
|
||||
echo -e "${GREEN}📊 Auto-detecting matrix dimensions...${NC}"
|
||||
|
||||
# Auto-detect styles, layouts, targets from file patterns
|
||||
# Pattern: {target}-style-{s}-layout-{l}.html
|
||||
styles=$(find . -maxdepth 1 -name "*-style-*-layout-*.html" | \
|
||||
sed 's/.*-style-\([0-9]\+\)-.*/\1/' | sort -un)
|
||||
layouts=$(find . -maxdepth 1 -name "*-style-*-layout-*.html" | \
|
||||
sed 's/.*-layout-\([0-9]\+\)\.html/\1/' | sort -un)
|
||||
targets=$(find . -maxdepth 1 -name "*-style-*-layout-*.html" | \
|
||||
sed 's/\.\///; s/-style-.*//' | sort -u)
|
||||
|
||||
S=$(echo "$styles" | wc -l)
|
||||
L=$(echo "$layouts" | wc -l)
|
||||
T=$(echo "$targets" | wc -l)
|
||||
|
||||
echo -e " Detected: ${GREEN}${S}${NC} styles × ${GREEN}${L}${NC} layouts × ${GREEN}${T}${NC} targets"
|
||||
|
||||
if [[ $S -eq 0 ]] || [[ $L -eq 0 ]] || [[ $T -eq 0 ]]; then
|
||||
echo -e "${RED}Error: No prototype files found matching pattern{target}-style-{s}-layout-{l}.html${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Generate compare.html
|
||||
echo -e "${YELLOW}🎨 Generating compare.html...${NC}"
|
||||
|
||||
cat > compare.html << 'EOF'
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>UI Design Matrix - Style × Layout Comparison</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
background: #f5f5f5;
|
||||
padding: 20px;
|
||||
}
|
||||
.header {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
.header h1 { margin-bottom: 10px; color: #333; }
|
||||
.header .stats { color: #666; font-size: 14px; }
|
||||
.controls {
|
||||
background: white;
|
||||
padding: 15px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
.controls label { margin-right: 10px; font-weight: 500; }
|
||||
.controls select {
|
||||
padding: 5px 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
.matrix-container { margin-bottom: 40px; }
|
||||
.matrix-title {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
padding: 15px 20px;
|
||||
border-radius: 8px 8px 0 0;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
.matrix {
|
||||
display: grid;
|
||||
gap: 20px;
|
||||
padding: 20px;
|
||||
background: white;
|
||||
border-radius: 0 0 8px 8px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
.cell {
|
||||
border: 2px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background: #fafafa;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
.cell:hover {
|
||||
border-color: #667eea;
|
||||
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
.cell-header {
|
||||
padding: 12px 15px;
|
||||
background: #f8f9fa;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
font-weight: 600;
|
||||
color: #495057;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.cell-header .badge {
|
||||
background: #667eea;
|
||||
color: white;
|
||||
padding: 2px 8px;
|
||||
border-radius: 12px;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
}
|
||||
.iframe-wrapper {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
padding-top: 75%; /* 4:3 aspect ratio */
|
||||
background: white;
|
||||
}
|
||||
iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: none;
|
||||
}
|
||||
.cell-footer {
|
||||
padding: 10px 15px;
|
||||
background: #f8f9fa;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
font-size: 12px;
|
||||
color: #6c757d;
|
||||
text-align: center;
|
||||
}
|
||||
.cell-footer a {
|
||||
color: #667eea;
|
||||
text-decoration: none;
|
||||
margin: 0 5px;
|
||||
}
|
||||
.cell-footer a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<h1>🎨 UI Design Matrix Comparison</h1>
|
||||
<div class="stats">
|
||||
<span id="matrix-stats"></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<label for="target-selector">Target:</label>
|
||||
<select id="target-selector"></select>
|
||||
|
||||
<label for="layout-cols">Columns:</label>
|
||||
<select id="layout-cols">
|
||||
<option value="1">1</option>
|
||||
<option value="2">2</option>
|
||||
<option value="3" selected>3</option>
|
||||
<option value="4">4</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div id="matrices-container"></div>
|
||||
|
||||
<script>
|
||||
// Data from script
|
||||
const styles = STYLES_PLACEHOLDER;
|
||||
const layouts = LAYOUTS_PLACEHOLDER;
|
||||
const targets = TARGETS_PLACEHOLDER;
|
||||
|
||||
// Update stats
|
||||
document.getElementById('matrix-stats').textContent =
|
||||
`${styles.length} styles × ${layouts.length} layouts × ${targets.length} targets = ${styles.length * layouts.length * targets.length} prototypes`;
|
||||
|
||||
// Populate target selector
|
||||
const targetSelector = document.getElementById('target-selector');
|
||||
targets.forEach((target, index) => {
|
||||
const option = document.createElement('option');
|
||||
option.value = target;
|
||||
option.textContent = target.charAt(0).toUpperCase() + target.slice(1);
|
||||
if (index === 0) option.selected = true;
|
||||
targetSelector.appendChild(option);
|
||||
});
|
||||
|
||||
// Generate matrices
|
||||
function renderMatrices(target) {
|
||||
const container = document.getElementById('matrices-container');
|
||||
container.innerHTML = '';
|
||||
|
||||
styles.forEach(styleId => {
|
||||
const matrixContainer = document.createElement('div');
|
||||
matrixContainer.className = 'matrix-container';
|
||||
|
||||
const title = document.createElement('div');
|
||||
title.className = 'matrix-title';
|
||||
title.textContent = `Style ${styleId} - ${target.charAt(0).toUpperCase() + target.slice(1)}`;
|
||||
|
||||
const matrix = document.createElement('div');
|
||||
matrix.className = 'matrix';
|
||||
matrix.id = `matrix-style-${styleId}`;
|
||||
|
||||
layouts.forEach(layoutId => {
|
||||
const cell = document.createElement('div');
|
||||
cell.className = 'cell';
|
||||
|
||||
const header = document.createElement('div');
|
||||
header.className = 'cell-header';
|
||||
header.innerHTML = `
|
||||
<span>Layout ${layoutId}</span>
|
||||
<span class="badge">S${styleId}L${layoutId}</span>
|
||||
`;
|
||||
|
||||
const iframeWrapper = document.createElement('div');
|
||||
iframeWrapper.className = 'iframe-wrapper';
|
||||
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = `./${target}-style-${styleId}-layout-${layoutId}.html`;
|
||||
iframe.loading = 'lazy';
|
||||
|
||||
const footer = document.createElement('div');
|
||||
footer.className = 'cell-footer';
|
||||
footer.innerHTML = `
|
||||
<a href="./${target}-style-${styleId}-layout-${layoutId}.html" target="_blank">Open ↗</a>
|
||||
<a href="./${target}-style-${styleId}-layout-${layoutId}.css" target="_blank">CSS</a>
|
||||
`;
|
||||
|
||||
iframeWrapper.appendChild(iframe);
|
||||
cell.appendChild(header);
|
||||
cell.appendChild(iframeWrapper);
|
||||
cell.appendChild(footer);
|
||||
matrix.appendChild(cell);
|
||||
});
|
||||
|
||||
matrixContainer.appendChild(title);
|
||||
matrixContainer.appendChild(matrix);
|
||||
container.appendChild(matrixContainer);
|
||||
});
|
||||
|
||||
updateGridColumns();
|
||||
}
|
||||
|
||||
function updateGridColumns() {
|
||||
const cols = document.getElementById('layout-cols').value;
|
||||
styles.forEach(styleId => {
|
||||
const matrix = document.getElementById(`matrix-style-${styleId}`);
|
||||
if (matrix) {
|
||||
matrix.style.gridTemplateColumns = `repeat(${cols}, 1fr)`;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Event listeners
|
||||
targetSelector.addEventListener('change', (e) => {
|
||||
renderMatrices(e.target.value);
|
||||
});
|
||||
|
||||
document.getElementById('layout-cols').addEventListener('change', updateGridColumns);
|
||||
|
||||
// Initial render
|
||||
renderMatrices(targets[0]);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
# Replace placeholders with actual data
|
||||
sed -i "s/STYLES_PLACEHOLDER/[$(echo "$styles" | tr '\n' ',' | sed 's/,$//' | sed 's/\([0-9]\+\)/"\1"/g')]/" compare.html
|
||||
sed -i "s/LAYOUTS_PLACEHOLDER/[$(echo "$layouts" | tr '\n' ',' | sed 's/,$//' | sed 's/\([0-9]\+\)/"\1"/g')]/" compare.html
|
||||
sed -i "s/TARGETS_PLACEHOLDER/[$(echo "$targets" | tr '\n' ',' | sed 's/,$//' | sed 's/\(.*\)/"\1"/g')]/" compare.html
|
||||
|
||||
echo -e "${GREEN} ✓ Generated compare.html${NC}"
|
||||
|
||||
# Generate index.html
|
||||
echo -e "${YELLOW}📋 Generating index.html...${NC}"
|
||||
|
||||
cat > index.html << EOF
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>UI Prototypes Index</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 40px 20px;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
h1 { margin-bottom: 10px; color: #333; }
|
||||
.subtitle { color: #666; margin-bottom: 30px; }
|
||||
.cta {
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 30px;
|
||||
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
|
||||
}
|
||||
.cta h2 { margin-bottom: 10px; }
|
||||
.cta a {
|
||||
display: inline-block;
|
||||
background: white;
|
||||
color: #667eea;
|
||||
padding: 10px 20px;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
margin-top: 10px;
|
||||
}
|
||||
.cta a:hover { background: #f8f9fa; }
|
||||
.style-section {
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
.style-section h2 {
|
||||
color: #495057;
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 2px solid #e9ecef;
|
||||
}
|
||||
.target-group {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.target-group h3 {
|
||||
color: #6c757d;
|
||||
font-size: 16px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.link-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
||||
gap: 10px;
|
||||
}
|
||||
.prototype-link {
|
||||
padding: 12px 16px;
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 6px;
|
||||
text-decoration: none;
|
||||
color: #495057;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.prototype-link:hover {
|
||||
background: #e9ecef;
|
||||
border-color: #667eea;
|
||||
transform: translateX(2px);
|
||||
}
|
||||
.prototype-link .label { font-weight: 500; }
|
||||
.prototype-link .icon { color: #667eea; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🎨 UI Prototypes Index</h1>
|
||||
<p class="subtitle">Generated ${S}×${L}×${T} = $((S*L*T)) prototypes</p>
|
||||
|
||||
<div class="cta">
|
||||
<h2>📊 Interactive Comparison</h2>
|
||||
<p>View all styles and layouts side-by-side in an interactive matrix</p>
|
||||
<a href="compare.html">Open Matrix View →</a>
|
||||
</div>
|
||||
|
||||
<h2>📂 All Prototypes</h2>
|
||||
EOF
|
||||
|
||||
# Generate index content
|
||||
for style in $styles; do
|
||||
echo "<div class='style-section'>" >> index.html
|
||||
echo "<h2>Style ${style}</h2>" >> index.html
|
||||
|
||||
for target in $targets; do
|
||||
target_capitalized="$(echo ${target:0:1} | tr '[:lower:]' '[:upper:]')${target:1}"
|
||||
echo "<div class='target-group'>" >> index.html
|
||||
echo "<h3>${target_capitalized}</h3>" >> index.html
|
||||
echo "<div class='link-grid'>" >> index.html
|
||||
|
||||
for layout in $layouts; do
|
||||
html_file="${target}-style-${style}-layout-${layout}.html"
|
||||
if [[ -f "$html_file" ]]; then
|
||||
echo "<a href='${html_file}' class='prototype-link' target='_blank'>" >> index.html
|
||||
echo "<span class='label'>Layout ${layout}</span>" >> index.html
|
||||
echo "<span class='icon'>↗</span>" >> index.html
|
||||
echo "</a>" >> index.html
|
||||
fi
|
||||
done
|
||||
|
||||
echo "</div></div>" >> index.html
|
||||
done
|
||||
|
||||
echo "</div>" >> index.html
|
||||
done
|
||||
|
||||
cat >> index.html << EOF
|
||||
</body>
|
||||
</html>
|
||||
EOF
|
||||
|
||||
echo -e "${GREEN} ✓ Generated index.html${NC}"
|
||||
|
||||
# Generate PREVIEW.md
|
||||
echo -e "${YELLOW}📝 Generating PREVIEW.md...${NC}"
|
||||
|
||||
cat > PREVIEW.md << EOF
|
||||
# UI Prototypes Preview Guide
|
||||
|
||||
Generated: $(date +"%Y-%m-%d %H:%M:%S")
|
||||
|
||||
## 📊 Matrix Dimensions
|
||||
|
||||
- **Styles**: ${S}
|
||||
- **Layouts**: ${L}
|
||||
- **Targets**: ${T}
|
||||
- **Total Prototypes**: $((S*L*T))
|
||||
|
||||
## 🌐 How to View
|
||||
|
||||
### Option 1: Interactive Matrix (Recommended)
|
||||
|
||||
Open \`compare.html\` in your browser to see all prototypes in an interactive matrix view.
|
||||
|
||||
**Features**:
|
||||
- Side-by-side comparison of all styles and layouts
|
||||
- Switch between targets using the dropdown
|
||||
- Adjust grid columns for better viewing
|
||||
- Direct links to full-page views
|
||||
|
||||
### Option 2: Simple Index
|
||||
|
||||
Open \`index.html\` for a simple list of all prototypes with direct links.
|
||||
|
||||
### Option 3: Direct File Access
|
||||
|
||||
Each prototype can be opened directly:
|
||||
- Pattern: \`{target}-style-{s}-layout-{l}.html\`
|
||||
- Example: \`dashboard-style-1-layout-1.html\`
|
||||
|
||||
## 📁 File Structure
|
||||
|
||||
\`\`\`
|
||||
prototypes/
|
||||
├── compare.html # Interactive matrix view
|
||||
├── index.html # Simple navigation index
|
||||
├── PREVIEW.md # This file
|
||||
$(for style in $styles; do
|
||||
for target in $targets; do
|
||||
for layout in $layouts; do
|
||||
echo "├── ${target}-style-${style}-layout-${layout}.html"
|
||||
echo "├── ${target}-style-${style}-layout-${layout}.css"
|
||||
done
|
||||
done
|
||||
done)
|
||||
\`\`\`
|
||||
|
||||
## 🎨 Style Variants
|
||||
|
||||
$(for style in $styles; do
|
||||
echo "### Style ${style}"
|
||||
echo ""
|
||||
style_guide="../style-consolidation/style-${style}/style-guide.md"
|
||||
if [[ -f "$style_guide" ]]; then
|
||||
head -n 10 "$style_guide" | tail -n +2 || echo "Design philosophy and tokens"
|
||||
else
|
||||
echo "Design system ${style}"
|
||||
fi
|
||||
echo ""
|
||||
done)
|
||||
|
||||
## 📐 Layout Variants
|
||||
|
||||
$(for layout in $layouts; do
|
||||
echo "### Layout ${layout}"
|
||||
echo ""
|
||||
for target in $targets; do
|
||||
layout_plan="_templates/${target}-layout-${layout}.json"
|
||||
if [[ -f "$layout_plan" ]]; then
|
||||
name=$(grep -o '"name":[[:space:]]*"[^"]*"' "$layout_plan" | head -1 | cut -d'"' -f4 || echo "Layout ${layout}")
|
||||
echo "- **${target}**: ${name}"
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
done)
|
||||
|
||||
## 🎯 Targets
|
||||
|
||||
$(for target in $targets; do
|
||||
target_capitalized="$(echo ${target:0:1} | tr '[:lower:]' '[:upper:]')${target:1}"
|
||||
echo "- **${target_capitalized}**: ${L} layouts × ${S} styles = $((L*S)) variations"
|
||||
done)
|
||||
|
||||
## 💡 Tips
|
||||
|
||||
1. **Comparison**: Use compare.html to see how different styles affect the same layout
|
||||
2. **Navigation**: Use index.html for quick access to specific prototypes
|
||||
3. **Inspection**: Open browser DevTools to inspect HTML structure and CSS
|
||||
4. **Sharing**: All files are standalone - can be shared or deployed directly
|
||||
|
||||
## 📝 Next Steps
|
||||
|
||||
1. Review prototypes in compare.html
|
||||
2. Select preferred style × layout combinations
|
||||
3. Provide feedback for refinement
|
||||
4. Use selected designs for implementation
|
||||
|
||||
---
|
||||
|
||||
Generated by /workflow:ui-design:generate-v2 (Style-Centric Architecture)
|
||||
EOF
|
||||
|
||||
echo -e "${GREEN} ✓ Generated PREVIEW.md${NC}"
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✅ Preview generation complete!${NC}"
|
||||
echo -e " Files created: compare.html, index.html, PREVIEW.md"
|
||||
echo -e " Matrix: ${S} styles × ${L} layouts × ${T} targets = $((S*L*T)) prototypes"
|
||||
echo ""
|
||||
echo -e "${YELLOW}🌐 Open compare.html to view interactive matrix${NC}"
|
||||
Reference in New Issue
Block a user