--- name: generate-v2 description: Generate UI prototypes using style-centric batch generation usage: /workflow:ui-design:generate-v2 [--targets ""] [--target-type "page|component"] [--base-path ] [--session ] [--style-variants ] [--layout-variants ] 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}/{layout_variants} BASE_PATH: {base_path} {IF synthesis_spec: PROJECT_REQUIREMENTS: {synthesis_spec}} ## Task Research common {target} {target_type} layout variations and select the #{layout_id} approach. Generate layout plan JSON that is STRUCTURALLY DIFFERENT from other layout IDs. ## Research (MCP Required) mcp__exa__web_search_exa( query=\"common {target} {target_type} layout patterns variations best practices 2024\", numResults=5 ) ## Selection Strategy From search results, identify multiple layout variations and select approach #{layout_id}. Ensure each layout_id uses a DIFFERENT structural pattern (not just styling differences). ## 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:
IF density == 'compact': → Use MORE containers, allow nesting → Example:
IF visual_weight == 'heavy': → Add extra wrapper divs for border effects → Example:
...
IF visual_weight == 'minimal' or 'light': → Minimal wrappers, direct structure → Example:
...
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("", \"\"\" \"\"\") # 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**: , , , - **Semantic elements**: Use
,