---
name: spec-driven-ui
description: >
  Generate front-end UI specifications, code, and a framework-agnostic Design
  Source of Truth (design.md) for Web, GUI, or Terminal interfaces through a
  9-phase workflow with structural anti-skip enforcement. Supports Web (React,
  Blazor, ASP.NET, HTML), Desktop GUI (WPF, Tkinter), and Terminal interfaces.
  Three modes: generated (interactive discovery), extracted (from existing
  mockup code via --extract), and hybrid. Produces design.md — a single
  document from which any AI can recreate the complete UI in any framework.
  Use when stories require UI components, when generating visual specifications
  from requirements, or when extracting a design source of truth from existing
  mockups. Always use this skill when the user runs /create-ui.
allowed-tools:
  - Read
  - Write
  - Edit
  - Glob
  - Grep
  - AskUserQuestion
  - Task
  - Bash(python:*)
  - Bash(devforgeai-validate:*)
  - Bash(npx:*)
  - Bash(node:*)
  - Bash(mkdir:*)
  - WebFetch
  - Skill
model: claude-opus-4-7
effort: Medium
version: "2.0.0"
last-updated: "2026-05-20"
topics: ui generation, design source of truth, design.md, mockup extraction, frontend, accessibility, design tokens, anti-skip
---

# Spec-Driven UI Generation

Generate front-end UI specifications and code, and produce the framework-agnostic
Design Source of Truth (`design.md`), through a 9-phase workflow with structural
anti-skip enforcement. Governed by **ADR-078** (modernization) + **ADR-075**
(design.md format-stay decision). Phase 03 includes a Claude Design fast-path
(Step 3.0) per **RESEARCH-010** REC-2: when a user has authored their design
in Claude Design and exported a handoff bundle, Step 3.0 routes through
`mockup-extractor` (FRAMEWORK="claude-design-bundle") and skips Steps 3.3 /
3.7 / 3.7a / 3.8 (visual-discovery questions whose answers are in the bundle).

This skill owns the UI specification phase of the modernized DevForgeAI pipeline.
It runs after `/create-solution-architecture` (or standalone) and produces the
UI artifacts consumed by `/dev`, `/qa`, and the 6 design.md consumer skills.

```
/create-solution-architecture → /create-ui (THIS SKILL) → /create-story → /dev
```

**Context files are THE LAW.** If ambiguous or conflicts detected: HALT and use
AskUserQuestion.

---

## Execution Model

See **`.claude/rules/core/anti-skip-behavior.md`** for the canonical execution
contract (expand inline; do not wait passively or offer execution options;
honor every step of every phase; Self-Check violation taxonomy; Token-
Optimization-Bias prohibition; governed by ADR-076). After invocation,
execute Phase 00 Initialization immediately.

---

## Anti-Skip Enforcement Contract

Enforced structurally outside LLM control, not by this prose — by the framework's deterministic gates wired for this workflow: the `devforgeai-validate` phase gates, the `settings.json`-registered `.claude/hooks/` scripts, and `.claude/hooks/phase-steps-registry.json` (ADR-076). Behavioral residue: `.claude/rules/core/anti-skip-behavior.md`.

