--- name: generate description: Generate UI prototypes in matrix mode (style × layout combinations) for pages or components usage: /workflow:ui-design:generate [--targets ""] [--target-type "page|component"] [--base-path ] [--session ] [--style-variants ] [--layout-variants ] argument-hint: "[--targets \"dashboard,auth,navbar,hero\"] [--target-type \"page\"] [--base-path \".workflow/WFS-xxx/design-run-xxx\"] [--style-variants 3] [--layout-variants 3]" parameters: - name: --style-variants type: number default: 3 description: "Number of style variants to generate prototypes for (1-5). Auto-validates against actual style-* directories. ⚠️ Recommend omitting to use auto-detection." - name: --layout-variants type: number default: auto-detected from layout-strategies.json description: "Number of layout variants. Default: loaded from consolidation output. Can override for manual testing." - name: --targets type: string description: "Comma-separated list of targets (pages or components) to generate" - name: --target-type type: string default: page description: "Type of targets: 'page' (full layout) or 'component' (isolated element)" examples: - /workflow:ui-design:generate --base-path ".workflow/WFS-auth/design-run-20250109-143022" --targets "dashboard,settings" --target-type "page" --style-variants 3 --layout-variants 3 - /workflow:ui-design:generate --session WFS-auth --targets "home,pricing" --target-type "page" --style-variants 2 --layout-variants 2 - /workflow:ui-design:generate --base-path "./.workflow/.design/run-20250109-150533" # ✅ Recommended: auto-detect variants - /workflow:ui-design:generate --targets "navbar,hero,card" --target-type "component" --style-variants 3 --layout-variants 2 - /workflow:ui-design:generate --pages "home,dashboard" --style-variants 2 --layout-variants 2 # Legacy syntax executor: → @ui-design-agent allowed-tools: TodoWrite(*), Read(*), Write(*), Task(ui-design-agent), Bash(*) --- # UI Generation Command (Matrix Mode) **Executor**: → @ui-design-agent **Parallel Generation**: Phase 2a → @ui-design-agent (L×T tasks) ## Overview Generate production-ready UI prototypes (HTML/CSS) in `style × layout` matrix mode, strictly adhering to consolidated design tokens from separate style design systems. Supports both full-page layouts and isolated component generation. ## Core Philosophy - **Unified Generation**: Single mode generating `style_variants × layout_variants × targets` prototypes - **Target Types**: Supports pages (full layouts) and components (isolated UI elements) - **Agent-Driven**: Uses `Task(ui-design-agent)` for parallel generation - **Token-Driven**: All styles reference per-style design-tokens.json; no hardcoded values - **Production-Ready**: Semantic HTML5, ARIA attributes, responsive design - **Template-Based**: Decouples HTML structure from CSS styling for optimal performance - **Adaptive Wrapper**: Full-page structure for pages, minimal wrapper for components ## Execution Protocol ### Phase 0: Load Layout Strategies ```bash # Determine base path first (using same logic as Phase 1) IF --base-path provided: base_path = {provided_base_path} ELSE IF --session provided: # Find latest design run in session base_path = find_latest_path_matching(".workflow/WFS-{session}/design-*") ELSE: base_path = find_latest_path_matching(".workflow/.design/*") # Load layout strategies from consolidation output layout_strategies_path = "{base_path}/style-consolidation/layout-strategies.json" VERIFY: exists(layout_strategies_path), "Layout strategies not found. Run /workflow:ui-design:consolidate first." layout_strategies = Read(layout_strategies_path) layout_variants = layout_strategies.layout_variants_count REPORT: "📐 Loaded {layout_variants} layout strategies:" FOR strategy IN layout_strategies.strategies: REPORT: " - {strategy.name}: {strategy.description}" # Override layout_variants if --layout-variants is provided (for manual runs) IF --layout-variants provided: WARN: "Overriding layout strategies count from {layout_variants} to {provided_count}" layout_variants = {provided_count} VALIDATE: 1 <= layout_variants <= len(layout_strategies.strategies) # Trim strategies to match count layout_strategies.strategies = layout_strategies.strategies[0:layout_variants] ``` ### Phase 1: Path Resolution & Context Loading ```bash # 1. Determine base path IF --base-path provided: base_path = {provided_base_path} ELSE IF --session provided: # Find latest design run in session base_path = find_latest_path_matching(".workflow/WFS-{session}/design-*") ELSE: base_path = find_latest_design_session(".workflow/.scratchpad/") # 2. Determine style variant count (layout_variants already loaded in Phase 0) style_variants = --style-variants OR 3 # Default to 3 # Validate range VALIDATE: 1 <= style_variants <= 5 # Validate against actual style directories (prevent style-N file generation for non-existent directories) actual_style_count = count_directories({base_path}/style-consolidation/style-*) IF actual_style_count == 0: ERROR: "No style directories found in {base_path}/style-consolidation/" SUGGEST: "Run /workflow:ui-design:consolidate first to generate style design systems" EXIT 1 IF style_variants > actual_style_count: WARN: "⚠️ Requested {style_variants} style variants, but only {actual_style_count} directories exist" REPORT: " Available styles: {list_directories({base_path}/style-consolidation/style-*)}" REPORT: " Auto-correcting to {actual_style_count} style variants" style_variants = actual_style_count REPORT: "✅ Validated style variants: {style_variants} (matching actual directory count)" # Note: layout_variants is loaded from layout-strategies.json in Phase 0 # 3. Enhanced target list parsing with type detection target_list = [] target_type = "page" # Default to page for backward compatibility # Priority 1: Unified --targets parameter IF --targets provided: raw_targets = {--targets value} # Split by comma, semicolon, or Chinese comma target_list = split_and_clean(raw_targets, delimiters=[",", ";", "、"]) # Clean: strip whitespace, lowercase, replace spaces with hyphens target_list = [t.strip().lower().replace(" ", "-") for t in target_list if t.strip()] # Get target type IF --target-type provided: target_type = {--target-type value} ELSE: # Auto-detect from target names (use same logic as explore-auto) target_type = detect_target_type(target_list) REPORT: "🎯 Using provided targets ({target_type}): {', '.join(target_list)}" # Priority 2: Legacy --pages parameter (backward compatibility) ELSE IF --pages provided: 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" # Synthesis typically defines pages 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 for later use STORE: target_list = target_list STORE: target_type = target_type # 5. Verify design systems exist FOR style_id IN range(1, style_variants + 1): VERIFY: {base_path}/style-consolidation/style-{style_id}/design-tokens.json exists VERIFY: {base_path}/style-consolidation/style-{style_id}/style-guide.md exists # 6. Load requirements (if integrated mode) IF --session: synthesis_spec = Read(.workflow/WFS-{session}/.brainstorming/synthesis-specification.md) ``` ### Phase 1.5: Token Variable Name Extraction ```bash # Load design-tokens.json from style-1 to extract exact variable names # This ensures template generation uses correct token names REPORT: "📋 Extracting design token variable names..." tokens_json_path = "{base_path}/style-consolidation/style-1/design-tokens.json" VERIFY: exists(tokens_json_path), "Design tokens not found. Run /workflow:ui-design:consolidate first." design_tokens = Read(tokens_json_path) # Extract all available token categories and variable names token_reference = { "colors": { "brand": list(design_tokens.colors.brand.keys()), # e.g., ["primary", "secondary", "accent"] "surface": list(design_tokens.colors.surface.keys()), # e.g., ["background", "elevated", "overlay"] "semantic": list(design_tokens.colors.semantic.keys()), # e.g., ["success", "warning", "error", "info"] "text": list(design_tokens.colors.text.keys()), # e.g., ["primary", "secondary", "tertiary", "inverse"] "border": list(design_tokens.colors.border.keys()) # e.g., ["default", "strong", "subtle"] }, "typography": { "font_family": list(design_tokens.typography.font_family.keys()), # e.g., ["heading", "body", "mono"] "font_size": list(design_tokens.typography.font_size.keys()), # e.g., ["xs", "sm", "base", "lg", "xl", "2xl", "3xl", "4xl"] "font_weight": list(design_tokens.typography.font_weight.keys()), # e.g., ["normal", "medium", "semibold", "bold"] "line_height": list(design_tokens.typography.line_height.keys()), # e.g., ["tight", "normal", "relaxed"] "letter_spacing": list(design_tokens.typography.letter_spacing.keys()) # e.g., ["tight", "normal", "wide"] }, "spacing": list(design_tokens.spacing.keys()), # e.g., ["0", "1", "2", ..., "24"] "border_radius": list(design_tokens.border_radius.keys()), # e.g., ["none", "sm", "md", "lg", "xl", "full"] "shadows": list(design_tokens.shadows.keys()), # e.g., ["sm", "md", "lg", "xl"] "breakpoints": list(design_tokens.breakpoints.keys()) # e.g., ["sm", "md", "lg", "xl", "2xl"] } # Generate complete variable name lists for Agent prompt color_vars = [] FOR category IN ["brand", "surface", "semantic", "text", "border"]: FOR key IN token_reference.colors[category]: color_vars.append(f"--color-{category}-{key}") typography_vars = [] FOR category IN ["font_family", "font_size", "font_weight", "line_height", "letter_spacing"]: prefix = "--" + category.replace("_", "-") FOR key IN token_reference.typography[category]: typography_vars.append(f"{prefix}-{key}") spacing_vars = [f"--spacing-{key}" for key in token_reference.spacing] radius_vars = [f"--border-radius-{key}" for key in token_reference.border_radius] shadow_vars = [f"--shadow-{key}" for key in token_reference.shadows] breakpoint_vars = [f"--breakpoint-{key}" for key in token_reference.breakpoints] all_token_vars = color_vars + typography_vars + spacing_vars + radius_vars + shadow_vars + breakpoint_vars REPORT: f"✅ Extracted {len(all_token_vars)} design token variables from design-tokens.json" REPORT: f" - Color variables: {len(color_vars)}" REPORT: f" - Typography variables: {len(typography_vars)}" REPORT: f" - Spacing variables: {len(spacing_vars)}" REPORT: f" - Other variables: {len(radius_vars) + len(shadow_vars) + len(breakpoint_vars)}" ``` ### Phase 2: Optimized Matrix UI Generation **Strategy**: Two-layer generation reduces complexity from `O(S×L×P)` to `O(L×P)`, achieving **`S` times faster** performance. - **Layer 1**: Generate `L × T` layout templates (HTML structure + structural CSS) by agent - **Layer 2**: Instantiate `S × L × T` final prototypes via fast file operations *T = targets (pages or components), P = pages (legacy notation)* #### Phase 2a: Layout Template Generation **Parallel Executor**: → @ui-design-agent Generate style-agnostic layout templates for each `{target} × {layout}` combination. Total agent tasks: `layout_variants × len(target_list)` ```bash # Create directories CREATE: {base_path}/prototypes/_templates/ CREATE: {base_path}/prototypes/ # Launch parallel template generation tasks → @ui-design-agent FOR layout_id IN range(1, layout_variants + 1): FOR target IN target_list: Task(ui-design-agent): " [UI_LAYOUT_TEMPLATE_GENERATION] 🚨 **CRITICAL: TARGET INDEPENDENCE REQUIREMENT** 🚨 You are generating a template for EXACTLY ONE target: '{target}'. - Do NOT include content from other targets in the workflow - This template is for '{target}' ONLY - treat it as a standalone UI entity - Even if '{target}' might coexist with other targets in a final application, your task is to create an INDEPENDENT, REUSABLE template for '{target}' alone Generate a **style-agnostic** layout template for a specific {target_type} and layout strategy. 🎯 **CRITICAL REQUIREMENTS**: ✅ **ADAPTIVE**: Multi-device responsive design (mobile, tablet, desktop) ✅ **STYLE-SWITCHABLE**: Support runtime theme/style switching via CSS variables ✅ **TOKEN-DRIVEN**: 100% CSS variable usage, zero hardcoded values ✅ **INDEPENDENT**: Template for '{target}' only, no other targets included ✅ **RESEARCH-INFORMED**: Use MCP tools to research modern UI patterns as needed ## Context LAYOUT_ID: {layout_id} TARGET: {target} TARGET_TYPE: {target_type} BASE_PATH: {base_path} {IF --session: - Requirements: .workflow/WFS-{session}/.brainstorming/synthesis-specification.md} **Target Type Details**: {IF target_type == "page": - Type: Full-page layout - Wrapper: Complete HTML document structure with , , - Navigation: Include header/navigation elements - Footer: Include page footer - Content: Complete page content structure } {ELSE IF target_type == "component": - Type: Isolated UI component - Wrapper: Minimal container for component demonstration - Navigation: Exclude header/footer (component-only) - Container: Simple wrapper (e.g.,
) - Content: Focus solely on the component design } ## Task Generate TWO files that work together as a reusable template: **File 1**: `{target}-layout-{layout_id}.html` - 🏗️ **SEMANTIC STRUCTURE**: HTML5 structure WITHOUT any style-specific values - {IF target_type == "page": "Complete HTML document with , , " ELSE: "Minimal wrapper with component container only"} - 🔗 **DYNAMIC STYLING**: Use placeholder links for runtime style switching: ```html ``` - ♿ **ACCESSIBILITY**: All semantic elements, ARIA attributes, responsive structure - 🚫 **ZERO HARDCODING**: NO inline styles, NO hardcoded colors/fonts/spacing - 🎨 **STYLE-AGNOSTIC**: HTML structure must work with ANY design token set **File 2**: `{target}-layout-{layout_id}.css` - 🎨 **TOKEN-DRIVEN STYLING**: ALL values use `var()` for dynamic theme switching - 🔄 **RUNTIME SWITCHABLE**: `background-color: var(--color-surface-background);` - 🚫 **ZERO LITERALS**: NO hardcoded values (#4F46E5, 16px, Arial) - 📐 **SEMANTIC NAMING**: BEM or descriptive class naming - 📱 **MOBILE-FIRST**: Responsive design using token-based breakpoints - 💡 **VARIABLE REFERENCES**: Every visual property must use var(--token-name) - {IF target_type == "component": "Focus styles on component only, minimal global styles"} ## Layout Diversity Strategy Apply the following strategy from the planned layout strategies (loaded from layout-strategies.json): **Layout ID**: {layout_id} **Name**: {layout_strategies.strategies[layout_id - 1].name} **Description**: {layout_strategies.strategies[layout_id - 1].description} Apply this strategy CONSISTENTLY to all styles. ## Token Usage Requirements (STRICT - USE EXACT NAMES) **CRITICAL**: You MUST use ONLY the variable names listed below. These are extracted from design-tokens.json. DO NOT invent variable names like --color-background-base, --radius-md, --transition-base, etc. **Available Color Variables** ({len(color_vars)} total): {', '.join(color_vars[:10])}... ({len(color_vars) - 10} more) **Key Color Variables**: - Brand: --color-brand-primary, --color-brand-secondary, --color-brand-accent - Surface: --color-surface-background, --color-surface-elevated, --color-surface-overlay - Text: --color-text-primary, --color-text-secondary, --color-text-tertiary, --color-text-inverse - Border: --color-border-default, --color-border-strong, --color-border-subtle - Semantic: --color-semantic-success, --color-semantic-warning, --color-semantic-error, --color-semantic-info **Available Typography Variables** ({len(typography_vars)} total): {', '.join(typography_vars[:10])}... ({len(typography_vars) - 10} more) **Key Typography Variables**: - Families: --font-family-heading, --font-family-body, --font-family-mono - Sizes: --font-size-xs, --font-size-sm, --font-size-base, --font-size-lg, --font-size-xl, --font-size-2xl, --font-size-3xl, --font-size-4xl - Weights: --font-weight-normal, --font-weight-medium, --font-weight-semibold, --font-weight-bold - Line heights: --line-height-tight, --line-height-normal, --line-height-relaxed - Letter spacing: --letter-spacing-tight, --letter-spacing-normal, --letter-spacing-wide **Available Spacing Variables** ({len(spacing_vars)} total): {', '.join(spacing_vars)} **Available Border Radius Variables** ({len(radius_vars)} total): {', '.join(radius_vars)} **Available Shadow Variables** ({len(shadow_vars)} total): {', '.join(shadow_vars)} **Available Breakpoint Variables** ({len(breakpoint_vars)} total): {', '.join(breakpoint_vars)} **STRICT RULES**: 1. Use ONLY the variables listed above - NO custom variable names 2. If you need a value not in the list, use the closest semantic match 3. For missing tokens (like transitions), use literal CSS values: `transition: all 0.2s ease;` 4. NO hardcoded colors, fonts, or spacing (e.g., #4F46E5, 16px, Arial) 5. All `var()` references must match exact variable names above ## HTML Requirements - 🏗️ **SEMANTIC STRUCTURE**: HTML5 elements (
,