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: opus 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 when the SOLARCH is UI-bearing (or standalone) and produces the
UI artifacts consumed by /dev, /qa, and the 4 design.md consumer skills.
/create-solution-architecture → (if UI-bearing: /create-ui (THIS SKILL)) → /create-development-architecture → /create-story → /dev
Context files are THE LAW. If ambiguous or conflicts detected: HALT and use AskUserQuestion.
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).
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.2a: VCS Posture Check (skip if git unavailable)
EXECUTE: Task(subagent_type="git-validator", ...) to check: (a) git available, (b) working tree dirty, (c) current branch name vs. the default branch, (d) merge/rebase/cherry-pick in progress.
VERIFY:
- If git is unavailable → log
"VCS check skipped (not a git repo)", set$VCS_AVAILABLE=false, and proceed to Step 0.3 (the Optional Worktree Offer step is also skipped). - If merge/rebase/cherry-pick in progress → HALT → AskUserQuestion: "A git operation is in progress. Resolve it before running /create-ui to avoid writing spec files into a broken state."
- If on default branch OR dirty working tree → display ADVISORY: "This session will write
design.md/visual-capture/directly into the current checkout without isolation. The Optional Worktree Offer step (after argument verification) will give you the chance to create one." Do NOT block — proceed.
Set $VCS_AVAILABLE=true on success.
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.4a: Optional Worktree Offer (skip if $VCS_AVAILABLE=false from Step 0.2a)
EXECUTE:
IF MODE == "story":
Task(subagent_type="git-worktree-manager",
prompt="Manage Git worktree for ${STORY_ID}. Report action_needed ∈ {CREATE, RESUME, REPAIR, NONE} and the suggested worktree path.")
# git-worktree-manager is report-only — it does NOT create the worktree.
ELIF MODE ∈ {"standalone", "extract"}:
Display: "To isolate this UI generation run: git worktree add worktrees/ui-<slug> -b feat/ui-<slug>"
If Step 0.2a found on-default-branch OR dirty-working-tree (and $VCS_AVAILABLE=true):
AskUserQuestion:
Question: "This session will write spec files to the current branch. Create a worktree for isolation?"
Header: "Worktree isolation"
Options:
- "Create worktree now" → orchestrator: git worktree add <path> -b <branch>
- "Continue on current branch" → proceed to Step 0.5
If user chose creation → VERIFY: git worktree list --porcelain contains path AND test -d <path>. HALT on failure.
RECORD (story mode only, after git-worktree-manager dispatched):
devforgeai-validate phase-record ${IDENTIFIER} ${WORKFLOW_FLAG} --phase=00 --subagent=git-worktree-manager --project-root=.
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:
- ENTRY GATE: Verify the previous phase completed (check phase state, or first-phase exemption for Phase 01).
- LOAD PHASE:
Read(file_path=".claude/skills/spec-driven-ui/phases/{phase_file}")FRESH. - LOAD REFERENCES: Each phase file specifies which references to load from
.claude/skills/spec-driven-ui/references/. Load them ALL viaRead(). - EXECUTE STEPS: Follow EVERY Execute-Verify-Record triplet in the phase file, IN ORDER. Do NOT compress or skip steps.
- EXIT GATE: Verify ALL mandatory exit conditions listed in the phase file before proceeding.
- UPDATE CHECKPOINT:
devforgeai-validate phase-complete ${IDENTIFIER} ${WORKFLOW_FLAG} --phase={N}. - 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 bydevforgeai-validate). - Updated: After every step via
phase-record; after every phase viaphase-complete. - Verified: Via
Glob()after every write. - Resume:
phase-initreturns 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 4 downstream skills (ideation, 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:
- HALT immediately.
- Use AskUserQuestion to explain the deviation and get user consent.
- Only proceed with explicit user approval.
- Record the deviation in the checkpoint under a
deviationskey.
Without user consent, no deviation is permitted.