diff --git a/research/docs/2026-04-17-claude-design-product-analysis.md b/research/docs/2026-04-17-claude-design-product-analysis.md new file mode 100644 index 000000000..e66707e31 --- /dev/null +++ b/research/docs/2026-04-17-claude-design-product-analysis.md @@ -0,0 +1,519 @@ +--- +topic: Claude Design by Anthropic Labs — Comprehensive Product Analysis +researched_at: 2026-04-17 +primary_source: https://www.anthropic.com/news/claude-design-anthropic-labs +raw_research: research/web/2026-04-17-claude-design-anthropic-labs.md +purpose: Open-source replica reference — full workflow phases, capabilities, and architecture +--- + +# Claude Design by Anthropic Labs — Comprehensive Product Analysis + +## Summary + +Claude Design is an AI-powered visual design product launched by Anthropic Labs on April 17, 2026. It enables users to create polished designs, interactive prototypes, slide decks, one-pagers, marketing collateral, and "frontier design" experiences (code-powered prototypes with voice, video, shaders, 3D, and AI) through conversational prompts and fine-grained editing controls. It is powered by Claude Opus 4.7 (Anthropic's most capable vision model at launch) and available in research preview to Pro, Max, Team, and Enterprise subscribers at claude.ai/design. + +The product follows a closed-loop design-to-development pipeline: +**Onboarding (design system) → Import/Prompt → Generate → Refine → Collaborate → Export/Handoff** + +--- + +## Target Users + +- **Experienced designers**: Get room to explore more directions than time normally allows +- **Founders / entrepreneurs**: Go from rough idea to shareable prototype without design background +- **Product managers**: Sketch feature flows, wireframe, and hand off to Claude Code +- **Marketers**: Create landing pages, social assets, campaign visuals +- **Account executives**: Build on-brand pitch decks in minutes +- **Anyone**: Build "frontier design" code-powered prototypes with multimedia capabilities + +--- + +## Workflow Phases — Official Breakdown + +The official Anthropic announcement describes the workflow as a "natural creative flow" with six named steps. These are the actual phases (not the four-phase research/planning/implementation/validation model the user initially hypothesized): + +--- + +### Phase 1: Design System Onboarding — "Your brand, built in" + +**What happens:** +During initial onboarding, Claude reads the team's codebase and design files and automatically constructs a design system encoding: +- Color palette +- Typography choices +- Component library + +**Key behaviors:** +- The system is built once, then automatically applied to every subsequent project +- Teams can maintain multiple design systems (e.g., one per product line) +- The system can be refined iteratively after the initial build +- Claude stores the design-system *representation*, not the raw source files themselves (privacy-preserving) +- Source code files are not uploaded to Anthropic's servers +- GitHub integration planned "coming weeks" + +**User interaction (HIL points):** +- Claude proposes colors, fonts, and design elements +- User gets to approve each aspect or request changes +- User can revisit and modify the design system after seeing final output +- Per The New Stack's first-person account: "It'll choose colors and fonts, and create the design elements for you, but you get to approve those or ask for changes." + +**Tools/capabilities used:** +- Codebase reader (reads local code without uploading) +- Design file parser (DOCX, PPTX, XLSX, and design tool files) +- Claude Opus 4.7 vision model + +--- + +### Phase 2: Import — "Import from anywhere" + +**What happens:** +Users initiate a design project through multiple input modalities: + +| Input Method | Description | +|---|---| +| Text prompt | Natural language description of what to create | +| Image upload | Upload screenshots, mockups, visual references | +| Document upload | DOCX, PPTX, XLSX files as content source | +| Codebase reference | Point Claude at the team's codebase | +| Web capture tool | Grab elements directly from a live website URL | + +**The web capture tool** is particularly notable: it scrapes visual elements from live websites so that prototypes match the look of the real product, rather than creating something generic. + +**User interaction (HIL points):** +- User chooses which input method(s) to use +- Can combine inputs (e.g., text prompt + screenshot reference) +- No approval required; Claude proceeds directly to generation + +**Tools/capabilities used:** +- Claude Opus 4.7 (text + multimodal vision — images up to 2,576px long edge / ~3.75 megapixels) +- Web scraping / web capture capability +- Document parsing (DOCX, PPTX, XLSX) + +--- + +### Phase 3: Generation — First Version Creation + +**What happens:** +Claude generates the first version of the requested artifact based on: +- The input provided in Phase 2 +- The team's design system (from Phase 1, if available) +- The conversation context + +Output types: +- Interactive prototypes (clickable, user-testable without code review or PRs) +- Product wireframes and mockups +- Pitch decks and presentations +- Marketing collateral (landing pages, social assets, campaign visuals) +- Frontier design experiences (voice, video, shaders, 3D, built-in AI) + +**Token usage note:** +Claude Design is "hungry for tokens." The New Stack reported using 50%+ of weekly allotment after: building a design system + news website prototype + a few tweaks + one explainer video. Users can choose between polished mockups or wireframes; wireframes use fewer tokens. + +**User interaction (HIL points):** +- User receives the first generated version +- No approval required before generation +- The output is the starting point for refinement + +**Tools/capabilities used:** +- Claude Opus 4.7 (generation engine) +- Design system context (from Phase 1) +- Code generation for "frontier design" features + +--- + +### Phase 4: Refinement — "Refine with fine-grained controls" + +**What happens:** +This is the iterative feedback loop. Users can refine the generated design through multiple mechanisms simultaneously: + +| Mechanism | Description | +|---|---| +| Chat conversation | Natural language requests in the conversation thread | +| Inline comments | Click on a specific element to comment on it directly | +| Direct text editing | Edit text content inline without prompting | +| Adjustment knobs/sliders | Claude-generated UI controls to tweak spacing, color, layout in real time | + +**The adjustment sliders are a distinctive feature:** Claude itself generates the specific sliders that make sense for each design (e.g., "padding", "primary color hue", "font size scale"). These let users tweak parameters live without prompting Claude. Users can then ask Claude to apply their slider changes across the full design. + +**Drawing on designs** is also supported — users can literally draw/annotate on the design canvas. + +**Example from Brilliant:** Most complex pages required 20+ prompts to recreate in other tools but only 2 prompts in Claude Design. + +**Example from Datadog:** Week-long cycle of briefs, mockups, and review rounds now happens in a single conversation. + +**User interaction (HIL points):** +- All refinement is user-initiated and iterative +- Multiple rounds of feedback supported +- User explicitly requests changes (conversation) or makes changes directly (editing, sliders) +- Claude can apply changes globally ("apply this across the full design") + +**Tools/capabilities used:** +- Claude Opus 4.7 (refinement engine) +- Custom-generated adjustment UI (sliders/knobs) — unique per design +- Canvas drawing/annotation +- Real-time layout updates + +--- + +### Phase 5: Collaboration — "Collaborate" + +**What happens:** +Designs have organization-scoped sharing controls: + +| Share Mode | Description | +|---|---| +| Private | Only the creator can see and edit | +| View-only link | Anyone in the organization with the link can view | +| Edit access | Colleagues can modify the design and chat with Claude in a group conversation | + +**Group conversation feature:** Multiple team members can collaborate with Claude simultaneously in a shared design session. + +**User interaction (HIL points):** +- Creator chooses share mode +- Collaborators can participate in the Claude conversation +- All team members interact with the same design artifact + +**Tools/capabilities used:** +- Organization-scoped access control +- Shared Claude conversation context (multi-user) + +--- + +### Phase 6: Export and Handoff — "Export anywhere" + "Handoff to Claude Code" + +**What happens:** +The design can be exported in multiple formats or handed off directly to Claude Code: + +**Export formats:** +| Format | Description | +|---|---| +| Internal URL | Organization-scoped link for sharing | +| Folder (save) | Save as a folder structure | +| Canva export | Send to Canva as fully editable, collaborative design | +| PDF | Export as PDF | +| PPTX | Export as PowerPoint (for presentations) | +| Standalone HTML | Export as standalone HTML file | + +**Claude Code Handoff (key differentiator):** +When a design is ready to build, Claude packages everything into a "handoff bundle" that includes: +- The design itself +- Design intent (the reasoning behind design decisions) +- Design tokens +- Component specifications + +This bundle can be passed to Claude Code with a single instruction. It creates a closed loop: exploration → prototype → production code, all within Anthropic's ecosystem. + +The Brilliant team testimonial confirms: "Including design intent in Claude Code handoffs has made the jump from prototype to production seamless." + +**Future integrations:** Anthropic committed to making it easier to connect Claude Design to more tools via MCPs "in the coming weeks." + +**User interaction (HIL points):** +- User chooses export format or handoff destination +- Canva export makes design "fully editable and collaborative" in Canva +- Claude Code handoff is a single instruction + +**Tools/capabilities used:** +- Export engine (PDF, PPTX, HTML, folder) +- Canva integration (partnership) +- Claude Code handoff packaging +- GitHub integration (planned) + +--- + +## The Design Plugin (Cowork/Claude Code Integration) + +Source: https://github.com/anthropics/knowledge-work-plugins/tree/main/design + +Claude Design also ships as a plugin (`knowledge-work-plugins/design`) for Claude Cowork and Claude Code. This exposes a distinct set of workflow tools: + +### Plugin Commands + +| Command | Trigger Phrases | Description | +|---|---|---| +| `/critique` | "review this design", "critique this mockup" | Structured design feedback on usability, hierarchy, accessibility, consistency | +| `/design-system` | "audit design system" | Audit, document, or extend component libraries and tokens | +| `/handoff` | "generate handoff specs" | Developer handoff with measurements, tokens, states, interactions, edge cases | +| `/ux-copy` | "write UX copy", "review microcopy" | Write/review microcopy, error messages, empty states, onboarding flows | +| `/accessibility` | "audit accessibility", "check a11y" | WCAG 2.1 AA compliance audit with specific severity ratings | +| `/research-synthesis` | "synthesize research" | Condense interviews, surveys, usability tests into actionable insights | + +### Critique Framework Details + +The `/critique` command evaluates: +1. **First Impression (2 seconds)**: Eye movement, emotional reaction, clarity of purpose +2. **Usability**: Goal accomplishment, navigation, interactive elements, unnecessary steps +3. **Visual Hierarchy**: Reading order, emphasis, whitespace, typography hierarchy +4. **Consistency**: Design system adherence, spacing, colors, behavior +5. **Accessibility**: Color contrast, touch targets, readability, alt text + +Output format: Markdown tables with severity ratings (Critical/Moderate/Minor) and recommendations. + +### Accessibility Audit (WCAG 2.1 AA) + +Checks against: +- Perceivable: alt text (1.1.1), semantic structure (1.3.1), contrast 4.5:1 (1.4.3), non-text contrast 3:1 (1.4.11) +- Operable: keyboard access (2.1.1), focus order (2.4.3), visible focus (2.4.7), touch targets 44x44px (2.5.5) +- Understandable: predictable focus (3.2.1), error identification (3.3.1), input labels (3.3.2) +- Robust: name/role/value (4.1.2) + +Testing approach: automated scan (~30% of issues) + keyboard navigation + screen reader + color contrast + 200% zoom test. + +### Developer Handoff Spec Format + +Includes: +- Visual Specifications: exact measurements (px), design token references, responsive breakpoints, component variants/states +- Interaction Specifications: click/tap, hover states, transitions (duration + easing), gesture support +- Content Specifications: character limits, truncation, empty/loading/error states +- Edge Cases: min/max content, international text, slow connections, missing data +- Accessibility: focus order, ARIA labels, keyboard interactions, screen reader announcements + +Principle: always reference design tokens (`spacing-md`) not raw values (`16px`). + +### MCP Connectors + +The plugin uses MCP (Model Context Protocol) for tool integrations: + +| Category | Placeholder | Default Servers | Alternatives | +|---|---|---|---| +| Design tool | `~~design tool` | Figma | Sketch, Adobe XD, Framer | +| Chat | `~~chat` | Slack | Microsoft Teams | +| Knowledge base | `~~knowledge base` | Notion | Confluence, Guru, Coda | +| Project tracker | `~~project tracker` | Linear, Asana, Atlassian | Shortcut, ClickUp | +| User feedback | `~~user feedback` | Intercom | Productboard, Canny, UserVoice, Dovetail | +| Product analytics | `~~product analytics` | (none default) | Amplitude, Mixpanel, Heap, FullStory | + +### Standalone vs. Supercharged + +Every command works standalone (screenshots, descriptions) but gets enhanced with MCP: +- Design critique standalone: paste screenshot or describe | supercharged: Figma MCP pulls design directly +- Handoff standalone: describe or screenshot | supercharged: Figma MCP provides exact measurements + tokens +- Accessibility standalone: describe or screenshot | supercharged: Figma MCP + real usage analytics +- Research synthesis standalone: paste transcripts | supercharged: user feedback tools pull raw data + +--- + +## Architecture and Technical Details + +### Model: Claude Opus 4.7 + +- Most capable generally available vision model from Anthropic (as of April 2026) +- Accepts images up to 2,576px on the long edge (~3.75 megapixels, 3x prior Claude models) +- 64.3% on SWE-bench Pro +- 13% improvement over Opus 4.6 on Anthropic's internal 93-task coding benchmark +- 98.5% on XBOW visual-acuity benchmark (vs 54.5% for Opus 4.6) +- API pricing: $5/M input tokens, $25/M output tokens + +### Data Privacy + +- Design system representation stored, not source files +- Local code references are not uploaded to Anthropic's servers +- Anthropic explicitly does not train on Claude Design data +- Enterprise: off by default, admin-controlled + +### Frontier Design Capabilities + +The "frontier design" category is explicitly listed as: +> Code-powered prototypes with voice, video, shaders, 3D and built-in AI + +This goes beyond static visuals into interactive, multimedia experiences generated without manual coding. + +### Design System Architecture + +Design systems in Claude Design: +- Built by reading codebase + existing design files at onboarding +- Encode: colors, typography, component library +- Applied automatically to every new project +- Multiple design systems per team supported +- Refine-able over time +- Stored as a representation (not the raw files) for privacy + +### Handoff Bundle Structure + +When handing off to Claude Code, the bundle includes: +- The design artifacts +- Design intent (reasoning, not just visuals) +- Design tokens +- Component specifications +- Interaction notes + +This is distinct from a simple export — it's an annotated specification that Claude Code can act on directly. + +--- + +## Competitive Context + +| Tool | Relationship to Claude Design | +|---|---| +| Figma | Primary incumbent; Anthropic CPO resigned from Figma board days before launch; Figma stock fell 5% | +| Canva | Partner (export integration); Anthropic says "complement not replace" | +| Adobe | Secondary incumbent targeted by design democratization angle | +| OpenAI Codex | Similar visual asset generation; Claude Design goes further with sliders, drawing, MCP | + +Claude Design's competitive differentiators: +1. Natural language refinement with generated adjustment sliders (not just chat) +2. Design intent preserved in Claude Code handoff bundles +3. Design system built from actual codebase (not generic templates) +4. Web capture tool (pull from live sites) +5. Closed-loop ecosystem with Claude Code +6. Frontier design (voice, video, 3D, shaders) without coding + +--- + +## Anthropic Labs Context + +- Claude Design is an Anthropic Labs product (not core Claude product) +- Labs team: Mike Krieger (co-founder of Instagram, former Anthropic CPO) + Ben Mann (engineering lead) +- Krieger reports to President Daniela Amodei +- Labs track record: Claude Code ($1B product in 6 months), MCP (100M monthly downloads), Cowork (built in 1.5 weeks), Skills, Claude in Chrome +- Labs operates as an R&D incubator freed from traditional product constraints + +--- + +## Workflow Summary Diagram + +``` +[Team Codebase / Design Files] + | + v +┌─────────────────────────────┐ +│ PHASE 1: ONBOARDING │ +│ Design System Construction │ ← Claude reads codebase + design files +│ Colors / Typography / │ ← User approves or requests changes +│ Components │ +└─────────────┬───────────────┘ + | + v +┌─────────────────────────────┐ +│ PHASE 2: IMPORT │ +│ Input Modalities: │ +│ - Text prompt │ +│ - Image/document upload │ +│ - Codebase reference │ +│ - Web capture tool │ +└─────────────┬───────────────┘ + | + v +┌─────────────────────────────┐ +│ PHASE 3: GENERATION │ +│ First Version Created: │ +│ - Prototypes │ +│ - Wireframes/Mockups │ +│ - Pitch Decks │ +│ - Marketing Collateral │ +│ - Frontier Design │ +└─────────────┬───────────────┘ + | + v +┌─────────────────────────────┐ +│ PHASE 4: REFINEMENT │ ← Iterative loop (multiple rounds) +│ Mechanisms: │ +│ - Chat conversation │ +│ - Inline comments │ +│ - Direct text editing │ +│ - Claude-generated sliders │ +│ - Drawing/annotation │ +│ - Global change propagation│ +└─────────────┬───────────────┘ + | + v +┌─────────────────────────────┐ +│ PHASE 5: COLLABORATION │ +│ - Private / View / Edit │ +│ - Group conversation with │ +│ Claude (multi-user) │ +└─────────────┬───────────────┘ + | + v +┌─────────────────────────────┐ +│ PHASE 6: EXPORT / HANDOFF │ +│ Export: │ +│ - Internal URL │ +│ - Canva (editable) │ +│ - PDF │ +│ - PPTX │ +│ - Standalone HTML │ +│ - Folder/save │ +│ │ +│ Handoff Bundle → Claude Code│ ← Design intent preserved +└─────────────────────────────┘ +``` + +--- + +## Open-Source Replica Implementation Notes + +For building an open-source replica of the Claude Design workflow: + +### Core Workflow Engine Requirements + +1. **Design System Builder** + - Read codebase files and extract design tokens (colors, fonts, spacing) + - Read existing design files (DOCX, PPTX, visual assets) + - Build a structured design system representation + - Human-in-the-loop approval at each major decision (color palette, typography, components) + - Support multiple design systems per workspace + +2. **Input Handler** + - Text prompt ingestion + - File upload handling (images, DOCX, PPTX, XLSX) + - Codebase reader (local, no-upload) + - Web capture tool (headless browser scraping of live URLs) + +3. **Generation Engine** + - Vision model integration (Claude Opus 4.7 or equivalent) + - Context injection (design system + input + conversation history) + - Output types: HTML/CSS prototypes, presentation decks, marketing assets + - Frontier design: voice/video/3D/shader integration + +4. **Refinement Interface** + - Chat thread for natural language requests + - Inline comment system on design elements + - Direct text editing + - Dynamic slider/knob generation (Claude generates the appropriate controls per design) + - Global change propagation ("apply across full design") + - Drawing/annotation layer + +5. **Collaboration Layer** + - Organization-scoped access control (private/view/edit) + - Shared conversation context (multi-user Claude session) + +6. **Export Engine** + - HTML export + - PDF generation + - PPTX generation + - URL sharing (internal) + - Canva API integration + - Claude Code handoff bundle packaging (design + intent + tokens + specs) + +7. **Plugin Commands (for Claude Code / Cowork integration)** + - `/critique` — structured design feedback + - `/design-system` — component library audit + - `/handoff` — developer specs + - `/ux-copy` — microcopy writing/review + - `/accessibility` — WCAG 2.1 AA audit + - `/research-synthesis` — user research condensation + +8. **MCP Connectors** + - Figma MCP (design inspection, component access, token retrieval) + - Slack MCP (sharing, notifications) + - Notion MCP (brand guidelines, design principles) + - Linear/Asana/Jira MCP (link designs to tickets) + - Analytics MCPs (Amplitude, Mixpanel) + +--- + +## All Source Links + +- [Official Anthropic Announcement](https://www.anthropic.com/news/claude-design-anthropic-labs) +- [TechCrunch](https://techcrunch.com/2026/04/17/anthropic-launches-claude-design-a-new-product-for-creating-quick-visuals/) +- [VentureBeat (most detailed)](https://venturebeat.com/technology/anthropic-just-launched-claude-design-an-ai-tool-that-turns-prompts-into-prototypes-and-challenges-figma) +- [The New Stack (first-person usage)](https://thenewstack.io/anthropic-claude-design-launch/) +- [GitHub Plugin Repository](https://github.com/anthropics/knowledge-work-plugins/tree/main/design) +- [Claude Design Plugin Page](https://claude.com/plugins/design) +- [Hacker News Discussion (459 pts, 288 comments)](https://news.ycombinator.com/item?id=47806725) +- [9to5Mac](https://9to5mac.com/2026/04/17/anthropic-launches-claude-design-for-mac-following-opus-4-7-model-upgrade/) +- [StartupHub.ai](https://www.startuphub.ai/ai-news/artificial-intelligence/2026/anthropic-unveils-claude-design) +- [Yahoo Tech](https://tech.yahoo.com/ai/claude/articles/anthropic-debuts-claude-design-building-150000621.html) +- [Canva Newsroom](https://www.canva.com/newsroom/news/canva-claude-design/) +- [Introducing Anthropic Labs](https://www.anthropic.com/news/introducing-anthropic-labs) +- [Claude X/Twitter announcement](https://x.com/claudeai/status/2045156267690213649) +- [Claude Design direct access](https://claude.ai/design) diff --git a/research/docs/2026-04-17-open-claude-design.md b/research/docs/2026-04-17-open-claude-design.md new file mode 100644 index 000000000..79175c39c --- /dev/null +++ b/research/docs/2026-04-17-open-claude-design.md @@ -0,0 +1,589 @@ +--- +date: 2026-04-17 11:09:30 PDT +researcher: Claude (Opus 4.6) +git_commit: 200d34dc71f85663a560c1d17aab66a40dd9e5b8 +branch: flora131/feature/open-claude-design +repository: atomic-open-claude-design +topic: "Open Claude Design — open-source replica of Anthropic's Claude Design using the Atomic workflow SDK" +tags: [research, workflow, claude-design, design-tool, open-source, sdk] +status: complete +last_updated: 2026-04-17 +last_updated_by: Claude (Opus 4.6) +--- + +# Open Claude Design — Research Document + +## Research Question + +Anthropic Labs released Claude Design (https://www.anthropic.com/news/claude-design-anthropic-labs) on April 17, 2026. The goal is to create an open-source replica of this product using the Atomic workflow SDK, offered as a built-in workflow called `open-claude-design` alongside the existing `deep-research-codebase` and `ralph` workflows. + +## Summary + +Claude Design is a 6-phase AI-powered design tool that enables conversational visual design — from design system onboarding through generation, refinement, and handoff to Claude Code. This research maps every phase to existing Atomic workflow SDK primitives and identifies what already exists in the codebase vs. what needs to be built. The Atomic SDK's `defineWorkflow().for<"claude">().run().compile()` pattern, combined with `ctx.stage()` for sub-agent orchestration, provides the full runtime needed to implement this workflow. The existing skills (`impeccable`, `critique`, `shape`, `playwright-cli`, etc.) and agent types (`planner`, `orchestrator`, `reviewer`, `worker`, `debugger`) cover ~70% of the required capabilities. + +--- + +## Part 1: Claude Design — Official Workflow (6 Phases) + +Source: [Anthropic Announcement](https://www.anthropic.com/news/claude-design-anthropic-labs) + +Claude Design's workflow is NOT the 4-phase model initially hypothesized (research/planning/implementation/validation). It is a **6-phase creative flow**: + +### Phase 1: Design System Onboarding — "Your brand, built in" + +| Aspect | Detail | +|---|---| +| **What happens** | Claude reads the team's codebase and design files, constructs a design system (colors, typography, components) | +| **User interaction** | Human-in-the-loop at each major decision — user approves or requests changes to each design element | +| **Output** | Structured design system representation (not raw files) | +| **Key behaviors** | Auto-applied to every subsequent project; supports multiple design systems per team; refine-able over time | +| **Data privacy** | Stores representation only; code is never uploaded to Anthropic servers | + +### Phase 2: Import — "Import from anywhere" + +| Aspect | Detail | +|---|---| +| **Input methods** | Text prompt, image upload, document upload (DOCX/PPTX/XLSX), codebase reference, **web capture tool** (scrapes live website) | +| **User interaction** | User chooses inputs; no approval gate — proceeds directly to generation | +| **Key capability** | Web capture tool scrapes visual elements from live URLs so prototypes match the real product | + +### Phase 3: Generation — First Version + +| Aspect | Detail | +|---|---| +| **What happens** | Claude generates the first version using design system + input + conversation context | +| **Output types** | Interactive prototypes, wireframes/mockups, pitch decks, marketing collateral, **frontier design** (voice/video/shaders/3D/AI) | +| **Model** | Claude Opus 4.7 (vision model, 2576px max long edge, 98.5% XBOW visual-acuity) | + +### Phase 4: Refinement — "Refine with fine-grained controls" + +| Aspect | Detail | +|---|---| +| **Mechanisms** | Chat conversation, inline comments, direct text editing, Claude-generated adjustment sliders/knobs, drawing/annotation, global change propagation | +| **Distinctive feature** | Claude generates context-specific sliders (spacing, color, layout) per design — live tweaking without prompting | +| **Iteration** | Multiple rounds; Brilliant example: 20+ prompts in other tools → 2 prompts in Claude Design | + +### Phase 5: Collaboration — "Collaborate" + +| Aspect | Detail | +|---|---| +| **Share modes** | Private, view-only link, edit access (multi-user Claude conversation) | +| **Key capability** | Group conversation — multiple team members interact with Claude simultaneously | + +### Phase 6: Export and Handoff + +| Aspect | Detail | +|---|---| +| **Export formats** | Internal URL, folder, Canva (fully editable), PDF, PPTX, standalone HTML | +| **Claude Code handoff** | Packages design + design intent + tokens + component specs into a bundle passable to Claude Code | +| **Key differentiator** | Closed loop: exploration → prototype → production code within Anthropic's ecosystem | + +### Design Plugin Commands (Claude Code/Cowork) + +Source: [GitHub Plugin Repository](https://github.com/anthropics/knowledge-work-plugins/tree/main/design) + +| Command | Description | +|---|---| +| `/critique` | Structured design feedback: usability, visual hierarchy, accessibility, consistency | +| `/design-system` | Audit, document, or extend component libraries and tokens | +| `/handoff` | Developer handoff specs: measurements, tokens, states, interactions, edge cases | +| `/ux-copy` | Write/review microcopy, error messages, empty states, onboarding flows | +| `/accessibility` | WCAG 2.1 AA compliance audit with severity ratings | +| `/research-synthesis` | Condense user research into actionable insights | + +--- + +## Part 2: Existing Atomic Workflow SDK — Architecture + +### Workflow Definition Pattern + +``` +src/sdk/workflows/builtin// +├── claude/index.ts ← defineWorkflow().for<"claude">().run().compile() +├── copilot/index.ts ← defineWorkflow().for<"copilot">().run().compile() +├── opencode/index.ts ← defineWorkflow().for<"opencode">().run().compile() +└── helpers/ + ├── prompts.ts ← All prompt builders + ├── review.ts ← Domain-specific logic + └── git.ts ← Utility helpers +``` + +**Key API surface:** + +| Primitive | Purpose | +|---|---| +| `defineWorkflow({ name, description, inputs })` | Create workflow builder with typed inputs | +| `.for<"claude">()` | Narrow agent type for TypeScript inference | +| `.run(async (ctx) => { ... })` | Define the workflow entry point | +| `.compile()` | Seal into `WorkflowDefinition` consumed by CLI | +| `ctx.stage(options, clientOpts, sessionOpts, callback)` | Spawn a sub-agent session | +| `ctx.transcript(handle)` | Read completed session output | +| `s.session.query(prompt, sdkOpts?)` | Send prompt to agent (visible or headless) | +| `s.save(sessionId)` | Persist session transcript | +| `extractAssistantText(result, afterIndex)` | Extract text from headless query result | + +### Stage Types + +| Type | Config | Behavior | +|---|---|---| +| **Visible** | `{ name: "...", headless: false }` + `clientOpts.chatFlags` | Spawns tmux window, visible in graph | +| **Headless** | `{ name: "...", headless: true }` + `sdkOpts: { agent, permissionMode }` | In-process via Agent SDK, invisible in graph | + +### Parallel Execution + +`Promise.all([ctx.stage(...), ctx.stage(...)])` — stages spawned in the same synchronous frame become siblings in the graph. The `GraphFrontierTracker` auto-infers topology from execution order. + +### Existing Built-in Workflows + +**Ralph** (`src/sdk/workflows/builtin/ralph/claude/index.ts`): +- Plan → Orchestrate → Review → Debug loop with bounded iteration (MAX_LOOPS=10) +- Uses visible stages for planner, orchestrator, reviewer, debugger +- Uses headless stages for infrastructure discovery (locator, analyzer, pattern-finder) +- Parallel reviewer passes (2 reviewers, merged results) +- Exit condition: both reviewers agree code is clean + +**deep-research-codebase** (`src/sdk/workflows/builtin/deep-research-codebase/claude/index.ts`): +- Scout → per-partition specialist fan-out → aggregator +- Pure deterministic synthesis (no LLM call for concatenation) +- Six specialist agents: locator, pattern-finder, analyzer, online-researcher, research-locator, research-analyzer + +### Available Agent Types + +These are defined as `.md` files in `.claude/agents/`: + +| Agent | Role | +|---|---| +| `orchestrator` | Delegate to sub-agents for complex tasks | +| `planner` | Author technical design documents / RFCs | +| `reviewer` | Code review with structured JSON output | +| `debugger` | Error investigation and root cause analysis | +| `worker` | Single task implementation | +| `codebase-locator` | Find files and components | +| `codebase-analyzer` | Analyze implementation details | +| `codebase-pattern-finder` | Find existing patterns and examples | +| `codebase-research-locator` | Discover research documents | +| `codebase-research-analyzer` | Extract insights from research docs | +| `codebase-online-researcher` | Fetch external documentation | +| `code-simplifier` | Simplify and refine code | + +### Available Design Skills + +Located in `.agents/skills/`: + +| Skill | Relevance to Open Claude Design | +|---|---| +| `impeccable` | **Core** — UI/UX design covering color, contrast, craft, interaction, motion, responsive, spatial, typography, UX writing | +| `critique` | **Core** — Design critique methodology with cognitive load, heuristic scoring, personas | +| `shape` | **Core** — UX/UI planning before code: structured discovery interview → design brief | +| `layout` | **Core** — Layout system, grid, spacing, visual hierarchy | +| `delight` | Enhancement — Micro-interactions, joy, personality | +| `polish` | Enhancement — Final quality pass for alignment, spacing, consistency | +| `animate` | Enhancement — Purposeful animations and motion effects | +| `adapt` | Responsive — Cross-screen/device/platform adaptation | +| `colorize` | Enhancement — Strategic color for visual interest | +| `typeset` | Enhancement — Typography hierarchy, font choices, readability | +| `clarify` | Enhancement — UX copy, error messages, microcopy | +| `harden` | Production — Error handling, empty states, edge cases | +| `audit` | Validation — Accessibility, performance, theming, responsive checks | +| `normalize` | Consistency — Design system alignment, token usage | +| `extract` | System — Extract reusable components and design tokens | +| `playwright-cli` | **Core** — Browser automation, screenshots, visual validation | +| `opentui` | Terminal UI — Components, layout, keyboard, animations | +| `typescript-react-reviewer` | Review — React code quality and anti-patterns | +| `workflow-creator` | Meta — Create workflows using the SDK | + +### Browser Automation (Playwright) + +The `playwright-cli` skill provides: +- Page navigation, screenshots, and visual snapshots +- Element interaction (click, fill, hover, drag) +- Network request interception and mocking +- Console message capture +- Session and storage state management +- Video recording and tracing +- Test generation from interactions + +--- + +## Part 3: Phase-by-Phase SDK Mapping + +### Phase 1: Design System Onboarding → `design-system-builder` stage + +**What to build:** + +``` +Stage: design-system-builder (visible) +Agent: orchestrator or custom "design-system-builder" agent +Skills: impeccable, extract, normalize, colorize, typeset +``` + +| Claude Design Capability | Atomic SDK Mapping | Status | +|---|---|---| +| Read codebase for design tokens | `codebase-locator` + `codebase-analyzer` (headless stages) | **Exists** | +| Extract colors, fonts, spacing | `extract` skill + custom prompt in `helpers/design-system.ts` | **Partial** — skill exists, prompt needs authoring | +| Read design files (DOCX/PPTX/XLSX) | `liteparse` skill | **Exists** | +| Human-in-the-loop approval | `ctx.stage()` with visible session — user interacts in tmux pane | **Exists** — Ralph's planner stage pattern | +| Persist design system | Write to `.open-claude-design/design-system.json` or similar | **New** — needs file format design | +| Multiple design systems | Config flag or prompt input | **New** | + +**Implementation approach:** +1. Headless `codebase-locator` stage finds CSS/Tailwind/design files +2. Headless `codebase-analyzer` stage extracts tokens (colors, fonts, spacing, components) +3. Visible `design-system-builder` stage presents findings, asks user to approve/modify +4. Helper function persists design system to a JSON/YAML file + +### Phase 2: Import → `import` stage + +**What to build:** + +``` +Stage: import (headless or visible depending on input type) +Skills: playwright-cli, liteparse +``` + +| Claude Design Capability | Atomic SDK Mapping | Status | +|---|---|---| +| Text prompt input | `ctx.inputs.prompt` — already the standard pattern | **Exists** | +| Image upload | Pass image path as input; Claude Opus vision processes it | **Exists** — model capability | +| Document upload (DOCX/PPTX/XLSX) | `liteparse` skill parses document → text/structure | **Exists** | +| Codebase reference | `codebase-locator` + `codebase-analyzer` stages | **Exists** | +| Web capture tool | `playwright-cli` skill: navigate to URL, take screenshot, extract DOM/CSS | **Exists** — skill is fully equipped | + +**Implementation approach:** +1. Workflow input accepts `prompt` (text), `reference` (file/URL), and `design-system` (path) +2. If URL detected: headless stage with `playwright-cli` captures screenshot + DOM structure +3. If file detected: `liteparse` parses content +4. All inputs aggregated into a structured context for the generation stage + +### Phase 3: Generation → `generator` stage + +**What to build:** + +``` +Stage: generator (visible) +Agent: custom "design-generator" agent +Skills: impeccable, shape, layout, colorize, typeset, delight +``` + +| Claude Design Capability | Atomic SDK Mapping | Status | +|---|---|---| +| Generate interactive prototype (HTML/CSS/JS) | Visible stage with `impeccable` skill — generates production-grade frontend code | **Exists** | +| Generate wireframes | `shape` skill — structured discovery → design brief → wireframe | **Exists** | +| Apply design system context | Inject design system from Phase 1 into prompt context | **New** — prompt template needed | +| Frontier design (voice/video/3D) | `impeccable` + `overdrive` skills; `animate` for motion | **Partial** — skills exist, 3D/shader would need model capability | + +**Implementation approach:** +1. Build `buildGeneratorPrompt()` in `helpers/prompts.ts` that injects: + - Design system (from Phase 1) + - Import context (from Phase 2) + - User's original prompt + - Output type preference (prototype/wireframe/deck/collateral) +2. Visible stage generates first version — user sees output in real time +3. Output is HTML/CSS/JS written to a scratch directory + +### Phase 4: Refinement → `refine-loop` (iterative stages) + +**What to build:** + +``` +Stages: refine-{iteration} (visible, looped) +Agent: custom "design-refiner" agent +Skills: impeccable, critique, layout, polish, adapt, clarify +``` + +| Claude Design Capability | Atomic SDK Mapping | Status | +|---|---|---| +| Chat conversation refinement | Visible stage — user chats in tmux pane | **Exists** | +| Inline comments | Not directly available in TUI; fallback: reference elements by description/selector | **Adaptation needed** | +| Direct text editing | User can edit generated files directly; re-run validation | **Exists** — file system is accessible | +| Claude-generated adjustment sliders | Not applicable in TUI context; adaptation: Claude proposes variations, user picks | **Adaptation needed** | +| Drawing/annotation | Not applicable in TUI; adaptation: describe changes verbally | **N/A for TUI** | +| Global change propagation | Agent applies changes across all generated files | **Exists** — worker agent can do this | + +**Implementation approach — borrowing from Ralph's review-debug loop:** + +```typescript +for (let iteration = 1; iteration <= MAX_REFINEMENTS; iteration++) { + // 1. User provides feedback in visible stage + const feedback = await ctx.stage( + { name: `refine-${iteration}` }, + { chatFlags: ["--agent", "design-refiner", ...SKIP_PERMS] }, + {}, + async (s) => { + await s.session.query(buildRefinePrompt(prompt, { iteration, designDir })); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ); + + // 2. Parallel validation (critique + screenshot comparison) + const [critiqueResult, screenshotResult] = await Promise.all([ + ctx.stage( + { name: `critique-${iteration}`, headless: true }, + {}, {}, + async (s) => { + const result = await s.session.query( + buildCritiquePrompt(designDir), + { agent: "reviewer", ...SUBAGENT_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ), + ctx.stage( + { name: `screenshot-${iteration}`, headless: true }, + {}, {}, + async (s) => { + // Use playwright to screenshot the generated HTML + const result = await s.session.query( + buildScreenshotValidationPrompt(designDir), + { agent: "codebase-analyzer", ...SUBAGENT_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ), + ]); + + // 3. If user signals "done" or critique passes → break + if (isRefinementComplete(feedback.result)) break; +} +``` + +### Phase 5: Collaboration → Out of scope for CLI workflow + +Collaboration (multi-user shared sessions) is a web UI feature, not replicable in a CLI/TUI workflow. The open-source version can support: +- Generating shareable artifacts (HTML files, URLs) +- Committing designs to git for team access +- Exporting to formats others can use + +### Phase 6: Export and Handoff → `export` stage + +**What to build:** + +``` +Stage: export (visible or headless) +Agent: custom "design-exporter" agent +Skills: pdf, pptx, docx, handoff +``` + +| Claude Design Capability | Atomic SDK Mapping | Status | +|---|---|---| +| Export as HTML | Write generated files to output directory | **Trivial** | +| Export as PDF | `pdf` skill | **Exists** | +| Export as PPTX | `pptx` skill | **Exists** | +| Canva export | Would need Canva API integration via MCP | **New** | +| Claude Code handoff bundle | Package design + intent + tokens → handoff spec | **New** — key deliverable | + +**Handoff bundle structure** (based on Claude Design's approach): + +``` +handoff/ +├── design/ ← Generated HTML/CSS/JS +├── design-system.json ← Design tokens, colors, typography +├── design-intent.md ← Reasoning behind design decisions +├── component-specs.md ← Component specifications +├── interaction-specs.md ← Interaction and state documentation +└── handoff-prompt.md ← Ready-to-use prompt for Claude Code +``` + +--- + +## Part 4: Proposed Workflow Architecture + +### Directory Structure + +``` +src/sdk/workflows/builtin/open-claude-design/ +├── claude/index.ts ← Main workflow definition +├── copilot/index.ts ← Copilot provider (future) +├── opencode/index.ts ← OpenCode provider (future) +└── helpers/ + ├── prompts.ts ← All prompt builders + ├── design-system.ts ← Design system persistence/loading + ├── web-capture.ts ← URL capture via playwright + ├── validation.ts ← Critique/screenshot validation + ├── export.ts ← Export format generators + └── handoff.ts ← Claude Code handoff bundle +``` + +### Workflow Topology (Claude provider) + +``` + ┌─→ codebase-locator (headless) + │ + design-system ────┤─→ codebase-analyzer (headless) + (visible, HIL) │ + └─→ file-parser (headless, if design files exist) + │ + ▼ + import (headless) ─── web-capture (headless, if URL input) + │ + ▼ + generator (visible) ─── applies design system + import context + │ + ▼ + ┌────────────────────────────────────────────────┐ + │ Refinement Loop (bounded, like Ralph) │ + │ │ + │ refine-{i} (visible, HIL) ─→ user feedback │ + │ │ │ + │ ├─→ critique-{i} (headless) │ + │ └─→ screenshot-{i} (headless) │ + │ │ │ + │ ▼ │ + │ apply-changes-{i} (visible) ─→ implements │ + │ │ feedback │ + │ ▼ │ + │ (loop until user approves or MAX_REFINEMENTS) │ + └────────────────────────────────────────────────┘ + │ + ▼ + export (visible) ─→ HTML / PDF / PPTX / handoff bundle +``` + +### Workflow Inputs + +```typescript +defineWorkflow({ + name: "open-claude-design", + description: "AI-powered design workflow: design system → generate → refine → export/handoff", + inputs: [ + { name: "prompt", type: "text", required: true, description: "Design request" }, + { name: "reference", type: "text", required: false, description: "URL, file path, or codebase path for import" }, + { name: "output-type", type: "enum", required: false, values: ["prototype", "wireframe", "deck", "collateral", "frontier"], default: "prototype", description: "Type of design output" }, + { name: "design-system", type: "text", required: false, description: "Path to existing design system file" }, + { name: "skip-onboarding", type: "enum", required: false, values: ["true", "false"], default: "false", description: "Skip design system onboarding if already exists" }, + ], +}) +``` + +### Key Prompt Builders Needed + +| Function | Purpose | Reference Pattern | +|---|---|---| +| `buildDesignSystemPrompt()` | Onboarding: extract + propose design system | Ralph's `buildPlannerPrompt()` | +| `buildImportPrompt()` | Parse inputs: URL capture, file parse, codebase scan | deep-research's `buildLocatorPrompt()` | +| `buildGeneratorPrompt()` | Generate first version with design system context | Custom — combines impeccable + shape skills | +| `buildRefinePrompt()` | Refinement iteration with previous version context | Ralph's `buildOrchestratorPrompt()` | +| `buildCritiquePrompt()` | Design critique with structured output | Ralph's `buildReviewPrompt()` pattern | +| `buildScreenshotValidationPrompt()` | Visual validation via playwright screenshot | Custom — uses playwright-cli skill | +| `buildExportPrompt()` | Generate export in requested format | Custom | +| `buildHandoffPrompt()` | Package handoff bundle with design intent | Custom — based on Claude Design's handoff spec | + +--- + +## Part 5: Existing Capabilities vs. New Work + +### Already Exists (can be directly reused) + +| Capability | Source | +|---|---| +| Workflow SDK (`defineWorkflow`, `ctx.stage`, `Promise.all`) | `src/sdk/define-workflow.ts`, `src/sdk/runtime/executor.ts` | +| Sub-agent dispatch (headless + visible) | `src/sdk/providers/claude.ts` | +| Iterative loop with exit condition | Ralph workflow pattern (`ralph/claude/index.ts`) | +| Parallel review/validation passes | Ralph's dual-reviewer pattern | +| Codebase analysis (locator + analyzer + pattern-finder) | deep-research-codebase pattern | +| Design skills (impeccable, critique, shape, layout, etc.) | `.agents/skills/` | +| Browser automation (playwright-cli) | `.agents/skills/playwright-cli/` | +| Document parsing (DOCX/PPTX/XLSX) | `liteparse` skill | +| Export formats (PDF, PPTX) | `pdf` and `pptx` skills | +| Git changeset capture | `ralph/helpers/git.ts` | +| Prompt builder pattern | `ralph/helpers/prompts.ts` | +| Structured review output (Zod schemas) | `ralph/helpers/prompts.ts` | +| Workflow registration/discovery | `src/sdk/runtime/discovery.ts` | + +### Needs to Be Built + +| Capability | Complexity | Notes | +|---|---|---| +| Design system extractor/persister | Medium | Read codebase → extract tokens → persist JSON | +| Web capture helper (URL → screenshot + DOM) | Low | Playwright-cli skill already does this; needs a helper wrapper | +| Generator prompt template | Medium | Combine design system + inputs → generation prompt | +| Refinement loop controller | Low | Follow Ralph's iterative loop pattern | +| Critique/validation structured output | Medium | Adapt Ralph's `ReviewResultSchema` for design critique | +| Screenshot comparison/validation | Medium | Use playwright to capture, model to compare | +| Export helper (HTML/PDF/PPTX) | Low | Thin wrappers around existing skills | +| Handoff bundle packager | Medium | Design intent extraction + token/spec packaging | +| Custom agent definitions | Low | New `.claude/agents/design-*.md` files | + +### Not Applicable (CLI/TUI limitations) + +| Claude Design Feature | Why N/A | Alternative | +|---|---|---| +| Inline comments on elements | Web UI feature | Describe elements verbally in chat | +| Claude-generated adjustment sliders | Web UI feature | Claude proposes variations, user picks | +| Drawing/annotation on canvas | Web UI feature | Verbal descriptions of desired changes | +| Multi-user collaboration | Web UI feature | Git-based sharing, exported artifacts | +| Real-time slider tweaking | Web UI feature | Iterative prompt refinement | + +--- + +## Part 6: Plugin Commands Mapping + +The Claude Design plugin commands map directly to existing Atomic skills: + +| Plugin Command | Atomic Skill(s) | Implementation | +|---|---|---| +| `/critique` | `critique` skill | Already exists — structured design feedback | +| `/design-system` | `extract` + `normalize` skills | Already exists — audit/extend component libraries | +| `/handoff` | New `handoff` helper | Needs implementation — measurements, tokens, states | +| `/ux-copy` | `clarify` skill | Already exists — microcopy, error messages, UX writing | +| `/accessibility` | `audit` skill | Already exists — WCAG compliance checks | +| `/research-synthesis` | `research-codebase` skill | Already exists — condense research into insights | + +--- + +## Code References + +- `src/sdk/define-workflow.ts:186-195` — `defineWorkflow()` entry point +- `src/sdk/workflows/builtin/ralph/claude/index.ts:54-248` — Ralph workflow (primary implementation reference) +- `src/sdk/workflows/builtin/ralph/helpers/prompts.ts:1-1078` — Ralph prompt builders (pattern reference) +- `src/sdk/workflows/builtin/ralph/helpers/review.ts:1-33` — Review analysis helpers +- `src/sdk/workflows/builtin/ralph/helpers/git.ts:1-201` — Git changeset capture +- `src/sdk/workflows/builtin/deep-research-codebase/claude/index.ts:96-413` — Deep research workflow (parallel sub-agent pattern) +- `src/sdk/workflows/index.ts:1-116` — Workflow SDK public exports +- `src/sdk/runtime/discovery.ts` — Workflow discovery and registration +- `src/sdk/runtime/loader.ts` — Workflow loading pipeline +- `src/sdk/runtime/executor.ts` — Workflow execution runtime +- `src/sdk/providers/claude.ts` — Claude provider (session, query, extract) +- `.agents/skills/impeccable/SKILL.md` — Core design skill +- `.agents/skills/critique/SKILL.md` — Design critique skill +- `.agents/skills/shape/SKILL.md` — UX/UI planning skill +- `.agents/skills/playwright-cli/SKILL.md` — Browser automation skill +- `.impeccable.md` — Project design context + +## Architecture Documentation + +The Atomic workflow SDK follows these patterns: + +1. **Builder pattern**: `defineWorkflow().for().run().compile()` creates a sealed `WorkflowDefinition` +2. **Stage-based orchestration**: `ctx.stage()` manages full sub-agent lifecycle (tmux window, provider init, callback, transcript save) +3. **Dual execution modes**: Visible stages spawn tmux windows with CLI flags; headless stages use Agent SDK's in-process `query()` +4. **Helpers pattern**: Prompt text and domain logic live in `helpers/`, topology in `index.ts` +5. **Parallel execution**: `Promise.all()` + `GraphFrontierTracker` for automatic topology inference +6. **Discovery**: Built-in workflows at `src/sdk/workflows/builtin///index.ts`, reserved names cannot be overridden + +## Historical Context (from research/) + +- `research/docs/2026-01-31-atomic-current-workflow-architecture.md` — Comprehensive workflow architecture analysis +- `research/docs/2026-01-31-claude-agent-sdk-research.md` — Claude Agent SDK research +- `research/docs/2026-02-02-atomic-builtin-workflows-research.md` — Built-in workflows research +- `research/docs/2026-02-05-pluggable-workflows-sdk-design.md` — Pluggable workflows SDK design +- `research/docs/2026-02-25-workflow-sdk-design.md` — Workflow SDK design +- `research/docs/2026-03-20-ralph-workflow-redesign-analysis.md` — Ralph workflow redesign analysis + +## Related Research + +- `research/docs/2026-04-17-claude-design-product-analysis.md` — Detailed Claude Design product analysis +- `research/web/2026-04-17-claude-design-anthropic-labs.md` — Raw source collection from online research + +## Open Questions + +1. **Design system persistence format**: JSON vs YAML vs TypeScript? Where should it be stored (`.open-claude-design/` in project root)? +2. **Refinement exit condition**: Should the user explicitly signal "done", or should the workflow detect satisfaction from conversation context? +3. **Screenshot validation approach**: Use playwright to render generated HTML and compare screenshots, or rely purely on model-based visual critique? +4. **Handoff bundle format**: What exact structure for the Claude Code handoff? Should it include a ready-to-use prompt or just specs? +5. **Frontier design scope**: How much of the voice/video/3D/shader capability is achievable in CLI context? Should this be deferred? +6. **Multi-agent scope for Claude-only vs. all providers**: Start with Claude-only (like deep-research), or scaffold all three providers from the start? +7. **Custom agent definitions**: Should we create new agents (`design-generator`, `design-refiner`, `design-exporter`) or reuse existing agents with skill-specific prompts? diff --git a/research/web/2026-04-17-claude-design-anthropic-labs.md b/research/web/2026-04-17-claude-design-anthropic-labs.md new file mode 100644 index 000000000..4033d11c9 --- /dev/null +++ b/research/web/2026-04-17-claude-design-anthropic-labs.md @@ -0,0 +1,269 @@ +--- +source_url: https://www.anthropic.com/news/claude-design-anthropic-labs +fetched_at: 2026-04-17 +fetch_method: html-parse + playwright-cli + web-search +topic: Claude Design by Anthropic Labs — official announcement, coverage, and plugin details +additional_sources: + - https://techcrunch.com/2026/04/17/anthropic-launches-claude-design-a-new-product-for-creating-quick-visuals/ + - https://venturebeat.com/technology/anthropic-just-launched-claude-design-an-ai-tool-that-turns-prompts-into-prototypes-and-challenges-figma + - https://thenewstack.io/anthropic-claude-design-launch/ + - https://github.com/anthropics/knowledge-work-plugins/tree/main/design + - https://claude.com/plugins/design + - https://news.ycombinator.com/item?id=47806725 + - https://www.startuphub.ai/ai-news/artificial-intelligence/2026/anthropic-unveils-claude-design + - https://www.canva.com/newsroom/news/canva-claude-design/ + - https://www.anthropic.com/news/introducing-anthropic-labs +--- + +# Claude Design by Anthropic Labs — Primary Source Collection + +## Official Anthropic Announcement (Full Extracted Text) + +Source: https://www.anthropic.com/news/claude-design-anthropic-labs +Published: April 17, 2026 + +> Today, we're launching Claude Design, a new Anthropic Labs product that lets you collaborate with Claude to create polished visual work like designs, prototypes, slides, one-pagers, and more. Claude Design is powered by our most capable vision model, Claude Opus 4.7, and is available in research preview for Claude Pro, Max, Team, and Enterprise subscribers. We're rolling out to users gradually throughout the day. + +### Design with Claude + +> Even experienced designers have to ration exploration—there's rarely time to prototype a dozen directions, so you limit yourself to a few. And for founders, product managers, and marketers with an idea but not a design background, creating and sharing those ideas can be daunting. Claude Design gives designers room to explore widely and everyone else a way to produce visual work. Describe what you need and Claude builds a first version. From there, you refine through conversation, inline comments, direct edits, or custom sliders (made by Claude) until it's right. When given access, Claude can also apply your team's design system to every project automatically, so the output is consistent with the rest of your company's designs. + +### Use Cases (from official announcement) + +Teams have been using Claude Design for: + +- **Realistic prototypes**: Designers can turn static mockups into easily-shareable interactive prototypes to gather feedback and user-test, without code review or PRs. +- **Product wireframes and mockups**: Product Managers can sketch out feature flows and hand them off to Claude Code for implementation, or share them with designers to refine further. +- **Design explorations**: Designers can quickly create a wide range of directions to explore. +- **Pitch decks and presentations**: Founders and Account Executives can go from a rough outline to a complete, on-brand deck in minutes, and then export as a PPTX or send to Canva. +- **Marketing collateral**: Marketers can create landing pages, social media assets, and campaign visuals, then loop in designers to polish. +- **Frontier design**: Anyone can build code-powered prototypes with voice, video, shaders, 3D and built-in AI. + +### How It Works (Official Workflow Description) + +Claude Design follows a natural creative flow: + +**1. Your brand, built in.** +> During onboarding, Claude builds a design system for your team by reading your codebase and design files. Every project after that uses your colors, typography, and components automatically. You can refine the system over time, and teams can maintain more than one. + +**2. Import from anywhere.** +> Start from a text prompt, upload images and documents (DOCX, PPTX, XLSX), or point Claude at your codebase. You can also use the web capture tool to grab elements directly from your website so prototypes look like the real product. + +**3. Refine with fine-grained controls.** +> Comment inline on specific elements, edit text directly, or use adjustment knobs to tweak spacing, color, and layout live. Then ask Claude to apply your changes across the full design. + +**4. Collaborate.** +> Designs have organization-scoped sharing. You can keep a document private, share it so anyone in your organization with the link can view it, or grant edit access so colleagues can modify the design and chat with Claude together in a group conversation. + +**5. Export anywhere.** +> Share designs as an internal URL within your organization, save as a folder, or export to Canva, PDF, PPTX, or standalone HTML files. + +**6. Handoff to Claude Code.** +> When a design is ready to build, Claude packages everything into a handoff bundle that you can pass to Claude Code with a single instruction. + +> Over the coming weeks, we'll make it easier to build integrations with Claude Design, so you can connect it to more of the tools your team already uses. + +### Partner Testimonials (Official) + +**Melanie Perkins, Co-Founder and CEO, Canva:** +> We've loved collaborating with Anthropic over the past couple of years and share a deep focus on making complex things simple. At Canva, our mission has always been to empower the world to design, and that means bringing Canva to wherever ideas begin. We're excited to build on our collaboration with Claude, making it seamless for people to bring ideas and drafts from Claude Design into Canva, where they instantly become fully editable and collaborative designs ready to refine, share, and publish. + +**Olivia Xu, Senior Product Designer, Brilliant:** +> Brilliant's intricate interactivity and animations are historically painful to prototype, but Claude Design's ability to turn static designs into interactive prototypes has been a step change for us. Our most complex pages, which took 20+ prompts to recreate in other tools, only required 2 prompts in Claude Design. Including design intent in Claude Code handoffs has made the jump from prototype to production seamless. + +**Aneesh Kethini, Product Manager, Datadog:** +> Claude Design has made prototyping dramatically faster for our team, enabling live design during conversations. We've gone from a rough idea to a working prototype before anyone leaves the room, and the output stays true to our brand and design guidelines. What used to take a week of back-and-forth between briefs, mockups, and review rounds now happens in a single conversation. + +### Access & Pricing + +- Available for Claude Pro, Max, Team, and Enterprise subscribers +- Included with plan subscription limits; extra usage available as pay-as-you-go +- For Enterprise: off by default, admins enable in Organization settings +- Entry point: claude.ai/design + +--- + +## TechCrunch Coverage + +Source: https://techcrunch.com/2026/04/17/anthropic-launches-claude-design-a-new-product-for-creating-quick-visuals/ +Author: Aisha Malik, Published: April 17, 2026 + +Key excerpts: +- Claude Design is "intended to help people like founders and product managers without a design background share their ideas more easily." +- "While Claude Design may initially seem like it's looking to compete with popular design app Canva... Anthropic told TechCrunch that it's intended to complement it rather than replace it." +- "Claude Design can also apply a team's design system to every project it creates so that the results are consistent with the company's overall visual style. Anthropic says Claude Design is able to do this by reading a company's codebase and design files." +- The launch follows Claude Cowork (January 2026) and agentic plug-ins for Cowork. +- Anthropic is in discussions for a potential IPO at ~$800B valuation. + +--- + +## VentureBeat Coverage (Most Detailed Technical/Business Analysis) + +Source: https://venturebeat.com/technology/anthropic-just-launched-claude-design-an-ai-tool-that-turns-prompts-into-prototypes-and-challenges-figma +Author: Michael Nuñez, Published: April 17, 2026 + +Key technical details: + +**Workflow:** +> The product follows a workflow that Anthropic has designed to feel like a natural creative conversation. Users describe what they need, and Claude generates a first version. From there, refinement happens through a combination of channels: chat-based conversation, inline comments on specific elements, direct text editing, and custom adjustment sliders that Claude itself generates to let users tweak spacing, color, and layout in real time. + +**Design System Onboarding:** +> During onboarding, Claude reads a team's codebase and design files and builds a design system — colors, typography, and components — that it automatically applies to every subsequent project. + +**Web Capture Tool:** +> A web capture tool grabs elements directly from a live website so prototypes look like the real product. + +**Handoff Mechanism:** +> What distinguishes Claude Design from the wave of AI design experiments that have proliferated in the past year is the handoff mechanism. When a design is ready to build, Claude packages everything into a handoff bundle that can be passed to Claude Code with a single instruction. That creates a closed loop — exploration to prototype to production code — all within Anthropic's ecosystem. + +**Export Options:** +> Users can also share designs as an internal URL within their organization, save as a folder, or export to Canva, PDF, PPTX, or standalone HTML files. + +**Data Privacy:** +> The system stores the design-system representation it generates — not the source files themselves. When users link a local copy of their code, it is not uploaded to or stored on Anthropic's servers. Anthropic states unequivocally that it does not train on this data. + +**Model (Claude Opus 4.7) details:** +- Reached 64.3% on SWE-bench Pro +- 13% resolution improvement over Opus 4.6 on internal 93-task coding benchmark +- Vision: can accept images up to 2,576 pixels on the long edge (~3.75 megapixels, 3x prior models) +- XBOW reported 98.5% on visual-acuity benchmark vs 54.5% for Opus 4.6 + +**Business Context:** +- Anthropic hit ~$20B ARR in early March 2026, ~$30B by early April 2026 +- In early IPO talks with Goldman Sachs, JPMorgan, Morgan Stanley (possible Oct 2026) +- Mike Krieger (Instagram co-founder, former Anthropic CPO) resigned from Figma's board April 14 +- Figma's stock lost another 5% right after Claude Design launched + +--- + +## The New Stack Coverage + +Source: https://thenewstack.io/anthropic-claude-design-launch/ +Author: Frederic Lardinois, Published: April 17, 2026 + +First-person usage notes: +- Claude Design comes with weekly token limits for paid plans; after building a design system and a news website prototype plus tweaks and one explainer video, used over 50% of weekly allotment. +- Option to build a wireframe instead of polished mockup (uses fewer tokens). +- Design system onboarding: Claude chooses colors and fonts, creates design elements, but user gets last word on virtually every aspect — approves or requests changes. +- Can go back and make changes after seeing final results. +- Inline commenting on specific design elements (similar to OpenAI Codex for visual assets). +- Can draw on designs and edit elements directly (background colors, fonts). +- Most interesting: the model generates sliders and options you'd like to see to tweak design in real-time, without having to ask Claude for changes. + +--- + +## GitHub Plugin Repository: knowledge-work-plugins/design + +Source: https://github.com/anthropics/knowledge-work-plugins/tree/main/design +Raw README: https://raw.githubusercontent.com/anthropics/knowledge-work-plugins/main/design/README.md + +### Plugin Commands (Slash Commands) + +| Command | Description | +|---|---| +| `/critique` | Get structured design feedback — usability, visual hierarchy, accessibility, and consistency | +| `/design-system` | Audit, document, or extend your design system — components, tokens, patterns | +| `/handoff` | Generate developer handoff specs — measurements, tokens, states, interactions, and edge cases | +| `/ux-copy` | Write or review UX copy — microcopy, error messages, empty states, onboarding flows | +| `/accessibility` | Run an accessibility audit — WCAG compliance, color contrast, screen reader, and keyboard navigation | +| `/research-synthesis` | Synthesize user research — interviews, surveys, usability tests into actionable insights | + +### Plugin Skills (Auto-triggered Domain Knowledge) + +| Skill | Description | +|---|---| +| `design-critique` | Evaluate designs for usability, visual hierarchy, consistency, and adherence to design principles | +| `design-system-management` | Manage design tokens, component libraries, and pattern documentation | +| `ux-writing` | Write effective microcopy — clear, concise, consistent, and brand-aligned | +| `accessibility-review` | Audit designs and code for WCAG 2.1 AA compliance | +| `user-research` | Plan, conduct, and synthesize user research — interviews, surveys, usability testing | +| `design-handoff` | Create comprehensive developer handoff documentation from designs | + +### MCP Integrations (Connectors) + +| Category | Included Servers | Other Options | +|---|---|---| +| Design tool | Figma | Sketch, Adobe XD, Framer | +| Chat | Slack | Microsoft Teams | +| Knowledge base | Notion | Confluence, Guru, Coda | +| Project tracker | Linear, Asana, Atlassian (Jira/Confluence) | Shortcut, ClickUp | +| User feedback | Intercom | Productboard, Canny, UserVoice, Dovetail | +| Product analytics | — | Amplitude, Mixpanel, Heap, FullStory | + +### Standalone vs. Supercharged + +| Capability | Standalone | Supercharged With | +|---|---|---| +| Design critique | Describe or screenshot | Figma MCP (pull designs directly) | +| Design system | Describe your system | Figma MCP (audit component library) | +| Handoff specs | Describe or screenshot | Figma MCP (exact measurements, tokens) | +| UX copy | Describe the context | Knowledge base (brand voice guidelines) | +| Accessibility | Describe or screenshot | Figma MCP, analytics for real usage data | +| Research synthesis | Paste transcripts | User feedback tools (pull raw data) | + +--- + +## Skill Detail: design-critique (from GitHub) + +Critique Framework: +1. First Impression (2 seconds) — What draws the eye, emotional reaction, is purpose clear +2. Usability — Can user accomplish their goal, navigation, interactive elements +3. Visual Hierarchy — Reading order, emphasis, whitespace, typography +4. Consistency — Design system adherence, spacing, colors, typography +5. Accessibility — Color contrast, touch targets, readability, alt text + +Output format: Markdown table of findings with severity (Critical/Moderate/Minor) and recommendations. + +--- + +## Skill Detail: design-handoff (from GitHub) + +Handoff spec includes: +- Visual Specifications: exact measurements, design token references, responsive breakpoints, component variants/states +- Interaction Specifications: click/tap behavior, hover states, transitions, gesture support +- Content Specifications: character limits, truncation, empty states, loading states, error states +- Edge Cases: min/max content, international text, slow connections, missing data +- Accessibility: focus order, ARIA labels, keyboard interactions, screen reader announcements + +Principles: +1. Don't assume — if not specified, developer will guess +2. Use tokens, not values — reference `spacing-md` not `16px` +3. Show all states — default, hover, active, disabled, loading, error, empty +4. Describe the why — helps developers make good judgment calls + +--- + +## Anthropic Labs Context + +Source: https://www.anthropic.com/news/introducing-anthropic-labs + +- Launched quietly in mid-2024 with 2 people +- Led by Mike Krieger (Instagram co-founder, former Anthropic CPO) and Ben Mann (product engineering lead) +- Krieger reports to Anthropic President Daniela Amodei +- Ami Vora took over the main Product organization +- Labs track record: Claude Code (became $1B product in 6 months), MCP (100M monthly downloads), Cowork (built in 1.5 weeks), Skills, Claude in Chrome +- Planning to double headcount within 6 months + +--- + +## Hacker News Discussion + +Source: https://news.ycombinator.com/item?id=47806725 +459 points, 288 comments (at time of fetch) + +Key community insight (pilgrim0): +> On Notes on the Synthesis of Form, Alexander defines design as the rationalization of the forces that define a problem... Anyone equipped with a synthesis tool and feeling empowered to quickly and cheaply generate forms will almost inevitably become blind to the very nature of the underlying problems they set to solve. + +(Community debate about whether AI design tools help or hinder genuine design thinking.) + +--- + +## Additional Sources + +- [9to5Mac coverage](https://9to5mac.com/2026/04/17/anthropic-launches-claude-design-for-mac-following-opus-4-7-model-upgrade/) +- [Yahoo Tech / The Information coverage](https://tech.yahoo.com/ai/claude/articles/anthropic-debuts-claude-design-building-150000621.html) +- [StartupHub.ai coverage](https://www.startuphub.ai/ai-news/artificial-intelligence/2026/anthropic-unveils-claude-design) +- [Canva Newsroom announcement](https://www.canva.com/newsroom/news/canva-claude-design/) +- [X/Twitter announcement by @claudeai](https://x.com/claudeai/status/2045156267690213649) +- [Claude Design plugin page](https://claude.com/plugins/design) +- [Claude plugins directory](https://claude.com/plugins) diff --git a/specs/2026-04-17-open-claude-design.md b/specs/2026-04-17-open-claude-design.md new file mode 100644 index 000000000..c000d78b9 --- /dev/null +++ b/specs/2026-04-17-open-claude-design.md @@ -0,0 +1,806 @@ +# Open Claude Design — Technical Design Document / RFC + +| Document Metadata | Details | +| ---------------------- | ------------------------------------------------------------------------------ | +| Author(s) | flora131 | +| Status | Draft (WIP) | +| Team / Owner | Atomic CLI | +| Created / Last Updated | 2026-04-17 | + +## 1. Executive Summary + +This RFC proposes a new built-in workflow called `open-claude-design` — an open-source replica of Anthropic's [Claude Design](https://www.anthropic.com/news/claude-design-anthropic-labs) product, implemented using the Atomic workflow SDK. The workflow orchestrates the existing design skill ecosystem (`impeccable`, `critique`, `shape`, `polish`, `audit`, `extract`, etc.) into a deterministic 5-phase pipeline: **Design System Onboarding → Import → Generation → Refinement Loop → Export/Handoff**. Every phase requiring user decisions uses the `AskUserQuestion` tool for human-in-the-loop (HIL) interaction. The workflow produces a `Design.md` design system file, production-grade frontend code, and a Claude Code handoff bundle — closing the loop from design exploration to production implementation. + +~70% of the required capabilities already exist in the codebase (skills, agent types, SDK primitives). The primary new work is prompt engineering, helper functions for design system persistence, and the workflow orchestration file itself. + +--- + +## 2. Context and Motivation + +### 2.1 Current State + +The Atomic CLI already ships two built-in workflows: +- **`deep-research-codebase`** — scout → per-partition specialist fan-out → aggregator ([research ref](../research/docs/2026-04-17-open-claude-design.md#part-2)) +- **`ralph`** — bounded iterative plan → orchestrate → review → debug loop ([research ref](../research/docs/2026-04-17-open-claude-design.md#part-2)) + +The design skill ecosystem (`.agents/skills/`) includes 17+ design-related skills (`impeccable`, `critique`, `shape`, `polish`, `audit`, `layout`, `colorize`, `typeset`, `animate`, `delight`, `adapt`, `clarify`, `harden`, `distill`, `bolder`, `quieter`, `normalize`), plus browser automation (`playwright-cli`), document parsing (`liteparse`), and export capabilities (`pdf`, `pptx`, `docx`). These skills are currently invoked individually via slash commands — there is no workflow that orchestrates them into a cohesive design pipeline. + +**Architecture:** The workflow SDK (`defineWorkflow().for<"claude">().run().compile()`) with `ctx.stage()` sub-agent orchestration, `Promise.all()` parallelism, and `extractAssistantText()` for headless stage results provides the full runtime needed. + +### 2.2 The Problem + +- **Fragmented design workflow:** Users must manually invoke `/impeccable teach`, then `/shape`, then `/impeccable craft`, then `/critique`, then `/polish` — each in separate conversations with no shared context pipeline. +- **No design system persistence:** The `.impeccable.md` file captures brand context but lacks structured design tokens (colors, fonts, spacing, components) extracted from the codebase. +- **No handoff path:** Designs generated via impeccable have no structured export or Claude Code handoff bundle — users manually copy files. +- **Competitive gap:** Anthropic launched Claude Design (2026-04-17) with a 6-phase pipeline. An open-source CLI equivalent would differentiate Atomic CLI. + +--- + +## 3. Goals and Non-Goals + +### 3.1 Functional Goals + +- [ ] **G1:** Implement a `open-claude-design` built-in workflow at `src/sdk/workflows/builtin/open-claude-design/claude/index.ts` +- [ ] **G2:** Phase 1 (Design System Onboarding) — extract design tokens from codebase, create/update `Design.md`, use `AskUserQuestion` for HIL approval of each design element +- [ ] **G3:** Phase 2 (Import) — accept text prompts, file references, URLs (via playwright web capture), and codebase references as input +- [ ] **G4:** Phase 3 (Generation) — generate first version using `impeccable` skill with design system context injection +- [ ] **G5:** Phase 4 (Refinement Loop) — bounded iterative loop (like Ralph) using `critique` + `polish` + `AskUserQuestion` for user feedback, with headless screenshot validation via playwright +- [ ] **G6:** Phase 5 (Export/Handoff) — export as standalone HTML and package a Claude Code handoff bundle (design + intent + tokens + specs) +- [ ] **G7:** Incorporate AI slop anti-pattern detection from `impeccable` and `critique` skills as automated quality gates in the refinement loop +- [ ] **G8:** All user-facing decisions use `AskUserQuestion` tool (not regular NL conversation) for HIL interaction +- [ ] **G9:** Create prompt builders in `helpers/prompts.ts` following the deep-research-codebase and Ralph patterns +- [ ] **G10:** Create a `Design.md` file (structured design system document) as the persistent output of the onboarding phase + +### 3.2 Non-Goals (Out of Scope) + +- [ ] Multi-user collaboration (Phase 5 of Claude Design) — web UI feature, not replicable in CLI/TUI +- [ ] Claude-generated adjustment sliders — web UI feature; adaptation: Claude proposes variations, user picks via `AskUserQuestion` +- [ ] Drawing/annotation on canvas — web UI feature; verbal descriptions of changes suffice +- [ ] Canva export integration — requires Canva API; deferred to future work +- [ ] Copilot and OpenCode providers — start with Claude-only (like deep-research-codebase); scaffold stubs for future +- [ ] Frontier design (voice/video/3D/shaders) — partially achievable but deferred; standard HTML/CSS/JS prototypes are the priority +- [ ] MCP connector integrations (Figma, Slack, Notion, Linear) — deferred to future work + +--- + +## 4. Proposed Solution (High-Level Design) + +### 4.1 System Architecture Diagram + +```mermaid +flowchart TB + classDef visible fill:#4a90e2,stroke:#357abd,stroke-width:2.5px,color:#ffffff,font-weight:600 + classDef headless fill:#667eea,stroke:#5a67d8,stroke-width:2px,color:#ffffff,font-size:12px + classDef deterministic fill:#48bb78,stroke:#38a169,stroke-width:2px,color:#ffffff,font-size:12px + classDef hil fill:#ed8936,stroke:#dd6b20,stroke-width:2.5px,color:#ffffff,font-weight:600 + + Start([open-claude-design]):::visible + + subgraph Phase1["Phase 1: Design System Onboarding"] + direction TB + DS_Locator["codebase-locator
(headless)"]:::headless + DS_Analyzer["codebase-analyzer
(headless)"]:::headless + DS_PatternFinder["pattern-finder
(headless)"]:::headless + DS_Builder["design-system-builder
(visible, HIL)"]:::hil + DS_Persist["persist Design.md
(deterministic TS)"]:::deterministic + end + + subgraph Phase2["Phase 2: Import"] + direction TB + WebCapture["web-capture
(headless, if URL)"]:::headless + FileParser["file-parser
(headless, if files)"]:::headless + ImportAggregator["import-aggregator
(deterministic TS)"]:::deterministic + end + + subgraph Phase3["Phase 3: Generation"] + Generator["generator
(visible)"]:::visible + end + + subgraph Phase4["Phase 4: Refinement Loop"] + direction TB + UserFeedback["user-feedback
(visible, HIL)"]:::hil + Critique["critique-i
(headless)"]:::headless + Screenshot["screenshot-i
(headless)"]:::headless + ApplyChanges["apply-changes-i
(visible)"]:::visible + LoopCheck{"user approves
or MAX_REFINEMENTS?"} + end + + subgraph Phase5["Phase 5: Export / Handoff"] + Exporter["exporter
(visible)"]:::visible + HandoffBundle["handoff-bundle
(deterministic TS)"]:::deterministic + end + + Start --> DS_Locator & DS_Analyzer & DS_PatternFinder + DS_Locator & DS_Analyzer & DS_PatternFinder --> DS_Builder + DS_Builder --> DS_Persist + DS_Persist --> WebCapture & FileParser + WebCapture & FileParser --> ImportAggregator + ImportAggregator --> Generator + Generator --> UserFeedback + UserFeedback --> Critique & Screenshot + Critique & Screenshot --> ApplyChanges + ApplyChanges --> LoopCheck + LoopCheck -->|No| UserFeedback + LoopCheck -->|Yes| Exporter + Exporter --> HandoffBundle +``` + +### 4.2 Architectural Pattern + +The workflow follows a **phased pipeline with bounded refinement loop**, combining patterns from both existing built-in workflows: + +- **deep-research-codebase pattern:** Parallel headless sub-agent fan-out for codebase analysis (Phase 1 + Phase 2), deterministic TypeScript synthesis (no LLM call for file concatenation) +- **Ralph pattern:** Bounded iterative loop with parallel validation passes and exit condition (Phase 4) +- **HIL pattern:** `AskUserQuestion` tool usage for user decisions (from `hil-favorite-color` example workflow) + +### 4.3 Model Strategy + +The workflow uses a **tiered model strategy** to balance output quality against cost and latency. Stages that require creative judgment or are user-facing inherit the orchestrator's model (presumably Opus). Headless stages that perform structured analysis, tool orchestration, or follow rigid rubrics use Sonnet. + +**Constants:** + +```typescript +/** Headless stages: structured analysis, tool orchestration, rubric-following. Sonnet. */ +const HEADLESS_OPTS = { + permissionMode: "bypassPermissions", + allowDangerouslySkipPermissions: true, + model: "sonnet", +} as const; + +/** Visible/creative stages: inherit orchestrator model (Opus). No model override. */ +const VISIBLE_OPTS = { + permissionMode: "bypassPermissions", + allowDangerouslySkipPermissions: true, +} as const; +``` + +**Per-stage model assignments:** + +| Stage | Model | Rationale | +|---|---|---| +| `ds-locator` (Phase 1) | Sonnet | File discovery — structured search, no creativity | +| `ds-analyzer` (Phase 1) | Sonnet | Extract values from code — pattern matching | +| `ds-patterns` (Phase 1) | Sonnet | Find component patterns — code search | +| `design-system-builder` (Phase 1) | Opus (inherit) | User-facing, synthesizes 3 headless outputs into coherent HIL flow | +| `web-capture` (Phase 2) | Sonnet | Navigate URL, screenshot, extract DOM — tool orchestration | +| `file-parser` (Phase 2) | Sonnet | Parse document — mechanical extraction | +| `generator` (Phase 3) | Opus (inherit) | Core creative output — design quality is the whole point | +| `user-feedback-{i}` (Phase 4) | Sonnet | Present state + ask one AskUserQuestion — thin interaction layer | +| `critique-{i}` (Phase 4) | Sonnet | Follows structured rubric (P0-P3 severity) — methodology-driven | +| `screenshot-{i}` (Phase 4) | Sonnet | Launch playwright, take screenshot, describe findings — tool use + basic visual analysis | +| `apply-changes-{i}` (Phase 4) | Opus (inherit) | Creative modification based on nuanced feedback + critique synthesis | +| `exporter` (Phase 5) | Sonnet | Copy files, generate markdown — mostly mechanical | + +This yields ~60-70% cost reduction on the 9 headless stages while keeping Opus for the 3 stages where design quality and creative synthesis matter most (`design-system-builder`, `generator`, `apply-changes-{i}`). + +### 4.4 Key Components + +| Component | Responsibility | Implementation | Justification | +|---|---|---|---| +| Design System Builder | Extract tokens from codebase, build Design.md | Headless locator/analyzer stages → visible HIL stage | Mirrors impeccable `teach` + `extract` modes | +| Import Handler | Parse text/files/URLs into structured context | Headless stages (playwright for URLs, liteparse for docs) | Reuses existing skills as sub-agent capabilities | +| Generator | Produce first design version | Visible stage with impeccable + shape skill context | Core creative output — user watches in real-time | +| Refinement Controller | Iterate on design with user feedback | Bounded loop: HIL feedback → headless critique/screenshot → visible apply | Adapts Ralph's review-debug loop pattern | +| Quality Gate | AI slop detection + design critique | Headless critique stage running `npx impeccable --json` + LLM critique | Automated anti-pattern enforcement | +| Export Engine | HTML export + handoff bundle | Visible stage + deterministic TS helper | Thin wrapper around existing export skills | + +--- + +## 5. Detailed Design + +### 5.1 Directory Structure + +``` +src/sdk/workflows/builtin/open-claude-design/ +├── claude/index.ts ← Main workflow definition +├── copilot/index.ts ← Stub (future provider) +├── opencode/index.ts ← Stub (future provider) +└── helpers/ + ├── prompts.ts ← All prompt builders (buildDesignSystemPrompt, etc.) + ├── design-system.ts ← Design.md persistence, token extraction, loading + ├── import.ts ← Input type detection, URL/file/codebase handling + ├── validation.ts ← Critique parsing, screenshot comparison, quality gates + ├── export.ts ← HTML export, handoff bundle packaging + └── constants.ts ← MAX_REFINEMENTS, HEADLESS_OPTS, VISIBLE_OPTS, file paths, anti-pattern lists +``` + +### 5.2 Workflow Inputs + +```typescript +defineWorkflow({ + name: "open-claude-design", + description: + "AI-powered design workflow: design system onboarding → import → generate → refine → export/handoff", + inputs: [ + { + name: "prompt", + type: "text", + required: true, + description: "What to design (e.g., 'a dashboard for monitoring API latency')", + }, + { + name: "reference", + type: "text", + required: false, + description: "URL, file path, or codebase path to import as design reference", + }, + { + name: "output-type", + type: "enum", + required: false, + values: ["prototype", "wireframe", "page", "component"], + default: "prototype", + description: "Type of design output to generate", + }, + { + name: "design-system", + type: "text", + required: false, + description: "Path to existing Design.md (skips onboarding if provided)", + }, + ], +}) +``` + +**Output Type Definitions:** + +All four output types produce the same file set (`index.html`, `styles.css`, `script.js`). They differ in scope and fidelity: + +| Output Type | What Gets Generated | How the User Uses It | +|---|---|---| +| **`prototype`** (default) | A fully interactive HTML/CSS/JS application — multiple views/screens, working navigation, real interactions (clicks, hovers, form submissions), state changes. Full visual fidelity with design system tokens applied. | Open `index.html` in a browser to click through the experience. Hand off via the bundle to implement as a real app. The "demo you can show stakeholders" artifact. | +| **`wireframe`** | A low-fidelity structural layout — boxes, placeholder text, visual hierarchy without polish. Grayscale, minimal styling, focused on information architecture. The workflow runs `/shape` first to produce a design brief before generating. | Early-stage exploration — validates layout and flow before investing in visual design. Useful input to a follow-up prototype pass or `/impeccable` run. | +| **`page`** | A single, fully designed page — one screen at full fidelity (colors, typography, spacing from Design.md). No multi-screen navigation or complex state. | When you need one specific view (a landing page, a settings screen, a dashboard) rather than a full multi-screen prototype. Narrower scope = faster iteration in the refinement loop. | +| **`component`** | A single reusable UI element — a button set, a card, a data table, a modal, a nav bar. Rendered in the HTML page as a component showcase with multiple variants and interactive states. | Building up a design system piece by piece, or designing a specific widget in isolation before integrating it. The handoff bundle's `component-specs.md` is especially relevant here. | + +### 5.3 Phase 1: Design System Onboarding + +**Purpose:** Read the codebase, extract design tokens, and build a `Design.md` file with HIL approval at each decision point. + +**Topology:** + +``` + codebase-locator (headless) ∥ codebase-analyzer (headless) ∥ pattern-finder (headless) + │ + ▼ + design-system-builder (visible, HIL) + │ + ▼ + persist Design.md (deterministic TS) +``` + +**Implementation:** + +```typescript +// Skip if user provided --design-system path +const designSystemPath = ctx.inputs["design-system"]; +let designSystem: DesignSystemData; + +if (designSystemPath) { + designSystem = await loadDesignSystem(designSystemPath); +} else { + // Layer 1: Parallel headless codebase analysis + const [locator, analyzer, patterns] = await Promise.all([ + ctx.stage( + { name: "ds-locator", headless: true, description: "Locate design files and tokens" }, + {}, {}, + async (s) => { + const result = await s.session.query( + buildDesignLocatorPrompt({ root }), + { agent: "codebase-locator", ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ), + ctx.stage( + { name: "ds-analyzer", headless: true, description: "Analyze design tokens and patterns" }, + {}, {}, + async (s) => { + const result = await s.session.query( + buildDesignAnalyzerPrompt({ root }), + { agent: "codebase-analyzer", ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ), + ctx.stage( + { name: "ds-patterns", headless: true, description: "Find existing design patterns" }, + {}, {}, + async (s) => { + const result = await s.session.query( + buildDesignPatternPrompt({ root }), + { agent: "codebase-pattern-finder", ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ), + ]); + + // Layer 2: Visible stage with HIL — presents findings, asks user to approve/modify + const dsBuilder = await ctx.stage( + { name: "design-system-builder", description: "Build design system with user approval (HIL)" }, + {}, {}, + async (s) => { + await s.session.query( + buildDesignSystemBuilderPrompt({ + root, + locatorOutput: locator.result, + analyzerOutput: analyzer.result, + patternsOutput: patterns.result, + existingImpeccable: await readImpeccableMd(root), + }), + ); + s.save(s.sessionId); + }, + ); + + // Deterministic: persist to Design.md + designSystem = await persistDesignSystem(root, dsBuilder); +} +``` + +**Key prompt behavior for `buildDesignSystemBuilderPrompt`:** + +The prompt instructs the agent to: +1. Present extracted colors, typography, spacing, and components to the user +2. Use `AskUserQuestion` tool to confirm each design element category: + - "Here are the colors I found in your codebase: [...]. Which should be part of your design system?" (with options) + - "I found these typography patterns: [...]. Which font stack should be primary?" (with options) + - "These spacing values appear most frequently: [...]. Should I use a 4pt or 8pt base scale?" (with options) +3. Synthesize approved elements into a structured Design.md format +4. Use `AskUserQuestion` one final time: "Here is your complete design system. Approve or request changes?" + +**Design.md structure:** + +```markdown +# Design System — [Project Name] + +## Colors +### Primary +- `--color-primary`: #4a90e2 +- `--color-primary-hover`: #357abd +### Neutral +- `--color-bg`: #1e1e2e +- `--color-surface`: #313244 +### Semantic +- `--color-success`: #a6e3a1 +- `--color-error`: #f38ba8 + +## Typography +### Font Stack +- Primary: "Geist", system-ui, sans-serif +- Monospace: "Geist Mono", ui-monospace, monospace +### Scale +- `--text-xs`: 0.75rem +- `--text-sm`: 0.875rem +- `--text-base`: 1rem +- `--text-lg`: 1.125rem +- `--text-xl`: 1.25rem + +## Spacing +### Base Unit: 4px +- `--space-1`: 4px +- `--space-2`: 8px +- `--space-3`: 12px +- `--space-4`: 16px + +## Components +### Identified Patterns +- Button (primary, secondary, ghost variants) +- Card (standard, elevated) +- Input (text, select, checkbox) + +## Anti-Patterns (from impeccable) +- NO side-stripe borders (border-left/right > 1px) +- NO gradient text (background-clip: text) +- NO AI color palette (cyan-on-dark, purple-to-blue gradients) +- NO reflex fonts (Inter, DM Sans, Fraunces, Poppins, etc.) + +## Brand Context (from .impeccable.md) +[Embedded from existing .impeccable.md if available] +``` + +### 5.4 Phase 2: Import + +**Purpose:** Aggregate all input sources into a structured context object for the generator. + +**Topology:** + +``` + web-capture (headless, conditional) ∥ file-parser (headless, conditional) + │ + ▼ + aggregate inputs (deterministic TS) +``` + +**Implementation:** + +```typescript +const prompt = ctx.inputs.prompt ?? ""; +const reference = ctx.inputs.reference ?? ""; + +const importResults = await Promise.all([ + // Web capture (only if reference is a URL) + isUrl(reference) + ? ctx.stage( + { name: "web-capture", headless: true, description: "Capture web reference via playwright" }, + {}, {}, + async (s) => { + const result = await s.session.query( + buildWebCapturePrompt({ url: reference, screenshotDir: scratchDir }), + { agent: "codebase-online-researcher", ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ) + : null, + + // File parser (only if reference is a file path) + isFilePath(reference) + ? ctx.stage( + { name: "file-parser", headless: true, description: "Parse reference document" }, + {}, {}, + async (s) => { + const result = await s.session.query( + buildFileParserPrompt({ filePath: reference }), + { agent: "codebase-analyzer", ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ) + : null, +]); + +// Deterministic aggregation +const importContext = aggregateImportResults({ + prompt, + reference, + webCapture: importResults[0]?.result ?? null, + fileParse: importResults[1]?.result ?? null, +}); +``` + +### 5.5 Phase 3: Generation + +**Purpose:** Generate the first design version using the design system and import context. + +**Topology:** Single visible stage — user watches generation in real-time. + +**Implementation:** + +```typescript +const outputType = ctx.inputs["output-type"] ?? "prototype"; + +const generator = await ctx.stage( + { name: "generator", description: "Generate first design version" }, + {}, {}, + async (s) => { + await s.session.query( + buildGeneratorPrompt({ + prompt, + outputType, + designSystem, + importContext, + root, + outputDir: designDir, + }), + ); + s.save(s.sessionId); + }, +); +``` + +**Key prompt behavior for `buildGeneratorPrompt`:** + +The prompt instructs the agent to: +1. Load the `/impeccable` skill context (reads Design.md + `.impeccable.md`) +2. If output type is `wireframe`, run `/shape` first to produce a design brief +3. Generate HTML/CSS/JS files in the `designDir` output directory +4. Apply the design system tokens from Design.md +5. Follow all impeccable DON'T guidelines and absolute bans +6. Use `AskUserQuestion` to confirm the output type if ambiguous: "I'll generate a [prototype/wireframe/page/component]. Does this match your intent?" +7. Write generated files to `{designDir}/index.html`, `{designDir}/styles.css`, `{designDir}/script.js` + +### 5.6 Phase 4: Refinement Loop + +**Purpose:** Iterative improvement of the generated design through user feedback, automated critique, and visual validation. + +**Topology (per iteration):** + +``` + user-feedback-{i} (visible, HIL) + │ + ├─→ critique-{i} (headless) + └─→ screenshot-{i} (headless) + │ + ▼ + apply-changes-{i} (visible) + │ + ▼ + (loop until user approves or MAX_REFINEMENTS) +``` + +**Implementation (adapted from Ralph's review-debug loop):** + +```typescript +const MAX_REFINEMENTS = 5; + +for (let iteration = 1; iteration <= MAX_REFINEMENTS; iteration++) { + // Step 1: Collect user feedback via HIL (Sonnet — thin interaction layer) + const feedback = await ctx.stage( + { name: `user-feedback-${iteration}`, description: `Collect refinement feedback (iteration ${iteration})` }, + {}, {}, + async (s) => { + const result = await s.session.query( + buildRefineFeedbackPrompt({ + prompt, + designDir, + iteration, + maxIterations: MAX_REFINEMENTS, + }), + { ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ); + + // Check if user signaled "done" via AskUserQuestion response + if (isRefinementComplete(feedback.result)) break; + + // Step 2: Parallel validation — critique + screenshot + const [critiqueResult, screenshotResult] = await Promise.all([ + ctx.stage( + { name: `critique-${iteration}`, headless: true, description: `Design critique (iteration ${iteration})` }, + {}, {}, + async (s) => { + const result = await s.session.query( + buildCritiquePrompt({ + designDir, + designSystem, + userFeedback: feedback.result, + }), + { agent: "reviewer", ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ), + ctx.stage( + { name: `screenshot-${iteration}`, headless: true, description: `Visual validation (iteration ${iteration})` }, + {}, {}, + async (s) => { + const result = await s.session.query( + buildScreenshotValidationPrompt({ designDir, scratchDir }), + { agent: "codebase-analyzer", ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ), + ]); + + // Step 3: Apply changes based on feedback + critique + await ctx.stage( + { name: `apply-changes-${iteration}`, description: `Apply refinements (iteration ${iteration})` }, + {}, {}, + async (s) => { + await s.session.query( + buildApplyChangesPrompt({ + prompt, + designDir, + designSystem, + userFeedback: feedback.result, + critiqueOutput: critiqueResult.result, + screenshotOutput: screenshotResult.result, + iteration, + }), + ); + s.save(s.sessionId); + }, + ); +} +``` + +**Key prompt behaviors:** + +- `buildRefineFeedbackPrompt`: Instructs the agent to present the current design state, then use `AskUserQuestion` with options like: "How would you like to proceed?" → ["Approve and export", "Request specific changes", "Run full critique", "Start over"] +- `buildCritiquePrompt`: Instructs the agent to invoke the `/critique` skill workflow — Assessment A (LLM design review + AI slop detection) and Assessment B (`npx impeccable --json` scanner), producing structured findings with P0-P3 severity +- `buildScreenshotValidationPrompt`: Uses `playwright-cli` to render the generated HTML, starts `npx impeccable live` to inject the anti-pattern overlay, then takes a screenshot with overlay annotations visible. The screenshot is fed to the multimodal model (Opus/Sonnet) for visual analysis — combining deterministic scanner findings with model-based visual judgment +- `buildApplyChangesPrompt`: Merges user feedback + critique findings into a prioritized change list, invokes `/impeccable` to apply fixes while respecting anti-pattern bans + +### 5.7 Phase 5: Export and Handoff + +**Purpose:** Export the final design and package a Claude Code handoff bundle. + +**Topology:** + +``` + exporter (visible) → handoff bundle (deterministic TS) +``` + +**Implementation:** + +```typescript +const finalDesignDir = path.join(root, "research/designs", slug); + +const exporter = await ctx.stage( + { name: "exporter", description: "Export design and create handoff bundle" }, + {}, {}, + async (s) => { + await s.session.query( + buildExportPrompt({ + prompt, + designDir, + finalDesignDir, + designSystem, + outputType, + }), + { ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + }, +); + +// Deterministic: package handoff bundle +await writeHandoffBundle(finalDesignDir, { + designSystem, + prompt, + outputType, +}); +``` + +**Handoff bundle structure (deterministic TS, no LLM):** + +``` +{finalDesignDir}/ +├── design/ ← Generated HTML/CSS/JS (copied from designDir) +│ ├── index.html +│ ├── styles.css +│ └── script.js +├── Design.md ← Design system tokens (copied from project root) +├── design-intent.md ← Extracted from generator + refine transcripts +├── component-specs.md ← Component specifications +├── handoff-prompt.md ← Ready-to-use prompt for Claude Code: +│ "Implement this design using the following specs..." +└── README.md ← How to use the handoff bundle +``` + +### 5.8 Prompt Builder Summary + +| Function | Phase | Purpose | Reference Pattern | +|---|---|---|---| +| `buildDesignLocatorPrompt()` | 1 | Find CSS/Tailwind/design files in codebase | deep-research `buildLocatorPrompt()` | +| `buildDesignAnalyzerPrompt()` | 1 | Extract colors, fonts, spacing from located files | deep-research `buildAnalyzerPrompt()` | +| `buildDesignPatternPrompt()` | 1 | Find existing component patterns | deep-research `buildPatternFinderPrompt()` | +| `buildDesignSystemBuilderPrompt()` | 1 | Present findings + HIL approval → Design.md | Custom (uses AskUserQuestion) | +| `buildWebCapturePrompt()` | 2 | Navigate URL, screenshot, extract DOM/CSS | Uses playwright-cli skill | +| `buildFileParserPrompt()` | 2 | Parse DOCX/PPTX/XLSX/image references | Uses liteparse skill | +| `buildGeneratorPrompt()` | 3 | Generate first version with design system context | Custom (invokes impeccable + shape) | +| `buildRefineFeedbackPrompt()` | 4 | Present design + collect user feedback via HIL | Custom (uses AskUserQuestion) | +| `buildCritiquePrompt()` | 4 | Automated design critique with structured output | Ralph `buildReviewPrompt()` | +| `buildScreenshotValidationPrompt()` | 4 | Visual validation via playwright screenshot | Custom (uses playwright-cli) | +| `buildApplyChangesPrompt()` | 4 | Apply feedback + critique findings to design | Ralph `buildDebuggerReportPrompt()` | +| `buildExportPrompt()` | 5 | Export + handoff bundle preparation | Custom | + +### 5.9 AskUserQuestion Integration + +All HIL interactions use the `AskUserQuestion` tool, not regular NL conversation. The prompts explicitly instruct the agent: + +``` +You MUST use the AskUserQuestion tool (not regular conversation) to ask the user +for decisions. Do not proceed without the user's explicit response via this tool. +``` + +**HIL decision points in the workflow:** + +| Phase | Decision | AskUserQuestion Usage | +|---|---|---| +| Phase 1 | Approve color palette | Options: ["Approve these colors", "Modify colors", "Start from scratch"] | +| Phase 1 | Approve typography | Options: ["Use [Font X]", "Use [Font Y]", "Suggest alternatives"] | +| Phase 1 | Approve spacing scale | Options: ["4pt base", "8pt base"] | +| Phase 1 | Approve full design system | Options: ["Approve Design.md", "Request changes"] | +| Phase 3 | Confirm output type | Options: ["Prototype", "Wireframe", "Page", "Component"] | +| Phase 4 | Refinement direction | Options: ["Approve and export", "Request changes", "Run full critique", "Start over"] | +| Phase 5 | Export format | Options: ["HTML only", "HTML + handoff bundle", "Full export (HTML + PDF + handoff)"] | + +### 5.10 AI Slop Anti-Pattern Integration + +The `impeccable` skill's anti-pattern system is integrated at two levels: + +**Level 1 — Prompt-level prevention (Phases 3 & 4):** +All generation and refinement prompts embed the impeccable DON'T guidelines and absolute bans directly: +- BAN 1: No side-stripe borders (`border-left/right` > 1px) +- BAN 2: No gradient text (`background-clip: text`) +- The 22-font reflex rejection list +- The full AI color palette ban (cyan-on-dark, purple-to-blue gradients, neon on dark) + +**Level 2 — Automated detection (Phase 4 critique):** +The headless critique stage runs `npx impeccable --json {designDir}` (the deterministic scanner) which flags 25 specific anti-patterns with exit code 2 if findings exist. Results are structured as P0-P3 severity and fed into the `apply-changes` stage. + +**Level 3 — Quality gate (Phase 4 loop exit):** +The refinement loop cannot exit with P0 or P1 anti-pattern findings. If the user signals "Approve and export" but the critique found P0/P1 issues, the workflow presents the findings via `AskUserQuestion`: "The design has [N] critical issues. Fix them before exporting, or export anyway?" + +--- + +## 6. Alternatives Considered + +| Option | Pros | Cons | Reason for Rejection | +|---|---|---|---| +| **A: Single-stage conversational workflow** | Simple implementation; one long agent session | Context window fills up; no parallelism; no deterministic checkpoints | Doesn't scale — generation + critique + refinement in one session exceeds context limits | +| **B: Pure orchestrator dispatch (like Ralph)** | Proven pattern; orchestrator manages all routing | Orchestrator context grows with each skill invocation; no deterministic synthesis | Open Claude Design has more phases than Ralph — orchestrator would become the bottleneck | +| **C: Phased pipeline with headless specialists (Selected)** | Bounded context per stage; parallel headless sub-agents; deterministic synthesis; proven in deep-research | More complex topology than A or B | **Selected:** Clean isolation between phases, parallel codebase analysis, and bounded refinement loop justify the complexity | +| **D: Skill-only approach (no workflow)** | Zero new code; user chains skills manually | No shared context; manual sequencing; no design system persistence | This is the current state — fragmented and error-prone | + +--- + +## 7. Cross-Cutting Concerns + +### 7.1 Security and Privacy + +- **No data upload:** Like Claude Design, the workflow reads the codebase locally. Design system tokens are stored in the project directory, not uploaded to external services. +- **File system scope:** All generated files are written within the project directory (`research/designs/`, `Design.md`). No writes outside the project root. +- **Permission model:** Headless sub-agents use `HEADLESS_OPTS` (bypass permissions + Sonnet model). Visible/creative stages use `VISIBLE_OPTS` (bypass permissions, inherit orchestrator model). Standard pattern for headless stages in existing workflows. + +### 7.2 Observability Strategy + +- **Graph visualization:** Visible stages (`design-system-builder`, `generator`, `apply-changes-{i}`, `exporter`) appear in the workflow graph. Headless stages are transparent. +- **HIL pulse:** When `AskUserQuestion` is pending, the graph node pulses blue ("awaiting_input") via the existing HIL detection in `src/sdk/providers/claude.ts`. +- **Scratch files:** Each phase writes intermediate outputs to `{scratchDir}/` for debugging (design system JSON, import context, critique results). + +### 7.3 Token Efficiency and Cost + +- **Tiered model strategy:** 9 headless stages run on Sonnet (~5x cheaper than Opus); only 3 creative/user-facing stages use Opus. See §4.3 for full breakdown. +- **Bounded context per stage:** Each headless sub-agent runs in an isolated conversation — the locator's file index doesn't pollute the analyzer's context. +- **Deterministic synthesis:** Design.md, import aggregation, and handoff bundle are written by TypeScript helpers, not LLM calls. +- **Refinement cap:** `MAX_REFINEMENTS = 5` bounds token cost for the iterative loop. + +--- + +## 8. Migration, Rollout, and Testing + +### 8.1 Deployment Strategy + +- [ ] **Phase 1:** Implement helpers (`design-system.ts`, `prompts.ts`, `import.ts`, `validation.ts`, `export.ts`) with unit tests +- [ ] **Phase 2:** Implement `claude/index.ts` workflow definition with integration test (single pass: onboard → generate → export, no refinement) +- [ ] **Phase 3:** Add refinement loop with critique/screenshot validation, test with 2-3 iteration cycles +- [ ] **Phase 4:** Add full HIL integration with `AskUserQuestion` at all decision points +- [ ] **Phase 5:** Add copilot/opencode stubs, documentation, and register as built-in workflow + +### 8.2 Test Plan + +- **Unit Tests:** Each helper function (design system parsing, import aggregation, critique parsing, handoff bundle writing) tested in isolation with `bun test` +- **Integration Tests:** Full workflow execution against a test fixture codebase (e.g., a small React app with Tailwind) — validate that Design.md is created, HTML is generated, handoff bundle is packaged +- **Anti-Pattern Tests:** Feed known AI slop patterns through the critique stage and verify they are flagged as P0/P1 +- **HIL Tests:** Verify `AskUserQuestion` is invoked (not skipped) at each decision point + +--- + +## 9. Open Questions / Unresolved Issues + +- [x] **Q1:** Design system persistence format — **Markdown**. Human-readable, matches `.impeccable.md` pattern, works naturally as LLM prompt context. No JSON sidecar needed. +- [x] **Q2:** Refinement exit condition — **Explicit user signal only**. Loop exits only when user selects "Approve and export" via AskUserQuestion. Critique P0/P1 findings are informational warnings, not blockers. User always has final say. +- [x] **Q3:** Screenshot validation approach — **Playwright + `npx impeccable live` overlay + model screenshot analysis**. Playwright renders the generated HTML, `npx impeccable live` injects the anti-pattern overlay, then the screenshot (with overlay annotations) is fed to the multimodal model (Opus/Sonnet) for visual analysis. This combines deterministic scanner results with the model's visual judgment in a single pass. +- [x] **Q4:** Handoff bundle format — **Full bundle with ready-to-use prompt**. Includes design files, Design.md tokens, component specs, design-intent.md, AND a `handoff-prompt.md` that Claude Code can execute directly. Matches Claude Design's official handoff approach. +- [x] **Q5:** Custom agent definitions — **Reuse existing agents** (worker, reviewer, codebase-locator, etc.) with skill-injected prompts that instruct the agent to invoke `/impeccable`, `/critique`, etc. No new `.claude/agents/` files needed. +- [x] **Q6:** Design.md vs .impeccable.md — **Separate files**. Design.md = structured design tokens (colors, fonts, spacing, components) for the workflow pipeline. `.impeccable.md` = brand context (users, personality, aesthetic, principles) for the skill ecosystem. Different audiences, different purposes. +- [x] **Q7:** Where to write generated design files — **`research/designs/` directory**. Consistent with the existing `research/docs/` pattern used by deep-research-codebase. Output goes to `research/designs/{slug}/` alongside existing research artifacts. + +--- + +## 10. References + +- [Claude Design Official Announcement](https://www.anthropic.com/news/claude-design-anthropic-labs) — Product reference +- [Research: Open Claude Design](../research/docs/2026-04-17-open-claude-design.md) — Phase-by-phase SDK mapping +- [Research: Claude Design Product Analysis](../research/docs/2026-04-17-claude-design-product-analysis.md) — Detailed product analysis +- [deep-research-codebase workflow](../src/sdk/workflows/builtin/deep-research-codebase/claude/index.ts) — Parallel sub-agent pattern reference +- [Ralph workflow](../src/sdk/workflows/builtin/ralph/claude/index.ts) — Iterative loop pattern reference +- [HIL favorite-color workflow](../.atomic/workflows/hil-favorite-color/claude/index.ts) — AskUserQuestion pattern reference +- [Impeccable skill](../.agents/skills/impeccable/SKILL.md) — Core design skill with anti-pattern system +- [Critique skill](../.agents/skills/critique/SKILL.md) — Design critique methodology +- [Workflow-creator skill](../.agents/skills/workflow-creator/SKILL.md) — Workflow authoring patterns and failure modes diff --git a/src/sdk/workflows/builtin/open-claude-design/claude/index.ts b/src/sdk/workflows/builtin/open-claude-design/claude/index.ts new file mode 100644 index 000000000..921138d82 --- /dev/null +++ b/src/sdk/workflows/builtin/open-claude-design/claude/index.ts @@ -0,0 +1,499 @@ +/** + * open-claude-design / claude + * + * An open-source replica of Anthropic's Claude Design product, implemented + * as an Atomic CLI workflow. Orchestrates the design skill ecosystem + * (impeccable, critique, shape, polish, audit, etc.) into a deterministic + * 5-phase pipeline: + * + * Phase 1: Design System Onboarding — extract tokens, build Design.md (HIL) + * Phase 2: Import — aggregate text/URL/file references + * Phase 3: Generation — produce first design version + * Phase 4: Refinement Loop — bounded iterate with critique + user feedback + * Phase 5: Export/Handoff — HTML export + Claude Code handoff bundle + * + * Topology: + * + * ┌─→ ds-locator (headless) ∥ ds-analyzer (headless) ∥ ds-patterns (headless) + * │ │ + * │ ▼ + * │ design-system-builder (visible, HIL) + * │ │ + * │ ▼ + * │ web-capture (headless, if URL) ∥ file-parser (headless, if file) + * │ │ + * │ ▼ + * │ generator (visible) + * │ │ + * │ ▼ + * │ ┌─→ user-feedback-i (visible, HIL) + * │ │ │ + * │ │ ├─→ critique-i (headless) ∥ screenshot-i (headless) + * │ │ │ + * │ │ ▼ + * │ │ apply-changes-i (visible) + * │ │ │ + * │ └─────────┘ (loop until approved or MAX_REFINEMENTS) + * │ │ + * │ ▼ + * │ exporter (visible) + * └────────────────────────────────────── + * + * Run: atomic workflow -n open-claude-design -a claude "design a dashboard" + */ + +import { defineWorkflow, extractAssistantText } from "../../../index.ts"; +import { mkdir } from "node:fs/promises"; +import path from "node:path"; + +import { + MAX_REFINEMENTS, + HEADLESS_OPTS, + DESIGNS_DIR, +} from "../helpers/constants.ts"; +import { + loadDesignSystem, + persistDesignSystem, + readImpeccableMd, + slugifyPrompt, + ensureScratchDir, +} from "../helpers/design-system.ts"; +import { + isUrl, + isFilePath, + aggregateImportResults, +} from "../helpers/import.ts"; +import { isRefinementComplete } from "../helpers/validation.ts"; +import { writeHandoffBundle } from "../helpers/export.ts"; +import { + hasBlockingFindings, + renderScanFindings, + runImpeccableScan, +} from "../helpers/scan.ts"; +import { + buildDesignLocatorPrompt, + buildDesignAnalyzerPrompt, + buildDesignPatternPrompt, + buildDesignSystemBuilderPrompt, + buildWebCapturePrompt, + buildFileParserPrompt, + buildGeneratorPrompt, + buildRefineFeedbackPrompt, + buildCritiquePrompt, + buildScreenshotValidationPrompt, + buildApplyChangesPrompt, + buildForcedFixPrompt, + buildExportPrompt, +} from "../helpers/prompts.ts"; + +export default defineWorkflow({ + name: "open-claude-design", + description: + "AI-powered design workflow: design system onboarding → import → generate → refine → export/handoff", + inputs: [ + { + name: "prompt", + type: "text", + required: true, + description: + "What to design (e.g., 'a dashboard for monitoring API latency')", + }, + { + name: "reference", + type: "text", + required: false, + description: + "URL, file path, or codebase path to import as design reference", + }, + { + name: "output-type", + type: "enum", + required: false, + values: ["prototype", "wireframe", "page", "component"], + default: "prototype", + description: "Type of design output to generate", + }, + { + name: "design-system", + type: "text", + required: false, + description: "Path to existing Design.md (skips onboarding if provided)", + }, + ], +}) + .for<"claude">() + .run(async (ctx) => { + const prompt = ctx.inputs.prompt ?? ""; + const reference = ctx.inputs.reference ?? ""; + const outputType = ctx.inputs["output-type"] ?? "prototype"; + const designSystemPath = ctx.inputs["design-system"] ?? ""; + + const root = process.cwd(); + const slug = slugifyPrompt(prompt); + const isoDate = new Date().toISOString().slice(0, 10); + const scratchDir = await ensureScratchDir(root); + const designDir = path.join(scratchDir, slug); + await mkdir(designDir, { recursive: true }); + + // ══════════════════════════════════════════════════════════════════════ + // PHASE 1: Design System Onboarding + // ══════════════════════════════════════════════════════════════════════ + + let designSystem; + + if (designSystemPath.trim()) { + // Skip onboarding — user provided an existing Design.md + designSystem = await loadDesignSystem(designSystemPath); + } else { + // Layer 1: Parallel headless codebase analysis + const [locator, analyzer, patterns] = await Promise.all([ + ctx.stage( + { + name: "ds-locator", + headless: true, + description: "Locate design files and tokens", + }, + {}, + {}, + async (s) => { + const result = await s.session.query( + buildDesignLocatorPrompt({ root }), + { agent: "codebase-locator", ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ), + ctx.stage( + { + name: "ds-analyzer", + headless: true, + description: "Analyze design tokens and patterns", + }, + {}, + {}, + async (s) => { + const result = await s.session.query( + buildDesignAnalyzerPrompt({ root }), + { agent: "codebase-analyzer", ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ), + ctx.stage( + { + name: "ds-patterns", + headless: true, + description: "Find existing design patterns", + }, + {}, + {}, + async (s) => { + const result = await s.session.query( + buildDesignPatternPrompt({ root }), + { agent: "codebase-pattern-finder", ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ), + ]); + + // Layer 2: Visible stage with HIL — presents findings, asks user to + // approve/modify each design element category + await ctx.stage( + { + name: "design-system-builder", + description: "Build design system with user approval (HIL)", + }, + {}, + {}, + async (s) => { + await s.session.query( + buildDesignSystemBuilderPrompt({ + root, + locatorOutput: locator.result, + analyzerOutput: analyzer.result, + patternsOutput: patterns.result, + existingImpeccable: await readImpeccableMd(root), + }), + ); + s.save(s.sessionId); + }, + ); + + // Deterministic: read back the Design.md the agent wrote + designSystem = await persistDesignSystem(root); + } + + // ══════════════════════════════════════════════════════════════════════ + // PHASE 2: Import + // ══════════════════════════════════════════════════════════════════════ + + const importResults = await Promise.all([ + // Web capture (only if reference is a URL) + isUrl(reference) + ? ctx.stage( + { + name: "web-capture", + headless: true, + description: "Capture web reference via playwright", + }, + {}, + {}, + async (s) => { + const result = await s.session.query( + buildWebCapturePrompt({ url: reference, screenshotDir: scratchDir }), + { agent: "codebase-online-researcher", ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ) + : null, + + // File parser (only if reference is a file path) + isFilePath(reference) + ? ctx.stage( + { + name: "file-parser", + headless: true, + description: "Parse reference document", + }, + {}, + {}, + async (s) => { + const result = await s.session.query( + buildFileParserPrompt({ filePath: reference }), + { agent: "codebase-analyzer", ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ) + : null, + ]); + + // Deterministic aggregation + const importContext = aggregateImportResults({ + prompt, + reference, + webCapture: importResults[0]?.result ?? null, + fileParse: importResults[1]?.result ?? null, + }); + + // ══════════════════════════════════════════════════════════════════════ + // PHASE 3: Generation + // ══════════════════════════════════════════════════════════════════════ + + await ctx.stage( + { name: "generator", description: "Generate first design version" }, + {}, + {}, + async (s) => { + await s.session.query( + buildGeneratorPrompt({ + prompt, + outputType, + designSystem, + importContext, + root, + outputDir: designDir, + }), + ); + s.save(s.sessionId); + }, + ); + + // ══════════════════════════════════════════════════════════════════════ + // PHASE 4: Refinement Loop + // ══════════════════════════════════════════════════════════════════════ + + for (let iteration = 1; iteration <= MAX_REFINEMENTS; iteration++) { + // Step 1: Collect user feedback via HIL + const feedback = await ctx.stage( + { + name: `user-feedback-${iteration}`, + description: `Collect refinement feedback (iteration ${iteration})`, + }, + {}, + {}, + async (s) => { + const result = await s.session.query( + buildRefineFeedbackPrompt({ + prompt, + designDir, + iteration, + maxIterations: MAX_REFINEMENTS, + }), + { ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ); + + // Check if user signaled "done" via AskUserQuestion response + if (isRefinementComplete(feedback.result)) break; + + // Step 2: Parallel validation — critique + screenshot + const [critiqueResult, screenshotResult] = await Promise.all([ + ctx.stage( + { + name: `critique-${iteration}`, + headless: true, + description: `Design critique (iteration ${iteration})`, + }, + {}, + {}, + async (s) => { + const result = await s.session.query( + buildCritiquePrompt({ + designDir, + designSystem, + userFeedback: feedback.result, + }), + { agent: "reviewer", ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ), + ctx.stage( + { + name: `screenshot-${iteration}`, + headless: true, + description: `Visual validation (iteration ${iteration})`, + }, + {}, + {}, + async (s) => { + const result = await s.session.query( + buildScreenshotValidationPrompt({ designDir, scratchDir }), + { agent: "codebase-analyzer", ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + return extractAssistantText(result, 0); + }, + ), + ]); + + // Step 3: Deterministic scan — surface banned anti-patterns to the + // agent so apply-changes can fix them alongside user feedback. No LLM + // call; runs the `impeccable detect` CLI directly. + const scan = await runImpeccableScan(designDir); + const scanFindings = + scan.available && scan.findings.length > 0 + ? renderScanFindings(scan.findings) + : scan.available + ? "" + : `(scanner unavailable: ${scan.reason} — proceed without scan input)`; + + // Step 4: Apply changes based on feedback + critique + scanner findings + await ctx.stage( + { + name: `apply-changes-${iteration}`, + description: `Apply refinements (iteration ${iteration})`, + }, + {}, + {}, + async (s) => { + await s.session.query( + buildApplyChangesPrompt({ + prompt, + designDir, + designSystem, + userFeedback: feedback.result, + critiqueOutput: critiqueResult.result, + screenshotOutput: screenshotResult.result, + scanFindings, + iteration, + }), + ); + s.save(s.sessionId); + }, + ); + } + + // ══════════════════════════════════════════════════════════════════════ + // Hard enforcement gate — runs before export, independent of the + // refinement loop's exit condition. Guarantees no design ships with + // scanner findings even if the user approved early or MAX_REFINEMENTS + // was reached with the agent still introducing banned patterns. + // ══════════════════════════════════════════════════════════════════════ + + const preExportScan = await runImpeccableScan(designDir); + if (hasBlockingFindings(preExportScan)) { + // TS narrowing: hasBlockingFindings guarantees available === true + const findings = ( + preExportScan as Extract + ).findings; + const findingsText = renderScanFindings(findings); + + await ctx.stage( + { + name: "forced-fix", + description: "Remove banned anti-patterns before export", + }, + {}, + {}, + async (s) => { + await s.session.query( + buildForcedFixPrompt({ + designDir, + designSystem, + scanFindings: findingsText, + }), + ); + s.save(s.sessionId); + }, + ); + + const rescan = await runImpeccableScan(designDir); + if (hasBlockingFindings(rescan)) { + const remaining = ( + rescan as Extract + ).findings; + throw new Error( + `open-claude-design: export blocked — ${remaining.length} ` + + `banned anti-pattern(s) remain after forced fix:\n` + + renderScanFindings(remaining), + ); + } + } + + // ══════════════════════════════════════════════════════════════════════ + // PHASE 5: Export / Handoff + // ══════════════════════════════════════════════════════════════════════ + + const finalDesignDir = path.join(root, DESIGNS_DIR, `${isoDate}-${slug}`); + + await ctx.stage( + { name: "exporter", description: "Export design and create handoff bundle" }, + {}, + {}, + async (s) => { + await s.session.query( + buildExportPrompt({ + prompt, + designDir, + finalDesignDir, + designSystem, + outputType, + }), + { ...HEADLESS_OPTS }, + ); + s.save(s.sessionId); + }, + ); + + // Deterministic: package handoff bundle (copies Design.md, writes + // handoff-prompt.md and README.md — no LLM call) + await writeHandoffBundle(finalDesignDir, { + designSystem, + prompt, + outputType, + }); + }) + .compile(); diff --git a/src/sdk/workflows/builtin/open-claude-design/copilot/index.ts b/src/sdk/workflows/builtin/open-claude-design/copilot/index.ts new file mode 100644 index 000000000..4ebdc751a --- /dev/null +++ b/src/sdk/workflows/builtin/open-claude-design/copilot/index.ts @@ -0,0 +1,507 @@ +/** + * open-claude-design / copilot + * + * Copilot replica of the Claude open-claude-design workflow. Orchestrates + * the design skill ecosystem (impeccable, critique, shape, polish, audit, + * etc.) into a deterministic 5-phase pipeline: + * + * Phase 1: Design System Onboarding — extract tokens, build Design.md (HIL) + * Phase 2: Import — aggregate text/URL/file references + * Phase 3: Generation — produce first design version + * Phase 4: Refinement Loop — bounded iterate with critique + user feedback + * Phase 5: Export/Handoff — HTML export + Claude Code handoff bundle + * + * Copilot-specific concerns (see references/failure-modes.md): + * + * • F5 — every `ctx.stage()` is a FRESH session. Every specialist receives + * its required context verbatim in its first prompt. + * • F1 — Copilot's last assistant turn is often empty when the agent ends + * on a tool call. Use `getAssistantText()` (concatenation of every + * top-level non-empty assistant turn, ignoring sub-agent + * `parentToolCallId` traffic) instead of `.at(-1).data.content`. + * • F9 — `s.save()` receives `SessionEvent[]` from `s.session.getMessages()`. + * + * Sub-agents are dispatched via `sessionOpts.agent` (the Copilot-native way + * to bind a session to a single named sub-agent). Permissions default to + * `approveAll` so headless stages run unattended. + * + * See claude/index.ts for the full topology diagram and design rationale. + * + * Run: atomic workflow -n open-claude-design -a copilot "design a dashboard" + */ + +import { defineWorkflow } from "../../../index.ts"; +import type { SessionEvent } from "@github/copilot-sdk"; +import { mkdir } from "node:fs/promises"; +import path from "node:path"; + +import { MAX_REFINEMENTS, DESIGNS_DIR } from "../helpers/constants.ts"; +import { + loadDesignSystem, + persistDesignSystem, + readImpeccableMd, + slugifyPrompt, + ensureScratchDir, +} from "../helpers/design-system.ts"; +import { + isUrl, + isFilePath, + aggregateImportResults, +} from "../helpers/import.ts"; +import { isRefinementComplete } from "../helpers/validation.ts"; +import { writeHandoffBundle } from "../helpers/export.ts"; +import { + hasBlockingFindings, + renderScanFindings, + runImpeccableScan, +} from "../helpers/scan.ts"; +import { + buildDesignLocatorPrompt, + buildDesignAnalyzerPrompt, + buildDesignPatternPrompt, + buildDesignSystemBuilderPrompt, + buildWebCapturePrompt, + buildFileParserPrompt, + buildGeneratorPrompt, + buildRefineFeedbackPrompt, + buildCritiquePrompt, + buildScreenshotValidationPrompt, + buildApplyChangesPrompt, + buildForcedFixPrompt, + buildExportPrompt, +} from "../helpers/prompts.ts"; + +/** + * Concatenate every top-level assistant turn's non-empty content. The final + * `assistant.message` of a Copilot turn is often empty when the agent ends + * on a tool call (F1), and sub-agent traffic is signalled by `parentToolCallId`. + */ +function getAssistantText(messages: SessionEvent[]): string { + return messages + .filter( + (m): m is Extract => + m.type === "assistant.message" && !m.data.parentToolCallId, + ) + .map((m) => m.data.content) + .filter((c) => c.length > 0) + .join("\n\n"); +} + +export default defineWorkflow({ + name: "open-claude-design", + description: + "AI-powered design workflow: design system onboarding → import → generate → refine → export/handoff", + inputs: [ + { + name: "prompt", + type: "text", + required: true, + description: + "What to design (e.g., 'a dashboard for monitoring API latency')", + }, + { + name: "reference", + type: "text", + required: false, + description: + "URL, file path, or codebase path to import as design reference", + }, + { + name: "output-type", + type: "enum", + required: false, + values: ["prototype", "wireframe", "page", "component"], + default: "prototype", + description: "Type of design output to generate", + }, + { + name: "design-system", + type: "text", + required: false, + description: "Path to existing Design.md (skips onboarding if provided)", + }, + ], +}) + .for<"copilot">() + .run(async (ctx) => { + const prompt = ctx.inputs.prompt ?? ""; + const reference = ctx.inputs.reference ?? ""; + const outputType = ctx.inputs["output-type"] ?? "prototype"; + const designSystemPath = ctx.inputs["design-system"] ?? ""; + + const root = process.cwd(); + const slug = slugifyPrompt(prompt); + const isoDate = new Date().toISOString().slice(0, 10); + const scratchDir = await ensureScratchDir(root); + const designDir = path.join(scratchDir, slug); + await mkdir(designDir, { recursive: true }); + + // ══════════════════════════════════════════════════════════════════════ + // PHASE 1: Design System Onboarding + // ══════════════════════════════════════════════════════════════════════ + + let designSystem; + + if (designSystemPath.trim()) { + // Skip onboarding — user provided an existing Design.md + designSystem = await loadDesignSystem(designSystemPath); + } else { + // Layer 1: Parallel headless codebase analysis + const [locator, analyzer, patterns] = await Promise.all([ + ctx.stage( + { + name: "ds-locator", + headless: true, + description: "Locate design files and tokens", + }, + {}, + { agent: "codebase-locator" }, + async (s) => { + await s.session.send({ + prompt: buildDesignLocatorPrompt({ root }), + }); + const messages = await s.session.getMessages(); + s.save(messages); + return getAssistantText(messages); + }, + ), + ctx.stage( + { + name: "ds-analyzer", + headless: true, + description: "Analyze design tokens and patterns", + }, + {}, + { agent: "codebase-analyzer" }, + async (s) => { + await s.session.send({ + prompt: buildDesignAnalyzerPrompt({ root }), + }); + const messages = await s.session.getMessages(); + s.save(messages); + return getAssistantText(messages); + }, + ), + ctx.stage( + { + name: "ds-patterns", + headless: true, + description: "Find existing design patterns", + }, + {}, + { agent: "codebase-pattern-finder" }, + async (s) => { + await s.session.send({ + prompt: buildDesignPatternPrompt({ root }), + }); + const messages = await s.session.getMessages(); + s.save(messages); + return getAssistantText(messages); + }, + ), + ]); + + // Layer 2: Visible stage with HIL — presents findings, asks user to + // approve/modify each design element category + await ctx.stage( + { + name: "design-system-builder", + description: "Build design system with user approval (HIL)", + }, + {}, + {}, + async (s) => { + await s.session.send({ + prompt: buildDesignSystemBuilderPrompt({ + root, + locatorOutput: locator.result, + analyzerOutput: analyzer.result, + patternsOutput: patterns.result, + existingImpeccable: await readImpeccableMd(root), + }), + }); + s.save(await s.session.getMessages()); + }, + ); + + // Deterministic: read back the Design.md the agent wrote + designSystem = await persistDesignSystem(root); + } + + // ══════════════════════════════════════════════════════════════════════ + // PHASE 2: Import + // ══════════════════════════════════════════════════════════════════════ + + const importResults = await Promise.all([ + // Web capture (only if reference is a URL) + isUrl(reference) + ? ctx.stage( + { + name: "web-capture", + headless: true, + description: "Capture web reference via playwright", + }, + {}, + { agent: "codebase-online-researcher" }, + async (s) => { + await s.session.send({ + prompt: buildWebCapturePrompt({ + url: reference, + screenshotDir: scratchDir, + }), + }); + const messages = await s.session.getMessages(); + s.save(messages); + return getAssistantText(messages); + }, + ) + : null, + + // File parser (only if reference is a file path) + isFilePath(reference) + ? ctx.stage( + { + name: "file-parser", + headless: true, + description: "Parse reference document", + }, + {}, + { agent: "codebase-analyzer" }, + async (s) => { + await s.session.send({ + prompt: buildFileParserPrompt({ filePath: reference }), + }); + const messages = await s.session.getMessages(); + s.save(messages); + return getAssistantText(messages); + }, + ) + : null, + ]); + + // Deterministic aggregation + const importContext = aggregateImportResults({ + prompt, + reference, + webCapture: importResults[0]?.result ?? null, + fileParse: importResults[1]?.result ?? null, + }); + + // ══════════════════════════════════════════════════════════════════════ + // PHASE 3: Generation + // ══════════════════════════════════════════════════════════════════════ + + await ctx.stage( + { name: "generator", description: "Generate first design version" }, + {}, + {}, + async (s) => { + await s.session.send({ + prompt: buildGeneratorPrompt({ + prompt, + outputType, + designSystem, + importContext, + root, + outputDir: designDir, + }), + }); + s.save(await s.session.getMessages()); + }, + ); + + // ══════════════════════════════════════════════════════════════════════ + // PHASE 4: Refinement Loop + // ══════════════════════════════════════════════════════════════════════ + + for (let iteration = 1; iteration <= MAX_REFINEMENTS; iteration++) { + // Step 1: Collect user feedback via HIL + const feedback = await ctx.stage( + { + name: `user-feedback-${iteration}`, + description: `Collect refinement feedback (iteration ${iteration})`, + }, + {}, + {}, + async (s) => { + await s.session.send({ + prompt: buildRefineFeedbackPrompt({ + prompt, + designDir, + iteration, + maxIterations: MAX_REFINEMENTS, + }), + }); + const messages = await s.session.getMessages(); + s.save(messages); + return getAssistantText(messages); + }, + ); + + // Check if user signaled "done" via HIL response + if (isRefinementComplete(feedback.result)) break; + + // Step 2: Parallel validation — critique + screenshot + const [critiqueResult, screenshotResult] = await Promise.all([ + ctx.stage( + { + name: `critique-${iteration}`, + headless: true, + description: `Design critique (iteration ${iteration})`, + }, + {}, + { agent: "reviewer" }, + async (s) => { + await s.session.send({ + prompt: buildCritiquePrompt({ + designDir, + designSystem, + userFeedback: feedback.result, + }), + }); + const messages = await s.session.getMessages(); + s.save(messages); + return getAssistantText(messages); + }, + ), + ctx.stage( + { + name: `screenshot-${iteration}`, + headless: true, + description: `Visual validation (iteration ${iteration})`, + }, + {}, + { agent: "codebase-analyzer" }, + async (s) => { + await s.session.send({ + prompt: buildScreenshotValidationPrompt({ + designDir, + scratchDir, + }), + }); + const messages = await s.session.getMessages(); + s.save(messages); + return getAssistantText(messages); + }, + ), + ]); + + // Step 3: Deterministic scan — surface banned anti-patterns so the + // apply-changes stage can fix them alongside user feedback. No LLM + // call; runs the `impeccable detect` CLI directly. + const scan = await runImpeccableScan(designDir); + const scanFindings = + scan.available && scan.findings.length > 0 + ? renderScanFindings(scan.findings) + : scan.available + ? "" + : `(scanner unavailable: ${scan.reason} — proceed without scan input)`; + + // Step 4: Apply changes based on feedback + critique + scanner findings + await ctx.stage( + { + name: `apply-changes-${iteration}`, + description: `Apply refinements (iteration ${iteration})`, + }, + {}, + {}, + async (s) => { + await s.session.send({ + prompt: buildApplyChangesPrompt({ + prompt, + designDir, + designSystem, + userFeedback: feedback.result, + critiqueOutput: critiqueResult.result, + screenshotOutput: screenshotResult.result, + scanFindings, + iteration, + }), + }); + s.save(await s.session.getMessages()); + }, + ); + } + + // ══════════════════════════════════════════════════════════════════════ + // Hard enforcement gate — runs before export, independent of the + // refinement loop's exit condition. Guarantees no design ships with + // scanner findings even if the user approved early or MAX_REFINEMENTS + // was reached with the agent still introducing banned patterns. + // ══════════════════════════════════════════════════════════════════════ + + const preExportScan = await runImpeccableScan(designDir); + if (hasBlockingFindings(preExportScan)) { + const findings = ( + preExportScan as Extract + ).findings; + const findingsText = renderScanFindings(findings); + + await ctx.stage( + { + name: "forced-fix", + description: "Remove banned anti-patterns before export", + }, + {}, + {}, + async (s) => { + await s.session.send({ + prompt: buildForcedFixPrompt({ + designDir, + designSystem, + scanFindings: findingsText, + }), + }); + s.save(await s.session.getMessages()); + }, + ); + + const rescan = await runImpeccableScan(designDir); + if (hasBlockingFindings(rescan)) { + const remaining = ( + rescan as Extract + ).findings; + throw new Error( + `open-claude-design: export blocked — ${remaining.length} ` + + `banned anti-pattern(s) remain after forced fix:\n` + + renderScanFindings(remaining), + ); + } + } + + // ══════════════════════════════════════════════════════════════════════ + // PHASE 5: Export / Handoff + // ══════════════════════════════════════════════════════════════════════ + + const finalDesignDir = path.join(root, DESIGNS_DIR, `${isoDate}-${slug}`); + + await ctx.stage( + { + name: "exporter", + description: "Export design and create handoff bundle", + }, + {}, + {}, + async (s) => { + await s.session.send({ + prompt: buildExportPrompt({ + prompt, + designDir, + finalDesignDir, + designSystem, + outputType, + }), + }); + s.save(await s.session.getMessages()); + }, + ); + + // Deterministic: package handoff bundle (copies Design.md, writes + // handoff-prompt.md and README.md — no LLM call) + await writeHandoffBundle(finalDesignDir, { + designSystem, + prompt, + outputType, + }); + }) + .compile(); diff --git a/src/sdk/workflows/builtin/open-claude-design/helpers/constants.ts b/src/sdk/workflows/builtin/open-claude-design/helpers/constants.ts new file mode 100644 index 000000000..2ca746e18 --- /dev/null +++ b/src/sdk/workflows/builtin/open-claude-design/helpers/constants.ts @@ -0,0 +1,159 @@ +/** + * Constants for the open-claude-design workflow. + * + * Design-rule constants (REFLEX_FONTS, IMPECCABLE_BANS, DESIGN_DONTS) mirror + * the canonical impeccable skill shipped at + * `~/.claude/skills/impeccable/SKILL.md`. The skill itself is only loaded + * opportunistically by the agent — so we inline the load-bearing rules here + * to guarantee every generation/refinement/critique turn sees them even if + * the skill is missing or fails to load. Re-sync when the skill updates. + */ + +/** Maximum refinement iterations before the loop exits unconditionally. */ +export const MAX_REFINEMENTS = 5; + +/** + * Headless stages: structured analysis, tool orchestration, rubric-following. + * Uses Sonnet for cost efficiency. Bypasses permissions for unattended operation. + */ +export const HEADLESS_OPTS = { + permissionMode: "bypassPermissions", + allowDangerouslySkipPermissions: true, + model: "sonnet", +} as const; + +/** + * Visible/creative stages: inherit orchestrator model (Opus). + * No model override — inherits from the parent session. + */ +export const VISIBLE_OPTS = { + permissionMode: "bypassPermissions", + allowDangerouslySkipPermissions: true, +} as const; + +/** Name of the design system file written to the project root. */ +export const DESIGN_SYSTEM_FILENAME = "Design.md"; + +/** Directory under project root where final design outputs are stored. */ +export const DESIGNS_DIR = "research/designs"; + +/** Name of the existing impeccable brand context file. */ +export const IMPECCABLE_FILENAME = ".impeccable.md"; + +/** + * Structured ban — rendered into generation/refinement/critique prompts as a + * `rule` (what is forbidden) plus `detail` (the CSS pattern + the rewrite). + */ +export interface ImpeccableBan { + readonly id: string; + readonly rule: string; + readonly detail: string; +} + +/** + * Absolute CSS bans from the canonical impeccable skill's `` + * section. These are the two patterns that the skill flags as "NEVER + * acceptable" regardless of color, radius, or CSS variable naming. If you + * change this list, re-sync with `~/.claude/skills/impeccable/SKILL.md`. + */ +export const IMPECCABLE_BANS: readonly ImpeccableBan[] = [ + { + id: "side-stripe-borders", + rule: "BAN 1 — Side-stripe borders on cards/list items/callouts/alerts", + detail: + "PATTERN: `border-left:` or `border-right:` with width greater than 1px. " + + "Forbidden for any color, any CSS variable name (including `--color-warning`, " + + "`--color-accent`, `--color-primary`). REWRITE: use a different element " + + "structure entirely — full borders, background tints, leading icons, numbers, " + + "or no visual indicator at all. Do NOT just swap to `box-shadow: inset`.", + }, + { + id: "gradient-text", + rule: "BAN 2 — Gradient text", + detail: + "PATTERN: `background-clip: text` (or `-webkit-background-clip: text`) combined " + + "with a `linear-gradient`, `radial-gradient`, or `conic-gradient` background. " + + "Forbidden on any text element — headings, metrics, or inline spans. " + + "REWRITE: solid colors only for text.", + }, +] as const; + +/** + * Canonical reflex fonts from the impeccable skill's + * `` list. These are the training-data defaults that + * create monoculture across projects; every one of them is banned. + */ +export const REFLEX_FONTS: readonly string[] = [ + "Fraunces", + "Newsreader", + "Lora", + "Crimson", + "Crimson Pro", + "Crimson Text", + "Playfair Display", + "Cormorant", + "Cormorant Garamond", + "Syne", + "IBM Plex Mono", + "IBM Plex Sans", + "IBM Plex Serif", + "Space Mono", + "Space Grotesk", + "Inter", + "DM Sans", + "DM Serif Display", + "DM Serif Text", + "Outfit", + "Plus Jakarta Sans", + "Instrument Sans", + "Instrument Serif", +] as const; + +/** + * Non-ban DON'Ts distilled from the impeccable skill sections on Typography, + * Color, Layout/Space, Motion, UX Writing, and Responsive. These are not + * absolute bans, but they are the recognizable AI fingerprints from + * 2024-2025 and must be avoided in generated designs. + */ +export const DESIGN_DONTS: readonly string[] = [ + // Typography + "Do not use monospace typography as lazy shorthand for 'technical/developer' vibes.", + "Do not put large icons with rounded corners above every heading.", + "Do not use only one font family for the entire page — pair a distinctive display font with a refined body font.", + "Do not use a flat type hierarchy where sizes are too close together — aim for at least a 1.25 ratio between steps.", + "Do not set long body passages in uppercase — reserve all-caps for short labels and headings.", + // Color & theme + "Do not use pure black (#000) or pure white (#fff) — always tint toward the brand hue.", + "Do not use the AI color palette (cyan-on-dark, purple-to-blue gradients, neon accents on dark backgrounds).", + "Do not default to dark mode with glowing accents, or to light mode 'to be safe' — derive theme from audience and viewing context.", + "Do not use gray text on colored backgrounds — use a shade of the background color instead.", + // Layout & space + "Do not wrap everything in cards — not everything needs a container.", + "Do not nest cards inside cards.", + "Do not use identical card grids (same-sized cards with icon + heading + text, repeated endlessly).", + "Do not use the hero metric layout template (big number, small label, supporting stats, gradient accent).", + "Do not center everything — left-aligned text with asymmetric layouts feels more designed.", + "Do not use the same spacing everywhere — create rhythm with tight groupings and generous separations.", + "Do not let body text wrap beyond ~80 characters per line — use a max-width like 65–75ch.", + // Motion + "Do not animate layout properties (width, height, padding, margin) — use transform and opacity only.", + "Do not use bounce or elastic easing — real objects decelerate smoothly.", + // UX writing + "Do not repeat information (redundant headers, intros that restate the heading).", + "Do not make every button primary — use ghost buttons, text links, and secondary styles for hierarchy.", + // Responsive + "Do not hide critical functionality on mobile — adapt the interface, don't amputate it.", +] as const; + +/** + * Command invocation for the impeccable scanner. The correct subcommand is + * `detect`; a bare `impeccable --json` just prints the top-level help. + * Exit code is always 0 — callers must parse the JSON array and check length + * to know whether findings exist. + */ +export const IMPECCABLE_SCAN_CMD = [ + "bunx", + "impeccable", + "detect", + "--json", +] as const; diff --git a/src/sdk/workflows/builtin/open-claude-design/helpers/design-system.ts b/src/sdk/workflows/builtin/open-claude-design/helpers/design-system.ts new file mode 100644 index 000000000..785d24123 --- /dev/null +++ b/src/sdk/workflows/builtin/open-claude-design/helpers/design-system.ts @@ -0,0 +1,88 @@ +/** + * Design.md persistence — loading, saving, and reading design system data. + * + * The Design.md file is a structured markdown document containing design + * tokens (colors, typography, spacing, components) extracted from the + * codebase and approved by the user via HIL. It serves as the single + * source of truth for all generation and refinement stages. + */ + +import { readFile } from "node:fs/promises"; +import path from "node:path"; +import { DESIGN_SYSTEM_FILENAME, IMPECCABLE_FILENAME } from "./constants.ts"; + +/** Structured representation of the design system data. */ +export interface DesignSystemData { + /** Raw markdown content of Design.md. */ + raw: string; + /** Absolute path to the Design.md file. */ + path: string; +} + +/** + * Load an existing Design.md from the given path. + * Used when the user provides `--design-system=`. + */ +export async function loadDesignSystem( + designSystemPath: string, +): Promise { + const resolved = path.resolve(designSystemPath); + const raw = await readFile(resolved, "utf-8"); + return { raw, path: resolved }; +} + +/** + * Persist the design system builder's output as Design.md in the project root. + * + * The builder stage produces a visible session where the agent constructs + * the Design.md content interactively with the user. We read the transcript + * and extract the final Design.md content that the agent wrote. + * + * For simplicity, the agent in the builder stage is instructed to write + * Design.md directly to disk. This function reads it back to populate + * the DesignSystemData for downstream stages. + */ +export async function persistDesignSystem( + root: string, +): Promise { + const designPath = path.join(root, DESIGN_SYSTEM_FILENAME); + const raw = await readFile(designPath, "utf-8"); + return { raw, path: designPath }; +} + +/** + * Read the existing .impeccable.md brand context file, if present. + * Returns empty string if the file does not exist. + */ +export async function readImpeccableMd(root: string): Promise { + try { + return await readFile(path.join(root, IMPECCABLE_FILENAME), "utf-8"); + } catch { + return ""; + } +} + +/** + * Derive a URL-safe slug from the user's prompt for directory naming. + */ +export function slugifyPrompt(prompt: string): string { + const slug = prompt + .toLowerCase() + .replace(/[^a-z0-9\s-]/g, "") + .split(/\s+/) + .filter(Boolean) + .slice(0, 6) + .join("-") + .substring(0, 60); + return slug || "design"; +} + +/** + * Ensure the scratch directory exists for intermediate workflow outputs. + */ +export async function ensureScratchDir(root: string): Promise { + const { mkdir } = await import("node:fs/promises"); + const scratchDir = path.join(root, "research", "designs", ".scratch"); + await mkdir(scratchDir, { recursive: true }); + return scratchDir; +} diff --git a/src/sdk/workflows/builtin/open-claude-design/helpers/export.ts b/src/sdk/workflows/builtin/open-claude-design/helpers/export.ts new file mode 100644 index 000000000..201a1a0fd --- /dev/null +++ b/src/sdk/workflows/builtin/open-claude-design/helpers/export.ts @@ -0,0 +1,193 @@ +/** + * Export engine — handoff bundle packaging. + * + * Writes the deterministic parts of the handoff bundle (no LLM call): + * - handoff-prompt.md — ready-to-use prompt for Claude Code + * - README.md — how to use the bundle + * + * The exporter stage (LLM) handles copying design files, writing + * design-intent.md and component-specs.md since those require + * understanding the generated design content. + */ + +import { writeFile, mkdir, copyFile } from "node:fs/promises"; +import path from "node:path"; +import type { DesignSystemData } from "./design-system.ts"; + +export interface HandoffBundleOptions { + designSystem: DesignSystemData; + prompt: string; + outputType: string; +} + +/** + * Write the deterministic handoff bundle files. + * + * The exporter stage is responsible for: + * - Copying design files (index.html, styles.css, script.js) to design/ + * - Writing design-intent.md from transcript analysis + * - Writing component-specs.md from design analysis + * + * This function writes the remaining deterministic files: + * - Design.md (copy of the design system) + * - handoff-prompt.md (ready-to-use implementation prompt) + * - README.md (bundle documentation) + */ +export async function writeHandoffBundle( + finalDesignDir: string, + opts: HandoffBundleOptions, +): Promise { + await mkdir(finalDesignDir, { recursive: true }); + await mkdir(path.join(finalDesignDir, "design"), { recursive: true }); + + // Copy Design.md + await copyFile( + opts.designSystem.path, + path.join(finalDesignDir, "Design.md"), + ); + + // Write handoff-prompt.md + const handoffPrompt = buildHandoffPrompt(opts); + await writeFile( + path.join(finalDesignDir, "handoff-prompt.md"), + handoffPrompt, + "utf-8", + ); + + // Write README.md + const readme = buildReadme(opts); + await writeFile( + path.join(finalDesignDir, "README.md"), + readme, + "utf-8", + ); +} + +function buildHandoffPrompt(opts: HandoffBundleOptions): string { + return `# Design Handoff — Implementation Prompt + +Use this prompt with Claude Code to implement the design in this bundle. + +## Original Design Request + +${opts.prompt} + +## Output Type + +${opts.outputType} + +## Instructions + +1. Read \`Design.md\` for the complete design system (colors, typography, spacing, components). +2. Open \`design/index.html\` in a browser to see the reference design. +3. Read \`design-intent.md\` for the design rationale and key decisions. +4. Read \`component-specs.md\` for individual component specifications. +5. Implement the design using the design system tokens from Design.md. +6. Match the reference design in \`design/\` as closely as possible. +7. Use semantic HTML, CSS custom properties for tokens, and progressive enhancement. + +## Design System Tokens + +The design tokens are defined in \`Design.md\`. Use CSS custom properties: + +\`\`\`css +:root { + /* Import all tokens from Design.md as custom properties */ +} +\`\`\` + +## Quality Checklist + +- [ ] All colors match Design.md tokens +- [ ] Typography follows the defined scale +- [ ] Spacing uses the defined base unit +- [ ] Components match the identified patterns +- [ ] No AI slop anti-patterns (gradient text, side-stripe borders, reflex fonts) +- [ ] Responsive at common breakpoints +- [ ] Accessible (WCAG 2.1 AA) +`; +} + +function buildReadme(opts: HandoffBundleOptions): string { + const extraFileRows = buildExtraFileRows(opts.outputType); + const previewSection = buildPreviewSection(opts.outputType); + + return `# Design Handoff Bundle + +Generated by the \`open-claude-design\` workflow. + +Output type: **${opts.outputType}** + +## Contents + +| File | Description | +|------|-------------| +| \`design/index.html\` | Generated HTML | +| \`design/styles.css\` | Generated CSS styles | +| \`design/script.js\` | Generated JavaScript |${extraFileRows} +| \`Design.md\` | Design system tokens (colors, typography, spacing) | +| \`design-intent.md\` | Design rationale and key decisions | +| \`component-specs.md\` | Component / page / wireframe / component-anatomy specs | +| \`handoff-prompt.md\` | Ready-to-use prompt for Claude Code | + +## Usage + +${previewSection} + +### Implement with Claude Code + +\`\`\`bash +# From the project root, run: +claude "$(cat ${opts.outputType === "component" ? "component-specs.md" : "handoff-prompt.md"})" +\`\`\` + +### Design System Reference + +All design tokens are in \`Design.md\`. Use these tokens when implementing +to ensure visual consistency with the generated design. + +## Original Request + +${opts.prompt} +`; +} + +function buildExtraFileRows(outputType: string): string { + if (outputType === "prototype") { + return ` +| \`design/server.ts\` | Zero-dependency Bun static-file server (port 4173) | +| \`design/package.json\` | Defines the \`start\` script |`; + } + if (outputType === "component") { + return ` +| \`design/snippet.html\` | Isolated component markup for copy-paste into a host app |`; + } + return ""; +} + +function buildPreviewSection(outputType: string): string { + if (outputType === "prototype") { + return `### Preview the Prototype + +The prototype ships with a runnable Bun server. + +\`\`\`bash +cd design +bun run start +# → Prototype running at http://localhost:4173 +\`\`\` + +Override the port with \`PORT=3000 bun run start\` if 4173 is taken.`; + } + if (outputType === "component") { + return `### Preview the Component + +Open \`design/index.html\` in a browser to view the component showcase +(all variants and states). Use \`design/snippet.html\` as a minimal +copy-paste target for dropping the component into a host application.`; + } + // page, wireframe, and any other future single-view output types + return `### Preview the Design + +Open \`design/index.html\` directly in a browser — no server required.`; +} diff --git a/src/sdk/workflows/builtin/open-claude-design/helpers/import.ts b/src/sdk/workflows/builtin/open-claude-design/helpers/import.ts new file mode 100644 index 000000000..c6a7cbaa1 --- /dev/null +++ b/src/sdk/workflows/builtin/open-claude-design/helpers/import.ts @@ -0,0 +1,52 @@ +/** + * Import handler — input type detection and aggregation. + * + * Classifies the user's `--reference` input as a URL, file path, or + * neither, and aggregates all import sources into a structured context + * object that the generator consumes. + */ + +/** Aggregated import context passed to the generator stage. */ +export interface ImportContext { + /** The user's free-form design prompt. */ + prompt: string; + /** Raw reference string (URL, file path, or empty). */ + reference: string; + /** Extracted content from a web URL capture, or null. */ + webCapture: string | null; + /** Extracted content from a parsed file, or null. */ + fileParse: string | null; +} + +/** Check whether the reference string looks like a URL. */ +export function isUrl(reference: string): boolean { + if (!reference.trim()) return false; + return /^https?:\/\//i.test(reference.trim()); +} + +/** Check whether the reference string looks like a file path. */ +export function isFilePath(reference: string): boolean { + const trimmed = reference.trim(); + if (!trimmed) return false; + if (isUrl(trimmed)) return false; + // Looks like a path: starts with /, ./, ~/, or contains file extension + return /^[./~]/.test(trimmed) || /\.\w{1,6}$/.test(trimmed); +} + +/** + * Aggregate all import results into a single context object. + * Pure deterministic function — no LLM call. + */ +export function aggregateImportResults(opts: { + prompt: string; + reference: string; + webCapture: string | null; + fileParse: string | null; +}): ImportContext { + return { + prompt: opts.prompt, + reference: opts.reference, + webCapture: opts.webCapture, + fileParse: opts.fileParse, + }; +} diff --git a/src/sdk/workflows/builtin/open-claude-design/helpers/prompts.ts b/src/sdk/workflows/builtin/open-claude-design/helpers/prompts.ts new file mode 100644 index 000000000..6832576b6 --- /dev/null +++ b/src/sdk/workflows/builtin/open-claude-design/helpers/prompts.ts @@ -0,0 +1,1110 @@ +/** + * Prompt builders for the open-claude-design workflow. + * + * Each builder produces a focused, single-responsibility prompt for one + * stage of the 5-phase design pipeline. Context-engineering principles: + * + * - Position-aware framing: key context (design prompt, design system) + * at the TOP and BOTTOM of every prompt. + * - Forward-only data flow: downstream stages embed upstream outputs + * verbatim — no re-discovery. + * - Trailing-prose guarantee: every prompt asks for a short prose recap + * so transcript reads never return empty. + * - HIL via AskUserQuestion: explicit instructions to use the tool, + * never regular NL conversation, for user decisions. + */ + +import { + DESIGN_DONTS, + IMPECCABLE_BANS, + IMPECCABLE_SCAN_CMD, + REFLEX_FONTS, +} from "./constants.ts"; +import type { ImportContext } from "./import.ts"; +import type { DesignSystemData } from "./design-system.ts"; + +// ============================================================================ +// SHARED HELPERS +// ============================================================================ + +const TRAILING_PROSE_REMINDER = + "End your turn with a short prose paragraph summarizing what you produced. " + + "Do NOT end the turn on a tool call — downstream stages read your assistant " + + "transcript and will see nothing if the final message is a tool invocation."; + +const HIL_INSTRUCTION = + "You MUST use the AskUserQuestion tool (not regular conversation) to ask " + + "the user for decisions. Do not proceed without the user's explicit " + + "response via this tool."; + +/** Shell string for the `impeccable detect` CLI, e.g. for inlining in prompts. */ +const SCAN_COMMAND_STR = IMPECCABLE_SCAN_CMD.join(" "); + +/** + * Render the full set of design rules — absolute bans, banned reflex fonts, + * and non-ban DON'Ts — into a single self-contained block. The agent MUST + * receive this content directly in the prompt because `/impeccable` skill + * loading is best-effort and not guaranteed. + */ +function renderDesignRules(): string { + const bans = IMPECCABLE_BANS.map( + (ban) => `- **${ban.rule}**\n ${ban.detail}`, + ).join("\n"); + const fonts = REFLEX_FONTS.map((f) => `\`${f}\``).join(", "); + const donts = DESIGN_DONTS.map((d) => `- ${d}`).join("\n"); + return [ + `### Absolute Bans (NEVER acceptable — rewrite the element entirely)`, + bans, + ``, + `### Banned Reflex Fonts (training-data defaults that create monoculture)`, + `Every one of the following is banned. Do not use any of them, and do not`, + `simply pick your second-favorite — look beyond this list.`, + fonts, + ``, + `### Design DON'Ts (AI-fingerprint patterns from 2024-2025)`, + donts, + ].join("\n"); +} + +// ============================================================================ +// PHASE 1: DESIGN SYSTEM ONBOARDING +// ============================================================================ + +/** Phase 1 — headless: find CSS/Tailwind/design files in codebase. */ +export function buildDesignLocatorPrompt(opts: { + root: string; +}): string { + return [ + ``, + `Locate all design-related files in this codebase that define or contain`, + `visual design tokens, styles, or theming configuration.`, + ``, + ``, + ``, + `Project root: \`${opts.root}\``, + ``, + ``, + ``, + `- CSS files (*.css, *.scss, *.less, *.pcss)`, + `- Tailwind config (tailwind.config.*, postcss.config.*)`, + `- CSS-in-JS theme files (theme.ts, tokens.ts, design-tokens.*)`, + `- CSS custom property definitions (:root { --color-*, --font-*, --space-* })`, + `- Component library config (chakra theme, MUI theme, shadcn components.json)`, + `- Global style entry points (globals.css, app.css, index.css)`, + `- Design system documentation (*.md files mentioning colors/fonts/spacing)`, + `- .impeccable.md brand context file`, + `- package.json (for design-related dependencies)`, + ``, + ``, + ``, + `Return a categorized list with absolute paths:`, + ``, + `### Style Files`, + `- \`\` — `, + ``, + `### Theme / Token Files`, + `- \`\` — `, + ``, + `### Configuration`, + `- \`\` — `, + ``, + `### Documentation`, + `- \`\` — `, + ``, + `Omit empty sections.`, + ``, + ``, + ``, + `Focus on LOCATION only — do not read file contents in depth.`, + `Use absolute paths throughout.`, + TRAILING_PROSE_REMINDER, + ``, + ].join("\n"); +} + +/** Phase 1 — headless: extract colors, fonts, spacing from located files. */ +export function buildDesignAnalyzerPrompt(opts: { + root: string; +}): string { + return [ + ``, + `Analyze this codebase to extract existing design tokens: colors,`, + `typography (fonts, sizes, weights), spacing values, and border/radius`, + `conventions. Report concrete values found in the code.`, + ``, + ``, + ``, + `Project root: \`${opts.root}\``, + ``, + ``, + ``, + `1. Search for CSS custom properties (--color-*, --font-*, --space-*, etc.)`, + `2. Search for Tailwind config color/font/spacing definitions`, + `3. Search for hardcoded hex/rgb/hsl color values in CSS/SCSS files`, + `4. Search for font-family declarations`, + `5. Search for consistent spacing patterns (margin/padding values)`, + `6. Search for border-radius, box-shadow, and transition patterns`, + ``, + ``, + ``, + `### Colors Found`, + `- \`\`: — used in `, + ``, + `### Typography Found`, + `- Font families: `, + `- Font sizes: `, + `- Font weights: `, + ``, + `### Spacing Found`, + `- Common values: `, + `- Base unit (if detectable): `, + ``, + `### Other Tokens`, + `- Border radius: `, + `- Box shadows: `, + `- Transitions: `, + ``, + `Omit empty sections. Use file:line references for every value.`, + ``, + ``, + ``, + `Report what EXISTS — do not suggest improvements or alternatives.`, + `Extract concrete values, not abstractions.`, + TRAILING_PROSE_REMINDER, + ``, + ].join("\n"); +} + +/** Phase 1 — headless: find existing component patterns in the codebase. */ +export function buildDesignPatternPrompt(opts: { + root: string; +}): string { + return [ + ``, + `Find existing UI component patterns in this codebase. Identify reusable`, + `components, their variants, and how they are currently styled.`, + ``, + ``, + ``, + `Project root: \`${opts.root}\``, + ``, + ``, + ``, + `1. Button components and their variants (primary, secondary, ghost, etc.)`, + `2. Card / container patterns`, + `3. Input / form elements`, + `4. Navigation components (navbar, sidebar, tabs)`, + `5. Layout patterns (grid, flex, container widths)`, + `6. Modal / dialog patterns`, + `7. Table / list patterns`, + `8. Any component library usage (shadcn, radix, chakra, MUI, etc.)`, + ``, + ``, + ``, + `For each component pattern found:`, + ``, + `#### `, + `**Where:** \`\``, + `**Variants:** `, + `**Styling approach:** `, + `**Key visual properties:** `, + ``, + `Aim for 5-10 distinct patterns. Skip trivial or one-off components.`, + ``, + ``, + ``, + `Document what EXISTS — do not propose new components.`, + `Use file:line references for every claim.`, + TRAILING_PROSE_REMINDER, + ``, + ].join("\n"); +} + +/** + * Phase 1 — visible, HIL: present findings and build Design.md with + * user approval at each decision point. + */ +export function buildDesignSystemBuilderPrompt(opts: { + root: string; + locatorOutput: string; + analyzerOutput: string; + patternsOutput: string; + existingImpeccable: string; +}): string { + const impeccableSection = + opts.existingImpeccable.trim().length > 0 + ? ` +The project has an existing .impeccable.md brand context file: + +${opts.existingImpeccable.trim()} +` + : ` +No .impeccable.md file found. You will build the design system from scratch +using the codebase analysis below. +`; + + return [ + ``, + `You are a design system builder. Three specialist sub-agents have analyzed`, + `the codebase for design tokens and patterns. Your job is to present their`, + `findings to the user, get approval for each design element category via`, + `the AskUserQuestion tool, and then write a structured Design.md file.`, + ``, + ``, + impeccableSection, + ``, + ``, + ``, + `### Design File Locations`, + opts.locatorOutput.trim() || "(no design files found)", + ``, + `### Extracted Design Tokens`, + opts.analyzerOutput.trim() || "(no tokens extracted)", + ``, + `### Component Patterns`, + opts.patternsOutput.trim() || "(no patterns found)", + ``, + ``, + ``, + ``, + ``, + `${HIL_INSTRUCTION}`, + ``, + `Follow these steps in order:`, + ``, + `**Step 1 — Colors:** Present the colors found in the codebase analysis.`, + `Use AskUserQuestion to ask: "Here are the colors I found in your codebase.`, + `Which should be part of your design system?"`, + `Provide options: ["Approve these colors", "Modify colors", "Start from scratch"]`, + `If "Modify" or "Start from scratch", follow up with another AskUserQuestion.`, + ``, + `**Step 2 — Typography:** Present the font families and scale found.`, + `Use AskUserQuestion to ask about the primary font stack.`, + `Provide options based on what was found, plus "Suggest alternatives".`, + ``, + `**Step 3 — Spacing:** Present the spacing values found.`, + `Use AskUserQuestion to ask: "Which spacing base unit should I use?"`, + `Provide options: ["4pt base", "8pt base", "Keep existing values"]`, + ``, + `**Step 4 — Components:** Present the component patterns found.`, + `Briefly summarize — no AskUserQuestion needed for this step.`, + ``, + `**Step 5 — Final Approval:** Write the complete Design.md file content,`, + `then use AskUserQuestion to ask: "Here is your complete design system.`, + `Approve or request changes?"`, + `Provide options: ["Approve Design.md", "Request changes"]`, + `If "Request changes", iterate until approved.`, + ``, + `**Step 6 — Write File:** Once approved, write the Design.md file to:`, + `\`${opts.root}/Design.md\``, + ``, + ``, + ``, + ``, + `The Design.md file MUST follow this exact structure:`, + ``, + "```markdown", + `# Design System — [Project Name]`, + ``, + `## Colors`, + `### Primary`, + `- \`--color-primary\`: `, + `### Neutral`, + `- \`--color-bg\`: `, + `### Semantic`, + `- \`--color-success\`: `, + ``, + `## Typography`, + `### Font Stack`, + `- Primary: `, + `- Monospace: `, + `### Scale`, + `- \`--text-xs\`: `, + ``, + `## Spacing`, + `### Base Unit: `, + `- \`--space-1\`: `, + ``, + `## Components`, + `### Identified Patterns`, + `- ()`, + ``, + `## Anti-Patterns (from impeccable)`, + `### Absolute Bans`, + `- NO side-stripe borders (border-left/right > 1px as accent, any color)`, + `- NO gradient text (background-clip: text with gradient)`, + ``, + `### Banned Reflex Fonts`, + `- Every font in the impeccable reflex-fonts list is banned (Inter, DM Sans,`, + ` Fraunces, Playfair Display, IBM Plex, Space Grotesk, Plus Jakarta Sans,`, + ` Outfit, Instrument Sans/Serif, Lora, Crimson*, Newsreader, Syne,`, + ` Cormorant*, Space Mono, DM Serif Display/Text).`, + ``, + `### Design DON'Ts`, + `- NO AI color palette (cyan-on-dark, purple-to-blue, neon-on-dark)`, + `- NO pure #000 or #fff — tint toward the brand hue`, + `- NO cards-in-cards, identical card grids, or hero-metric template`, + `- NO animated layout properties; transform/opacity only; no bounce/elastic`, + ``, + `## Brand Context (from .impeccable.md)`, + `[Embedded if available]`, + "```", + ``, + ``, + ``, + `- Use AskUserQuestion for EVERY decision point (Steps 1-3, 5).`, + `- Do NOT skip any step or auto-approve on the user's behalf.`, + `- Include the full Anti-Patterns section (absolute bans + reflex fonts + DON'Ts).`, + `- If no existing tokens are found, propose reasonable defaults and confirm with user.`, + TRAILING_PROSE_REMINDER, + ``, + ].join("\n"); +} + +// ============================================================================ +// PHASE 2: IMPORT +// ============================================================================ + +/** Phase 2 — headless: navigate URL, screenshot, extract DOM/CSS. */ +export function buildWebCapturePrompt(opts: { + url: string; + screenshotDir: string; +}): string { + return [ + ``, + `Navigate to the URL below, take a screenshot, and extract the key visual`, + `design elements (layout, colors, typography, component patterns) as a`, + `structured reference for generating a new design.`, + ``, + ``, + `${opts.url}`, + ``, + ``, + `1. Use playwright-cli to navigate to the URL.`, + `2. Take a full-page screenshot and save it to: \`${opts.screenshotDir}/reference.png\``, + `3. Extract the page's visual design characteristics:`, + ` - Overall layout structure (grid, sidebar, header, etc.)`, + ` - Color scheme (primary, accent, background, text colors)`, + ` - Typography (font families, sizes visible)`, + ` - Key component patterns (buttons, cards, inputs, navigation)`, + ` - Spacing and visual rhythm`, + `4. If the page has multiple views/states, capture the most representative one.`, + ``, + ``, + ``, + `### Layout`, + ``, + ``, + `### Visual Style`, + `- Colors: `, + `- Typography: `, + `- Spacing: `, + ``, + `### Key Components`, + `- : `, + ``, + `### Screenshot`, + `Saved to: \`${opts.screenshotDir}/reference.png\``, + ``, + ``, + ``, + `Focus on extractable design patterns, not content.`, + `If the URL fails to load, report the error and continue with whatever partial info is available.`, + TRAILING_PROSE_REMINDER, + ``, + ].join("\n"); +} + +/** Phase 2 — headless: parse document reference (DOCX/PPTX/XLSX/image/PDF). */ +export function buildFileParserPrompt(opts: { + filePath: string; +}): string { + return [ + ``, + `Parse the reference document below and extract design-relevant information`, + `(visual specs, wireframes, mockup descriptions, brand guidelines, color`, + `palettes, typography specs) that can inform design generation.`, + ``, + ``, + `${opts.filePath}`, + ``, + ``, + `1. Read the file using the appropriate tool (Read for text/markdown/images,`, + ` liteparse for DOCX/PPTX/XLSX/PDF).`, + `2. Extract design-relevant content:`, + ` - Color specifications or palettes`, + ` - Typography preferences`, + ` - Layout descriptions or wireframes`, + ` - Component requirements`, + ` - Brand guidelines or constraints`, + ` - Any visual mockup descriptions`, + `3. Ignore non-design content (business logic, data models, etc.)`, + ``, + ``, + ``, + `### Design Requirements Extracted`, + ``, + ``, + `### Visual Specifications`, + ``, + ``, + `### Layout Requirements`, + ``, + ``, + `If the file contains no design-relevant information, say so explicitly.`, + ``, + ``, + ``, + `Extract only design-relevant information.`, + `Do not fabricate specifications not present in the document.`, + TRAILING_PROSE_REMINDER, + ``, + ].join("\n"); +} + +// ============================================================================ +// PHASE 3: GENERATION +// ============================================================================ + +/** Phase 3 — visible: generate first design version. */ +export function buildGeneratorPrompt(opts: { + prompt: string; + outputType: string; + designSystem: DesignSystemData; + importContext: ImportContext; + root: string; + outputDir: string; +}): string { + const referenceSection = + opts.importContext.webCapture || opts.importContext.fileParse + ? ` +${opts.importContext.webCapture ? `### Web Reference\n${opts.importContext.webCapture}\n` : ""} +${opts.importContext.fileParse ? `### File Reference\n${opts.importContext.fileParse}\n` : ""} +` + : ""; + + const outputTypeInstructions: Record = { + prototype: `Generate a fully interactive HTML/CSS/JS application with multiple views/screens, +working navigation, real interactions (clicks, hovers, form submissions), and state +changes. Full visual fidelity with design system tokens applied.`, + + wireframe: `Generate a low-fidelity structural layout with boxes, placeholder text, and visual +hierarchy WITHOUT polish. Use grayscale, minimal styling. Focus on information +architecture. Run the /shape skill first to produce a design brief before generating.`, + + page: `Generate a single, fully designed page at full fidelity (colors, typography, spacing +from Design.md). No multi-screen navigation or complex state. One screen, fully polished.`, + + component: `Generate a single reusable UI element rendered as a component showcase with multiple +variants and interactive states. Show the component in isolation with different sizes, +colors, and states (default, hover, active, disabled, etc.).`, + }; + + return [ + ``, + opts.prompt, + ``, + ``, + ``, + `You are generating a **${opts.outputType}**.`, + ``, + outputTypeInstructions[opts.outputType] ?? outputTypeInstructions.prototype, + ``, + ``, + ``, + opts.designSystem.raw, + ``, + ``, + referenceSection, + ``, + ``, + ``, + `1. The design rules below are INLINED and authoritative — you do not need`, + ` to load the /impeccable skill for correctness. If /impeccable is`, + ` available it is optional supplementary context only.`, + `2. ${opts.outputType === "wireframe" ? "Run /shape first to produce a design brief, then generate based on that brief." : "Generate the design directly based on the design request and design system."}`, + `3. Write all generated files to: \`${opts.outputDir}/\``, + ` - \`${opts.outputDir}/index.html\` — Main HTML file`, + ` - \`${opts.outputDir}/styles.css\` — All CSS styles`, + ` - \`${opts.outputDir}/script.js\` — All JavaScript (if needed)`, + `4. Apply ALL design system tokens from the section above.`, + ` Use CSS custom properties for every color, font, and spacing value.`, + `5. Follow ALL design rules below — absolute bans, banned fonts, DON'Ts.`, + `6. Your output WILL be scanned with \`${SCAN_COMMAND_STR} ${opts.outputDir}\``, + ` before export. Any finding from the scanner blocks export, so avoid`, + ` the banned patterns preemptively rather than risk a rework loop.`, + ``, + ``, + ``, + ``, + renderDesignRules(), + ``, + ``, + ``, + `- Semantic HTML (proper heading hierarchy, landmarks, ARIA where needed)`, + `- CSS custom properties for all design tokens (--color-*, --font-*, --space-*)`, + `- Mobile-first responsive design`, + `- Self-contained: all CSS inline or in styles.css, all JS in script.js`, + `- No external CDN dependencies — everything must work offline`, + `- The HTML file must be openable directly in a browser`, + ``, + ``, + ``, + `Write the actual files — do not just describe what you would create.`, + `Apply the design system tokens from Design.md — do not invent new colors/fonts.`, + TRAILING_PROSE_REMINDER, + ``, + ``, + ``, + opts.prompt, + ``, + ].join("\n"); +} + +// ============================================================================ +// PHASE 4: REFINEMENT LOOP +// ============================================================================ + +/** Phase 4 — visible, HIL: collect user feedback on the current design. */ +export function buildRefineFeedbackPrompt(opts: { + prompt: string; + designDir: string; + iteration: number; + maxIterations: number; +}): string { + return [ + ``, + `You are collecting user feedback on the current design iteration.`, + `This is iteration ${opts.iteration} of ${opts.maxIterations}.`, + ``, + ``, + ``, + `The current design files are at: \`${opts.designDir}/\``, + `- \`${opts.designDir}/index.html\``, + `- \`${opts.designDir}/styles.css\``, + `- \`${opts.designDir}/script.js\``, + ``, + ``, + ``, + ``, + `${HIL_INSTRUCTION}`, + ``, + `1. FIRST — before any tool call such as ToolSearch or AskUserQuestion —`, + ` output a plaintext summary (2-4 sentences) covering what was generated`, + ` or changed in this iteration and reminding the user they can open`, + ` \`${opts.designDir}/index.html\` in a browser to preview. This`, + ` plaintext block MUST appear in your response before you invoke any tools.`, + `2. THEN use AskUserQuestion to ask: "How would you like to proceed?"`, + ` Provide these options:`, + ` - "Approve and export" — finalize the design and create handoff bundle`, + ` - "Request specific changes" — describe what to modify`, + ` - "Run full critique" — automated design quality analysis`, + ` - "Start over" — regenerate from scratch`, + `3. If the user selects "Request specific changes", capture their feedback`, + ` using a follow-up AskUserQuestion with free-text input.`, + `4. Echo back the user's choice and feedback clearly.`, + ``, + `If the user chose "Approve and export", include the phrase "user approved"`, + `in your response so the workflow can detect completion.`, + ``, + ``, + ``, + opts.prompt, + ``, + ``, + ``, + `- Do NOT make any changes to the design files yourself.`, + `- Do NOT skip the AskUserQuestion — the user MUST choose.`, + `- Keep your summary brief (2-3 sentences).`, + TRAILING_PROSE_REMINDER, + ``, + ].join("\n"); +} + +/** Phase 4 — headless: automated design critique with structured output. */ +export function buildCritiquePrompt(opts: { + designDir: string; + designSystem: DesignSystemData; + userFeedback: string; +}): string { + return [ + ``, + `Perform a comprehensive design critique of the generated design files.`, + `Combine automated scanning with design review expertise.`, + ``, + ``, + ``, + `\`${opts.designDir}/index.html\``, + `\`${opts.designDir}/styles.css\``, + `\`${opts.designDir}/script.js\``, + ``, + ``, + ``, + opts.designSystem.raw, + ``, + ``, + ``, + opts.userFeedback.trim() || "(no specific user feedback)", + ``, + ``, + ``, + ``, + `**Assessment A — Design Review (LLM analysis):**`, + `1. Read all three design files in full.`, + `2. Check design system compliance: are Design.md tokens actually used?`, + `3. Check visual hierarchy, layout balance, and information architecture.`, + `4. Check every rule below. Each violation is a P0 finding:`, + renderDesignRules(), + `5. Check accessibility basics (contrast, semantic HTML, ARIA).`, + `6. Check responsiveness (media queries, flexible layouts).`, + `7. Address any specific points from the user feedback above.`, + ``, + `**Assessment B — Automated scanning (informational):**`, + `Note: the orchestrator runs \`${SCAN_COMMAND_STR} ${opts.designDir}\``, + `deterministically after this stage, and its findings gate the export. You`, + `do not need to run the scanner yourself, but if you do, treat any finding`, + `(non-empty JSON array) as a P0 issue to remove.`, + ``, + ``, + ``, + ``, + `Report findings with P0-P3 severity:`, + ``, + `### P0 — Critical (must fix before export)`, + `- `, + ``, + `### P1 — Important`, + `- `, + ``, + `### P2 — Moderate`, + `- `, + ``, + `### P3 — Minor (informational)`, + `- `, + ``, + `### User Feedback Alignment`, + `- `, + ``, + `### Scanner Results`, + `- `, + ``, + `Omit empty severity sections.`, + ``, + ``, + ``, + `Be specific — cite file:line for every finding.`, + `Prioritize user feedback alignment over general design critique.`, + TRAILING_PROSE_REMINDER, + ``, + ].join("\n"); +} + +/** Phase 4 — headless: visual validation via playwright screenshot. */ +export function buildScreenshotValidationPrompt(opts: { + designDir: string; + scratchDir: string; +}): string { + return [ + ``, + `Render the generated design in a browser via playwright and take a`, + `screenshot for visual validation. Describe what you see.`, + ``, + ``, + ``, + `\`${opts.designDir}/index.html\``, + ``, + ``, + ``, + `1. Use playwright-cli to open \`${opts.designDir}/index.html\` as a local file.`, + `2. Set viewport to 1280x800 (standard desktop).`, + `3. Wait for the page to fully render (fonts, animations, etc.).`, + `4. Take a screenshot and save to: \`${opts.scratchDir}/screenshot-validation.png\``, + `5. If the page has interactive elements, take a second screenshot after`, + ` hovering over the primary CTA button (if present).`, + `6. Describe what you observe visually:`, + ` - Does the layout render correctly?`, + ` - Are there any visual glitches, overflow issues, or broken layouts?`, + ` - Do colors and typography look intentional?`, + ` - Is there enough contrast for readability?`, + ` - Any elements that appear AI-generated or generic?`, + ``, + ``, + ``, + `### Render Status`, + ``, + ``, + `### Visual Assessment`, + `- Layout: `, + `- Colors: `, + `- Typography: `, + `- Spacing: `, + `- Interactions: `, + ``, + `### Issues Found`, + `- `, + ``, + `### Screenshot`, + `Saved to: \`${opts.scratchDir}/screenshot-validation.png\``, + ``, + ``, + ``, + `Report what you SEE — do not speculate about code issues.`, + `If the HTML fails to render, report the error.`, + TRAILING_PROSE_REMINDER, + ``, + ].join("\n"); +} + +/** Phase 4 — visible: apply feedback + critique findings to the design. */ +export function buildApplyChangesPrompt(opts: { + prompt: string; + designDir: string; + designSystem: DesignSystemData; + userFeedback: string; + critiqueOutput: string; + screenshotOutput: string; + scanFindings: string; + iteration: number; +}): string { + return [ + ``, + opts.prompt, + ``, + ``, + ``, + `Apply refinements to the design based on user feedback, automated critique`, + `findings, and visual validation results. This is iteration ${opts.iteration}.`, + ``, + ``, + ``, + `Edit these files in place:`, + `- \`${opts.designDir}/index.html\``, + `- \`${opts.designDir}/styles.css\``, + `- \`${opts.designDir}/script.js\``, + ``, + ``, + ``, + opts.designSystem.raw, + ``, + ``, + ``, + opts.userFeedback.trim() || "(no specific user feedback)", + ``, + ``, + ``, + opts.critiqueOutput.trim() || "(no critique findings)", + ``, + ``, + ``, + opts.screenshotOutput.trim() || "(no visual validation performed)", + ``, + ``, + ``, + `The \`${SCAN_COMMAND_STR}\` scanner produced the following findings against`, + `the current design. Every one of these MUST be removed — the scanner will`, + `run again before export and any remaining finding blocks handoff.`, + ``, + opts.scanFindings.trim() || "(no scanner findings — clean on this dimension)", + ``, + ``, + ``, + `Apply changes in this priority order:`, + `1. Scanner findings — deterministic bans that gate export`, + `2. User feedback — the user's requests take next priority`, + `3. P0 critique findings — critical issues that must be fixed`, + `4. P1 critique findings — important issues`, + `5. Visual validation issues — rendering problems`, + `6. P2 critique findings — moderate issues (if time permits)`, + `7. Skip P3 findings — they are informational only`, + ``, + ``, + ``, + `The following rules are inlined and authoritative — do not introduce any`, + `of these patterns while fixing other issues. Loading the /impeccable skill`, + `is optional supplementary context only.`, + ``, + renderDesignRules(), + ``, + ``, + ``, + `1. Read the current design files.`, + `2. Plan your changes based on the priority order above.`, + `3. Apply changes by editing the files in place.`, + `4. Ensure all design system tokens from Design.md are still used correctly.`, + `5. Do NOT remove functionality that was working correctly.`, + `6. After making changes, briefly summarize what you changed and why.`, + ``, + ``, + ``, + `- Edit files in place — do not create new files.`, + `- Maintain design system compliance — use tokens from Design.md.`, + `- User feedback overrides automated critique when they conflict.`, + TRAILING_PROSE_REMINDER, + ``, + ``, + ``, + opts.prompt, + ``, + ].join("\n"); +} + +/** + * Phase 4 — visible: final deterministic gate. Runs when the post-loop + * scanner still reports findings. The agent MUST remove every one before + * export; no ambiguity, no negotiation, no new features. + */ +export function buildForcedFixPrompt(opts: { + designDir: string; + designSystem: DesignSystemData; + scanFindings: string; +}): string { + return [ + ``, + `The deterministic scanner \`${SCAN_COMMAND_STR}\` still reports banned`, + `anti-patterns in the design files. Export is BLOCKED until every one of`, + `them is removed. This is a forced-fix pass — make the minimal edits`, + `needed to eliminate the findings; do not refactor, restyle, or add`, + `features.`, + ``, + ``, + ``, + `Edit these files in place:`, + `- \`${opts.designDir}/index.html\``, + `- \`${opts.designDir}/styles.css\``, + `- \`${opts.designDir}/script.js\``, + ``, + ``, + ``, + opts.designSystem.raw, + ``, + ``, + ``, + opts.scanFindings.trim() || + "(no findings provided — if you see this, the orchestrator is buggy)", + ``, + ``, + ``, + renderDesignRules(), + ``, + ``, + ``, + `1. For each finding, open the cited file and remove the banned pattern.`, + `2. For side-stripe borders: delete the rule entirely and rewrite the`, + ` element with a different structure (full border, background tint,`, + ` leading icon/number, or no indicator). Do NOT swap to inset shadow.`, + `3. For gradient text: replace with a solid color from the design system.`, + `4. For overused/reflex fonts: pick a distinctive replacement that fits`, + ` the brand voice and is NOT in the banned-fonts list. Update every`, + ` reference to the old font family.`, + `5. For AI color-palette findings: re-pick from the Design.md tokens.`, + `6. Do NOT introduce new banned patterns while fixing these.`, + `7. After editing, briefly list each finding and the file:line you fixed.`, + ``, + ``, + ``, + `- Edit files in place — do not create new files.`, + `- Keep the design system tokens from Design.md intact.`, + `- Do NOT alter working functionality, content, or copy.`, + TRAILING_PROSE_REMINDER, + ``, + ].join("\n"); +} + +// ============================================================================ +// PHASE 5: EXPORT / HANDOFF +// ============================================================================ + +/** Phase 5 — visible: export design and create output-type-tailored assets. */ +export function buildExportPrompt(opts: { + prompt: string; + designDir: string; + finalDesignDir: string; + designSystem: DesignSystemData; + outputType: string; +}): string { + return [ + ``, + `Export the final design and create handoff assets tailored to the`, + `output type the user selected at workflow invocation. Do NOT ask the`, + `user any further questions — the output type is already decided and`, + `the assets below are what they expect.`, + ``, + ``, + ``, + `You are exporting a **${opts.outputType}**. Follow the matching asset`, + `section below (exactly one applies) and skip the others.`, + ``, + ``, + ``, + `Source design files: \`${opts.designDir}/\``, + `Final export directory: \`${opts.finalDesignDir}/\``, + ``, + ``, + ``, + ``, + `**Step 1 — Copy design files** (all output types):`, + `- \`${opts.designDir}/index.html\` → \`${opts.finalDesignDir}/design/index.html\``, + `- \`${opts.designDir}/styles.css\` → \`${opts.finalDesignDir}/design/styles.css\``, + `- \`${opts.designDir}/script.js\` → \`${opts.finalDesignDir}/design/script.js\``, + ``, + `**Step 2 — Output-type-specific assets** (follow the one block matching \`${opts.outputType}\`):`, + ``, + buildPrototypeAssetsBlock(opts.finalDesignDir), + ``, + buildWireframeAssetsBlock(), + ``, + buildPageAssetsBlock(), + ``, + buildComponentAssetsBlock(opts.finalDesignDir), + ``, + `**Step 3 — Write \`${opts.finalDesignDir}/design-intent.md\`** (all output types):`, + ` - Original design request (verbatim)`, + ` - Key design decisions made during generation and refinement`, + ` - Design rationale for layout, color, and typography choices`, + ` - Output type: ${opts.outputType}`, + ` - For \`wireframe\`: focus rationale on information architecture and structure rather than color/polish.`, + ``, + `**Step 4 — Write \`${opts.finalDesignDir}/component-specs.md\`** (all output types — keep this filename stable):`, + ` Tailor the content to the output type:`, + ` - \`prototype\`: full component catalog. For each: name, purpose, variants, key CSS properties, interaction states, navigation role.`, + ` - \`page\`: section-by-section breakdown of the single page (header, main, footer, etc.), responsive behavior, content hierarchy.`, + ` - \`wireframe\`: IA notes, region annotations, which areas are placeholder vs locked, user flow described in text.`, + ` - \`component\`: detailed anatomy of the single component — props/variants table, full state matrix (default/hover/active/focus/disabled/loading), accessibility notes, CSS custom-property API the component exposes, usage snippet.`, + ` Always reference the design system tokens used (from Design.md).`, + ``, + `**Step 5 — Report** the final export location and, for \`prototype\` only, the exact command to run the server (\`cd ${opts.finalDesignDir}/design && bun run start\`).`, + ``, + ``, + ``, + ``, + opts.prompt, + ``, + ``, + ``, + `- Do NOT use the AskUserQuestion tool — the user has already chosen the output type.`, + `- Create the export directory structure if it doesn't exist.`, + `- Do NOT modify the original design files — only copy them.`, + `- For \`prototype\`: the server MUST be zero-dependency Bun.serve — no Express, http-server, or any other library.`, + `- Keep \`design-intent.md\` and \`component-specs.md\` concise and actionable.`, + TRAILING_PROSE_REMINDER, + ``, + ].join("\n"); +} + +/** Prototype: runnable Bun static-file server on port 4173. */ +function buildPrototypeAssetsBlock(finalDesignDir: string): string { + return [ + ` (emit only if outputType === "prototype")`, + ``, + `Create a runnable Bun static-file server so the user can preview and`, + `interact with the prototype immediately.`, + ``, + `a. Write \`${finalDesignDir}/design/server.ts\` with EXACTLY this content:`, + ``, + "```ts", + `import { file } from "bun";`, + `import { dirname, extname, join, normalize } from "node:path";`, + `import { fileURLToPath } from "node:url";`, + ``, + `const ROOT = dirname(fileURLToPath(import.meta.url));`, + `const PORT = Number(process.env.PORT ?? 4173);`, + ``, + `const MIME: Record = {`, + ` ".html": "text/html; charset=utf-8",`, + ` ".css": "text/css; charset=utf-8",`, + ` ".js": "application/javascript; charset=utf-8",`, + ` ".json": "application/json; charset=utf-8",`, + ` ".svg": "image/svg+xml",`, + ` ".png": "image/png",`, + ` ".jpg": "image/jpeg",`, + ` ".jpeg": "image/jpeg",`, + ` ".gif": "image/gif",`, + ` ".ico": "image/x-icon",`, + ` ".webp": "image/webp",`, + ` ".woff": "font/woff",`, + ` ".woff2": "font/woff2",`, + `};`, + ``, + `Bun.serve({`, + ` port: PORT,`, + ` async fetch(req) {`, + ` const url = new URL(req.url);`, + ` const pathname = url.pathname === "/" ? "/index.html" : url.pathname;`, + ` const resolved = normalize(join(ROOT, pathname));`, + ` if (!resolved.startsWith(ROOT)) return new Response("Forbidden", { status: 403 });`, + ` const f = file(resolved);`, + ` if (!(await f.exists())) return new Response("Not Found", { status: 404 });`, + ` const type = MIME[extname(resolved).toLowerCase()] ?? "application/octet-stream";`, + ` return new Response(f, { headers: { "Content-Type": type } });`, + ` },`, + `});`, + ``, + `console.log(\`Prototype running at http://localhost:\${PORT}\`);`, + "```", + ``, + `b. Write \`${finalDesignDir}/design/package.json\` with EXACTLY this content`, + ` (replacing \`\` with a lowercase-kebab slug derived from the design request):`, + ``, + "```json", + `{`, + ` "name": "-prototype",`, + ` "private": true,`, + ` "type": "module",`, + ` "scripts": {`, + ` "start": "bun run server.ts"`, + ` }`, + `}`, + "```", + ``, + ``, + ].join("\n"); +} + +/** Wireframe: no server, no extra files beyond the core three. */ +function buildWireframeAssetsBlock(): string { + return [ + ` (emit only if outputType === "wireframe")`, + ``, + `No server or package.json — wireframes are viewed by opening`, + `\`design/index.html\` directly in a browser. Do NOT create \`server.ts\``, + `or \`package.json\` for this output type.`, + ``, + ``, + ].join("\n"); +} + +/** Page: no server, no extra files beyond the core three. */ +function buildPageAssetsBlock(): string { + return [ + ` (emit only if outputType === "page")`, + ``, + `No server or package.json — the user opens \`design/index.html\` directly.`, + `Do NOT create \`server.ts\` or \`package.json\` for this output type.`, + ``, + ``, + ].join("\n"); +} + +/** Component: showcase in index.html plus an isolated copy-paste snippet. */ +function buildComponentAssetsBlock(finalDesignDir: string): string { + return [ + ` (emit only if outputType === "component")`, + ``, + `In addition to the core three files, write a standalone snippet for`, + `easy copy-paste into a host application:`, + ``, + `\`${finalDesignDir}/design/snippet.html\``, + `- Just the component markup (no showcase chrome, no variant grid).`, + `- A single \`