The `ui` / `ui-extract` phase-gate is advisory / non-blocking (gh#211/212); the skill runs under the layers above.

---

## Parameter Extraction

Extract from conversation context (set by the invoking `/create-ui` command, by
a punting skill, or by the resume flag):

| Parameter | Source | Default |
|-----------|--------|---------|
| `$ARG` | `/create-ui` positional argument | empty |
| `$MODE` | Derived from `$ARG` and `--extract` flag | see Step 0.1 |
| `$IDENTIFIER` | Derived from `$MODE` and `$TARGET` | see Step 0.1 |
| `$TARGET` | `$ARG` value | required |
| `$EXTRACT_PATH` | `--extract <path>` argument | null (extract mode only) |
| `$EXTRACT_URL` | `--url=<url>` argument | null |
| `$ORIGIN` | `--origin=<skill:id>` argument | null |
| `$WORKFLOW_FLAG` | Derived from `$MODE` (Step 0.1b) | `--workflow=ui` (or `--workflow=ui-extract` for extract) |

---

## Phase 00: Initialization [INLINE — Bootstraps State]

This phase runs inline because it creates the state every other phase depends
on. The five steps below execute in order, with no skipping.

### Step 0.1: Working Directory + Argument Parse

**EXECUTE:**
```
Read(file_path="CLAUDE.md")  # confirms project root
```

Parse the `/create-ui` invocation arguments from conversation context:

```
IF context contains "--extract <path>" OR "**Mode:** extract":
  MODE = "extract"
  EXTRACT_PATH = value after --extract
  IDENTIFIER = "UI-EXTRACT"
  TARGET = EXTRACT_PATH
ELIF $ARG matches /^STORY-[0-9]+$/:
  MODE = "story"
  STORY_ID = $ARG
  IDENTIFIER = STORY_ID
  TARGET = STORY_ID
ELIF $ARG is empty:
  AskUserQuestion:
    Question: "No argument provided. What UI should I generate?"
    Header: "UI Generation"
    Options:
      - "List stories with UI requirements" (Glob devforgeai/specs/Stories/*.story.md and present)
      - "Standalone component (I'll describe it)"
      - "Show /create-ui syntax"
    multiSelect: false
  After answer: re-parse $ARG and re-enter Step 0.1.
ELSE:
  MODE = "standalone"
  IDENTIFIER = "UI-STANDALONE"
  TARGET = $ARG
```

Optional parameters:
```
IF context contains "--url=<url>":
  EXTRACT_URL = value after --url=
  Validate: starts with "http://" or "https://"; HALT if invalid.
IF context contains "--origin=<skill:id>":
  ORIGIN_SKILL, ORIGIN_ID = parts split on ":"
```

**VERIFY:** `CLAUDE.md` content contains "DevForgeAI"; `MODE` ∈ {story,
standalone, extract}; `IDENTIFIER` and `TARGET` set; optional URL is `http(s)`.

### Step 0.1b: Select Workflow Flag by Mode

`spec-driven-ui` exposes two workflow keys (gh#211) because extract mode runs a
non-linear phase sequence (`01 → 02a → 06 → 07 → 08`) that the linear `ui` schema
cannot represent. Resolve the flag ONCE here; every phase-gate call below uses
`${WORKFLOW_FLAG}`.

```
IF MODE == "extract":
  WORKFLOW_FLAG = "--workflow=ui-extract"
ELSE:
  WORKFLOW_FLAG = "--workflow=ui"
```

**VERIFY:** `WORKFLOW_FLAG` is `--workflow=ui-extract` for extract mode, else
`--workflow=ui`.

### Step 0.2: Initialize Phase State Tracking

**EXECUTE:**
```
Bash(command="devforgeai-validate phase-init ${IDENTIFIER} ${WORKFLOW_FLAG} --project-root=. 2>&1")
```

**VERIFY:** Exit code 0 or 2 (exit 2 = identifier format not recognized;
proceed with backward compatibility). **If exit 127:** CLI not installed —
continue WITHOUT the CLI-gate layer but execute ALL phases and steps regardless.

### Step 0.3: Verify Story File Exists (Story Mode Only)

**EXECUTE:**
```
IF MODE == "story":
  Glob(pattern="devforgeai/specs/Stories/${STORY_ID}*.story.md")
  IF found: Read the story file.
  IF NOT found:
    AskUserQuestion:
      Question: "Story ${STORY_ID} not found. What should I do?"
      Header: "Story not found"
      Options:
        - "List all available stories" (Glob devforgeai/specs/Stories/*.story.md and present)
        - "Use standalone mode" (MODE = "standalone"; IDENTIFIER = "UI-STANDALONE")
        - "Cancel" (HALT)
ELSE:
  SKIP — non-story modes do not require a story file.
```

### Step 0.4: Verify Extract Path Exists (Extract Mode Only)

**EXECUTE:**
```
IF MODE == "extract":
  Glob(pattern="${EXTRACT_PATH}/**/*.{jsx,tsx,vue,html,css,py,xaml}")
  IF no files found: HALT with error "No UI source files found at: ${EXTRACT_PATH}"
ELSE:
  SKIP — non-extract modes do not require an extract path.
```

### Step 0.5: Display Initialization Banner

```
Display:
"━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
  DevForgeAI UI Generation Session
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Session:    ${IDENTIFIER}
Mode:       ${MODE}
Target:     ${TARGET}
${EXTRACT_URL?  "Visual capture: ${EXTRACT_URL}" : ""}
${ORIGIN?       "Origin:         ${ORIGIN_SKILL}:${ORIGIN_ID}" : ""}
Phases: 9 (Context > Story Analysis > [Extract |] Discovery >
           Templates > Codegen > Documentation > Validation > Feedback)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
```

Set `CURRENT_PHASE = 1`. **GOTO Phase Orchestration Loop at Phase 01.**

---

## Phase Orchestration Loop

For each phase from `CURRENT_PHASE` to the final phase:

1. **ENTRY GATE:** Verify the previous phase completed (check phase state, or
   first-phase exemption for Phase 01).
2. **LOAD PHASE:** `Read(file_path=".claude/skills/spec-driven-ui/phases/{phase_file}")` FRESH.
3. **LOAD REFERENCES:** Each phase file specifies which references to load from
   `.claude/skills/spec-driven-ui/references/`. Load them ALL via `Read()`.
4. **EXECUTE STEPS:** Follow EVERY Execute-Verify-Record triplet in the phase
   file, IN ORDER. Do NOT compress or skip steps.
5. **EXIT GATE:** Verify ALL mandatory exit conditions listed in the phase
   file before proceeding.
6. **UPDATE CHECKPOINT:**
   `devforgeai-validate phase-complete ${IDENTIFIER} ${WORKFLOW_FLAG} --phase={N}`.
7. **DISPLAY TRANSITION:** Show phase completion and the next phase name.

---

## Phase Table

| Phase | Name | File | Required Subagents |
|-------|------|------|--------------------|
| 01 | Context Validation | `phases/phase-01-context-validation.md` | — |
| 02 | Story Analysis | `phases/phase-02-story-analysis.md` | — |
| 02a | Mockup Extraction (Extract Mode Only — skips 02–05) | `phases/phase-02a-mockup-extraction.md` | **mockup-extractor** |
| 03 | Interactive Discovery | `phases/phase-03-interactive-discovery.md` | — |
| 04 | Template Loading | `phases/phase-04-template-loading.md` | — |
| 05 | Code Generation | `phases/phase-05-code-generation.md` | — |
| 06 | Documentation | `phases/phase-06-documentation.md` | **ui-spec-formatter** |
| 07 | Specification Validation | `phases/phase-07-specification-validation.md` | — |
| 08 | Feedback & Completion | `phases/phase-08-feedback-completion.md` | — |

Phases 01, 06, 07, 08 run on every invocation. **Story / standalone** mode
additionally runs 02 → 03 → 04 → 05 (`--workflow=ui`). **Extract** mode runs
Phase 02a (Mockup Extraction) instead, skipping 02–05 and proceeding directly to
06 (`--workflow=ui-extract`). See `references/shared-protocols.md` for the
per-mode phase sequences.

---

## Subagents

**mockup-extractor** (Phase 02a) — Reads existing component files (React, Vue,
HTML, WPF, Tkinter) from `${EXTRACT_PATH}`; extracts design tokens, component
hierarchy, interactions, and accessibility attributes; returns
`design_md_content` for the orchestrator to persist. Status: BLOCKING (extract
mode cannot proceed without its output).

**ui-spec-formatter** (Phase 06, Step 6.5) — Validates generated specifications
against framework constraints; formats results for user-facing display; returns
structured JSON with `SUCCESS / PARTIAL / FAILED` status. Status: BLOCKING
(documentation phase cannot complete without its verdict). Reference:
`references/ui-result-formatting-guide.md`.

---

## State Persistence

- **Checkpoint:** `devforgeai/workflows/${IDENTIFIER}-ui-phase-state.json`
  (managed by `devforgeai-validate`).
- **Updated:** After every step via `phase-record`; after every phase via
  `phase-complete`.
- **Verified:** Via `Glob()` after every write.
- **Resume:** `phase-init` returns the current phase from the existing state
  file; the orchestration loop resumes from that phase.

---

## Workflow Completion Validation

```
IF MODE == "extract":
  Verify: Glob("devforgeai/specs/ui/design.md") returns 1 file
  Verify: Glob("devforgeai/specs/ui/UI-SPEC-SUMMARY.md") returns 1 file
ELSE:
  Verify: Glob("devforgeai/specs/ui/design.md") returns 1 file
  Verify: Glob("devforgeai/specs/ui/UI-SPEC-SUMMARY.md") returns 1 file
  Verify: at least one component code file produced under the framework's
          path per source-tree/
```

IF any verification fails: HALT and report the missing artifact.

---

## Success Criteria

| Outcome | Condition |
|---------|-----------|
| SUCCESS | UI spec generated, components created per source-tree/, no placeholders, all constraints validated, formatter returns `SUCCESS`. |
| PARTIAL | UI spec generated with minor warnings, user accepted PARTIAL in Phase 07. |
| FAILED  | Context files missing, critical constraint violations, or user chose to halt in Phase 07. |

`design.md` is consumed by 6 downstream skills (brainstorming, ideation,
solution-architecture, stories, dev, qa) plus external AI; it must remain the
authoritative framework-agnostic Design Source of Truth.

---

## Deviation Protocol

If you need to deviate from ANY phase step:

1. HALT immediately.
2. Use AskUserQuestion to explain the deviation and get user consent.
3. Only proceed with explicit user approval.
4. Record the deviation in the checkpoint under a `deviations` key.

**Without user consent, no deviation is permitted.**
