From af2d6e1194843aa5d0242f32fa149620fab8e98a Mon Sep 17 00:00:00 2001 From: Paul Bakaus Date: Mon, 13 Apr 2026 18:14:13 -0700 Subject: [PATCH] Support PRODUCT.md + DESIGN.md as canonical context files MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pioneers a two-file convention for project context: - PRODUCT.md (strategic): users, brand, principles — answers who/what/why - DESIGN.md (visual): follows Google's Stitch DESIGN.md spec — answers how-it-looks Both files live at the repo root. Filename matching is case-insensitive. DESIGN.md wins on visual conflicts, PRODUCT.md wins on strategic/voice. Legacy .impeccable.md is auto-migrated to PRODUCT.md on first read by the new shared loader. This is silent and one-shot — the rename is permanent. What changed: - New scripts/load-context.mjs: shared context loader used by every command that needs project context. Reads both files, handles legacy migration. - New reference/document.md: /impeccable document command that generates DESIGN.md by auto-extracting tokens (colors, typography, spacing, radii, shadows, components) from CSS/Tailwind/theme files, then asking the user to confirm descriptive language for atmosphere and color character. Follows Google's Stitch DESIGN.md format for tool compatibility. - SKILL.md Context Gathering Protocol updated to load both files and nudge the user to run /impeccable document when DESIGN.md is missing. - reference/teach.md rewritten to split discovery cleanly: strategic questions go to PRODUCT.md, visual/design-system work is delegated to /impeccable document (skipped on empty projects). - reference/live.md consumes {product, design, productPath, designPath, migrated} from the loader instead of a single context blob. - scripts/live.mjs uses the shared loader instead of inline file reading. - Command count updated 22 → 23 (new: document). Metadata, router table, command menu, periodic table viz, and homepage data all updated. - .gitignore adds PRODUCT.md + DESIGN.md (repo-local, not shared). Co-Authored-By: Claude Opus 4.6 (1M context) --- .agents/skills/impeccable/SKILL.md | 21 ++- .agents/skills/impeccable/reference/audit.md | 4 +- .../skills/impeccable/reference/critique.md | 4 +- .../skills/impeccable/reference/document.md | 126 ++++++++++++++++++ .agents/skills/impeccable/reference/live.md | 15 ++- .agents/skills/impeccable/reference/teach.md | 81 ++++++++--- .../impeccable/scripts/command-metadata.json | 6 +- .agents/skills/impeccable/scripts/live.mjs | 16 ++- .../impeccable/scripts/load-context.mjs | 93 +++++++++++++ .agents/skills/impeccable/scripts/pin.mjs | 2 +- .claude-plugin/marketplace.json | 4 +- .claude-plugin/plugin.json | 2 +- .claude/skills/impeccable/SKILL.md | 23 +++- .claude/skills/impeccable/reference/audit.md | 4 +- .../skills/impeccable/reference/critique.md | 4 +- .../skills/impeccable/reference/document.md | 126 ++++++++++++++++++ .claude/skills/impeccable/reference/live.md | 15 ++- .claude/skills/impeccable/reference/teach.md | 81 ++++++++--- .../impeccable/scripts/command-metadata.json | 6 +- .claude/skills/impeccable/scripts/live.mjs | 16 ++- .../impeccable/scripts/load-context.mjs | 93 +++++++++++++ .claude/skills/impeccable/scripts/pin.mjs | 2 +- .cursor/skills/impeccable/SKILL.md | 21 ++- .cursor/skills/impeccable/reference/audit.md | 4 +- .../skills/impeccable/reference/critique.md | 4 +- .../skills/impeccable/reference/document.md | 126 ++++++++++++++++++ .cursor/skills/impeccable/reference/live.md | 15 ++- .cursor/skills/impeccable/reference/teach.md | 81 ++++++++--- .../impeccable/scripts/command-metadata.json | 6 +- .cursor/skills/impeccable/scripts/live.mjs | 16 ++- .../impeccable/scripts/load-context.mjs | 93 +++++++++++++ .cursor/skills/impeccable/scripts/pin.mjs | 2 +- .gemini/skills/impeccable/SKILL.md | 21 ++- .gemini/skills/impeccable/reference/audit.md | 4 +- .../skills/impeccable/reference/critique.md | 4 +- .../skills/impeccable/reference/document.md | 126 ++++++++++++++++++ .gemini/skills/impeccable/reference/live.md | 15 ++- .gemini/skills/impeccable/reference/teach.md | 81 ++++++++--- .../impeccable/scripts/command-metadata.json | 6 +- .gemini/skills/impeccable/scripts/live.mjs | 16 ++- .../impeccable/scripts/load-context.mjs | 93 +++++++++++++ .gemini/skills/impeccable/scripts/pin.mjs | 2 +- .github/skills/impeccable/SKILL.md | 23 +++- .github/skills/impeccable/reference/audit.md | 4 +- .../skills/impeccable/reference/critique.md | 4 +- .../skills/impeccable/reference/document.md | 126 ++++++++++++++++++ .github/skills/impeccable/reference/live.md | 15 ++- .github/skills/impeccable/reference/teach.md | 81 ++++++++--- .../impeccable/scripts/command-metadata.json | 6 +- .github/skills/impeccable/scripts/live.mjs | 16 ++- .../impeccable/scripts/load-context.mjs | 93 +++++++++++++ .github/skills/impeccable/scripts/pin.mjs | 2 +- .gitignore | 5 +- .kiro/skills/impeccable/SKILL.md | 21 ++- .kiro/skills/impeccable/reference/audit.md | 4 +- .kiro/skills/impeccable/reference/critique.md | 4 +- .kiro/skills/impeccable/reference/document.md | 126 ++++++++++++++++++ .kiro/skills/impeccable/reference/live.md | 15 ++- .kiro/skills/impeccable/reference/teach.md | 81 ++++++++--- .../impeccable/scripts/command-metadata.json | 6 +- .kiro/skills/impeccable/scripts/live.mjs | 16 ++- .../impeccable/scripts/load-context.mjs | 93 +++++++++++++ .kiro/skills/impeccable/scripts/pin.mjs | 2 +- .opencode/skills/impeccable/SKILL.md | 23 +++- .../skills/impeccable/reference/audit.md | 4 +- .../skills/impeccable/reference/critique.md | 4 +- .../skills/impeccable/reference/document.md | 126 ++++++++++++++++++ .opencode/skills/impeccable/reference/live.md | 15 ++- .../skills/impeccable/reference/teach.md | 81 ++++++++--- .../impeccable/scripts/command-metadata.json | 6 +- .opencode/skills/impeccable/scripts/live.mjs | 16 ++- .../impeccable/scripts/load-context.mjs | 93 +++++++++++++ .opencode/skills/impeccable/scripts/pin.mjs | 2 +- .pi/skills/impeccable/SKILL.md | 21 ++- .pi/skills/impeccable/reference/audit.md | 4 +- .pi/skills/impeccable/reference/critique.md | 4 +- .pi/skills/impeccable/reference/document.md | 126 ++++++++++++++++++ .pi/skills/impeccable/reference/live.md | 15 ++- .pi/skills/impeccable/reference/teach.md | 81 ++++++++--- .../impeccable/scripts/command-metadata.json | 6 +- .pi/skills/impeccable/scripts/live.mjs | 16 ++- .../impeccable/scripts/load-context.mjs | 93 +++++++++++++ .pi/skills/impeccable/scripts/pin.mjs | 2 +- .rovodev/skills/impeccable/SKILL.md | 23 +++- .rovodev/skills/impeccable/reference/audit.md | 4 +- .../skills/impeccable/reference/critique.md | 4 +- .../skills/impeccable/reference/document.md | 126 ++++++++++++++++++ .rovodev/skills/impeccable/reference/live.md | 15 ++- .rovodev/skills/impeccable/reference/teach.md | 81 ++++++++--- .../impeccable/scripts/command-metadata.json | 6 +- .rovodev/skills/impeccable/scripts/live.mjs | 16 ++- .../impeccable/scripts/load-context.mjs | 93 +++++++++++++ .rovodev/skills/impeccable/scripts/pin.mjs | 2 +- .trae-cn/skills/impeccable/SKILL.md | 23 +++- .trae-cn/skills/impeccable/reference/audit.md | 4 +- .../skills/impeccable/reference/critique.md | 4 +- .../skills/impeccable/reference/document.md | 126 ++++++++++++++++++ .trae-cn/skills/impeccable/reference/live.md | 15 ++- .trae-cn/skills/impeccable/reference/teach.md | 81 ++++++++--- .../impeccable/scripts/command-metadata.json | 6 +- .trae-cn/skills/impeccable/scripts/live.mjs | 16 ++- .../impeccable/scripts/load-context.mjs | 93 +++++++++++++ .trae-cn/skills/impeccable/scripts/pin.mjs | 2 +- .trae/skills/impeccable/SKILL.md | 23 +++- .trae/skills/impeccable/reference/audit.md | 4 +- .trae/skills/impeccable/reference/critique.md | 4 +- .trae/skills/impeccable/reference/document.md | 126 ++++++++++++++++++ .trae/skills/impeccable/reference/live.md | 15 ++- .trae/skills/impeccable/reference/teach.md | 81 ++++++++--- .../impeccable/scripts/command-metadata.json | 6 +- .trae/skills/impeccable/scripts/live.mjs | 16 ++- .../impeccable/scripts/load-context.mjs | 93 +++++++++++++ .trae/skills/impeccable/scripts/pin.mjs | 2 +- NOTICE.md | 2 +- README.md | 9 +- public/index.html | 22 +-- public/js/components/framework-viz.js | 3 +- public/js/data.js | 2 + public/js/generated/counts.js | 2 +- scripts/lib/sub-pages-data.js | 6 +- scripts/lib/utils.js | 4 +- source/skills/impeccable/SKILL.md | 21 ++- .../skills/impeccable/reference/document.md | 126 ++++++++++++++++++ source/skills/impeccable/reference/live.md | 15 ++- source/skills/impeccable/reference/teach.md | 81 ++++++++--- .../impeccable/scripts/command-metadata.json | 6 +- source/skills/impeccable/scripts/live.mjs | 16 ++- .../impeccable/scripts/load-context.mjs | 93 +++++++++++++ source/skills/impeccable/scripts/pin.mjs | 2 +- 129 files changed, 3937 insertions(+), 544 deletions(-) create mode 100644 .agents/skills/impeccable/reference/document.md create mode 100644 .agents/skills/impeccable/scripts/load-context.mjs create mode 100644 .claude/skills/impeccable/reference/document.md create mode 100644 .claude/skills/impeccable/scripts/load-context.mjs create mode 100644 .cursor/skills/impeccable/reference/document.md create mode 100644 .cursor/skills/impeccable/scripts/load-context.mjs create mode 100644 .gemini/skills/impeccable/reference/document.md create mode 100644 .gemini/skills/impeccable/scripts/load-context.mjs create mode 100644 .github/skills/impeccable/reference/document.md create mode 100644 .github/skills/impeccable/scripts/load-context.mjs create mode 100644 .kiro/skills/impeccable/reference/document.md create mode 100644 .kiro/skills/impeccable/scripts/load-context.mjs create mode 100644 .opencode/skills/impeccable/reference/document.md create mode 100644 .opencode/skills/impeccable/scripts/load-context.mjs create mode 100644 .pi/skills/impeccable/reference/document.md create mode 100644 .pi/skills/impeccable/scripts/load-context.mjs create mode 100644 .rovodev/skills/impeccable/reference/document.md create mode 100644 .rovodev/skills/impeccable/scripts/load-context.mjs create mode 100644 .trae-cn/skills/impeccable/reference/document.md create mode 100644 .trae-cn/skills/impeccable/scripts/load-context.mjs create mode 100644 .trae/skills/impeccable/reference/document.md create mode 100644 .trae/skills/impeccable/scripts/load-context.mjs create mode 100644 source/skills/impeccable/reference/document.md create mode 100644 source/skills/impeccable/scripts/load-context.mjs diff --git a/.agents/skills/impeccable/SKILL.md b/.agents/skills/impeccable/SKILL.md index 454b52cf2..66520b836 100644 --- a/.agents/skills/impeccable/SKILL.md +++ b/.agents/skills/impeccable/SKILL.md @@ -25,10 +25,17 @@ After running the script, delete this entire section (from ` **Build & Plan** > `$impeccable craft [feature]` - Shape, then build a feature end-to-end > `$impeccable shape [feature]` - Plan UX/UI before writing code -> `$impeccable teach` - Set up design context for this project (one-time) +> `$impeccable teach` - Set up PRODUCT.md and DESIGN.md context for this project +> `$impeccable document` - Generate DESIGN.md from existing project code > `$impeccable extract [target]` - Pull reusable tokens and components into design system > > **Evaluate** @@ -343,6 +351,7 @@ When a sub-command is matched, load the linked reference and follow its instruct | `craft` | [craft](reference/craft.md) | Full shape-then-build flow with visual iteration | | `teach` | [teach](reference/teach.md) | One-time setup: gather design context for the project | | `extract` | [extract](reference/extract.md) | Pull reusable tokens and components into design system | +| `document` | [document](reference/document.md) | Generate DESIGN.md from existing project code (visual design system doc) | | `shape` | [shape](reference/shape.md) | Plan UX and UI before writing code (produces a design brief) | | `critique` | [critique](reference/critique.md) | UX design review with heuristic scoring and persona testing | | `audit` | [audit](reference/audit.md) | Technical quality checks across a11y, perf, theming, responsive, anti-patterns | diff --git a/.agents/skills/impeccable/reference/audit.md b/.agents/skills/impeccable/reference/audit.md index ab5552ecd..fa480e345 100644 --- a/.agents/skills/impeccable/reference/audit.md +++ b/.agents/skills/impeccable/reference/audit.md @@ -95,7 +95,7 @@ For each issue, document: - **Impact**: How it affects users - **WCAG/Standard**: Which standard it violates (if applicable) - **Recommendation**: How to fix it -- **Suggested command**: Which command to use (prefer: $impeccable adapt, $impeccable animate, $impeccable audit, $impeccable bolder, $impeccable clarify, $impeccable colorize, $impeccable critique, $impeccable delight, $impeccable distill, $impeccable harden, $impeccable layout, $impeccable onboard, $impeccable optimize, $impeccable overdrive, $impeccable polish, $impeccable quieter, $impeccable shape, $impeccable typeset) +- **Suggested command**: Which command to use (prefer: $impeccable adapt, $impeccable animate, $impeccable audit, $impeccable bolder, $impeccable clarify, $impeccable colorize, $impeccable critique, $impeccable delight, $impeccable distill, $impeccable document, $impeccable harden, $impeccable layout, $impeccable onboard, $impeccable optimize, $impeccable overdrive, $impeccable polish, $impeccable quieter, $impeccable shape, $impeccable typeset) ### Patterns & Systemic Issues @@ -114,7 +114,7 @@ List recommended commands in priority order (P0 first, then P1, then P2): 1. **[P?] `$command-name`** — Brief description (specific context from audit findings) 2. **[P?] `$command-name`** — Brief description (specific context) -**Rules**: Only recommend commands from: $impeccable adapt, $impeccable animate, $impeccable audit, $impeccable bolder, $impeccable clarify, $impeccable colorize, $impeccable critique, $impeccable delight, $impeccable distill, $impeccable harden, $impeccable layout, $impeccable onboard, $impeccable optimize, $impeccable overdrive, $impeccable polish, $impeccable quieter, $impeccable shape, $impeccable typeset. Map findings to the most appropriate command. End with `$impeccable polish` as the final step if any fixes were recommended. +**Rules**: Only recommend commands from: $impeccable adapt, $impeccable animate, $impeccable audit, $impeccable bolder, $impeccable clarify, $impeccable colorize, $impeccable critique, $impeccable delight, $impeccable distill, $impeccable document, $impeccable harden, $impeccable layout, $impeccable onboard, $impeccable optimize, $impeccable overdrive, $impeccable polish, $impeccable quieter, $impeccable shape, $impeccable typeset. Map findings to the most appropriate command. End with `$impeccable polish` as the final step if any fixes were recommended. After presenting the summary, tell the user: diff --git a/.agents/skills/impeccable/reference/critique.md b/.agents/skills/impeccable/reference/critique.md index cc0944eca..4fc63a08f 100644 --- a/.agents/skills/impeccable/reference/critique.md +++ b/.agents/skills/impeccable/reference/critique.md @@ -132,7 +132,7 @@ For each issue, tag with **P0-P3 severity** (consult [heuristics-scoring](heuris - **[P?] What**: Name the problem clearly - **Why it matters**: How this hurts users or undermines goals - **Fix**: What to do about it (be concrete) -- **Suggested command**: Which command could address this (from: $impeccable adapt, $impeccable animate, $impeccable audit, $impeccable bolder, $impeccable clarify, $impeccable colorize, $impeccable critique, $impeccable delight, $impeccable distill, $impeccable harden, $impeccable layout, $impeccable onboard, $impeccable optimize, $impeccable overdrive, $impeccable polish, $impeccable quieter, $impeccable shape, $impeccable typeset) +- **Suggested command**: Which command could address this (from: $impeccable adapt, $impeccable animate, $impeccable audit, $impeccable bolder, $impeccable clarify, $impeccable colorize, $impeccable critique, $impeccable delight, $impeccable distill, $impeccable document, $impeccable harden, $impeccable layout, $impeccable onboard, $impeccable optimize, $impeccable overdrive, $impeccable polish, $impeccable quieter, $impeccable shape, $impeccable typeset) #### Persona Red Flags > *Consult [personas](personas.md)* @@ -197,7 +197,7 @@ List recommended commands in priority order, based on the user's answers: ... **Rules for recommendations**: -- Only recommend commands from: $impeccable adapt, $impeccable animate, $impeccable audit, $impeccable bolder, $impeccable clarify, $impeccable colorize, $impeccable critique, $impeccable delight, $impeccable distill, $impeccable harden, $impeccable layout, $impeccable onboard, $impeccable optimize, $impeccable overdrive, $impeccable polish, $impeccable quieter, $impeccable shape, $impeccable typeset +- Only recommend commands from: $impeccable adapt, $impeccable animate, $impeccable audit, $impeccable bolder, $impeccable clarify, $impeccable colorize, $impeccable critique, $impeccable delight, $impeccable distill, $impeccable document, $impeccable harden, $impeccable layout, $impeccable onboard, $impeccable optimize, $impeccable overdrive, $impeccable polish, $impeccable quieter, $impeccable shape, $impeccable typeset - Order by the user's stated priorities first, then by impact - Each item's description should carry enough context that the command knows what to focus on - Map each Priority Issue to the appropriate command diff --git a/.agents/skills/impeccable/reference/document.md b/.agents/skills/impeccable/reference/document.md new file mode 100644 index 000000000..34fb926f5 --- /dev/null +++ b/.agents/skills/impeccable/reference/document.md @@ -0,0 +1,126 @@ +Generate a DESIGN.md file in the project root that captures the current visual design system, so AI agents generating new screens stay on-brand. + +DESIGN.md follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/): a single markdown file at the project root with five fixed sections describing colors, typography, components, layout, and overall atmosphere. Keep section headers exactly as specified so the file stays compatible with other DESIGN.md-aware tools. + +## When to run + +- The user just ran `$impeccable teach` and needs the visual side documented. +- The skill noticed no `DESIGN.md` exists and nudged the user to create one. +- An existing `DESIGN.md` is stale (the design has drifted). +- Before a large redesign, to capture the current state as a reference. + +If a `DESIGN.md` already exists, **do not silently overwrite it**. Show the user the existing file and ask the user directly to clarify what you cannot infer. whether to refresh it, overwrite it, or merge into it. + +## Process (approach C: auto-extract, then confirm descriptive language) + +### Step 1: Find the design assets + +Search the codebase in priority order: + +1. **CSS custom properties** — grep for `--color-`, `--font-`, `--spacing-`, `--radius-`, `--shadow-`, `--ease-`, `--duration-` declarations in CSS files (usually `src/styles/`, `public/css/`, `app/globals.css`, etc.). Record name, value, and the file it's defined in. +2. **Tailwind config** — if `tailwind.config.{js,ts,mjs}` exists, read the `theme.extend` block for colors, fontFamily, spacing, borderRadius, boxShadow. +3. **CSS-in-JS theme files** — if the project uses styled-components, emotion, vanilla-extract, stitches, etc., look for `theme.ts`, `tokens.ts`, or equivalent. +4. **Design token files** — `tokens.json`, `design-tokens.json`, Style Dictionary output, W3C token community group format. +5. **Component library** — scan the main button, card, input, navigation, dialog components. Note their variant APIs and default styles. +6. **Global stylesheet** — the root CSS file usually has the base typography and color assignments. +7. **Visible rendered output** — if browser automation tools are available, load the live site and sample computed styles from key elements (body, h1, a, button, .card). This catches values that tokens miss. + +### Step 2: Auto-extract what can be auto-extracted + +Build a structured draft from the discovered tokens. For each token class: + +- **Colors**: Group by hue family. Convert hex → OKLCH to infer lightness/chroma. Identify background vs. text vs. accent by usage patterns in CSS (`background`, `color`, `border`, `fill`). Flag any that are only used once (possibly one-off, not system tokens). +- **Typography**: Extract font families and their declared stacks. Extract the scale (all `font-size` values used in CSS custom props + component styles). Extract weights actually used. Detect the scale ratio (1.125, 1.2, 1.25, 1.333, 1.5, golden). +- **Spacing**: Extract the scale, detect the base unit (4px, 8px, other). +- **Radii & shadows**: List the values used. +- **Components**: For each common component (button, card, input, nav, dialog), extract shape (radius), color assignment, hover/focus treatment, internal padding. + +### Step 3: Ask the user for qualitative language + +The following sections require creative input that cannot be auto-extracted reliably. ask the user directly to clarify what you cannot infer. for each (group them into one interaction if possible): + +- **Visual Theme & Atmosphere**: mood adjectives (airy/dense, minimal/maximalist, editorial/utilitarian, warm/clinical), aesthetic philosophy in 2-3 sentences, key characteristics as a bullet list. +- **Color character** (for auto-extracted colors): descriptive names ("Deep Muted Teal-Navy", not "blue-800"). Suggest 2-3 options per color based on the hue/saturation, let the user pick. +- **Typographic character**: describe the font pairing ("Modern geometric sans-serif with humanist warmth" > "Manrope 500"). Describe letter-spacing strategy. +- **Spacing philosophy**: 1-2 sentences on whitespace strategy ("generous breathing room that prioritizes photography"). +- **Component philosophy**: brief description of the feel of buttons, cards, inputs ("refined and understated" vs. "tactile and confident"). + +If the user has a `PRODUCT.md` that covers brand personality, quote a line from it so they see their own strategic language carry over. + +### Step 4: Write DESIGN.md + +Use this exact structure (section headers must match the Google spec character-for-character): + +```markdown +# Design System: [Project Title] +**Project ID:** [optional — only if a Stitch project ID exists] + +## 1. Visual Theme & Atmosphere + +[2-3 paragraph description using evocative adjectives. Start with the overall sanctuary/laboratory/workshop/stage analogy if one fits. End with a short **Key Characteristics:** bullet list.] + +## 2. Color Palette & Roles + +### [Semantic group name: Primary Foundation, Accent & Interactive, Typography & Text Hierarchy, Functional States, etc.] +- **[Descriptive Name]** (#HEX) – [Functional role. Where/why it's used.] + +## 3. Typography Rules + +**Primary Font Family:** [Name] +**Character:** [1-sentence personality description.] + +### Hierarchy & Weights +- **[Role (e.g. Display Headlines H1)]:** [Weight] weight ([num]), [letter-spacing], [size]. [Purpose.] + +### Spacing Principles +[Short list of rules about leading, letter-spacing, vertical rhythm.] + +## 4. Component Stylings + +### Buttons +- **Shape:** [radius description with px value in parens] +- **Primary CTA:** [color assignment + padding] +- **Hover State:** [transition description] +- **Focus State:** [accessibility treatment] +- **Secondary CTA (if applicable):** [description] + +### Cards & Containers +- **Corner Style:** [description] +- **Background:** [colors used] +- **Shadow Strategy:** [flat / soft / heavy] +- **Border:** [if any] +- **Internal Padding:** [scale] +- **Image Treatment:** [if relevant] + +### Navigation +- [Style, typography, default/hover/active states, mobile treatment] + +### Inputs/Forms +- [Stroke style, background, focus treatment] + +## 5. Layout Principles + +[Paragraph or short list describing whitespace strategy, margin scale, grid system, responsive breakpoints. Include px/rem values in parens.] +``` + +### Step 5: Write & confirm + +1. Write the file to `PROJECT_ROOT/DESIGN.md` (uppercase, at root). +2. Show the user the full DESIGN.md you wrote, briefly highlighting the non-obvious creative choices (descriptive color names, atmosphere language). +3. Offer to refine any section: "Want me to revise a section, add component patterns I missed, or adjust the atmosphere language?" + +## Style guidelines + +- **Descriptive > technical**: "Gently curved edges (8px radius)" > "rounded-lg". Include the technical value in parens, lead with the description. +- **Functional > decorative**: for each token, explain WHERE and WHY it's used, not just WHAT it is. +- **Exact values in parens**: hex codes, px/rem values, font weights — always the number in parens alongside the description. +- **Group colors semantically**: Foundation (backgrounds), Accent (interactive), Typography (text hierarchy), States (success/warning/error), not hex-sorted. +- **Reference the user's domain**: if the project is a DEX, say "trading-focused"; if it's a CMS, say "editorial". Domain-aware language helps agents pick sensible defaults. + +## Pitfalls + +- Don't paste raw CSS class names. Translate to descriptive language. +- Don't extract every token. Stop at what's actually reused — one-offs pollute the system. +- Don't invent components that don't exist. If the project only has buttons and cards, only document those. +- Don't overwrite an existing DESIGN.md without asking. +- Don't duplicate content from PRODUCT.md. DESIGN.md is strictly visual. diff --git a/.agents/skills/impeccable/reference/live.md b/.agents/skills/impeccable/reference/live.md index 3388e1897..b7bd999bb 100644 --- a/.agents/skills/impeccable/reference/live.md +++ b/.agents/skills/impeccable/reference/live.md @@ -21,12 +21,21 @@ Output JSON: "serverPort": 8400, "serverToken": "...", "pageFile": "public/index.html", - "hasContext": true, - "context": "...full .impeccable.md contents..." + "hasProduct": true, + "product": "...full PRODUCT.md contents...", + "productPath": "PRODUCT.md", + "hasDesign": true, + "design": "...full DESIGN.md contents...", + "designPath": "DESIGN.md", + "migrated": false } ``` -Keep the `context` in mind for variant generation. If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. +Keep **PRODUCT.md** (strategic: users, brand, principles) and **DESIGN.md** (visual: colors, typography, components) in mind for variant generation. **DESIGN.md wins on visual decisions; PRODUCT.md wins on strategic/voice decisions.** + +If `migrated` is true, the loader auto-renamed legacy `.impeccable.md` to `PRODUCT.md` — mention this once to the user and suggest running `$impeccable document` to also generate a `DESIGN.md`. + +If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. ### First-time setup (config missing) diff --git a/.agents/skills/impeccable/reference/teach.md b/.agents/skills/impeccable/reference/teach.md index 2d9f768f1..9d3c7e4a9 100644 --- a/.agents/skills/impeccable/reference/teach.md +++ b/.agents/skills/impeccable/reference/teach.md @@ -1,8 +1,31 @@ # Teach Flow -One-time setup that gathers design context for a project. Design without context produces generic output, so every other command reads this file before doing any work. +Gathers design context for a project and writes two complementary files at the project root: -## Step 1: Explore the Codebase +- **PRODUCT.md** (strategic): target users, product purpose, brand personality, anti-references, strategic design principles. Answers "who/what/why". +- **DESIGN.md** (visual): visual theme, color palette, typography, components, layout. Follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/). Answers "how it looks". + +Every other impeccable command reads these files before doing any work. + +## Step 1: Load current state + +Run the shared loader first so you know what already exists: + +```bash +node {{scripts_path}}/load-context.mjs +``` + +The output tells you whether PRODUCT.md and/or DESIGN.md already exist. If `migrated: true`, legacy `.impeccable.md` was auto-renamed to `PRODUCT.md`. Mention this once to the user. + +Decision tree: +- **Neither file exists (empty project or no context yet)**: do Steps 2-4 (write PRODUCT.md), then decide on DESIGN.md based on whether there's code to analyze. +- **PRODUCT.md exists, DESIGN.md missing**: skip to Step 5 — offer to run `$impeccable document` for DESIGN.md. +- **Both exist**: ask the user directly to clarify what you cannot infer. which to refresh. Skip the one the user doesn't want changed. +- **Just DESIGN.md exists (unusual)**: do Steps 2-4 to produce PRODUCT.md. + +Never silently overwrite an existing file. Always confirm first. + +## Step 2: Explore the codebase Before asking questions, thoroughly scan the project to discover what you can: @@ -13,9 +36,9 @@ Before asking questions, thoroughly scan the project to discover what you can: - **Design tokens / CSS variables**: Existing color palettes, font stacks, spacing scales - **Any style guides or brand documentation** -Note what you've learned and what remains unclear. +Note what you've learned and what remains unclear. This exploration feeds both PRODUCT.md and DESIGN.md. -## Step 2: Ask UX-Focused Questions +## Step 3: Ask strategic questions (for PRODUCT.md) ask the user directly to clarify what you cannot infer. Focus only on what you couldn't infer from the codebase: @@ -29,39 +52,53 @@ ask the user directly to clarify what you cannot infer. Focus only on what you c - Any reference sites or apps that capture the right feel? What specifically about them? - What should this explicitly NOT look like? Any anti-references? -### Aesthetic Preferences -- Any strong preferences for visual direction? (minimal, bold, elegant, playful, technical, organic, etc.) -- Light mode, dark mode, or both? -- Any colors that must be used or avoided? - ### Accessibility & Inclusion - Specific accessibility requirements? (WCAG level, known user needs) - Considerations for reduced motion, color blindness, or other accommodations? -Skip questions where the answer is already clear from the codebase exploration. +Skip questions where the answer is already clear. **Do NOT ask about colors, fonts, radii, or visual styling here** — those belong in DESIGN.md, not PRODUCT.md. -## Step 3: Write Design Context +## Step 4: Write PRODUCT.md -Synthesize your findings and the user's answers into a `## Design Context` section: +Synthesize into a strategic document: ```markdown -## Design Context +# Product -### Users +## Users [Who they are, their context, the job to be done] -### Brand Personality +## Product Purpose +[What this product does, why it exists, what success looks like] + +## Brand Personality [Voice, tone, 3-word personality, emotional goals] -### Aesthetic Direction -[Visual tone, references, anti-references, theme] +## Anti-references +[What this should NOT look like. Specific bad-example sites or patterns to avoid.] -### Design Principles -[3-5 principles derived from the conversation that should guide all design decisions] +## Design Principles +[3-5 strategic principles derived from the conversation. Principles like "practice what you preach", "editorial over marketing", "expert confidence" — NOT visual rules like "use OKLCH" or "magenta accent".] + +## Accessibility & Inclusion +[WCAG level, known user needs, considerations] ``` -Write this section to `.impeccable.md` in the project root. If the file already exists, update the Design Context section in place. +Write to `PROJECT_ROOT/PRODUCT.md`. If `.impeccable.md` existed, the loader already renamed it — merge into that content rather than starting from scratch. -Then ask the user directly to clarify what you cannot infer. whether they'd also like the Design Context appended to AGENTS.md. If yes, append or update the section there as well. +## Step 5: Decide on DESIGN.md -Confirm completion and summarize the key design principles that will now guide all future work. +If the project has meaningful code to analyze (CSS tokens, components, a running site), **offer to run `$impeccable document`** next: "I can also generate a DESIGN.md that captures your visual design system (colors, typography, components) so variants stay on-brand. Want to do that now?" + +If the user agrees, delegate to `$impeccable document` (load its reference and follow that flow). + +If the project is empty (no code yet, pre-implementation), skip DESIGN.md — there's nothing visual to document yet. Mention: "Once you've built some of the interface, run `$impeccable document` to generate a DESIGN.md." + +## Step 6: Confirm and wrap up + +Summarize: +- What was written (PRODUCT.md, DESIGN.md, or both) +- The 3-5 strategic principles from PRODUCT.md that will guide future work +- If DESIGN.md is pending, remind the user how to generate it later + +Optionally ask the user directly to clarify what you cannot infer. whether they'd like a brief summary of PRODUCT.md appended to AGENTS.md for easier agent reference. If yes, append a short **Design Context** pointer section there. diff --git a/.agents/skills/impeccable/scripts/command-metadata.json b/.agents/skills/impeccable/scripts/command-metadata.json index 2974e08f6..d8282689a 100644 --- a/.agents/skills/impeccable/scripts/command-metadata.json +++ b/.agents/skills/impeccable/scripts/command-metadata.json @@ -4,7 +4,11 @@ "argumentHint": "[feature description]" }, "teach": { - "description": "One-time setup that gathers design context for a project. Runs a short discovery interview and writes the answers to .impeccable.md. Every other command reads this file before doing work. Use once per project.", + "description": "Gathers design context for a project. Runs a short discovery interview and writes PRODUCT.md (strategic: users, brand, principles) and, when code exists to analyze, DESIGN.md (visual: colors, typography, components). Every other command reads these files before doing work. Use once per project.", + "argumentHint": "" + }, + "document": { + "description": "Generate a DESIGN.md file that captures the current visual design system. Auto-extracts colors, typography, spacing, radii, and component patterns from the codebase, then asks the user to confirm descriptive language for atmosphere and color character. Follows the Google Stitch DESIGN.md format so the file is tool-compatible. Use when you need a visual design spec an AI agent can follow to stay on-brand.", "argumentHint": "" }, "extract": { diff --git a/.agents/skills/impeccable/scripts/live.mjs b/.agents/skills/impeccable/scripts/live.mjs index 93f05456e..37b6f8997 100644 --- a/.agents/skills/impeccable/scripts/live.mjs +++ b/.agents/skills/impeccable/scripts/live.mjs @@ -21,10 +21,10 @@ import { execSync } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { loadContext } from './load-context.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const PID_FILE = path.join(process.cwd(), '.impeccable-live.json'); -const CONTEXT_FILE = path.join(process.cwd(), '.impeccable.md'); async function liveCli() { const args = process.argv.slice(2); @@ -79,9 +79,8 @@ The agent should then: process.exit(1); } - // 4. Load design context if available - let context = null; - try { context = fs.readFileSync(CONTEXT_FILE, 'utf-8'); } catch { /* optional */ } + // 4. Load PRODUCT.md + DESIGN.md context (auto-migrates legacy .impeccable.md) + const ctx = loadContext(process.cwd()); // 5. Emit everything the agent needs console.log(JSON.stringify({ @@ -89,8 +88,13 @@ The agent should then: serverPort: serverInfo.port, serverToken: serverInfo.token, pageFile: checkResult.config.file, - hasContext: !!context, - context, + hasProduct: ctx.hasProduct, + product: ctx.product, + productPath: ctx.productPath, + hasDesign: ctx.hasDesign, + design: ctx.design, + designPath: ctx.designPath, + migrated: ctx.migrated, }, null, 2)); } diff --git a/.agents/skills/impeccable/scripts/load-context.mjs b/.agents/skills/impeccable/scripts/load-context.mjs new file mode 100644 index 000000000..ab3be08f1 --- /dev/null +++ b/.agents/skills/impeccable/scripts/load-context.mjs @@ -0,0 +1,93 @@ +/** + * Shared context loader for every impeccable command that needs to know + * "who is this for" and "what does this look like". + * + * Input: project root (process.cwd()). + * + * Output (JSON to stdout): + * { + * hasProduct: boolean, // PRODUCT.md found (or auto-migrated) + * product: string | null, // PRODUCT.md contents + * productPath: string | null, // relative path + * hasDesign: boolean, // DESIGN.md found + * design: string | null, // DESIGN.md contents + * designPath: string | null, + * migrated: boolean, // true if we auto-renamed .impeccable.md -> PRODUCT.md + * } + * + * Filename matching is case-insensitive for PRODUCT.md and DESIGN.md. The + * Google DESIGN.md convention is uppercase at repo root; Kiro-style and + * lowercase variants are also matched so users don't get punished for case. + */ + +import fs from 'node:fs'; +import path from 'node:path'; + +const PRODUCT_NAMES = ['PRODUCT.md', 'Product.md', 'product.md']; +const DESIGN_NAMES = ['DESIGN.md', 'Design.md', 'design.md']; +const LEGACY_NAMES = ['.impeccable.md']; + +export function loadContext(cwd = process.cwd()) { + let migrated = false; + + // 1. Look for PRODUCT.md (case-insensitive) + let productPath = firstExisting(cwd, PRODUCT_NAMES); + + // 2. Legacy: if no PRODUCT.md but .impeccable.md exists, rename in place + if (!productPath) { + const legacyPath = firstExisting(cwd, LEGACY_NAMES); + if (legacyPath) { + const newPath = path.join(cwd, 'PRODUCT.md'); + try { + fs.renameSync(legacyPath, newPath); + productPath = newPath; + migrated = true; + } catch { + // Rename failed (permissions, etc.) — fall back to reading legacy in place + productPath = legacyPath; + } + } + } + + // 3. DESIGN.md (case-insensitive) + const designPath = firstExisting(cwd, DESIGN_NAMES); + + const product = productPath ? safeRead(productPath) : null; + const design = designPath ? safeRead(designPath) : null; + + return { + hasProduct: !!product, + product, + productPath: productPath ? path.relative(cwd, productPath) : null, + hasDesign: !!design, + design, + designPath: designPath ? path.relative(cwd, designPath) : null, + migrated, + }; +} + +function firstExisting(cwd, names) { + for (const name of names) { + const abs = path.join(cwd, name); + if (fs.existsSync(abs)) return abs; + } + return null; +} + +function safeRead(p) { + try { return fs.readFileSync(p, 'utf-8'); } catch { return null; } +} + +// --------------------------------------------------------------------------- +// CLI mode — print the context as JSON +// --------------------------------------------------------------------------- + +function cli() { + const result = loadContext(process.cwd()); + console.log(JSON.stringify(result, null, 2)); +} + +const _running = process.argv[1]; +if (_running?.endsWith('load-context.mjs') || _running?.endsWith('load-context.mjs/')) { + cli(); +} diff --git a/.agents/skills/impeccable/scripts/pin.mjs b/.agents/skills/impeccable/scripts/pin.mjs index 89a6babeb..ba02783fb 100644 --- a/.agents/skills/impeccable/scripts/pin.mjs +++ b/.agents/skills/impeccable/scripts/pin.mjs @@ -27,7 +27,7 @@ const HARNESS_DIRS = [ // Valid sub-command names const VALID_COMMANDS = [ - 'craft', 'teach', 'extract', 'shape', + 'craft', 'teach', 'extract', 'document', 'shape', 'critique', 'audit', 'polish', 'bolder', 'quieter', 'distill', 'harden', 'onboard', 'live', 'animate', 'colorize', 'typeset', 'layout', 'delight', 'overdrive', diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index e45a1f1ce..09c58cec3 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -2,7 +2,7 @@ "$schema": "https://anthropic.com/claude-code/marketplace.schema.json", "name": "impeccable", "metadata": { - "description": "Design fluency for AI harnesses. 1 skill, 22 commands, and curated anti-patterns for impeccable frontend design." + "description": "Design fluency for AI harnesses. 1 skill, 23 commands, and curated anti-patterns for impeccable frontend design." }, "owner": { "name": "Paul Bakaus", @@ -11,7 +11,7 @@ "plugins": [ { "name": "impeccable", - "description": "Design fluency for frontend development. 1 skill with 22 commands (/impeccable polish, /impeccable audit, /impeccable critique, etc.) and curated anti-pattern detection.", + "description": "Design fluency for frontend development. 1 skill with 23 commands (/impeccable polish, /impeccable audit, /impeccable critique, etc.) and curated anti-pattern detection.", "version": "3.0.0", "author": { "name": "Paul Bakaus", diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index db007a953..f88a5b075 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "impeccable", - "description": "Design fluency for frontend development. 1 skill with 22 commands (/impeccable polish, /impeccable audit, /impeccable critique, etc.) and curated anti-pattern detection.", + "description": "Design fluency for frontend development. 1 skill with 23 commands (/impeccable polish, /impeccable audit, /impeccable critique, etc.) and curated anti-pattern detection.", "version": "3.0.0", "author": { "name": "Paul Bakaus", diff --git a/.claude/skills/impeccable/SKILL.md b/.claude/skills/impeccable/SKILL.md index c7a126c6f..dce25b9d1 100644 --- a/.claude/skills/impeccable/SKILL.md +++ b/.claude/skills/impeccable/SKILL.md @@ -3,7 +3,7 @@ name: impeccable description: Use when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a frontend interface. Covers websites, landing pages, dashboards, product UI, app shells, components, forms, settings, onboarding, and empty states. Handles UX review, visual hierarchy, information architecture, cognitive load, accessibility, performance, responsive behavior, theming, anti-patterns, typography, fonts, spacing, layout, alignment, color, motion, micro-interactions, UX copy, error states, edge cases, i18n, and reusable design systems or tokens. Also use for bland designs that need to become bolder or more delightful, loud designs that should become quieter, live browser iteration on UI elements, or ambitious visual effects that should feel technically extraordinary. Not for backend-only or non-UI tasks. version: 3.0.0 user-invocable: true -argument-hint: "[craft|shape · audit|critique · animate|bolder|colorize|delight|layout|overdrive|quieter|typeset · adapt|clarify|distill · harden|onboard|optimize|polish · teach|extract|live] [target]" +argument-hint: "[craft|shape · audit|critique · animate|bolder|colorize|delight|layout|overdrive|quieter|typeset · adapt|clarify|distill · harden|onboard|optimize|polish · teach|document|extract|live] [target]" license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. allowed-tools: - Bash(npx impeccable *) @@ -31,10 +31,17 @@ After running the script, delete this entire section (from ` **Build & Plan** > `/impeccable craft [feature]` - Shape, then build a feature end-to-end > `/impeccable shape [feature]` - Plan UX/UI before writing code -> `/impeccable teach` - Set up design context for this project (one-time) +> `/impeccable teach` - Set up PRODUCT.md and DESIGN.md context for this project +> `/impeccable document` - Generate DESIGN.md from existing project code > `/impeccable extract [target]` - Pull reusable tokens and components into design system > > **Evaluate** @@ -349,6 +357,7 @@ When a sub-command is matched, load the linked reference and follow its instruct | `craft` | [craft](reference/craft.md) | Full shape-then-build flow with visual iteration | | `teach` | [teach](reference/teach.md) | One-time setup: gather design context for the project | | `extract` | [extract](reference/extract.md) | Pull reusable tokens and components into design system | +| `document` | [document](reference/document.md) | Generate DESIGN.md from existing project code (visual design system doc) | | `shape` | [shape](reference/shape.md) | Plan UX and UI before writing code (produces a design brief) | | `critique` | [critique](reference/critique.md) | UX design review with heuristic scoring and persona testing | | `audit` | [audit](reference/audit.md) | Technical quality checks across a11y, perf, theming, responsive, anti-patterns | diff --git a/.claude/skills/impeccable/reference/audit.md b/.claude/skills/impeccable/reference/audit.md index bbba2401b..c2258ac54 100644 --- a/.claude/skills/impeccable/reference/audit.md +++ b/.claude/skills/impeccable/reference/audit.md @@ -95,7 +95,7 @@ For each issue, document: - **Impact**: How it affects users - **WCAG/Standard**: Which standard it violates (if applicable) - **Recommendation**: How to fix it -- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) ### Patterns & Systemic Issues @@ -114,7 +114,7 @@ List recommended commands in priority order (P0 first, then P1, then P2): 1. **[P?] `/command-name`** — Brief description (specific context from audit findings) 2. **[P?] `/command-name`** — Brief description (specific context) -**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. +**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. After presenting the summary, tell the user: diff --git a/.claude/skills/impeccable/reference/critique.md b/.claude/skills/impeccable/reference/critique.md index 1da3f7efb..dd14afae8 100644 --- a/.claude/skills/impeccable/reference/critique.md +++ b/.claude/skills/impeccable/reference/critique.md @@ -132,7 +132,7 @@ For each issue, tag with **P0-P3 severity** (consult [heuristics-scoring](heuris - **[P?] What**: Name the problem clearly - **Why it matters**: How this hurts users or undermines goals - **Fix**: What to do about it (be concrete) -- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) #### Persona Red Flags > *Consult [personas](personas.md)* @@ -197,7 +197,7 @@ List recommended commands in priority order, based on the user's answers: ... **Rules for recommendations**: -- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset +- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset - Order by the user's stated priorities first, then by impact - Each item's description should carry enough context that the command knows what to focus on - Map each Priority Issue to the appropriate command diff --git a/.claude/skills/impeccable/reference/document.md b/.claude/skills/impeccable/reference/document.md new file mode 100644 index 000000000..4f3e3dfdf --- /dev/null +++ b/.claude/skills/impeccable/reference/document.md @@ -0,0 +1,126 @@ +Generate a DESIGN.md file in the project root that captures the current visual design system, so AI agents generating new screens stay on-brand. + +DESIGN.md follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/): a single markdown file at the project root with five fixed sections describing colors, typography, components, layout, and overall atmosphere. Keep section headers exactly as specified so the file stays compatible with other DESIGN.md-aware tools. + +## When to run + +- The user just ran `/impeccable teach` and needs the visual side documented. +- The skill noticed no `DESIGN.md` exists and nudged the user to create one. +- An existing `DESIGN.md` is stale (the design has drifted). +- Before a large redesign, to capture the current state as a reference. + +If a `DESIGN.md` already exists, **do not silently overwrite it**. Show the user the existing file and STOP and call the AskUserQuestion tool to clarify. whether to refresh it, overwrite it, or merge into it. + +## Process (approach C: auto-extract, then confirm descriptive language) + +### Step 1: Find the design assets + +Search the codebase in priority order: + +1. **CSS custom properties** — grep for `--color-`, `--font-`, `--spacing-`, `--radius-`, `--shadow-`, `--ease-`, `--duration-` declarations in CSS files (usually `src/styles/`, `public/css/`, `app/globals.css`, etc.). Record name, value, and the file it's defined in. +2. **Tailwind config** — if `tailwind.config.{js,ts,mjs}` exists, read the `theme.extend` block for colors, fontFamily, spacing, borderRadius, boxShadow. +3. **CSS-in-JS theme files** — if the project uses styled-components, emotion, vanilla-extract, stitches, etc., look for `theme.ts`, `tokens.ts`, or equivalent. +4. **Design token files** — `tokens.json`, `design-tokens.json`, Style Dictionary output, W3C token community group format. +5. **Component library** — scan the main button, card, input, navigation, dialog components. Note their variant APIs and default styles. +6. **Global stylesheet** — the root CSS file usually has the base typography and color assignments. +7. **Visible rendered output** — if browser automation tools are available, load the live site and sample computed styles from key elements (body, h1, a, button, .card). This catches values that tokens miss. + +### Step 2: Auto-extract what can be auto-extracted + +Build a structured draft from the discovered tokens. For each token class: + +- **Colors**: Group by hue family. Convert hex → OKLCH to infer lightness/chroma. Identify background vs. text vs. accent by usage patterns in CSS (`background`, `color`, `border`, `fill`). Flag any that are only used once (possibly one-off, not system tokens). +- **Typography**: Extract font families and their declared stacks. Extract the scale (all `font-size` values used in CSS custom props + component styles). Extract weights actually used. Detect the scale ratio (1.125, 1.2, 1.25, 1.333, 1.5, golden). +- **Spacing**: Extract the scale, detect the base unit (4px, 8px, other). +- **Radii & shadows**: List the values used. +- **Components**: For each common component (button, card, input, nav, dialog), extract shape (radius), color assignment, hover/focus treatment, internal padding. + +### Step 3: Ask the user for qualitative language + +The following sections require creative input that cannot be auto-extracted reliably. STOP and call the AskUserQuestion tool to clarify. for each (group them into one interaction if possible): + +- **Visual Theme & Atmosphere**: mood adjectives (airy/dense, minimal/maximalist, editorial/utilitarian, warm/clinical), aesthetic philosophy in 2-3 sentences, key characteristics as a bullet list. +- **Color character** (for auto-extracted colors): descriptive names ("Deep Muted Teal-Navy", not "blue-800"). Suggest 2-3 options per color based on the hue/saturation, let the user pick. +- **Typographic character**: describe the font pairing ("Modern geometric sans-serif with humanist warmth" > "Manrope 500"). Describe letter-spacing strategy. +- **Spacing philosophy**: 1-2 sentences on whitespace strategy ("generous breathing room that prioritizes photography"). +- **Component philosophy**: brief description of the feel of buttons, cards, inputs ("refined and understated" vs. "tactile and confident"). + +If the user has a `PRODUCT.md` that covers brand personality, quote a line from it so they see their own strategic language carry over. + +### Step 4: Write DESIGN.md + +Use this exact structure (section headers must match the Google spec character-for-character): + +```markdown +# Design System: [Project Title] +**Project ID:** [optional — only if a Stitch project ID exists] + +## 1. Visual Theme & Atmosphere + +[2-3 paragraph description using evocative adjectives. Start with the overall sanctuary/laboratory/workshop/stage analogy if one fits. End with a short **Key Characteristics:** bullet list.] + +## 2. Color Palette & Roles + +### [Semantic group name: Primary Foundation, Accent & Interactive, Typography & Text Hierarchy, Functional States, etc.] +- **[Descriptive Name]** (#HEX) – [Functional role. Where/why it's used.] + +## 3. Typography Rules + +**Primary Font Family:** [Name] +**Character:** [1-sentence personality description.] + +### Hierarchy & Weights +- **[Role (e.g. Display Headlines H1)]:** [Weight] weight ([num]), [letter-spacing], [size]. [Purpose.] + +### Spacing Principles +[Short list of rules about leading, letter-spacing, vertical rhythm.] + +## 4. Component Stylings + +### Buttons +- **Shape:** [radius description with px value in parens] +- **Primary CTA:** [color assignment + padding] +- **Hover State:** [transition description] +- **Focus State:** [accessibility treatment] +- **Secondary CTA (if applicable):** [description] + +### Cards & Containers +- **Corner Style:** [description] +- **Background:** [colors used] +- **Shadow Strategy:** [flat / soft / heavy] +- **Border:** [if any] +- **Internal Padding:** [scale] +- **Image Treatment:** [if relevant] + +### Navigation +- [Style, typography, default/hover/active states, mobile treatment] + +### Inputs/Forms +- [Stroke style, background, focus treatment] + +## 5. Layout Principles + +[Paragraph or short list describing whitespace strategy, margin scale, grid system, responsive breakpoints. Include px/rem values in parens.] +``` + +### Step 5: Write & confirm + +1. Write the file to `PROJECT_ROOT/DESIGN.md` (uppercase, at root). +2. Show the user the full DESIGN.md you wrote, briefly highlighting the non-obvious creative choices (descriptive color names, atmosphere language). +3. Offer to refine any section: "Want me to revise a section, add component patterns I missed, or adjust the atmosphere language?" + +## Style guidelines + +- **Descriptive > technical**: "Gently curved edges (8px radius)" > "rounded-lg". Include the technical value in parens, lead with the description. +- **Functional > decorative**: for each token, explain WHERE and WHY it's used, not just WHAT it is. +- **Exact values in parens**: hex codes, px/rem values, font weights — always the number in parens alongside the description. +- **Group colors semantically**: Foundation (backgrounds), Accent (interactive), Typography (text hierarchy), States (success/warning/error), not hex-sorted. +- **Reference the user's domain**: if the project is a DEX, say "trading-focused"; if it's a CMS, say "editorial". Domain-aware language helps agents pick sensible defaults. + +## Pitfalls + +- Don't paste raw CSS class names. Translate to descriptive language. +- Don't extract every token. Stop at what's actually reused — one-offs pollute the system. +- Don't invent components that don't exist. If the project only has buttons and cards, only document those. +- Don't overwrite an existing DESIGN.md without asking. +- Don't duplicate content from PRODUCT.md. DESIGN.md is strictly visual. diff --git a/.claude/skills/impeccable/reference/live.md b/.claude/skills/impeccable/reference/live.md index 3388e1897..19c16fa38 100644 --- a/.claude/skills/impeccable/reference/live.md +++ b/.claude/skills/impeccable/reference/live.md @@ -21,12 +21,21 @@ Output JSON: "serverPort": 8400, "serverToken": "...", "pageFile": "public/index.html", - "hasContext": true, - "context": "...full .impeccable.md contents..." + "hasProduct": true, + "product": "...full PRODUCT.md contents...", + "productPath": "PRODUCT.md", + "hasDesign": true, + "design": "...full DESIGN.md contents...", + "designPath": "DESIGN.md", + "migrated": false } ``` -Keep the `context` in mind for variant generation. If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. +Keep **PRODUCT.md** (strategic: users, brand, principles) and **DESIGN.md** (visual: colors, typography, components) in mind for variant generation. **DESIGN.md wins on visual decisions; PRODUCT.md wins on strategic/voice decisions.** + +If `migrated` is true, the loader auto-renamed legacy `.impeccable.md` to `PRODUCT.md` — mention this once to the user and suggest running `/impeccable document` to also generate a `DESIGN.md`. + +If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. ### First-time setup (config missing) diff --git a/.claude/skills/impeccable/reference/teach.md b/.claude/skills/impeccable/reference/teach.md index 6fa81b276..0e7f815c9 100644 --- a/.claude/skills/impeccable/reference/teach.md +++ b/.claude/skills/impeccable/reference/teach.md @@ -1,8 +1,31 @@ # Teach Flow -One-time setup that gathers design context for a project. Design without context produces generic output, so every other command reads this file before doing any work. +Gathers design context for a project and writes two complementary files at the project root: -## Step 1: Explore the Codebase +- **PRODUCT.md** (strategic): target users, product purpose, brand personality, anti-references, strategic design principles. Answers "who/what/why". +- **DESIGN.md** (visual): visual theme, color palette, typography, components, layout. Follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/). Answers "how it looks". + +Every other impeccable command reads these files before doing any work. + +## Step 1: Load current state + +Run the shared loader first so you know what already exists: + +```bash +node {{scripts_path}}/load-context.mjs +``` + +The output tells you whether PRODUCT.md and/or DESIGN.md already exist. If `migrated: true`, legacy `.impeccable.md` was auto-renamed to `PRODUCT.md`. Mention this once to the user. + +Decision tree: +- **Neither file exists (empty project or no context yet)**: do Steps 2-4 (write PRODUCT.md), then decide on DESIGN.md based on whether there's code to analyze. +- **PRODUCT.md exists, DESIGN.md missing**: skip to Step 5 — offer to run `/impeccable document` for DESIGN.md. +- **Both exist**: STOP and call the AskUserQuestion tool to clarify. which to refresh. Skip the one the user doesn't want changed. +- **Just DESIGN.md exists (unusual)**: do Steps 2-4 to produce PRODUCT.md. + +Never silently overwrite an existing file. Always confirm first. + +## Step 2: Explore the codebase Before asking questions, thoroughly scan the project to discover what you can: @@ -13,9 +36,9 @@ Before asking questions, thoroughly scan the project to discover what you can: - **Design tokens / CSS variables**: Existing color palettes, font stacks, spacing scales - **Any style guides or brand documentation** -Note what you've learned and what remains unclear. +Note what you've learned and what remains unclear. This exploration feeds both PRODUCT.md and DESIGN.md. -## Step 2: Ask UX-Focused Questions +## Step 3: Ask strategic questions (for PRODUCT.md) STOP and call the AskUserQuestion tool to clarify. Focus only on what you couldn't infer from the codebase: @@ -29,39 +52,53 @@ STOP and call the AskUserQuestion tool to clarify. Focus only on what you couldn - Any reference sites or apps that capture the right feel? What specifically about them? - What should this explicitly NOT look like? Any anti-references? -### Aesthetic Preferences -- Any strong preferences for visual direction? (minimal, bold, elegant, playful, technical, organic, etc.) -- Light mode, dark mode, or both? -- Any colors that must be used or avoided? - ### Accessibility & Inclusion - Specific accessibility requirements? (WCAG level, known user needs) - Considerations for reduced motion, color blindness, or other accommodations? -Skip questions where the answer is already clear from the codebase exploration. +Skip questions where the answer is already clear. **Do NOT ask about colors, fonts, radii, or visual styling here** — those belong in DESIGN.md, not PRODUCT.md. -## Step 3: Write Design Context +## Step 4: Write PRODUCT.md -Synthesize your findings and the user's answers into a `## Design Context` section: +Synthesize into a strategic document: ```markdown -## Design Context +# Product -### Users +## Users [Who they are, their context, the job to be done] -### Brand Personality +## Product Purpose +[What this product does, why it exists, what success looks like] + +## Brand Personality [Voice, tone, 3-word personality, emotional goals] -### Aesthetic Direction -[Visual tone, references, anti-references, theme] +## Anti-references +[What this should NOT look like. Specific bad-example sites or patterns to avoid.] -### Design Principles -[3-5 principles derived from the conversation that should guide all design decisions] +## Design Principles +[3-5 strategic principles derived from the conversation. Principles like "practice what you preach", "editorial over marketing", "expert confidence" — NOT visual rules like "use OKLCH" or "magenta accent".] + +## Accessibility & Inclusion +[WCAG level, known user needs, considerations] ``` -Write this section to `.impeccable.md` in the project root. If the file already exists, update the Design Context section in place. +Write to `PROJECT_ROOT/PRODUCT.md`. If `.impeccable.md` existed, the loader already renamed it — merge into that content rather than starting from scratch. -Then STOP and call the AskUserQuestion tool to clarify. whether they'd also like the Design Context appended to CLAUDE.md. If yes, append or update the section there as well. +## Step 5: Decide on DESIGN.md -Confirm completion and summarize the key design principles that will now guide all future work. +If the project has meaningful code to analyze (CSS tokens, components, a running site), **offer to run `/impeccable document`** next: "I can also generate a DESIGN.md that captures your visual design system (colors, typography, components) so variants stay on-brand. Want to do that now?" + +If the user agrees, delegate to `/impeccable document` (load its reference and follow that flow). + +If the project is empty (no code yet, pre-implementation), skip DESIGN.md — there's nothing visual to document yet. Mention: "Once you've built some of the interface, run `/impeccable document` to generate a DESIGN.md." + +## Step 6: Confirm and wrap up + +Summarize: +- What was written (PRODUCT.md, DESIGN.md, or both) +- The 3-5 strategic principles from PRODUCT.md that will guide future work +- If DESIGN.md is pending, remind the user how to generate it later + +Optionally STOP and call the AskUserQuestion tool to clarify. whether they'd like a brief summary of PRODUCT.md appended to CLAUDE.md for easier agent reference. If yes, append a short **Design Context** pointer section there. diff --git a/.claude/skills/impeccable/scripts/command-metadata.json b/.claude/skills/impeccable/scripts/command-metadata.json index 2974e08f6..d8282689a 100644 --- a/.claude/skills/impeccable/scripts/command-metadata.json +++ b/.claude/skills/impeccable/scripts/command-metadata.json @@ -4,7 +4,11 @@ "argumentHint": "[feature description]" }, "teach": { - "description": "One-time setup that gathers design context for a project. Runs a short discovery interview and writes the answers to .impeccable.md. Every other command reads this file before doing work. Use once per project.", + "description": "Gathers design context for a project. Runs a short discovery interview and writes PRODUCT.md (strategic: users, brand, principles) and, when code exists to analyze, DESIGN.md (visual: colors, typography, components). Every other command reads these files before doing work. Use once per project.", + "argumentHint": "" + }, + "document": { + "description": "Generate a DESIGN.md file that captures the current visual design system. Auto-extracts colors, typography, spacing, radii, and component patterns from the codebase, then asks the user to confirm descriptive language for atmosphere and color character. Follows the Google Stitch DESIGN.md format so the file is tool-compatible. Use when you need a visual design spec an AI agent can follow to stay on-brand.", "argumentHint": "" }, "extract": { diff --git a/.claude/skills/impeccable/scripts/live.mjs b/.claude/skills/impeccable/scripts/live.mjs index 93f05456e..37b6f8997 100644 --- a/.claude/skills/impeccable/scripts/live.mjs +++ b/.claude/skills/impeccable/scripts/live.mjs @@ -21,10 +21,10 @@ import { execSync } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { loadContext } from './load-context.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const PID_FILE = path.join(process.cwd(), '.impeccable-live.json'); -const CONTEXT_FILE = path.join(process.cwd(), '.impeccable.md'); async function liveCli() { const args = process.argv.slice(2); @@ -79,9 +79,8 @@ The agent should then: process.exit(1); } - // 4. Load design context if available - let context = null; - try { context = fs.readFileSync(CONTEXT_FILE, 'utf-8'); } catch { /* optional */ } + // 4. Load PRODUCT.md + DESIGN.md context (auto-migrates legacy .impeccable.md) + const ctx = loadContext(process.cwd()); // 5. Emit everything the agent needs console.log(JSON.stringify({ @@ -89,8 +88,13 @@ The agent should then: serverPort: serverInfo.port, serverToken: serverInfo.token, pageFile: checkResult.config.file, - hasContext: !!context, - context, + hasProduct: ctx.hasProduct, + product: ctx.product, + productPath: ctx.productPath, + hasDesign: ctx.hasDesign, + design: ctx.design, + designPath: ctx.designPath, + migrated: ctx.migrated, }, null, 2)); } diff --git a/.claude/skills/impeccable/scripts/load-context.mjs b/.claude/skills/impeccable/scripts/load-context.mjs new file mode 100644 index 000000000..ab3be08f1 --- /dev/null +++ b/.claude/skills/impeccable/scripts/load-context.mjs @@ -0,0 +1,93 @@ +/** + * Shared context loader for every impeccable command that needs to know + * "who is this for" and "what does this look like". + * + * Input: project root (process.cwd()). + * + * Output (JSON to stdout): + * { + * hasProduct: boolean, // PRODUCT.md found (or auto-migrated) + * product: string | null, // PRODUCT.md contents + * productPath: string | null, // relative path + * hasDesign: boolean, // DESIGN.md found + * design: string | null, // DESIGN.md contents + * designPath: string | null, + * migrated: boolean, // true if we auto-renamed .impeccable.md -> PRODUCT.md + * } + * + * Filename matching is case-insensitive for PRODUCT.md and DESIGN.md. The + * Google DESIGN.md convention is uppercase at repo root; Kiro-style and + * lowercase variants are also matched so users don't get punished for case. + */ + +import fs from 'node:fs'; +import path from 'node:path'; + +const PRODUCT_NAMES = ['PRODUCT.md', 'Product.md', 'product.md']; +const DESIGN_NAMES = ['DESIGN.md', 'Design.md', 'design.md']; +const LEGACY_NAMES = ['.impeccable.md']; + +export function loadContext(cwd = process.cwd()) { + let migrated = false; + + // 1. Look for PRODUCT.md (case-insensitive) + let productPath = firstExisting(cwd, PRODUCT_NAMES); + + // 2. Legacy: if no PRODUCT.md but .impeccable.md exists, rename in place + if (!productPath) { + const legacyPath = firstExisting(cwd, LEGACY_NAMES); + if (legacyPath) { + const newPath = path.join(cwd, 'PRODUCT.md'); + try { + fs.renameSync(legacyPath, newPath); + productPath = newPath; + migrated = true; + } catch { + // Rename failed (permissions, etc.) — fall back to reading legacy in place + productPath = legacyPath; + } + } + } + + // 3. DESIGN.md (case-insensitive) + const designPath = firstExisting(cwd, DESIGN_NAMES); + + const product = productPath ? safeRead(productPath) : null; + const design = designPath ? safeRead(designPath) : null; + + return { + hasProduct: !!product, + product, + productPath: productPath ? path.relative(cwd, productPath) : null, + hasDesign: !!design, + design, + designPath: designPath ? path.relative(cwd, designPath) : null, + migrated, + }; +} + +function firstExisting(cwd, names) { + for (const name of names) { + const abs = path.join(cwd, name); + if (fs.existsSync(abs)) return abs; + } + return null; +} + +function safeRead(p) { + try { return fs.readFileSync(p, 'utf-8'); } catch { return null; } +} + +// --------------------------------------------------------------------------- +// CLI mode — print the context as JSON +// --------------------------------------------------------------------------- + +function cli() { + const result = loadContext(process.cwd()); + console.log(JSON.stringify(result, null, 2)); +} + +const _running = process.argv[1]; +if (_running?.endsWith('load-context.mjs') || _running?.endsWith('load-context.mjs/')) { + cli(); +} diff --git a/.claude/skills/impeccable/scripts/pin.mjs b/.claude/skills/impeccable/scripts/pin.mjs index 89a6babeb..ba02783fb 100644 --- a/.claude/skills/impeccable/scripts/pin.mjs +++ b/.claude/skills/impeccable/scripts/pin.mjs @@ -27,7 +27,7 @@ const HARNESS_DIRS = [ // Valid sub-command names const VALID_COMMANDS = [ - 'craft', 'teach', 'extract', 'shape', + 'craft', 'teach', 'extract', 'document', 'shape', 'critique', 'audit', 'polish', 'bolder', 'quieter', 'distill', 'harden', 'onboard', 'live', 'animate', 'colorize', 'typeset', 'layout', 'delight', 'overdrive', diff --git a/.cursor/skills/impeccable/SKILL.md b/.cursor/skills/impeccable/SKILL.md index 25b3b1b12..eae8b86e5 100644 --- a/.cursor/skills/impeccable/SKILL.md +++ b/.cursor/skills/impeccable/SKILL.md @@ -27,10 +27,17 @@ After running the script, delete this entire section (from ` **Build & Plan** > `/impeccable craft [feature]` - Shape, then build a feature end-to-end > `/impeccable shape [feature]` - Plan UX/UI before writing code -> `/impeccable teach` - Set up design context for this project (one-time) +> `/impeccable teach` - Set up PRODUCT.md and DESIGN.md context for this project +> `/impeccable document` - Generate DESIGN.md from existing project code > `/impeccable extract [target]` - Pull reusable tokens and components into design system > > **Evaluate** @@ -345,6 +353,7 @@ When a sub-command is matched, load the linked reference and follow its instruct | `craft` | [craft](reference/craft.md) | Full shape-then-build flow with visual iteration | | `teach` | [teach](reference/teach.md) | One-time setup: gather design context for the project | | `extract` | [extract](reference/extract.md) | Pull reusable tokens and components into design system | +| `document` | [document](reference/document.md) | Generate DESIGN.md from existing project code (visual design system doc) | | `shape` | [shape](reference/shape.md) | Plan UX and UI before writing code (produces a design brief) | | `critique` | [critique](reference/critique.md) | UX design review with heuristic scoring and persona testing | | `audit` | [audit](reference/audit.md) | Technical quality checks across a11y, perf, theming, responsive, anti-patterns | diff --git a/.cursor/skills/impeccable/reference/audit.md b/.cursor/skills/impeccable/reference/audit.md index bbba2401b..c2258ac54 100644 --- a/.cursor/skills/impeccable/reference/audit.md +++ b/.cursor/skills/impeccable/reference/audit.md @@ -95,7 +95,7 @@ For each issue, document: - **Impact**: How it affects users - **WCAG/Standard**: Which standard it violates (if applicable) - **Recommendation**: How to fix it -- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) ### Patterns & Systemic Issues @@ -114,7 +114,7 @@ List recommended commands in priority order (P0 first, then P1, then P2): 1. **[P?] `/command-name`** — Brief description (specific context from audit findings) 2. **[P?] `/command-name`** — Brief description (specific context) -**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. +**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. After presenting the summary, tell the user: diff --git a/.cursor/skills/impeccable/reference/critique.md b/.cursor/skills/impeccable/reference/critique.md index 4684cb5c0..34f93efb9 100644 --- a/.cursor/skills/impeccable/reference/critique.md +++ b/.cursor/skills/impeccable/reference/critique.md @@ -132,7 +132,7 @@ For each issue, tag with **P0-P3 severity** (consult [heuristics-scoring](heuris - **[P?] What**: Name the problem clearly - **Why it matters**: How this hurts users or undermines goals - **Fix**: What to do about it (be concrete) -- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) #### Persona Red Flags > *Consult [personas](personas.md)* @@ -197,7 +197,7 @@ List recommended commands in priority order, based on the user's answers: ... **Rules for recommendations**: -- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset +- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset - Order by the user's stated priorities first, then by impact - Each item's description should carry enough context that the command knows what to focus on - Map each Priority Issue to the appropriate command diff --git a/.cursor/skills/impeccable/reference/document.md b/.cursor/skills/impeccable/reference/document.md new file mode 100644 index 000000000..ebf90bbf3 --- /dev/null +++ b/.cursor/skills/impeccable/reference/document.md @@ -0,0 +1,126 @@ +Generate a DESIGN.md file in the project root that captures the current visual design system, so AI agents generating new screens stay on-brand. + +DESIGN.md follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/): a single markdown file at the project root with five fixed sections describing colors, typography, components, layout, and overall atmosphere. Keep section headers exactly as specified so the file stays compatible with other DESIGN.md-aware tools. + +## When to run + +- The user just ran `/impeccable teach` and needs the visual side documented. +- The skill noticed no `DESIGN.md` exists and nudged the user to create one. +- An existing `DESIGN.md` is stale (the design has drifted). +- Before a large redesign, to capture the current state as a reference. + +If a `DESIGN.md` already exists, **do not silently overwrite it**. Show the user the existing file and ask the user directly to clarify what you cannot infer. whether to refresh it, overwrite it, or merge into it. + +## Process (approach C: auto-extract, then confirm descriptive language) + +### Step 1: Find the design assets + +Search the codebase in priority order: + +1. **CSS custom properties** — grep for `--color-`, `--font-`, `--spacing-`, `--radius-`, `--shadow-`, `--ease-`, `--duration-` declarations in CSS files (usually `src/styles/`, `public/css/`, `app/globals.css`, etc.). Record name, value, and the file it's defined in. +2. **Tailwind config** — if `tailwind.config.{js,ts,mjs}` exists, read the `theme.extend` block for colors, fontFamily, spacing, borderRadius, boxShadow. +3. **CSS-in-JS theme files** — if the project uses styled-components, emotion, vanilla-extract, stitches, etc., look for `theme.ts`, `tokens.ts`, or equivalent. +4. **Design token files** — `tokens.json`, `design-tokens.json`, Style Dictionary output, W3C token community group format. +5. **Component library** — scan the main button, card, input, navigation, dialog components. Note their variant APIs and default styles. +6. **Global stylesheet** — the root CSS file usually has the base typography and color assignments. +7. **Visible rendered output** — if browser automation tools are available, load the live site and sample computed styles from key elements (body, h1, a, button, .card). This catches values that tokens miss. + +### Step 2: Auto-extract what can be auto-extracted + +Build a structured draft from the discovered tokens. For each token class: + +- **Colors**: Group by hue family. Convert hex → OKLCH to infer lightness/chroma. Identify background vs. text vs. accent by usage patterns in CSS (`background`, `color`, `border`, `fill`). Flag any that are only used once (possibly one-off, not system tokens). +- **Typography**: Extract font families and their declared stacks. Extract the scale (all `font-size` values used in CSS custom props + component styles). Extract weights actually used. Detect the scale ratio (1.125, 1.2, 1.25, 1.333, 1.5, golden). +- **Spacing**: Extract the scale, detect the base unit (4px, 8px, other). +- **Radii & shadows**: List the values used. +- **Components**: For each common component (button, card, input, nav, dialog), extract shape (radius), color assignment, hover/focus treatment, internal padding. + +### Step 3: Ask the user for qualitative language + +The following sections require creative input that cannot be auto-extracted reliably. ask the user directly to clarify what you cannot infer. for each (group them into one interaction if possible): + +- **Visual Theme & Atmosphere**: mood adjectives (airy/dense, minimal/maximalist, editorial/utilitarian, warm/clinical), aesthetic philosophy in 2-3 sentences, key characteristics as a bullet list. +- **Color character** (for auto-extracted colors): descriptive names ("Deep Muted Teal-Navy", not "blue-800"). Suggest 2-3 options per color based on the hue/saturation, let the user pick. +- **Typographic character**: describe the font pairing ("Modern geometric sans-serif with humanist warmth" > "Manrope 500"). Describe letter-spacing strategy. +- **Spacing philosophy**: 1-2 sentences on whitespace strategy ("generous breathing room that prioritizes photography"). +- **Component philosophy**: brief description of the feel of buttons, cards, inputs ("refined and understated" vs. "tactile and confident"). + +If the user has a `PRODUCT.md` that covers brand personality, quote a line from it so they see their own strategic language carry over. + +### Step 4: Write DESIGN.md + +Use this exact structure (section headers must match the Google spec character-for-character): + +```markdown +# Design System: [Project Title] +**Project ID:** [optional — only if a Stitch project ID exists] + +## 1. Visual Theme & Atmosphere + +[2-3 paragraph description using evocative adjectives. Start with the overall sanctuary/laboratory/workshop/stage analogy if one fits. End with a short **Key Characteristics:** bullet list.] + +## 2. Color Palette & Roles + +### [Semantic group name: Primary Foundation, Accent & Interactive, Typography & Text Hierarchy, Functional States, etc.] +- **[Descriptive Name]** (#HEX) – [Functional role. Where/why it's used.] + +## 3. Typography Rules + +**Primary Font Family:** [Name] +**Character:** [1-sentence personality description.] + +### Hierarchy & Weights +- **[Role (e.g. Display Headlines H1)]:** [Weight] weight ([num]), [letter-spacing], [size]. [Purpose.] + +### Spacing Principles +[Short list of rules about leading, letter-spacing, vertical rhythm.] + +## 4. Component Stylings + +### Buttons +- **Shape:** [radius description with px value in parens] +- **Primary CTA:** [color assignment + padding] +- **Hover State:** [transition description] +- **Focus State:** [accessibility treatment] +- **Secondary CTA (if applicable):** [description] + +### Cards & Containers +- **Corner Style:** [description] +- **Background:** [colors used] +- **Shadow Strategy:** [flat / soft / heavy] +- **Border:** [if any] +- **Internal Padding:** [scale] +- **Image Treatment:** [if relevant] + +### Navigation +- [Style, typography, default/hover/active states, mobile treatment] + +### Inputs/Forms +- [Stroke style, background, focus treatment] + +## 5. Layout Principles + +[Paragraph or short list describing whitespace strategy, margin scale, grid system, responsive breakpoints. Include px/rem values in parens.] +``` + +### Step 5: Write & confirm + +1. Write the file to `PROJECT_ROOT/DESIGN.md` (uppercase, at root). +2. Show the user the full DESIGN.md you wrote, briefly highlighting the non-obvious creative choices (descriptive color names, atmosphere language). +3. Offer to refine any section: "Want me to revise a section, add component patterns I missed, or adjust the atmosphere language?" + +## Style guidelines + +- **Descriptive > technical**: "Gently curved edges (8px radius)" > "rounded-lg". Include the technical value in parens, lead with the description. +- **Functional > decorative**: for each token, explain WHERE and WHY it's used, not just WHAT it is. +- **Exact values in parens**: hex codes, px/rem values, font weights — always the number in parens alongside the description. +- **Group colors semantically**: Foundation (backgrounds), Accent (interactive), Typography (text hierarchy), States (success/warning/error), not hex-sorted. +- **Reference the user's domain**: if the project is a DEX, say "trading-focused"; if it's a CMS, say "editorial". Domain-aware language helps agents pick sensible defaults. + +## Pitfalls + +- Don't paste raw CSS class names. Translate to descriptive language. +- Don't extract every token. Stop at what's actually reused — one-offs pollute the system. +- Don't invent components that don't exist. If the project only has buttons and cards, only document those. +- Don't overwrite an existing DESIGN.md without asking. +- Don't duplicate content from PRODUCT.md. DESIGN.md is strictly visual. diff --git a/.cursor/skills/impeccable/reference/live.md b/.cursor/skills/impeccable/reference/live.md index 3388e1897..19c16fa38 100644 --- a/.cursor/skills/impeccable/reference/live.md +++ b/.cursor/skills/impeccable/reference/live.md @@ -21,12 +21,21 @@ Output JSON: "serverPort": 8400, "serverToken": "...", "pageFile": "public/index.html", - "hasContext": true, - "context": "...full .impeccable.md contents..." + "hasProduct": true, + "product": "...full PRODUCT.md contents...", + "productPath": "PRODUCT.md", + "hasDesign": true, + "design": "...full DESIGN.md contents...", + "designPath": "DESIGN.md", + "migrated": false } ``` -Keep the `context` in mind for variant generation. If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. +Keep **PRODUCT.md** (strategic: users, brand, principles) and **DESIGN.md** (visual: colors, typography, components) in mind for variant generation. **DESIGN.md wins on visual decisions; PRODUCT.md wins on strategic/voice decisions.** + +If `migrated` is true, the loader auto-renamed legacy `.impeccable.md` to `PRODUCT.md` — mention this once to the user and suggest running `/impeccable document` to also generate a `DESIGN.md`. + +If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. ### First-time setup (config missing) diff --git a/.cursor/skills/impeccable/reference/teach.md b/.cursor/skills/impeccable/reference/teach.md index 952cf898a..a78f4059b 100644 --- a/.cursor/skills/impeccable/reference/teach.md +++ b/.cursor/skills/impeccable/reference/teach.md @@ -1,8 +1,31 @@ # Teach Flow -One-time setup that gathers design context for a project. Design without context produces generic output, so every other command reads this file before doing any work. +Gathers design context for a project and writes two complementary files at the project root: -## Step 1: Explore the Codebase +- **PRODUCT.md** (strategic): target users, product purpose, brand personality, anti-references, strategic design principles. Answers "who/what/why". +- **DESIGN.md** (visual): visual theme, color palette, typography, components, layout. Follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/). Answers "how it looks". + +Every other impeccable command reads these files before doing any work. + +## Step 1: Load current state + +Run the shared loader first so you know what already exists: + +```bash +node {{scripts_path}}/load-context.mjs +``` + +The output tells you whether PRODUCT.md and/or DESIGN.md already exist. If `migrated: true`, legacy `.impeccable.md` was auto-renamed to `PRODUCT.md`. Mention this once to the user. + +Decision tree: +- **Neither file exists (empty project or no context yet)**: do Steps 2-4 (write PRODUCT.md), then decide on DESIGN.md based on whether there's code to analyze. +- **PRODUCT.md exists, DESIGN.md missing**: skip to Step 5 — offer to run `/impeccable document` for DESIGN.md. +- **Both exist**: ask the user directly to clarify what you cannot infer. which to refresh. Skip the one the user doesn't want changed. +- **Just DESIGN.md exists (unusual)**: do Steps 2-4 to produce PRODUCT.md. + +Never silently overwrite an existing file. Always confirm first. + +## Step 2: Explore the codebase Before asking questions, thoroughly scan the project to discover what you can: @@ -13,9 +36,9 @@ Before asking questions, thoroughly scan the project to discover what you can: - **Design tokens / CSS variables**: Existing color palettes, font stacks, spacing scales - **Any style guides or brand documentation** -Note what you've learned and what remains unclear. +Note what you've learned and what remains unclear. This exploration feeds both PRODUCT.md and DESIGN.md. -## Step 2: Ask UX-Focused Questions +## Step 3: Ask strategic questions (for PRODUCT.md) ask the user directly to clarify what you cannot infer. Focus only on what you couldn't infer from the codebase: @@ -29,39 +52,53 @@ ask the user directly to clarify what you cannot infer. Focus only on what you c - Any reference sites or apps that capture the right feel? What specifically about them? - What should this explicitly NOT look like? Any anti-references? -### Aesthetic Preferences -- Any strong preferences for visual direction? (minimal, bold, elegant, playful, technical, organic, etc.) -- Light mode, dark mode, or both? -- Any colors that must be used or avoided? - ### Accessibility & Inclusion - Specific accessibility requirements? (WCAG level, known user needs) - Considerations for reduced motion, color blindness, or other accommodations? -Skip questions where the answer is already clear from the codebase exploration. +Skip questions where the answer is already clear. **Do NOT ask about colors, fonts, radii, or visual styling here** — those belong in DESIGN.md, not PRODUCT.md. -## Step 3: Write Design Context +## Step 4: Write PRODUCT.md -Synthesize your findings and the user's answers into a `## Design Context` section: +Synthesize into a strategic document: ```markdown -## Design Context +# Product -### Users +## Users [Who they are, their context, the job to be done] -### Brand Personality +## Product Purpose +[What this product does, why it exists, what success looks like] + +## Brand Personality [Voice, tone, 3-word personality, emotional goals] -### Aesthetic Direction -[Visual tone, references, anti-references, theme] +## Anti-references +[What this should NOT look like. Specific bad-example sites or patterns to avoid.] -### Design Principles -[3-5 principles derived from the conversation that should guide all design decisions] +## Design Principles +[3-5 strategic principles derived from the conversation. Principles like "practice what you preach", "editorial over marketing", "expert confidence" — NOT visual rules like "use OKLCH" or "magenta accent".] + +## Accessibility & Inclusion +[WCAG level, known user needs, considerations] ``` -Write this section to `.impeccable.md` in the project root. If the file already exists, update the Design Context section in place. +Write to `PROJECT_ROOT/PRODUCT.md`. If `.impeccable.md` existed, the loader already renamed it — merge into that content rather than starting from scratch. -Then ask the user directly to clarify what you cannot infer. whether they'd also like the Design Context appended to .cursorrules. If yes, append or update the section there as well. +## Step 5: Decide on DESIGN.md -Confirm completion and summarize the key design principles that will now guide all future work. +If the project has meaningful code to analyze (CSS tokens, components, a running site), **offer to run `/impeccable document`** next: "I can also generate a DESIGN.md that captures your visual design system (colors, typography, components) so variants stay on-brand. Want to do that now?" + +If the user agrees, delegate to `/impeccable document` (load its reference and follow that flow). + +If the project is empty (no code yet, pre-implementation), skip DESIGN.md — there's nothing visual to document yet. Mention: "Once you've built some of the interface, run `/impeccable document` to generate a DESIGN.md." + +## Step 6: Confirm and wrap up + +Summarize: +- What was written (PRODUCT.md, DESIGN.md, or both) +- The 3-5 strategic principles from PRODUCT.md that will guide future work +- If DESIGN.md is pending, remind the user how to generate it later + +Optionally ask the user directly to clarify what you cannot infer. whether they'd like a brief summary of PRODUCT.md appended to .cursorrules for easier agent reference. If yes, append a short **Design Context** pointer section there. diff --git a/.cursor/skills/impeccable/scripts/command-metadata.json b/.cursor/skills/impeccable/scripts/command-metadata.json index 2974e08f6..d8282689a 100644 --- a/.cursor/skills/impeccable/scripts/command-metadata.json +++ b/.cursor/skills/impeccable/scripts/command-metadata.json @@ -4,7 +4,11 @@ "argumentHint": "[feature description]" }, "teach": { - "description": "One-time setup that gathers design context for a project. Runs a short discovery interview and writes the answers to .impeccable.md. Every other command reads this file before doing work. Use once per project.", + "description": "Gathers design context for a project. Runs a short discovery interview and writes PRODUCT.md (strategic: users, brand, principles) and, when code exists to analyze, DESIGN.md (visual: colors, typography, components). Every other command reads these files before doing work. Use once per project.", + "argumentHint": "" + }, + "document": { + "description": "Generate a DESIGN.md file that captures the current visual design system. Auto-extracts colors, typography, spacing, radii, and component patterns from the codebase, then asks the user to confirm descriptive language for atmosphere and color character. Follows the Google Stitch DESIGN.md format so the file is tool-compatible. Use when you need a visual design spec an AI agent can follow to stay on-brand.", "argumentHint": "" }, "extract": { diff --git a/.cursor/skills/impeccable/scripts/live.mjs b/.cursor/skills/impeccable/scripts/live.mjs index 93f05456e..37b6f8997 100644 --- a/.cursor/skills/impeccable/scripts/live.mjs +++ b/.cursor/skills/impeccable/scripts/live.mjs @@ -21,10 +21,10 @@ import { execSync } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { loadContext } from './load-context.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const PID_FILE = path.join(process.cwd(), '.impeccable-live.json'); -const CONTEXT_FILE = path.join(process.cwd(), '.impeccable.md'); async function liveCli() { const args = process.argv.slice(2); @@ -79,9 +79,8 @@ The agent should then: process.exit(1); } - // 4. Load design context if available - let context = null; - try { context = fs.readFileSync(CONTEXT_FILE, 'utf-8'); } catch { /* optional */ } + // 4. Load PRODUCT.md + DESIGN.md context (auto-migrates legacy .impeccable.md) + const ctx = loadContext(process.cwd()); // 5. Emit everything the agent needs console.log(JSON.stringify({ @@ -89,8 +88,13 @@ The agent should then: serverPort: serverInfo.port, serverToken: serverInfo.token, pageFile: checkResult.config.file, - hasContext: !!context, - context, + hasProduct: ctx.hasProduct, + product: ctx.product, + productPath: ctx.productPath, + hasDesign: ctx.hasDesign, + design: ctx.design, + designPath: ctx.designPath, + migrated: ctx.migrated, }, null, 2)); } diff --git a/.cursor/skills/impeccable/scripts/load-context.mjs b/.cursor/skills/impeccable/scripts/load-context.mjs new file mode 100644 index 000000000..ab3be08f1 --- /dev/null +++ b/.cursor/skills/impeccable/scripts/load-context.mjs @@ -0,0 +1,93 @@ +/** + * Shared context loader for every impeccable command that needs to know + * "who is this for" and "what does this look like". + * + * Input: project root (process.cwd()). + * + * Output (JSON to stdout): + * { + * hasProduct: boolean, // PRODUCT.md found (or auto-migrated) + * product: string | null, // PRODUCT.md contents + * productPath: string | null, // relative path + * hasDesign: boolean, // DESIGN.md found + * design: string | null, // DESIGN.md contents + * designPath: string | null, + * migrated: boolean, // true if we auto-renamed .impeccable.md -> PRODUCT.md + * } + * + * Filename matching is case-insensitive for PRODUCT.md and DESIGN.md. The + * Google DESIGN.md convention is uppercase at repo root; Kiro-style and + * lowercase variants are also matched so users don't get punished for case. + */ + +import fs from 'node:fs'; +import path from 'node:path'; + +const PRODUCT_NAMES = ['PRODUCT.md', 'Product.md', 'product.md']; +const DESIGN_NAMES = ['DESIGN.md', 'Design.md', 'design.md']; +const LEGACY_NAMES = ['.impeccable.md']; + +export function loadContext(cwd = process.cwd()) { + let migrated = false; + + // 1. Look for PRODUCT.md (case-insensitive) + let productPath = firstExisting(cwd, PRODUCT_NAMES); + + // 2. Legacy: if no PRODUCT.md but .impeccable.md exists, rename in place + if (!productPath) { + const legacyPath = firstExisting(cwd, LEGACY_NAMES); + if (legacyPath) { + const newPath = path.join(cwd, 'PRODUCT.md'); + try { + fs.renameSync(legacyPath, newPath); + productPath = newPath; + migrated = true; + } catch { + // Rename failed (permissions, etc.) — fall back to reading legacy in place + productPath = legacyPath; + } + } + } + + // 3. DESIGN.md (case-insensitive) + const designPath = firstExisting(cwd, DESIGN_NAMES); + + const product = productPath ? safeRead(productPath) : null; + const design = designPath ? safeRead(designPath) : null; + + return { + hasProduct: !!product, + product, + productPath: productPath ? path.relative(cwd, productPath) : null, + hasDesign: !!design, + design, + designPath: designPath ? path.relative(cwd, designPath) : null, + migrated, + }; +} + +function firstExisting(cwd, names) { + for (const name of names) { + const abs = path.join(cwd, name); + if (fs.existsSync(abs)) return abs; + } + return null; +} + +function safeRead(p) { + try { return fs.readFileSync(p, 'utf-8'); } catch { return null; } +} + +// --------------------------------------------------------------------------- +// CLI mode — print the context as JSON +// --------------------------------------------------------------------------- + +function cli() { + const result = loadContext(process.cwd()); + console.log(JSON.stringify(result, null, 2)); +} + +const _running = process.argv[1]; +if (_running?.endsWith('load-context.mjs') || _running?.endsWith('load-context.mjs/')) { + cli(); +} diff --git a/.cursor/skills/impeccable/scripts/pin.mjs b/.cursor/skills/impeccable/scripts/pin.mjs index 89a6babeb..ba02783fb 100644 --- a/.cursor/skills/impeccable/scripts/pin.mjs +++ b/.cursor/skills/impeccable/scripts/pin.mjs @@ -27,7 +27,7 @@ const HARNESS_DIRS = [ // Valid sub-command names const VALID_COMMANDS = [ - 'craft', 'teach', 'extract', 'shape', + 'craft', 'teach', 'extract', 'document', 'shape', 'critique', 'audit', 'polish', 'bolder', 'quieter', 'distill', 'harden', 'onboard', 'live', 'animate', 'colorize', 'typeset', 'layout', 'delight', 'overdrive', diff --git a/.gemini/skills/impeccable/SKILL.md b/.gemini/skills/impeccable/SKILL.md index cd1f44743..aa1a08169 100644 --- a/.gemini/skills/impeccable/SKILL.md +++ b/.gemini/skills/impeccable/SKILL.md @@ -26,10 +26,17 @@ After running the script, delete this entire section (from ` **Build & Plan** > `/impeccable craft [feature]` - Shape, then build a feature end-to-end > `/impeccable shape [feature]` - Plan UX/UI before writing code -> `/impeccable teach` - Set up design context for this project (one-time) +> `/impeccable teach` - Set up PRODUCT.md and DESIGN.md context for this project +> `/impeccable document` - Generate DESIGN.md from existing project code > `/impeccable extract [target]` - Pull reusable tokens and components into design system > > **Evaluate** @@ -344,6 +352,7 @@ When a sub-command is matched, load the linked reference and follow its instruct | `craft` | [craft](reference/craft.md) | Full shape-then-build flow with visual iteration | | `teach` | [teach](reference/teach.md) | One-time setup: gather design context for the project | | `extract` | [extract](reference/extract.md) | Pull reusable tokens and components into design system | +| `document` | [document](reference/document.md) | Generate DESIGN.md from existing project code (visual design system doc) | | `shape` | [shape](reference/shape.md) | Plan UX and UI before writing code (produces a design brief) | | `critique` | [critique](reference/critique.md) | UX design review with heuristic scoring and persona testing | | `audit` | [audit](reference/audit.md) | Technical quality checks across a11y, perf, theming, responsive, anti-patterns | diff --git a/.gemini/skills/impeccable/reference/audit.md b/.gemini/skills/impeccable/reference/audit.md index bbba2401b..c2258ac54 100644 --- a/.gemini/skills/impeccable/reference/audit.md +++ b/.gemini/skills/impeccable/reference/audit.md @@ -95,7 +95,7 @@ For each issue, document: - **Impact**: How it affects users - **WCAG/Standard**: Which standard it violates (if applicable) - **Recommendation**: How to fix it -- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) ### Patterns & Systemic Issues @@ -114,7 +114,7 @@ List recommended commands in priority order (P0 first, then P1, then P2): 1. **[P?] `/command-name`** — Brief description (specific context from audit findings) 2. **[P?] `/command-name`** — Brief description (specific context) -**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. +**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. After presenting the summary, tell the user: diff --git a/.gemini/skills/impeccable/reference/critique.md b/.gemini/skills/impeccable/reference/critique.md index f0f30e36c..fe74a6075 100644 --- a/.gemini/skills/impeccable/reference/critique.md +++ b/.gemini/skills/impeccable/reference/critique.md @@ -132,7 +132,7 @@ For each issue, tag with **P0-P3 severity** (consult [heuristics-scoring](heuris - **[P?] What**: Name the problem clearly - **Why it matters**: How this hurts users or undermines goals - **Fix**: What to do about it (be concrete) -- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) #### Persona Red Flags > *Consult [personas](personas.md)* @@ -197,7 +197,7 @@ List recommended commands in priority order, based on the user's answers: ... **Rules for recommendations**: -- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset +- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset - Order by the user's stated priorities first, then by impact - Each item's description should carry enough context that the command knows what to focus on - Map each Priority Issue to the appropriate command diff --git a/.gemini/skills/impeccable/reference/document.md b/.gemini/skills/impeccable/reference/document.md new file mode 100644 index 000000000..ebf90bbf3 --- /dev/null +++ b/.gemini/skills/impeccable/reference/document.md @@ -0,0 +1,126 @@ +Generate a DESIGN.md file in the project root that captures the current visual design system, so AI agents generating new screens stay on-brand. + +DESIGN.md follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/): a single markdown file at the project root with five fixed sections describing colors, typography, components, layout, and overall atmosphere. Keep section headers exactly as specified so the file stays compatible with other DESIGN.md-aware tools. + +## When to run + +- The user just ran `/impeccable teach` and needs the visual side documented. +- The skill noticed no `DESIGN.md` exists and nudged the user to create one. +- An existing `DESIGN.md` is stale (the design has drifted). +- Before a large redesign, to capture the current state as a reference. + +If a `DESIGN.md` already exists, **do not silently overwrite it**. Show the user the existing file and ask the user directly to clarify what you cannot infer. whether to refresh it, overwrite it, or merge into it. + +## Process (approach C: auto-extract, then confirm descriptive language) + +### Step 1: Find the design assets + +Search the codebase in priority order: + +1. **CSS custom properties** — grep for `--color-`, `--font-`, `--spacing-`, `--radius-`, `--shadow-`, `--ease-`, `--duration-` declarations in CSS files (usually `src/styles/`, `public/css/`, `app/globals.css`, etc.). Record name, value, and the file it's defined in. +2. **Tailwind config** — if `tailwind.config.{js,ts,mjs}` exists, read the `theme.extend` block for colors, fontFamily, spacing, borderRadius, boxShadow. +3. **CSS-in-JS theme files** — if the project uses styled-components, emotion, vanilla-extract, stitches, etc., look for `theme.ts`, `tokens.ts`, or equivalent. +4. **Design token files** — `tokens.json`, `design-tokens.json`, Style Dictionary output, W3C token community group format. +5. **Component library** — scan the main button, card, input, navigation, dialog components. Note their variant APIs and default styles. +6. **Global stylesheet** — the root CSS file usually has the base typography and color assignments. +7. **Visible rendered output** — if browser automation tools are available, load the live site and sample computed styles from key elements (body, h1, a, button, .card). This catches values that tokens miss. + +### Step 2: Auto-extract what can be auto-extracted + +Build a structured draft from the discovered tokens. For each token class: + +- **Colors**: Group by hue family. Convert hex → OKLCH to infer lightness/chroma. Identify background vs. text vs. accent by usage patterns in CSS (`background`, `color`, `border`, `fill`). Flag any that are only used once (possibly one-off, not system tokens). +- **Typography**: Extract font families and their declared stacks. Extract the scale (all `font-size` values used in CSS custom props + component styles). Extract weights actually used. Detect the scale ratio (1.125, 1.2, 1.25, 1.333, 1.5, golden). +- **Spacing**: Extract the scale, detect the base unit (4px, 8px, other). +- **Radii & shadows**: List the values used. +- **Components**: For each common component (button, card, input, nav, dialog), extract shape (radius), color assignment, hover/focus treatment, internal padding. + +### Step 3: Ask the user for qualitative language + +The following sections require creative input that cannot be auto-extracted reliably. ask the user directly to clarify what you cannot infer. for each (group them into one interaction if possible): + +- **Visual Theme & Atmosphere**: mood adjectives (airy/dense, minimal/maximalist, editorial/utilitarian, warm/clinical), aesthetic philosophy in 2-3 sentences, key characteristics as a bullet list. +- **Color character** (for auto-extracted colors): descriptive names ("Deep Muted Teal-Navy", not "blue-800"). Suggest 2-3 options per color based on the hue/saturation, let the user pick. +- **Typographic character**: describe the font pairing ("Modern geometric sans-serif with humanist warmth" > "Manrope 500"). Describe letter-spacing strategy. +- **Spacing philosophy**: 1-2 sentences on whitespace strategy ("generous breathing room that prioritizes photography"). +- **Component philosophy**: brief description of the feel of buttons, cards, inputs ("refined and understated" vs. "tactile and confident"). + +If the user has a `PRODUCT.md` that covers brand personality, quote a line from it so they see their own strategic language carry over. + +### Step 4: Write DESIGN.md + +Use this exact structure (section headers must match the Google spec character-for-character): + +```markdown +# Design System: [Project Title] +**Project ID:** [optional — only if a Stitch project ID exists] + +## 1. Visual Theme & Atmosphere + +[2-3 paragraph description using evocative adjectives. Start with the overall sanctuary/laboratory/workshop/stage analogy if one fits. End with a short **Key Characteristics:** bullet list.] + +## 2. Color Palette & Roles + +### [Semantic group name: Primary Foundation, Accent & Interactive, Typography & Text Hierarchy, Functional States, etc.] +- **[Descriptive Name]** (#HEX) – [Functional role. Where/why it's used.] + +## 3. Typography Rules + +**Primary Font Family:** [Name] +**Character:** [1-sentence personality description.] + +### Hierarchy & Weights +- **[Role (e.g. Display Headlines H1)]:** [Weight] weight ([num]), [letter-spacing], [size]. [Purpose.] + +### Spacing Principles +[Short list of rules about leading, letter-spacing, vertical rhythm.] + +## 4. Component Stylings + +### Buttons +- **Shape:** [radius description with px value in parens] +- **Primary CTA:** [color assignment + padding] +- **Hover State:** [transition description] +- **Focus State:** [accessibility treatment] +- **Secondary CTA (if applicable):** [description] + +### Cards & Containers +- **Corner Style:** [description] +- **Background:** [colors used] +- **Shadow Strategy:** [flat / soft / heavy] +- **Border:** [if any] +- **Internal Padding:** [scale] +- **Image Treatment:** [if relevant] + +### Navigation +- [Style, typography, default/hover/active states, mobile treatment] + +### Inputs/Forms +- [Stroke style, background, focus treatment] + +## 5. Layout Principles + +[Paragraph or short list describing whitespace strategy, margin scale, grid system, responsive breakpoints. Include px/rem values in parens.] +``` + +### Step 5: Write & confirm + +1. Write the file to `PROJECT_ROOT/DESIGN.md` (uppercase, at root). +2. Show the user the full DESIGN.md you wrote, briefly highlighting the non-obvious creative choices (descriptive color names, atmosphere language). +3. Offer to refine any section: "Want me to revise a section, add component patterns I missed, or adjust the atmosphere language?" + +## Style guidelines + +- **Descriptive > technical**: "Gently curved edges (8px radius)" > "rounded-lg". Include the technical value in parens, lead with the description. +- **Functional > decorative**: for each token, explain WHERE and WHY it's used, not just WHAT it is. +- **Exact values in parens**: hex codes, px/rem values, font weights — always the number in parens alongside the description. +- **Group colors semantically**: Foundation (backgrounds), Accent (interactive), Typography (text hierarchy), States (success/warning/error), not hex-sorted. +- **Reference the user's domain**: if the project is a DEX, say "trading-focused"; if it's a CMS, say "editorial". Domain-aware language helps agents pick sensible defaults. + +## Pitfalls + +- Don't paste raw CSS class names. Translate to descriptive language. +- Don't extract every token. Stop at what's actually reused — one-offs pollute the system. +- Don't invent components that don't exist. If the project only has buttons and cards, only document those. +- Don't overwrite an existing DESIGN.md without asking. +- Don't duplicate content from PRODUCT.md. DESIGN.md is strictly visual. diff --git a/.gemini/skills/impeccable/reference/live.md b/.gemini/skills/impeccable/reference/live.md index 3388e1897..19c16fa38 100644 --- a/.gemini/skills/impeccable/reference/live.md +++ b/.gemini/skills/impeccable/reference/live.md @@ -21,12 +21,21 @@ Output JSON: "serverPort": 8400, "serverToken": "...", "pageFile": "public/index.html", - "hasContext": true, - "context": "...full .impeccable.md contents..." + "hasProduct": true, + "product": "...full PRODUCT.md contents...", + "productPath": "PRODUCT.md", + "hasDesign": true, + "design": "...full DESIGN.md contents...", + "designPath": "DESIGN.md", + "migrated": false } ``` -Keep the `context` in mind for variant generation. If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. +Keep **PRODUCT.md** (strategic: users, brand, principles) and **DESIGN.md** (visual: colors, typography, components) in mind for variant generation. **DESIGN.md wins on visual decisions; PRODUCT.md wins on strategic/voice decisions.** + +If `migrated` is true, the loader auto-renamed legacy `.impeccable.md` to `PRODUCT.md` — mention this once to the user and suggest running `/impeccable document` to also generate a `DESIGN.md`. + +If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. ### First-time setup (config missing) diff --git a/.gemini/skills/impeccable/reference/teach.md b/.gemini/skills/impeccable/reference/teach.md index b081ec456..ec35593f9 100644 --- a/.gemini/skills/impeccable/reference/teach.md +++ b/.gemini/skills/impeccable/reference/teach.md @@ -1,8 +1,31 @@ # Teach Flow -One-time setup that gathers design context for a project. Design without context produces generic output, so every other command reads this file before doing any work. +Gathers design context for a project and writes two complementary files at the project root: -## Step 1: Explore the Codebase +- **PRODUCT.md** (strategic): target users, product purpose, brand personality, anti-references, strategic design principles. Answers "who/what/why". +- **DESIGN.md** (visual): visual theme, color palette, typography, components, layout. Follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/). Answers "how it looks". + +Every other impeccable command reads these files before doing any work. + +## Step 1: Load current state + +Run the shared loader first so you know what already exists: + +```bash +node {{scripts_path}}/load-context.mjs +``` + +The output tells you whether PRODUCT.md and/or DESIGN.md already exist. If `migrated: true`, legacy `.impeccable.md` was auto-renamed to `PRODUCT.md`. Mention this once to the user. + +Decision tree: +- **Neither file exists (empty project or no context yet)**: do Steps 2-4 (write PRODUCT.md), then decide on DESIGN.md based on whether there's code to analyze. +- **PRODUCT.md exists, DESIGN.md missing**: skip to Step 5 — offer to run `/impeccable document` for DESIGN.md. +- **Both exist**: ask the user directly to clarify what you cannot infer. which to refresh. Skip the one the user doesn't want changed. +- **Just DESIGN.md exists (unusual)**: do Steps 2-4 to produce PRODUCT.md. + +Never silently overwrite an existing file. Always confirm first. + +## Step 2: Explore the codebase Before asking questions, thoroughly scan the project to discover what you can: @@ -13,9 +36,9 @@ Before asking questions, thoroughly scan the project to discover what you can: - **Design tokens / CSS variables**: Existing color palettes, font stacks, spacing scales - **Any style guides or brand documentation** -Note what you've learned and what remains unclear. +Note what you've learned and what remains unclear. This exploration feeds both PRODUCT.md and DESIGN.md. -## Step 2: Ask UX-Focused Questions +## Step 3: Ask strategic questions (for PRODUCT.md) ask the user directly to clarify what you cannot infer. Focus only on what you couldn't infer from the codebase: @@ -29,39 +52,53 @@ ask the user directly to clarify what you cannot infer. Focus only on what you c - Any reference sites or apps that capture the right feel? What specifically about them? - What should this explicitly NOT look like? Any anti-references? -### Aesthetic Preferences -- Any strong preferences for visual direction? (minimal, bold, elegant, playful, technical, organic, etc.) -- Light mode, dark mode, or both? -- Any colors that must be used or avoided? - ### Accessibility & Inclusion - Specific accessibility requirements? (WCAG level, known user needs) - Considerations for reduced motion, color blindness, or other accommodations? -Skip questions where the answer is already clear from the codebase exploration. +Skip questions where the answer is already clear. **Do NOT ask about colors, fonts, radii, or visual styling here** — those belong in DESIGN.md, not PRODUCT.md. -## Step 3: Write Design Context +## Step 4: Write PRODUCT.md -Synthesize your findings and the user's answers into a `## Design Context` section: +Synthesize into a strategic document: ```markdown -## Design Context +# Product -### Users +## Users [Who they are, their context, the job to be done] -### Brand Personality +## Product Purpose +[What this product does, why it exists, what success looks like] + +## Brand Personality [Voice, tone, 3-word personality, emotional goals] -### Aesthetic Direction -[Visual tone, references, anti-references, theme] +## Anti-references +[What this should NOT look like. Specific bad-example sites or patterns to avoid.] -### Design Principles -[3-5 principles derived from the conversation that should guide all design decisions] +## Design Principles +[3-5 strategic principles derived from the conversation. Principles like "practice what you preach", "editorial over marketing", "expert confidence" — NOT visual rules like "use OKLCH" or "magenta accent".] + +## Accessibility & Inclusion +[WCAG level, known user needs, considerations] ``` -Write this section to `.impeccable.md` in the project root. If the file already exists, update the Design Context section in place. +Write to `PROJECT_ROOT/PRODUCT.md`. If `.impeccable.md` existed, the loader already renamed it — merge into that content rather than starting from scratch. -Then ask the user directly to clarify what you cannot infer. whether they'd also like the Design Context appended to GEMINI.md. If yes, append or update the section there as well. +## Step 5: Decide on DESIGN.md -Confirm completion and summarize the key design principles that will now guide all future work. +If the project has meaningful code to analyze (CSS tokens, components, a running site), **offer to run `/impeccable document`** next: "I can also generate a DESIGN.md that captures your visual design system (colors, typography, components) so variants stay on-brand. Want to do that now?" + +If the user agrees, delegate to `/impeccable document` (load its reference and follow that flow). + +If the project is empty (no code yet, pre-implementation), skip DESIGN.md — there's nothing visual to document yet. Mention: "Once you've built some of the interface, run `/impeccable document` to generate a DESIGN.md." + +## Step 6: Confirm and wrap up + +Summarize: +- What was written (PRODUCT.md, DESIGN.md, or both) +- The 3-5 strategic principles from PRODUCT.md that will guide future work +- If DESIGN.md is pending, remind the user how to generate it later + +Optionally ask the user directly to clarify what you cannot infer. whether they'd like a brief summary of PRODUCT.md appended to GEMINI.md for easier agent reference. If yes, append a short **Design Context** pointer section there. diff --git a/.gemini/skills/impeccable/scripts/command-metadata.json b/.gemini/skills/impeccable/scripts/command-metadata.json index 2974e08f6..d8282689a 100644 --- a/.gemini/skills/impeccable/scripts/command-metadata.json +++ b/.gemini/skills/impeccable/scripts/command-metadata.json @@ -4,7 +4,11 @@ "argumentHint": "[feature description]" }, "teach": { - "description": "One-time setup that gathers design context for a project. Runs a short discovery interview and writes the answers to .impeccable.md. Every other command reads this file before doing work. Use once per project.", + "description": "Gathers design context for a project. Runs a short discovery interview and writes PRODUCT.md (strategic: users, brand, principles) and, when code exists to analyze, DESIGN.md (visual: colors, typography, components). Every other command reads these files before doing work. Use once per project.", + "argumentHint": "" + }, + "document": { + "description": "Generate a DESIGN.md file that captures the current visual design system. Auto-extracts colors, typography, spacing, radii, and component patterns from the codebase, then asks the user to confirm descriptive language for atmosphere and color character. Follows the Google Stitch DESIGN.md format so the file is tool-compatible. Use when you need a visual design spec an AI agent can follow to stay on-brand.", "argumentHint": "" }, "extract": { diff --git a/.gemini/skills/impeccable/scripts/live.mjs b/.gemini/skills/impeccable/scripts/live.mjs index 93f05456e..37b6f8997 100644 --- a/.gemini/skills/impeccable/scripts/live.mjs +++ b/.gemini/skills/impeccable/scripts/live.mjs @@ -21,10 +21,10 @@ import { execSync } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { loadContext } from './load-context.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const PID_FILE = path.join(process.cwd(), '.impeccable-live.json'); -const CONTEXT_FILE = path.join(process.cwd(), '.impeccable.md'); async function liveCli() { const args = process.argv.slice(2); @@ -79,9 +79,8 @@ The agent should then: process.exit(1); } - // 4. Load design context if available - let context = null; - try { context = fs.readFileSync(CONTEXT_FILE, 'utf-8'); } catch { /* optional */ } + // 4. Load PRODUCT.md + DESIGN.md context (auto-migrates legacy .impeccable.md) + const ctx = loadContext(process.cwd()); // 5. Emit everything the agent needs console.log(JSON.stringify({ @@ -89,8 +88,13 @@ The agent should then: serverPort: serverInfo.port, serverToken: serverInfo.token, pageFile: checkResult.config.file, - hasContext: !!context, - context, + hasProduct: ctx.hasProduct, + product: ctx.product, + productPath: ctx.productPath, + hasDesign: ctx.hasDesign, + design: ctx.design, + designPath: ctx.designPath, + migrated: ctx.migrated, }, null, 2)); } diff --git a/.gemini/skills/impeccable/scripts/load-context.mjs b/.gemini/skills/impeccable/scripts/load-context.mjs new file mode 100644 index 000000000..ab3be08f1 --- /dev/null +++ b/.gemini/skills/impeccable/scripts/load-context.mjs @@ -0,0 +1,93 @@ +/** + * Shared context loader for every impeccable command that needs to know + * "who is this for" and "what does this look like". + * + * Input: project root (process.cwd()). + * + * Output (JSON to stdout): + * { + * hasProduct: boolean, // PRODUCT.md found (or auto-migrated) + * product: string | null, // PRODUCT.md contents + * productPath: string | null, // relative path + * hasDesign: boolean, // DESIGN.md found + * design: string | null, // DESIGN.md contents + * designPath: string | null, + * migrated: boolean, // true if we auto-renamed .impeccable.md -> PRODUCT.md + * } + * + * Filename matching is case-insensitive for PRODUCT.md and DESIGN.md. The + * Google DESIGN.md convention is uppercase at repo root; Kiro-style and + * lowercase variants are also matched so users don't get punished for case. + */ + +import fs from 'node:fs'; +import path from 'node:path'; + +const PRODUCT_NAMES = ['PRODUCT.md', 'Product.md', 'product.md']; +const DESIGN_NAMES = ['DESIGN.md', 'Design.md', 'design.md']; +const LEGACY_NAMES = ['.impeccable.md']; + +export function loadContext(cwd = process.cwd()) { + let migrated = false; + + // 1. Look for PRODUCT.md (case-insensitive) + let productPath = firstExisting(cwd, PRODUCT_NAMES); + + // 2. Legacy: if no PRODUCT.md but .impeccable.md exists, rename in place + if (!productPath) { + const legacyPath = firstExisting(cwd, LEGACY_NAMES); + if (legacyPath) { + const newPath = path.join(cwd, 'PRODUCT.md'); + try { + fs.renameSync(legacyPath, newPath); + productPath = newPath; + migrated = true; + } catch { + // Rename failed (permissions, etc.) — fall back to reading legacy in place + productPath = legacyPath; + } + } + } + + // 3. DESIGN.md (case-insensitive) + const designPath = firstExisting(cwd, DESIGN_NAMES); + + const product = productPath ? safeRead(productPath) : null; + const design = designPath ? safeRead(designPath) : null; + + return { + hasProduct: !!product, + product, + productPath: productPath ? path.relative(cwd, productPath) : null, + hasDesign: !!design, + design, + designPath: designPath ? path.relative(cwd, designPath) : null, + migrated, + }; +} + +function firstExisting(cwd, names) { + for (const name of names) { + const abs = path.join(cwd, name); + if (fs.existsSync(abs)) return abs; + } + return null; +} + +function safeRead(p) { + try { return fs.readFileSync(p, 'utf-8'); } catch { return null; } +} + +// --------------------------------------------------------------------------- +// CLI mode — print the context as JSON +// --------------------------------------------------------------------------- + +function cli() { + const result = loadContext(process.cwd()); + console.log(JSON.stringify(result, null, 2)); +} + +const _running = process.argv[1]; +if (_running?.endsWith('load-context.mjs') || _running?.endsWith('load-context.mjs/')) { + cli(); +} diff --git a/.gemini/skills/impeccable/scripts/pin.mjs b/.gemini/skills/impeccable/scripts/pin.mjs index 89a6babeb..ba02783fb 100644 --- a/.gemini/skills/impeccable/scripts/pin.mjs +++ b/.gemini/skills/impeccable/scripts/pin.mjs @@ -27,7 +27,7 @@ const HARNESS_DIRS = [ // Valid sub-command names const VALID_COMMANDS = [ - 'craft', 'teach', 'extract', 'shape', + 'craft', 'teach', 'extract', 'document', 'shape', 'critique', 'audit', 'polish', 'bolder', 'quieter', 'distill', 'harden', 'onboard', 'live', 'animate', 'colorize', 'typeset', 'layout', 'delight', 'overdrive', diff --git a/.github/skills/impeccable/SKILL.md b/.github/skills/impeccable/SKILL.md index 8d199dedf..404bffa38 100644 --- a/.github/skills/impeccable/SKILL.md +++ b/.github/skills/impeccable/SKILL.md @@ -3,7 +3,7 @@ name: impeccable description: Use when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a frontend interface. Covers websites, landing pages, dashboards, product UI, app shells, components, forms, settings, onboarding, and empty states. Handles UX review, visual hierarchy, information architecture, cognitive load, accessibility, performance, responsive behavior, theming, anti-patterns, typography, fonts, spacing, layout, alignment, color, motion, micro-interactions, UX copy, error states, edge cases, i18n, and reusable design systems or tokens. Also use for bland designs that need to become bolder or more delightful, loud designs that should become quieter, live browser iteration on UI elements, or ambitious visual effects that should feel technically extraordinary. Not for backend-only or non-UI tasks. version: 3.0.0 user-invocable: true -argument-hint: "[craft|shape · audit|critique · animate|bolder|colorize|delight|layout|overdrive|quieter|typeset · adapt|clarify|distill · harden|onboard|optimize|polish · teach|extract|live] [target]" +argument-hint: "[craft|shape · audit|critique · animate|bolder|colorize|delight|layout|overdrive|quieter|typeset · adapt|clarify|distill · harden|onboard|optimize|polish · teach|document|extract|live] [target]" license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. --- @@ -29,10 +29,17 @@ After running the script, delete this entire section (from ` **Build & Plan** > `/impeccable craft [feature]` - Shape, then build a feature end-to-end > `/impeccable shape [feature]` - Plan UX/UI before writing code -> `/impeccable teach` - Set up design context for this project (one-time) +> `/impeccable teach` - Set up PRODUCT.md and DESIGN.md context for this project +> `/impeccable document` - Generate DESIGN.md from existing project code > `/impeccable extract [target]` - Pull reusable tokens and components into design system > > **Evaluate** @@ -347,6 +355,7 @@ When a sub-command is matched, load the linked reference and follow its instruct | `craft` | [craft](reference/craft.md) | Full shape-then-build flow with visual iteration | | `teach` | [teach](reference/teach.md) | One-time setup: gather design context for the project | | `extract` | [extract](reference/extract.md) | Pull reusable tokens and components into design system | +| `document` | [document](reference/document.md) | Generate DESIGN.md from existing project code (visual design system doc) | | `shape` | [shape](reference/shape.md) | Plan UX and UI before writing code (produces a design brief) | | `critique` | [critique](reference/critique.md) | UX design review with heuristic scoring and persona testing | | `audit` | [audit](reference/audit.md) | Technical quality checks across a11y, perf, theming, responsive, anti-patterns | diff --git a/.github/skills/impeccable/reference/audit.md b/.github/skills/impeccable/reference/audit.md index bbba2401b..c2258ac54 100644 --- a/.github/skills/impeccable/reference/audit.md +++ b/.github/skills/impeccable/reference/audit.md @@ -95,7 +95,7 @@ For each issue, document: - **Impact**: How it affects users - **WCAG/Standard**: Which standard it violates (if applicable) - **Recommendation**: How to fix it -- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) ### Patterns & Systemic Issues @@ -114,7 +114,7 @@ List recommended commands in priority order (P0 first, then P1, then P2): 1. **[P?] `/command-name`** — Brief description (specific context from audit findings) 2. **[P?] `/command-name`** — Brief description (specific context) -**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. +**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. After presenting the summary, tell the user: diff --git a/.github/skills/impeccable/reference/critique.md b/.github/skills/impeccable/reference/critique.md index 16280db0c..18a549d18 100644 --- a/.github/skills/impeccable/reference/critique.md +++ b/.github/skills/impeccable/reference/critique.md @@ -132,7 +132,7 @@ For each issue, tag with **P0-P3 severity** (consult [heuristics-scoring](heuris - **[P?] What**: Name the problem clearly - **Why it matters**: How this hurts users or undermines goals - **Fix**: What to do about it (be concrete) -- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) #### Persona Red Flags > *Consult [personas](personas.md)* @@ -197,7 +197,7 @@ List recommended commands in priority order, based on the user's answers: ... **Rules for recommendations**: -- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset +- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset - Order by the user's stated priorities first, then by impact - Each item's description should carry enough context that the command knows what to focus on - Map each Priority Issue to the appropriate command diff --git a/.github/skills/impeccable/reference/document.md b/.github/skills/impeccable/reference/document.md new file mode 100644 index 000000000..ebf90bbf3 --- /dev/null +++ b/.github/skills/impeccable/reference/document.md @@ -0,0 +1,126 @@ +Generate a DESIGN.md file in the project root that captures the current visual design system, so AI agents generating new screens stay on-brand. + +DESIGN.md follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/): a single markdown file at the project root with five fixed sections describing colors, typography, components, layout, and overall atmosphere. Keep section headers exactly as specified so the file stays compatible with other DESIGN.md-aware tools. + +## When to run + +- The user just ran `/impeccable teach` and needs the visual side documented. +- The skill noticed no `DESIGN.md` exists and nudged the user to create one. +- An existing `DESIGN.md` is stale (the design has drifted). +- Before a large redesign, to capture the current state as a reference. + +If a `DESIGN.md` already exists, **do not silently overwrite it**. Show the user the existing file and ask the user directly to clarify what you cannot infer. whether to refresh it, overwrite it, or merge into it. + +## Process (approach C: auto-extract, then confirm descriptive language) + +### Step 1: Find the design assets + +Search the codebase in priority order: + +1. **CSS custom properties** — grep for `--color-`, `--font-`, `--spacing-`, `--radius-`, `--shadow-`, `--ease-`, `--duration-` declarations in CSS files (usually `src/styles/`, `public/css/`, `app/globals.css`, etc.). Record name, value, and the file it's defined in. +2. **Tailwind config** — if `tailwind.config.{js,ts,mjs}` exists, read the `theme.extend` block for colors, fontFamily, spacing, borderRadius, boxShadow. +3. **CSS-in-JS theme files** — if the project uses styled-components, emotion, vanilla-extract, stitches, etc., look for `theme.ts`, `tokens.ts`, or equivalent. +4. **Design token files** — `tokens.json`, `design-tokens.json`, Style Dictionary output, W3C token community group format. +5. **Component library** — scan the main button, card, input, navigation, dialog components. Note their variant APIs and default styles. +6. **Global stylesheet** — the root CSS file usually has the base typography and color assignments. +7. **Visible rendered output** — if browser automation tools are available, load the live site and sample computed styles from key elements (body, h1, a, button, .card). This catches values that tokens miss. + +### Step 2: Auto-extract what can be auto-extracted + +Build a structured draft from the discovered tokens. For each token class: + +- **Colors**: Group by hue family. Convert hex → OKLCH to infer lightness/chroma. Identify background vs. text vs. accent by usage patterns in CSS (`background`, `color`, `border`, `fill`). Flag any that are only used once (possibly one-off, not system tokens). +- **Typography**: Extract font families and their declared stacks. Extract the scale (all `font-size` values used in CSS custom props + component styles). Extract weights actually used. Detect the scale ratio (1.125, 1.2, 1.25, 1.333, 1.5, golden). +- **Spacing**: Extract the scale, detect the base unit (4px, 8px, other). +- **Radii & shadows**: List the values used. +- **Components**: For each common component (button, card, input, nav, dialog), extract shape (radius), color assignment, hover/focus treatment, internal padding. + +### Step 3: Ask the user for qualitative language + +The following sections require creative input that cannot be auto-extracted reliably. ask the user directly to clarify what you cannot infer. for each (group them into one interaction if possible): + +- **Visual Theme & Atmosphere**: mood adjectives (airy/dense, minimal/maximalist, editorial/utilitarian, warm/clinical), aesthetic philosophy in 2-3 sentences, key characteristics as a bullet list. +- **Color character** (for auto-extracted colors): descriptive names ("Deep Muted Teal-Navy", not "blue-800"). Suggest 2-3 options per color based on the hue/saturation, let the user pick. +- **Typographic character**: describe the font pairing ("Modern geometric sans-serif with humanist warmth" > "Manrope 500"). Describe letter-spacing strategy. +- **Spacing philosophy**: 1-2 sentences on whitespace strategy ("generous breathing room that prioritizes photography"). +- **Component philosophy**: brief description of the feel of buttons, cards, inputs ("refined and understated" vs. "tactile and confident"). + +If the user has a `PRODUCT.md` that covers brand personality, quote a line from it so they see their own strategic language carry over. + +### Step 4: Write DESIGN.md + +Use this exact structure (section headers must match the Google spec character-for-character): + +```markdown +# Design System: [Project Title] +**Project ID:** [optional — only if a Stitch project ID exists] + +## 1. Visual Theme & Atmosphere + +[2-3 paragraph description using evocative adjectives. Start with the overall sanctuary/laboratory/workshop/stage analogy if one fits. End with a short **Key Characteristics:** bullet list.] + +## 2. Color Palette & Roles + +### [Semantic group name: Primary Foundation, Accent & Interactive, Typography & Text Hierarchy, Functional States, etc.] +- **[Descriptive Name]** (#HEX) – [Functional role. Where/why it's used.] + +## 3. Typography Rules + +**Primary Font Family:** [Name] +**Character:** [1-sentence personality description.] + +### Hierarchy & Weights +- **[Role (e.g. Display Headlines H1)]:** [Weight] weight ([num]), [letter-spacing], [size]. [Purpose.] + +### Spacing Principles +[Short list of rules about leading, letter-spacing, vertical rhythm.] + +## 4. Component Stylings + +### Buttons +- **Shape:** [radius description with px value in parens] +- **Primary CTA:** [color assignment + padding] +- **Hover State:** [transition description] +- **Focus State:** [accessibility treatment] +- **Secondary CTA (if applicable):** [description] + +### Cards & Containers +- **Corner Style:** [description] +- **Background:** [colors used] +- **Shadow Strategy:** [flat / soft / heavy] +- **Border:** [if any] +- **Internal Padding:** [scale] +- **Image Treatment:** [if relevant] + +### Navigation +- [Style, typography, default/hover/active states, mobile treatment] + +### Inputs/Forms +- [Stroke style, background, focus treatment] + +## 5. Layout Principles + +[Paragraph or short list describing whitespace strategy, margin scale, grid system, responsive breakpoints. Include px/rem values in parens.] +``` + +### Step 5: Write & confirm + +1. Write the file to `PROJECT_ROOT/DESIGN.md` (uppercase, at root). +2. Show the user the full DESIGN.md you wrote, briefly highlighting the non-obvious creative choices (descriptive color names, atmosphere language). +3. Offer to refine any section: "Want me to revise a section, add component patterns I missed, or adjust the atmosphere language?" + +## Style guidelines + +- **Descriptive > technical**: "Gently curved edges (8px radius)" > "rounded-lg". Include the technical value in parens, lead with the description. +- **Functional > decorative**: for each token, explain WHERE and WHY it's used, not just WHAT it is. +- **Exact values in parens**: hex codes, px/rem values, font weights — always the number in parens alongside the description. +- **Group colors semantically**: Foundation (backgrounds), Accent (interactive), Typography (text hierarchy), States (success/warning/error), not hex-sorted. +- **Reference the user's domain**: if the project is a DEX, say "trading-focused"; if it's a CMS, say "editorial". Domain-aware language helps agents pick sensible defaults. + +## Pitfalls + +- Don't paste raw CSS class names. Translate to descriptive language. +- Don't extract every token. Stop at what's actually reused — one-offs pollute the system. +- Don't invent components that don't exist. If the project only has buttons and cards, only document those. +- Don't overwrite an existing DESIGN.md without asking. +- Don't duplicate content from PRODUCT.md. DESIGN.md is strictly visual. diff --git a/.github/skills/impeccable/reference/live.md b/.github/skills/impeccable/reference/live.md index 3388e1897..19c16fa38 100644 --- a/.github/skills/impeccable/reference/live.md +++ b/.github/skills/impeccable/reference/live.md @@ -21,12 +21,21 @@ Output JSON: "serverPort": 8400, "serverToken": "...", "pageFile": "public/index.html", - "hasContext": true, - "context": "...full .impeccable.md contents..." + "hasProduct": true, + "product": "...full PRODUCT.md contents...", + "productPath": "PRODUCT.md", + "hasDesign": true, + "design": "...full DESIGN.md contents...", + "designPath": "DESIGN.md", + "migrated": false } ``` -Keep the `context` in mind for variant generation. If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. +Keep **PRODUCT.md** (strategic: users, brand, principles) and **DESIGN.md** (visual: colors, typography, components) in mind for variant generation. **DESIGN.md wins on visual decisions; PRODUCT.md wins on strategic/voice decisions.** + +If `migrated` is true, the loader auto-renamed legacy `.impeccable.md` to `PRODUCT.md` — mention this once to the user and suggest running `/impeccable document` to also generate a `DESIGN.md`. + +If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. ### First-time setup (config missing) diff --git a/.github/skills/impeccable/reference/teach.md b/.github/skills/impeccable/reference/teach.md index 5ebd3ed67..8d0fdf14a 100644 --- a/.github/skills/impeccable/reference/teach.md +++ b/.github/skills/impeccable/reference/teach.md @@ -1,8 +1,31 @@ # Teach Flow -One-time setup that gathers design context for a project. Design without context produces generic output, so every other command reads this file before doing any work. +Gathers design context for a project and writes two complementary files at the project root: -## Step 1: Explore the Codebase +- **PRODUCT.md** (strategic): target users, product purpose, brand personality, anti-references, strategic design principles. Answers "who/what/why". +- **DESIGN.md** (visual): visual theme, color palette, typography, components, layout. Follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/). Answers "how it looks". + +Every other impeccable command reads these files before doing any work. + +## Step 1: Load current state + +Run the shared loader first so you know what already exists: + +```bash +node {{scripts_path}}/load-context.mjs +``` + +The output tells you whether PRODUCT.md and/or DESIGN.md already exist. If `migrated: true`, legacy `.impeccable.md` was auto-renamed to `PRODUCT.md`. Mention this once to the user. + +Decision tree: +- **Neither file exists (empty project or no context yet)**: do Steps 2-4 (write PRODUCT.md), then decide on DESIGN.md based on whether there's code to analyze. +- **PRODUCT.md exists, DESIGN.md missing**: skip to Step 5 — offer to run `/impeccable document` for DESIGN.md. +- **Both exist**: ask the user directly to clarify what you cannot infer. which to refresh. Skip the one the user doesn't want changed. +- **Just DESIGN.md exists (unusual)**: do Steps 2-4 to produce PRODUCT.md. + +Never silently overwrite an existing file. Always confirm first. + +## Step 2: Explore the codebase Before asking questions, thoroughly scan the project to discover what you can: @@ -13,9 +36,9 @@ Before asking questions, thoroughly scan the project to discover what you can: - **Design tokens / CSS variables**: Existing color palettes, font stacks, spacing scales - **Any style guides or brand documentation** -Note what you've learned and what remains unclear. +Note what you've learned and what remains unclear. This exploration feeds both PRODUCT.md and DESIGN.md. -## Step 2: Ask UX-Focused Questions +## Step 3: Ask strategic questions (for PRODUCT.md) ask the user directly to clarify what you cannot infer. Focus only on what you couldn't infer from the codebase: @@ -29,39 +52,53 @@ ask the user directly to clarify what you cannot infer. Focus only on what you c - Any reference sites or apps that capture the right feel? What specifically about them? - What should this explicitly NOT look like? Any anti-references? -### Aesthetic Preferences -- Any strong preferences for visual direction? (minimal, bold, elegant, playful, technical, organic, etc.) -- Light mode, dark mode, or both? -- Any colors that must be used or avoided? - ### Accessibility & Inclusion - Specific accessibility requirements? (WCAG level, known user needs) - Considerations for reduced motion, color blindness, or other accommodations? -Skip questions where the answer is already clear from the codebase exploration. +Skip questions where the answer is already clear. **Do NOT ask about colors, fonts, radii, or visual styling here** — those belong in DESIGN.md, not PRODUCT.md. -## Step 3: Write Design Context +## Step 4: Write PRODUCT.md -Synthesize your findings and the user's answers into a `## Design Context` section: +Synthesize into a strategic document: ```markdown -## Design Context +# Product -### Users +## Users [Who they are, their context, the job to be done] -### Brand Personality +## Product Purpose +[What this product does, why it exists, what success looks like] + +## Brand Personality [Voice, tone, 3-word personality, emotional goals] -### Aesthetic Direction -[Visual tone, references, anti-references, theme] +## Anti-references +[What this should NOT look like. Specific bad-example sites or patterns to avoid.] -### Design Principles -[3-5 principles derived from the conversation that should guide all design decisions] +## Design Principles +[3-5 strategic principles derived from the conversation. Principles like "practice what you preach", "editorial over marketing", "expert confidence" — NOT visual rules like "use OKLCH" or "magenta accent".] + +## Accessibility & Inclusion +[WCAG level, known user needs, considerations] ``` -Write this section to `.impeccable.md` in the project root. If the file already exists, update the Design Context section in place. +Write to `PROJECT_ROOT/PRODUCT.md`. If `.impeccable.md` existed, the loader already renamed it — merge into that content rather than starting from scratch. -Then ask the user directly to clarify what you cannot infer. whether they'd also like the Design Context appended to .github/copilot-instructions.md. If yes, append or update the section there as well. +## Step 5: Decide on DESIGN.md -Confirm completion and summarize the key design principles that will now guide all future work. +If the project has meaningful code to analyze (CSS tokens, components, a running site), **offer to run `/impeccable document`** next: "I can also generate a DESIGN.md that captures your visual design system (colors, typography, components) so variants stay on-brand. Want to do that now?" + +If the user agrees, delegate to `/impeccable document` (load its reference and follow that flow). + +If the project is empty (no code yet, pre-implementation), skip DESIGN.md — there's nothing visual to document yet. Mention: "Once you've built some of the interface, run `/impeccable document` to generate a DESIGN.md." + +## Step 6: Confirm and wrap up + +Summarize: +- What was written (PRODUCT.md, DESIGN.md, or both) +- The 3-5 strategic principles from PRODUCT.md that will guide future work +- If DESIGN.md is pending, remind the user how to generate it later + +Optionally ask the user directly to clarify what you cannot infer. whether they'd like a brief summary of PRODUCT.md appended to .github/copilot-instructions.md for easier agent reference. If yes, append a short **Design Context** pointer section there. diff --git a/.github/skills/impeccable/scripts/command-metadata.json b/.github/skills/impeccable/scripts/command-metadata.json index 2974e08f6..d8282689a 100644 --- a/.github/skills/impeccable/scripts/command-metadata.json +++ b/.github/skills/impeccable/scripts/command-metadata.json @@ -4,7 +4,11 @@ "argumentHint": "[feature description]" }, "teach": { - "description": "One-time setup that gathers design context for a project. Runs a short discovery interview and writes the answers to .impeccable.md. Every other command reads this file before doing work. Use once per project.", + "description": "Gathers design context for a project. Runs a short discovery interview and writes PRODUCT.md (strategic: users, brand, principles) and, when code exists to analyze, DESIGN.md (visual: colors, typography, components). Every other command reads these files before doing work. Use once per project.", + "argumentHint": "" + }, + "document": { + "description": "Generate a DESIGN.md file that captures the current visual design system. Auto-extracts colors, typography, spacing, radii, and component patterns from the codebase, then asks the user to confirm descriptive language for atmosphere and color character. Follows the Google Stitch DESIGN.md format so the file is tool-compatible. Use when you need a visual design spec an AI agent can follow to stay on-brand.", "argumentHint": "" }, "extract": { diff --git a/.github/skills/impeccable/scripts/live.mjs b/.github/skills/impeccable/scripts/live.mjs index 93f05456e..37b6f8997 100644 --- a/.github/skills/impeccable/scripts/live.mjs +++ b/.github/skills/impeccable/scripts/live.mjs @@ -21,10 +21,10 @@ import { execSync } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { loadContext } from './load-context.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const PID_FILE = path.join(process.cwd(), '.impeccable-live.json'); -const CONTEXT_FILE = path.join(process.cwd(), '.impeccable.md'); async function liveCli() { const args = process.argv.slice(2); @@ -79,9 +79,8 @@ The agent should then: process.exit(1); } - // 4. Load design context if available - let context = null; - try { context = fs.readFileSync(CONTEXT_FILE, 'utf-8'); } catch { /* optional */ } + // 4. Load PRODUCT.md + DESIGN.md context (auto-migrates legacy .impeccable.md) + const ctx = loadContext(process.cwd()); // 5. Emit everything the agent needs console.log(JSON.stringify({ @@ -89,8 +88,13 @@ The agent should then: serverPort: serverInfo.port, serverToken: serverInfo.token, pageFile: checkResult.config.file, - hasContext: !!context, - context, + hasProduct: ctx.hasProduct, + product: ctx.product, + productPath: ctx.productPath, + hasDesign: ctx.hasDesign, + design: ctx.design, + designPath: ctx.designPath, + migrated: ctx.migrated, }, null, 2)); } diff --git a/.github/skills/impeccable/scripts/load-context.mjs b/.github/skills/impeccable/scripts/load-context.mjs new file mode 100644 index 000000000..ab3be08f1 --- /dev/null +++ b/.github/skills/impeccable/scripts/load-context.mjs @@ -0,0 +1,93 @@ +/** + * Shared context loader for every impeccable command that needs to know + * "who is this for" and "what does this look like". + * + * Input: project root (process.cwd()). + * + * Output (JSON to stdout): + * { + * hasProduct: boolean, // PRODUCT.md found (or auto-migrated) + * product: string | null, // PRODUCT.md contents + * productPath: string | null, // relative path + * hasDesign: boolean, // DESIGN.md found + * design: string | null, // DESIGN.md contents + * designPath: string | null, + * migrated: boolean, // true if we auto-renamed .impeccable.md -> PRODUCT.md + * } + * + * Filename matching is case-insensitive for PRODUCT.md and DESIGN.md. The + * Google DESIGN.md convention is uppercase at repo root; Kiro-style and + * lowercase variants are also matched so users don't get punished for case. + */ + +import fs from 'node:fs'; +import path from 'node:path'; + +const PRODUCT_NAMES = ['PRODUCT.md', 'Product.md', 'product.md']; +const DESIGN_NAMES = ['DESIGN.md', 'Design.md', 'design.md']; +const LEGACY_NAMES = ['.impeccable.md']; + +export function loadContext(cwd = process.cwd()) { + let migrated = false; + + // 1. Look for PRODUCT.md (case-insensitive) + let productPath = firstExisting(cwd, PRODUCT_NAMES); + + // 2. Legacy: if no PRODUCT.md but .impeccable.md exists, rename in place + if (!productPath) { + const legacyPath = firstExisting(cwd, LEGACY_NAMES); + if (legacyPath) { + const newPath = path.join(cwd, 'PRODUCT.md'); + try { + fs.renameSync(legacyPath, newPath); + productPath = newPath; + migrated = true; + } catch { + // Rename failed (permissions, etc.) — fall back to reading legacy in place + productPath = legacyPath; + } + } + } + + // 3. DESIGN.md (case-insensitive) + const designPath = firstExisting(cwd, DESIGN_NAMES); + + const product = productPath ? safeRead(productPath) : null; + const design = designPath ? safeRead(designPath) : null; + + return { + hasProduct: !!product, + product, + productPath: productPath ? path.relative(cwd, productPath) : null, + hasDesign: !!design, + design, + designPath: designPath ? path.relative(cwd, designPath) : null, + migrated, + }; +} + +function firstExisting(cwd, names) { + for (const name of names) { + const abs = path.join(cwd, name); + if (fs.existsSync(abs)) return abs; + } + return null; +} + +function safeRead(p) { + try { return fs.readFileSync(p, 'utf-8'); } catch { return null; } +} + +// --------------------------------------------------------------------------- +// CLI mode — print the context as JSON +// --------------------------------------------------------------------------- + +function cli() { + const result = loadContext(process.cwd()); + console.log(JSON.stringify(result, null, 2)); +} + +const _running = process.argv[1]; +if (_running?.endsWith('load-context.mjs') || _running?.endsWith('load-context.mjs/')) { + cli(); +} diff --git a/.github/skills/impeccable/scripts/pin.mjs b/.github/skills/impeccable/scripts/pin.mjs index 89a6babeb..ba02783fb 100644 --- a/.github/skills/impeccable/scripts/pin.mjs +++ b/.github/skills/impeccable/scripts/pin.mjs @@ -27,7 +27,7 @@ const HARNESS_DIRS = [ // Valid sub-command names const VALID_COMMANDS = [ - 'craft', 'teach', 'extract', 'shape', + 'craft', 'teach', 'extract', 'document', 'shape', 'critique', 'audit', 'polish', 'bolder', 'quieter', 'distill', 'harden', 'onboard', 'live', 'animate', 'colorize', 'typeset', 'layout', 'delight', 'overdrive', diff --git a/.gitignore b/.gitignore index 631650cc6..ded1cc474 100644 --- a/.gitignore +++ b/.gitignore @@ -42,8 +42,11 @@ Thumbs.db # Extension build artifacts extension/detector/ -# User design context +# User design context (this repo's private project briefs — users can choose +# whether to commit these in their own projects) .impeccable.md +PRODUCT.md +DESIGN.md # Evals (private, commercial) evals/ diff --git a/.kiro/skills/impeccable/SKILL.md b/.kiro/skills/impeccable/SKILL.md index d3084ea1d..6d27dd679 100644 --- a/.kiro/skills/impeccable/SKILL.md +++ b/.kiro/skills/impeccable/SKILL.md @@ -27,10 +27,17 @@ After running the script, delete this entire section (from ` **Build & Plan** > `/impeccable craft [feature]` - Shape, then build a feature end-to-end > `/impeccable shape [feature]` - Plan UX/UI before writing code -> `/impeccable teach` - Set up design context for this project (one-time) +> `/impeccable teach` - Set up PRODUCT.md and DESIGN.md context for this project +> `/impeccable document` - Generate DESIGN.md from existing project code > `/impeccable extract [target]` - Pull reusable tokens and components into design system > > **Evaluate** @@ -345,6 +353,7 @@ When a sub-command is matched, load the linked reference and follow its instruct | `craft` | [craft](reference/craft.md) | Full shape-then-build flow with visual iteration | | `teach` | [teach](reference/teach.md) | One-time setup: gather design context for the project | | `extract` | [extract](reference/extract.md) | Pull reusable tokens and components into design system | +| `document` | [document](reference/document.md) | Generate DESIGN.md from existing project code (visual design system doc) | | `shape` | [shape](reference/shape.md) | Plan UX and UI before writing code (produces a design brief) | | `critique` | [critique](reference/critique.md) | UX design review with heuristic scoring and persona testing | | `audit` | [audit](reference/audit.md) | Technical quality checks across a11y, perf, theming, responsive, anti-patterns | diff --git a/.kiro/skills/impeccable/reference/audit.md b/.kiro/skills/impeccable/reference/audit.md index bbba2401b..c2258ac54 100644 --- a/.kiro/skills/impeccable/reference/audit.md +++ b/.kiro/skills/impeccable/reference/audit.md @@ -95,7 +95,7 @@ For each issue, document: - **Impact**: How it affects users - **WCAG/Standard**: Which standard it violates (if applicable) - **Recommendation**: How to fix it -- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) ### Patterns & Systemic Issues @@ -114,7 +114,7 @@ List recommended commands in priority order (P0 first, then P1, then P2): 1. **[P?] `/command-name`** — Brief description (specific context from audit findings) 2. **[P?] `/command-name`** — Brief description (specific context) -**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. +**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. After presenting the summary, tell the user: diff --git a/.kiro/skills/impeccable/reference/critique.md b/.kiro/skills/impeccable/reference/critique.md index f0e1374b5..31a1d7c66 100644 --- a/.kiro/skills/impeccable/reference/critique.md +++ b/.kiro/skills/impeccable/reference/critique.md @@ -132,7 +132,7 @@ For each issue, tag with **P0-P3 severity** (consult [heuristics-scoring](heuris - **[P?] What**: Name the problem clearly - **Why it matters**: How this hurts users or undermines goals - **Fix**: What to do about it (be concrete) -- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) #### Persona Red Flags > *Consult [personas](personas.md)* @@ -197,7 +197,7 @@ List recommended commands in priority order, based on the user's answers: ... **Rules for recommendations**: -- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset +- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset - Order by the user's stated priorities first, then by impact - Each item's description should carry enough context that the command knows what to focus on - Map each Priority Issue to the appropriate command diff --git a/.kiro/skills/impeccable/reference/document.md b/.kiro/skills/impeccable/reference/document.md new file mode 100644 index 000000000..ebf90bbf3 --- /dev/null +++ b/.kiro/skills/impeccable/reference/document.md @@ -0,0 +1,126 @@ +Generate a DESIGN.md file in the project root that captures the current visual design system, so AI agents generating new screens stay on-brand. + +DESIGN.md follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/): a single markdown file at the project root with five fixed sections describing colors, typography, components, layout, and overall atmosphere. Keep section headers exactly as specified so the file stays compatible with other DESIGN.md-aware tools. + +## When to run + +- The user just ran `/impeccable teach` and needs the visual side documented. +- The skill noticed no `DESIGN.md` exists and nudged the user to create one. +- An existing `DESIGN.md` is stale (the design has drifted). +- Before a large redesign, to capture the current state as a reference. + +If a `DESIGN.md` already exists, **do not silently overwrite it**. Show the user the existing file and ask the user directly to clarify what you cannot infer. whether to refresh it, overwrite it, or merge into it. + +## Process (approach C: auto-extract, then confirm descriptive language) + +### Step 1: Find the design assets + +Search the codebase in priority order: + +1. **CSS custom properties** — grep for `--color-`, `--font-`, `--spacing-`, `--radius-`, `--shadow-`, `--ease-`, `--duration-` declarations in CSS files (usually `src/styles/`, `public/css/`, `app/globals.css`, etc.). Record name, value, and the file it's defined in. +2. **Tailwind config** — if `tailwind.config.{js,ts,mjs}` exists, read the `theme.extend` block for colors, fontFamily, spacing, borderRadius, boxShadow. +3. **CSS-in-JS theme files** — if the project uses styled-components, emotion, vanilla-extract, stitches, etc., look for `theme.ts`, `tokens.ts`, or equivalent. +4. **Design token files** — `tokens.json`, `design-tokens.json`, Style Dictionary output, W3C token community group format. +5. **Component library** — scan the main button, card, input, navigation, dialog components. Note their variant APIs and default styles. +6. **Global stylesheet** — the root CSS file usually has the base typography and color assignments. +7. **Visible rendered output** — if browser automation tools are available, load the live site and sample computed styles from key elements (body, h1, a, button, .card). This catches values that tokens miss. + +### Step 2: Auto-extract what can be auto-extracted + +Build a structured draft from the discovered tokens. For each token class: + +- **Colors**: Group by hue family. Convert hex → OKLCH to infer lightness/chroma. Identify background vs. text vs. accent by usage patterns in CSS (`background`, `color`, `border`, `fill`). Flag any that are only used once (possibly one-off, not system tokens). +- **Typography**: Extract font families and their declared stacks. Extract the scale (all `font-size` values used in CSS custom props + component styles). Extract weights actually used. Detect the scale ratio (1.125, 1.2, 1.25, 1.333, 1.5, golden). +- **Spacing**: Extract the scale, detect the base unit (4px, 8px, other). +- **Radii & shadows**: List the values used. +- **Components**: For each common component (button, card, input, nav, dialog), extract shape (radius), color assignment, hover/focus treatment, internal padding. + +### Step 3: Ask the user for qualitative language + +The following sections require creative input that cannot be auto-extracted reliably. ask the user directly to clarify what you cannot infer. for each (group them into one interaction if possible): + +- **Visual Theme & Atmosphere**: mood adjectives (airy/dense, minimal/maximalist, editorial/utilitarian, warm/clinical), aesthetic philosophy in 2-3 sentences, key characteristics as a bullet list. +- **Color character** (for auto-extracted colors): descriptive names ("Deep Muted Teal-Navy", not "blue-800"). Suggest 2-3 options per color based on the hue/saturation, let the user pick. +- **Typographic character**: describe the font pairing ("Modern geometric sans-serif with humanist warmth" > "Manrope 500"). Describe letter-spacing strategy. +- **Spacing philosophy**: 1-2 sentences on whitespace strategy ("generous breathing room that prioritizes photography"). +- **Component philosophy**: brief description of the feel of buttons, cards, inputs ("refined and understated" vs. "tactile and confident"). + +If the user has a `PRODUCT.md` that covers brand personality, quote a line from it so they see their own strategic language carry over. + +### Step 4: Write DESIGN.md + +Use this exact structure (section headers must match the Google spec character-for-character): + +```markdown +# Design System: [Project Title] +**Project ID:** [optional — only if a Stitch project ID exists] + +## 1. Visual Theme & Atmosphere + +[2-3 paragraph description using evocative adjectives. Start with the overall sanctuary/laboratory/workshop/stage analogy if one fits. End with a short **Key Characteristics:** bullet list.] + +## 2. Color Palette & Roles + +### [Semantic group name: Primary Foundation, Accent & Interactive, Typography & Text Hierarchy, Functional States, etc.] +- **[Descriptive Name]** (#HEX) – [Functional role. Where/why it's used.] + +## 3. Typography Rules + +**Primary Font Family:** [Name] +**Character:** [1-sentence personality description.] + +### Hierarchy & Weights +- **[Role (e.g. Display Headlines H1)]:** [Weight] weight ([num]), [letter-spacing], [size]. [Purpose.] + +### Spacing Principles +[Short list of rules about leading, letter-spacing, vertical rhythm.] + +## 4. Component Stylings + +### Buttons +- **Shape:** [radius description with px value in parens] +- **Primary CTA:** [color assignment + padding] +- **Hover State:** [transition description] +- **Focus State:** [accessibility treatment] +- **Secondary CTA (if applicable):** [description] + +### Cards & Containers +- **Corner Style:** [description] +- **Background:** [colors used] +- **Shadow Strategy:** [flat / soft / heavy] +- **Border:** [if any] +- **Internal Padding:** [scale] +- **Image Treatment:** [if relevant] + +### Navigation +- [Style, typography, default/hover/active states, mobile treatment] + +### Inputs/Forms +- [Stroke style, background, focus treatment] + +## 5. Layout Principles + +[Paragraph or short list describing whitespace strategy, margin scale, grid system, responsive breakpoints. Include px/rem values in parens.] +``` + +### Step 5: Write & confirm + +1. Write the file to `PROJECT_ROOT/DESIGN.md` (uppercase, at root). +2. Show the user the full DESIGN.md you wrote, briefly highlighting the non-obvious creative choices (descriptive color names, atmosphere language). +3. Offer to refine any section: "Want me to revise a section, add component patterns I missed, or adjust the atmosphere language?" + +## Style guidelines + +- **Descriptive > technical**: "Gently curved edges (8px radius)" > "rounded-lg". Include the technical value in parens, lead with the description. +- **Functional > decorative**: for each token, explain WHERE and WHY it's used, not just WHAT it is. +- **Exact values in parens**: hex codes, px/rem values, font weights — always the number in parens alongside the description. +- **Group colors semantically**: Foundation (backgrounds), Accent (interactive), Typography (text hierarchy), States (success/warning/error), not hex-sorted. +- **Reference the user's domain**: if the project is a DEX, say "trading-focused"; if it's a CMS, say "editorial". Domain-aware language helps agents pick sensible defaults. + +## Pitfalls + +- Don't paste raw CSS class names. Translate to descriptive language. +- Don't extract every token. Stop at what's actually reused — one-offs pollute the system. +- Don't invent components that don't exist. If the project only has buttons and cards, only document those. +- Don't overwrite an existing DESIGN.md without asking. +- Don't duplicate content from PRODUCT.md. DESIGN.md is strictly visual. diff --git a/.kiro/skills/impeccable/reference/live.md b/.kiro/skills/impeccable/reference/live.md index 3388e1897..19c16fa38 100644 --- a/.kiro/skills/impeccable/reference/live.md +++ b/.kiro/skills/impeccable/reference/live.md @@ -21,12 +21,21 @@ Output JSON: "serverPort": 8400, "serverToken": "...", "pageFile": "public/index.html", - "hasContext": true, - "context": "...full .impeccable.md contents..." + "hasProduct": true, + "product": "...full PRODUCT.md contents...", + "productPath": "PRODUCT.md", + "hasDesign": true, + "design": "...full DESIGN.md contents...", + "designPath": "DESIGN.md", + "migrated": false } ``` -Keep the `context` in mind for variant generation. If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. +Keep **PRODUCT.md** (strategic: users, brand, principles) and **DESIGN.md** (visual: colors, typography, components) in mind for variant generation. **DESIGN.md wins on visual decisions; PRODUCT.md wins on strategic/voice decisions.** + +If `migrated` is true, the loader auto-renamed legacy `.impeccable.md` to `PRODUCT.md` — mention this once to the user and suggest running `/impeccable document` to also generate a `DESIGN.md`. + +If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. ### First-time setup (config missing) diff --git a/.kiro/skills/impeccable/reference/teach.md b/.kiro/skills/impeccable/reference/teach.md index 046f6065d..5b89def79 100644 --- a/.kiro/skills/impeccable/reference/teach.md +++ b/.kiro/skills/impeccable/reference/teach.md @@ -1,8 +1,31 @@ # Teach Flow -One-time setup that gathers design context for a project. Design without context produces generic output, so every other command reads this file before doing any work. +Gathers design context for a project and writes two complementary files at the project root: -## Step 1: Explore the Codebase +- **PRODUCT.md** (strategic): target users, product purpose, brand personality, anti-references, strategic design principles. Answers "who/what/why". +- **DESIGN.md** (visual): visual theme, color palette, typography, components, layout. Follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/). Answers "how it looks". + +Every other impeccable command reads these files before doing any work. + +## Step 1: Load current state + +Run the shared loader first so you know what already exists: + +```bash +node {{scripts_path}}/load-context.mjs +``` + +The output tells you whether PRODUCT.md and/or DESIGN.md already exist. If `migrated: true`, legacy `.impeccable.md` was auto-renamed to `PRODUCT.md`. Mention this once to the user. + +Decision tree: +- **Neither file exists (empty project or no context yet)**: do Steps 2-4 (write PRODUCT.md), then decide on DESIGN.md based on whether there's code to analyze. +- **PRODUCT.md exists, DESIGN.md missing**: skip to Step 5 — offer to run `/impeccable document` for DESIGN.md. +- **Both exist**: ask the user directly to clarify what you cannot infer. which to refresh. Skip the one the user doesn't want changed. +- **Just DESIGN.md exists (unusual)**: do Steps 2-4 to produce PRODUCT.md. + +Never silently overwrite an existing file. Always confirm first. + +## Step 2: Explore the codebase Before asking questions, thoroughly scan the project to discover what you can: @@ -13,9 +36,9 @@ Before asking questions, thoroughly scan the project to discover what you can: - **Design tokens / CSS variables**: Existing color palettes, font stacks, spacing scales - **Any style guides or brand documentation** -Note what you've learned and what remains unclear. +Note what you've learned and what remains unclear. This exploration feeds both PRODUCT.md and DESIGN.md. -## Step 2: Ask UX-Focused Questions +## Step 3: Ask strategic questions (for PRODUCT.md) ask the user directly to clarify what you cannot infer. Focus only on what you couldn't infer from the codebase: @@ -29,39 +52,53 @@ ask the user directly to clarify what you cannot infer. Focus only on what you c - Any reference sites or apps that capture the right feel? What specifically about them? - What should this explicitly NOT look like? Any anti-references? -### Aesthetic Preferences -- Any strong preferences for visual direction? (minimal, bold, elegant, playful, technical, organic, etc.) -- Light mode, dark mode, or both? -- Any colors that must be used or avoided? - ### Accessibility & Inclusion - Specific accessibility requirements? (WCAG level, known user needs) - Considerations for reduced motion, color blindness, or other accommodations? -Skip questions where the answer is already clear from the codebase exploration. +Skip questions where the answer is already clear. **Do NOT ask about colors, fonts, radii, or visual styling here** — those belong in DESIGN.md, not PRODUCT.md. -## Step 3: Write Design Context +## Step 4: Write PRODUCT.md -Synthesize your findings and the user's answers into a `## Design Context` section: +Synthesize into a strategic document: ```markdown -## Design Context +# Product -### Users +## Users [Who they are, their context, the job to be done] -### Brand Personality +## Product Purpose +[What this product does, why it exists, what success looks like] + +## Brand Personality [Voice, tone, 3-word personality, emotional goals] -### Aesthetic Direction -[Visual tone, references, anti-references, theme] +## Anti-references +[What this should NOT look like. Specific bad-example sites or patterns to avoid.] -### Design Principles -[3-5 principles derived from the conversation that should guide all design decisions] +## Design Principles +[3-5 strategic principles derived from the conversation. Principles like "practice what you preach", "editorial over marketing", "expert confidence" — NOT visual rules like "use OKLCH" or "magenta accent".] + +## Accessibility & Inclusion +[WCAG level, known user needs, considerations] ``` -Write this section to `.impeccable.md` in the project root. If the file already exists, update the Design Context section in place. +Write to `PROJECT_ROOT/PRODUCT.md`. If `.impeccable.md` existed, the loader already renamed it — merge into that content rather than starting from scratch. -Then ask the user directly to clarify what you cannot infer. whether they'd also like the Design Context appended to .kiro/settings.json. If yes, append or update the section there as well. +## Step 5: Decide on DESIGN.md -Confirm completion and summarize the key design principles that will now guide all future work. +If the project has meaningful code to analyze (CSS tokens, components, a running site), **offer to run `/impeccable document`** next: "I can also generate a DESIGN.md that captures your visual design system (colors, typography, components) so variants stay on-brand. Want to do that now?" + +If the user agrees, delegate to `/impeccable document` (load its reference and follow that flow). + +If the project is empty (no code yet, pre-implementation), skip DESIGN.md — there's nothing visual to document yet. Mention: "Once you've built some of the interface, run `/impeccable document` to generate a DESIGN.md." + +## Step 6: Confirm and wrap up + +Summarize: +- What was written (PRODUCT.md, DESIGN.md, or both) +- The 3-5 strategic principles from PRODUCT.md that will guide future work +- If DESIGN.md is pending, remind the user how to generate it later + +Optionally ask the user directly to clarify what you cannot infer. whether they'd like a brief summary of PRODUCT.md appended to .kiro/settings.json for easier agent reference. If yes, append a short **Design Context** pointer section there. diff --git a/.kiro/skills/impeccable/scripts/command-metadata.json b/.kiro/skills/impeccable/scripts/command-metadata.json index 2974e08f6..d8282689a 100644 --- a/.kiro/skills/impeccable/scripts/command-metadata.json +++ b/.kiro/skills/impeccable/scripts/command-metadata.json @@ -4,7 +4,11 @@ "argumentHint": "[feature description]" }, "teach": { - "description": "One-time setup that gathers design context for a project. Runs a short discovery interview and writes the answers to .impeccable.md. Every other command reads this file before doing work. Use once per project.", + "description": "Gathers design context for a project. Runs a short discovery interview and writes PRODUCT.md (strategic: users, brand, principles) and, when code exists to analyze, DESIGN.md (visual: colors, typography, components). Every other command reads these files before doing work. Use once per project.", + "argumentHint": "" + }, + "document": { + "description": "Generate a DESIGN.md file that captures the current visual design system. Auto-extracts colors, typography, spacing, radii, and component patterns from the codebase, then asks the user to confirm descriptive language for atmosphere and color character. Follows the Google Stitch DESIGN.md format so the file is tool-compatible. Use when you need a visual design spec an AI agent can follow to stay on-brand.", "argumentHint": "" }, "extract": { diff --git a/.kiro/skills/impeccable/scripts/live.mjs b/.kiro/skills/impeccable/scripts/live.mjs index 93f05456e..37b6f8997 100644 --- a/.kiro/skills/impeccable/scripts/live.mjs +++ b/.kiro/skills/impeccable/scripts/live.mjs @@ -21,10 +21,10 @@ import { execSync } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { loadContext } from './load-context.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const PID_FILE = path.join(process.cwd(), '.impeccable-live.json'); -const CONTEXT_FILE = path.join(process.cwd(), '.impeccable.md'); async function liveCli() { const args = process.argv.slice(2); @@ -79,9 +79,8 @@ The agent should then: process.exit(1); } - // 4. Load design context if available - let context = null; - try { context = fs.readFileSync(CONTEXT_FILE, 'utf-8'); } catch { /* optional */ } + // 4. Load PRODUCT.md + DESIGN.md context (auto-migrates legacy .impeccable.md) + const ctx = loadContext(process.cwd()); // 5. Emit everything the agent needs console.log(JSON.stringify({ @@ -89,8 +88,13 @@ The agent should then: serverPort: serverInfo.port, serverToken: serverInfo.token, pageFile: checkResult.config.file, - hasContext: !!context, - context, + hasProduct: ctx.hasProduct, + product: ctx.product, + productPath: ctx.productPath, + hasDesign: ctx.hasDesign, + design: ctx.design, + designPath: ctx.designPath, + migrated: ctx.migrated, }, null, 2)); } diff --git a/.kiro/skills/impeccable/scripts/load-context.mjs b/.kiro/skills/impeccable/scripts/load-context.mjs new file mode 100644 index 000000000..ab3be08f1 --- /dev/null +++ b/.kiro/skills/impeccable/scripts/load-context.mjs @@ -0,0 +1,93 @@ +/** + * Shared context loader for every impeccable command that needs to know + * "who is this for" and "what does this look like". + * + * Input: project root (process.cwd()). + * + * Output (JSON to stdout): + * { + * hasProduct: boolean, // PRODUCT.md found (or auto-migrated) + * product: string | null, // PRODUCT.md contents + * productPath: string | null, // relative path + * hasDesign: boolean, // DESIGN.md found + * design: string | null, // DESIGN.md contents + * designPath: string | null, + * migrated: boolean, // true if we auto-renamed .impeccable.md -> PRODUCT.md + * } + * + * Filename matching is case-insensitive for PRODUCT.md and DESIGN.md. The + * Google DESIGN.md convention is uppercase at repo root; Kiro-style and + * lowercase variants are also matched so users don't get punished for case. + */ + +import fs from 'node:fs'; +import path from 'node:path'; + +const PRODUCT_NAMES = ['PRODUCT.md', 'Product.md', 'product.md']; +const DESIGN_NAMES = ['DESIGN.md', 'Design.md', 'design.md']; +const LEGACY_NAMES = ['.impeccable.md']; + +export function loadContext(cwd = process.cwd()) { + let migrated = false; + + // 1. Look for PRODUCT.md (case-insensitive) + let productPath = firstExisting(cwd, PRODUCT_NAMES); + + // 2. Legacy: if no PRODUCT.md but .impeccable.md exists, rename in place + if (!productPath) { + const legacyPath = firstExisting(cwd, LEGACY_NAMES); + if (legacyPath) { + const newPath = path.join(cwd, 'PRODUCT.md'); + try { + fs.renameSync(legacyPath, newPath); + productPath = newPath; + migrated = true; + } catch { + // Rename failed (permissions, etc.) — fall back to reading legacy in place + productPath = legacyPath; + } + } + } + + // 3. DESIGN.md (case-insensitive) + const designPath = firstExisting(cwd, DESIGN_NAMES); + + const product = productPath ? safeRead(productPath) : null; + const design = designPath ? safeRead(designPath) : null; + + return { + hasProduct: !!product, + product, + productPath: productPath ? path.relative(cwd, productPath) : null, + hasDesign: !!design, + design, + designPath: designPath ? path.relative(cwd, designPath) : null, + migrated, + }; +} + +function firstExisting(cwd, names) { + for (const name of names) { + const abs = path.join(cwd, name); + if (fs.existsSync(abs)) return abs; + } + return null; +} + +function safeRead(p) { + try { return fs.readFileSync(p, 'utf-8'); } catch { return null; } +} + +// --------------------------------------------------------------------------- +// CLI mode — print the context as JSON +// --------------------------------------------------------------------------- + +function cli() { + const result = loadContext(process.cwd()); + console.log(JSON.stringify(result, null, 2)); +} + +const _running = process.argv[1]; +if (_running?.endsWith('load-context.mjs') || _running?.endsWith('load-context.mjs/')) { + cli(); +} diff --git a/.kiro/skills/impeccable/scripts/pin.mjs b/.kiro/skills/impeccable/scripts/pin.mjs index 89a6babeb..ba02783fb 100644 --- a/.kiro/skills/impeccable/scripts/pin.mjs +++ b/.kiro/skills/impeccable/scripts/pin.mjs @@ -27,7 +27,7 @@ const HARNESS_DIRS = [ // Valid sub-command names const VALID_COMMANDS = [ - 'craft', 'teach', 'extract', 'shape', + 'craft', 'teach', 'extract', 'document', 'shape', 'critique', 'audit', 'polish', 'bolder', 'quieter', 'distill', 'harden', 'onboard', 'live', 'animate', 'colorize', 'typeset', 'layout', 'delight', 'overdrive', diff --git a/.opencode/skills/impeccable/SKILL.md b/.opencode/skills/impeccable/SKILL.md index d403702fa..f6db8c6c6 100644 --- a/.opencode/skills/impeccable/SKILL.md +++ b/.opencode/skills/impeccable/SKILL.md @@ -3,7 +3,7 @@ name: impeccable description: Use when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a frontend interface. Covers websites, landing pages, dashboards, product UI, app shells, components, forms, settings, onboarding, and empty states. Handles UX review, visual hierarchy, information architecture, cognitive load, accessibility, performance, responsive behavior, theming, anti-patterns, typography, fonts, spacing, layout, alignment, color, motion, micro-interactions, UX copy, error states, edge cases, i18n, and reusable design systems or tokens. Also use for bland designs that need to become bolder or more delightful, loud designs that should become quieter, live browser iteration on UI elements, or ambitious visual effects that should feel technically extraordinary. Not for backend-only or non-UI tasks. version: 3.0.0 user-invocable: true -argument-hint: "[craft|shape · audit|critique · animate|bolder|colorize|delight|layout|overdrive|quieter|typeset · adapt|clarify|distill · harden|onboard|optimize|polish · teach|extract|live] [target]" +argument-hint: "[craft|shape · audit|critique · animate|bolder|colorize|delight|layout|overdrive|quieter|typeset · adapt|clarify|distill · harden|onboard|optimize|polish · teach|document|extract|live] [target]" license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. allowed-tools: - Bash(npx impeccable *) @@ -31,10 +31,17 @@ After running the script, delete this entire section (from ` **Build & Plan** > `/impeccable craft [feature]` - Shape, then build a feature end-to-end > `/impeccable shape [feature]` - Plan UX/UI before writing code -> `/impeccable teach` - Set up design context for this project (one-time) +> `/impeccable teach` - Set up PRODUCT.md and DESIGN.md context for this project +> `/impeccable document` - Generate DESIGN.md from existing project code > `/impeccable extract [target]` - Pull reusable tokens and components into design system > > **Evaluate** @@ -349,6 +357,7 @@ When a sub-command is matched, load the linked reference and follow its instruct | `craft` | [craft](reference/craft.md) | Full shape-then-build flow with visual iteration | | `teach` | [teach](reference/teach.md) | One-time setup: gather design context for the project | | `extract` | [extract](reference/extract.md) | Pull reusable tokens and components into design system | +| `document` | [document](reference/document.md) | Generate DESIGN.md from existing project code (visual design system doc) | | `shape` | [shape](reference/shape.md) | Plan UX and UI before writing code (produces a design brief) | | `critique` | [critique](reference/critique.md) | UX design review with heuristic scoring and persona testing | | `audit` | [audit](reference/audit.md) | Technical quality checks across a11y, perf, theming, responsive, anti-patterns | diff --git a/.opencode/skills/impeccable/reference/audit.md b/.opencode/skills/impeccable/reference/audit.md index bbba2401b..c2258ac54 100644 --- a/.opencode/skills/impeccable/reference/audit.md +++ b/.opencode/skills/impeccable/reference/audit.md @@ -95,7 +95,7 @@ For each issue, document: - **Impact**: How it affects users - **WCAG/Standard**: Which standard it violates (if applicable) - **Recommendation**: How to fix it -- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) ### Patterns & Systemic Issues @@ -114,7 +114,7 @@ List recommended commands in priority order (P0 first, then P1, then P2): 1. **[P?] `/command-name`** — Brief description (specific context from audit findings) 2. **[P?] `/command-name`** — Brief description (specific context) -**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. +**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. After presenting the summary, tell the user: diff --git a/.opencode/skills/impeccable/reference/critique.md b/.opencode/skills/impeccable/reference/critique.md index b6d5084d0..01aeb7a9f 100644 --- a/.opencode/skills/impeccable/reference/critique.md +++ b/.opencode/skills/impeccable/reference/critique.md @@ -132,7 +132,7 @@ For each issue, tag with **P0-P3 severity** (consult [heuristics-scoring](heuris - **[P?] What**: Name the problem clearly - **Why it matters**: How this hurts users or undermines goals - **Fix**: What to do about it (be concrete) -- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) #### Persona Red Flags > *Consult [personas](personas.md)* @@ -197,7 +197,7 @@ List recommended commands in priority order, based on the user's answers: ... **Rules for recommendations**: -- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset +- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset - Order by the user's stated priorities first, then by impact - Each item's description should carry enough context that the command knows what to focus on - Map each Priority Issue to the appropriate command diff --git a/.opencode/skills/impeccable/reference/document.md b/.opencode/skills/impeccable/reference/document.md new file mode 100644 index 000000000..ade0b5682 --- /dev/null +++ b/.opencode/skills/impeccable/reference/document.md @@ -0,0 +1,126 @@ +Generate a DESIGN.md file in the project root that captures the current visual design system, so AI agents generating new screens stay on-brand. + +DESIGN.md follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/): a single markdown file at the project root with five fixed sections describing colors, typography, components, layout, and overall atmosphere. Keep section headers exactly as specified so the file stays compatible with other DESIGN.md-aware tools. + +## When to run + +- The user just ran `/impeccable teach` and needs the visual side documented. +- The skill noticed no `DESIGN.md` exists and nudged the user to create one. +- An existing `DESIGN.md` is stale (the design has drifted). +- Before a large redesign, to capture the current state as a reference. + +If a `DESIGN.md` already exists, **do not silently overwrite it**. Show the user the existing file and STOP and call the `question` tool to clarify. whether to refresh it, overwrite it, or merge into it. + +## Process (approach C: auto-extract, then confirm descriptive language) + +### Step 1: Find the design assets + +Search the codebase in priority order: + +1. **CSS custom properties** — grep for `--color-`, `--font-`, `--spacing-`, `--radius-`, `--shadow-`, `--ease-`, `--duration-` declarations in CSS files (usually `src/styles/`, `public/css/`, `app/globals.css`, etc.). Record name, value, and the file it's defined in. +2. **Tailwind config** — if `tailwind.config.{js,ts,mjs}` exists, read the `theme.extend` block for colors, fontFamily, spacing, borderRadius, boxShadow. +3. **CSS-in-JS theme files** — if the project uses styled-components, emotion, vanilla-extract, stitches, etc., look for `theme.ts`, `tokens.ts`, or equivalent. +4. **Design token files** — `tokens.json`, `design-tokens.json`, Style Dictionary output, W3C token community group format. +5. **Component library** — scan the main button, card, input, navigation, dialog components. Note their variant APIs and default styles. +6. **Global stylesheet** — the root CSS file usually has the base typography and color assignments. +7. **Visible rendered output** — if browser automation tools are available, load the live site and sample computed styles from key elements (body, h1, a, button, .card). This catches values that tokens miss. + +### Step 2: Auto-extract what can be auto-extracted + +Build a structured draft from the discovered tokens. For each token class: + +- **Colors**: Group by hue family. Convert hex → OKLCH to infer lightness/chroma. Identify background vs. text vs. accent by usage patterns in CSS (`background`, `color`, `border`, `fill`). Flag any that are only used once (possibly one-off, not system tokens). +- **Typography**: Extract font families and their declared stacks. Extract the scale (all `font-size` values used in CSS custom props + component styles). Extract weights actually used. Detect the scale ratio (1.125, 1.2, 1.25, 1.333, 1.5, golden). +- **Spacing**: Extract the scale, detect the base unit (4px, 8px, other). +- **Radii & shadows**: List the values used. +- **Components**: For each common component (button, card, input, nav, dialog), extract shape (radius), color assignment, hover/focus treatment, internal padding. + +### Step 3: Ask the user for qualitative language + +The following sections require creative input that cannot be auto-extracted reliably. STOP and call the `question` tool to clarify. for each (group them into one interaction if possible): + +- **Visual Theme & Atmosphere**: mood adjectives (airy/dense, minimal/maximalist, editorial/utilitarian, warm/clinical), aesthetic philosophy in 2-3 sentences, key characteristics as a bullet list. +- **Color character** (for auto-extracted colors): descriptive names ("Deep Muted Teal-Navy", not "blue-800"). Suggest 2-3 options per color based on the hue/saturation, let the user pick. +- **Typographic character**: describe the font pairing ("Modern geometric sans-serif with humanist warmth" > "Manrope 500"). Describe letter-spacing strategy. +- **Spacing philosophy**: 1-2 sentences on whitespace strategy ("generous breathing room that prioritizes photography"). +- **Component philosophy**: brief description of the feel of buttons, cards, inputs ("refined and understated" vs. "tactile and confident"). + +If the user has a `PRODUCT.md` that covers brand personality, quote a line from it so they see their own strategic language carry over. + +### Step 4: Write DESIGN.md + +Use this exact structure (section headers must match the Google spec character-for-character): + +```markdown +# Design System: [Project Title] +**Project ID:** [optional — only if a Stitch project ID exists] + +## 1. Visual Theme & Atmosphere + +[2-3 paragraph description using evocative adjectives. Start with the overall sanctuary/laboratory/workshop/stage analogy if one fits. End with a short **Key Characteristics:** bullet list.] + +## 2. Color Palette & Roles + +### [Semantic group name: Primary Foundation, Accent & Interactive, Typography & Text Hierarchy, Functional States, etc.] +- **[Descriptive Name]** (#HEX) – [Functional role. Where/why it's used.] + +## 3. Typography Rules + +**Primary Font Family:** [Name] +**Character:** [1-sentence personality description.] + +### Hierarchy & Weights +- **[Role (e.g. Display Headlines H1)]:** [Weight] weight ([num]), [letter-spacing], [size]. [Purpose.] + +### Spacing Principles +[Short list of rules about leading, letter-spacing, vertical rhythm.] + +## 4. Component Stylings + +### Buttons +- **Shape:** [radius description with px value in parens] +- **Primary CTA:** [color assignment + padding] +- **Hover State:** [transition description] +- **Focus State:** [accessibility treatment] +- **Secondary CTA (if applicable):** [description] + +### Cards & Containers +- **Corner Style:** [description] +- **Background:** [colors used] +- **Shadow Strategy:** [flat / soft / heavy] +- **Border:** [if any] +- **Internal Padding:** [scale] +- **Image Treatment:** [if relevant] + +### Navigation +- [Style, typography, default/hover/active states, mobile treatment] + +### Inputs/Forms +- [Stroke style, background, focus treatment] + +## 5. Layout Principles + +[Paragraph or short list describing whitespace strategy, margin scale, grid system, responsive breakpoints. Include px/rem values in parens.] +``` + +### Step 5: Write & confirm + +1. Write the file to `PROJECT_ROOT/DESIGN.md` (uppercase, at root). +2. Show the user the full DESIGN.md you wrote, briefly highlighting the non-obvious creative choices (descriptive color names, atmosphere language). +3. Offer to refine any section: "Want me to revise a section, add component patterns I missed, or adjust the atmosphere language?" + +## Style guidelines + +- **Descriptive > technical**: "Gently curved edges (8px radius)" > "rounded-lg". Include the technical value in parens, lead with the description. +- **Functional > decorative**: for each token, explain WHERE and WHY it's used, not just WHAT it is. +- **Exact values in parens**: hex codes, px/rem values, font weights — always the number in parens alongside the description. +- **Group colors semantically**: Foundation (backgrounds), Accent (interactive), Typography (text hierarchy), States (success/warning/error), not hex-sorted. +- **Reference the user's domain**: if the project is a DEX, say "trading-focused"; if it's a CMS, say "editorial". Domain-aware language helps agents pick sensible defaults. + +## Pitfalls + +- Don't paste raw CSS class names. Translate to descriptive language. +- Don't extract every token. Stop at what's actually reused — one-offs pollute the system. +- Don't invent components that don't exist. If the project only has buttons and cards, only document those. +- Don't overwrite an existing DESIGN.md without asking. +- Don't duplicate content from PRODUCT.md. DESIGN.md is strictly visual. diff --git a/.opencode/skills/impeccable/reference/live.md b/.opencode/skills/impeccable/reference/live.md index 3388e1897..19c16fa38 100644 --- a/.opencode/skills/impeccable/reference/live.md +++ b/.opencode/skills/impeccable/reference/live.md @@ -21,12 +21,21 @@ Output JSON: "serverPort": 8400, "serverToken": "...", "pageFile": "public/index.html", - "hasContext": true, - "context": "...full .impeccable.md contents..." + "hasProduct": true, + "product": "...full PRODUCT.md contents...", + "productPath": "PRODUCT.md", + "hasDesign": true, + "design": "...full DESIGN.md contents...", + "designPath": "DESIGN.md", + "migrated": false } ``` -Keep the `context` in mind for variant generation. If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. +Keep **PRODUCT.md** (strategic: users, brand, principles) and **DESIGN.md** (visual: colors, typography, components) in mind for variant generation. **DESIGN.md wins on visual decisions; PRODUCT.md wins on strategic/voice decisions.** + +If `migrated` is true, the loader auto-renamed legacy `.impeccable.md` to `PRODUCT.md` — mention this once to the user and suggest running `/impeccable document` to also generate a `DESIGN.md`. + +If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. ### First-time setup (config missing) diff --git a/.opencode/skills/impeccable/reference/teach.md b/.opencode/skills/impeccable/reference/teach.md index c72139b7d..86289f443 100644 --- a/.opencode/skills/impeccable/reference/teach.md +++ b/.opencode/skills/impeccable/reference/teach.md @@ -1,8 +1,31 @@ # Teach Flow -One-time setup that gathers design context for a project. Design without context produces generic output, so every other command reads this file before doing any work. +Gathers design context for a project and writes two complementary files at the project root: -## Step 1: Explore the Codebase +- **PRODUCT.md** (strategic): target users, product purpose, brand personality, anti-references, strategic design principles. Answers "who/what/why". +- **DESIGN.md** (visual): visual theme, color palette, typography, components, layout. Follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/). Answers "how it looks". + +Every other impeccable command reads these files before doing any work. + +## Step 1: Load current state + +Run the shared loader first so you know what already exists: + +```bash +node {{scripts_path}}/load-context.mjs +``` + +The output tells you whether PRODUCT.md and/or DESIGN.md already exist. If `migrated: true`, legacy `.impeccable.md` was auto-renamed to `PRODUCT.md`. Mention this once to the user. + +Decision tree: +- **Neither file exists (empty project or no context yet)**: do Steps 2-4 (write PRODUCT.md), then decide on DESIGN.md based on whether there's code to analyze. +- **PRODUCT.md exists, DESIGN.md missing**: skip to Step 5 — offer to run `/impeccable document` for DESIGN.md. +- **Both exist**: STOP and call the `question` tool to clarify. which to refresh. Skip the one the user doesn't want changed. +- **Just DESIGN.md exists (unusual)**: do Steps 2-4 to produce PRODUCT.md. + +Never silently overwrite an existing file. Always confirm first. + +## Step 2: Explore the codebase Before asking questions, thoroughly scan the project to discover what you can: @@ -13,9 +36,9 @@ Before asking questions, thoroughly scan the project to discover what you can: - **Design tokens / CSS variables**: Existing color palettes, font stacks, spacing scales - **Any style guides or brand documentation** -Note what you've learned and what remains unclear. +Note what you've learned and what remains unclear. This exploration feeds both PRODUCT.md and DESIGN.md. -## Step 2: Ask UX-Focused Questions +## Step 3: Ask strategic questions (for PRODUCT.md) STOP and call the `question` tool to clarify. Focus only on what you couldn't infer from the codebase: @@ -29,39 +52,53 @@ STOP and call the `question` tool to clarify. Focus only on what you couldn't in - Any reference sites or apps that capture the right feel? What specifically about them? - What should this explicitly NOT look like? Any anti-references? -### Aesthetic Preferences -- Any strong preferences for visual direction? (minimal, bold, elegant, playful, technical, organic, etc.) -- Light mode, dark mode, or both? -- Any colors that must be used or avoided? - ### Accessibility & Inclusion - Specific accessibility requirements? (WCAG level, known user needs) - Considerations for reduced motion, color blindness, or other accommodations? -Skip questions where the answer is already clear from the codebase exploration. +Skip questions where the answer is already clear. **Do NOT ask about colors, fonts, radii, or visual styling here** — those belong in DESIGN.md, not PRODUCT.md. -## Step 3: Write Design Context +## Step 4: Write PRODUCT.md -Synthesize your findings and the user's answers into a `## Design Context` section: +Synthesize into a strategic document: ```markdown -## Design Context +# Product -### Users +## Users [Who they are, their context, the job to be done] -### Brand Personality +## Product Purpose +[What this product does, why it exists, what success looks like] + +## Brand Personality [Voice, tone, 3-word personality, emotional goals] -### Aesthetic Direction -[Visual tone, references, anti-references, theme] +## Anti-references +[What this should NOT look like. Specific bad-example sites or patterns to avoid.] -### Design Principles -[3-5 principles derived from the conversation that should guide all design decisions] +## Design Principles +[3-5 strategic principles derived from the conversation. Principles like "practice what you preach", "editorial over marketing", "expert confidence" — NOT visual rules like "use OKLCH" or "magenta accent".] + +## Accessibility & Inclusion +[WCAG level, known user needs, considerations] ``` -Write this section to `.impeccable.md` in the project root. If the file already exists, update the Design Context section in place. +Write to `PROJECT_ROOT/PRODUCT.md`. If `.impeccable.md` existed, the loader already renamed it — merge into that content rather than starting from scratch. -Then STOP and call the `question` tool to clarify. whether they'd also like the Design Context appended to AGENTS.md. If yes, append or update the section there as well. +## Step 5: Decide on DESIGN.md -Confirm completion and summarize the key design principles that will now guide all future work. +If the project has meaningful code to analyze (CSS tokens, components, a running site), **offer to run `/impeccable document`** next: "I can also generate a DESIGN.md that captures your visual design system (colors, typography, components) so variants stay on-brand. Want to do that now?" + +If the user agrees, delegate to `/impeccable document` (load its reference and follow that flow). + +If the project is empty (no code yet, pre-implementation), skip DESIGN.md — there's nothing visual to document yet. Mention: "Once you've built some of the interface, run `/impeccable document` to generate a DESIGN.md." + +## Step 6: Confirm and wrap up + +Summarize: +- What was written (PRODUCT.md, DESIGN.md, or both) +- The 3-5 strategic principles from PRODUCT.md that will guide future work +- If DESIGN.md is pending, remind the user how to generate it later + +Optionally STOP and call the `question` tool to clarify. whether they'd like a brief summary of PRODUCT.md appended to AGENTS.md for easier agent reference. If yes, append a short **Design Context** pointer section there. diff --git a/.opencode/skills/impeccable/scripts/command-metadata.json b/.opencode/skills/impeccable/scripts/command-metadata.json index 2974e08f6..d8282689a 100644 --- a/.opencode/skills/impeccable/scripts/command-metadata.json +++ b/.opencode/skills/impeccable/scripts/command-metadata.json @@ -4,7 +4,11 @@ "argumentHint": "[feature description]" }, "teach": { - "description": "One-time setup that gathers design context for a project. Runs a short discovery interview and writes the answers to .impeccable.md. Every other command reads this file before doing work. Use once per project.", + "description": "Gathers design context for a project. Runs a short discovery interview and writes PRODUCT.md (strategic: users, brand, principles) and, when code exists to analyze, DESIGN.md (visual: colors, typography, components). Every other command reads these files before doing work. Use once per project.", + "argumentHint": "" + }, + "document": { + "description": "Generate a DESIGN.md file that captures the current visual design system. Auto-extracts colors, typography, spacing, radii, and component patterns from the codebase, then asks the user to confirm descriptive language for atmosphere and color character. Follows the Google Stitch DESIGN.md format so the file is tool-compatible. Use when you need a visual design spec an AI agent can follow to stay on-brand.", "argumentHint": "" }, "extract": { diff --git a/.opencode/skills/impeccable/scripts/live.mjs b/.opencode/skills/impeccable/scripts/live.mjs index 93f05456e..37b6f8997 100644 --- a/.opencode/skills/impeccable/scripts/live.mjs +++ b/.opencode/skills/impeccable/scripts/live.mjs @@ -21,10 +21,10 @@ import { execSync } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { loadContext } from './load-context.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const PID_FILE = path.join(process.cwd(), '.impeccable-live.json'); -const CONTEXT_FILE = path.join(process.cwd(), '.impeccable.md'); async function liveCli() { const args = process.argv.slice(2); @@ -79,9 +79,8 @@ The agent should then: process.exit(1); } - // 4. Load design context if available - let context = null; - try { context = fs.readFileSync(CONTEXT_FILE, 'utf-8'); } catch { /* optional */ } + // 4. Load PRODUCT.md + DESIGN.md context (auto-migrates legacy .impeccable.md) + const ctx = loadContext(process.cwd()); // 5. Emit everything the agent needs console.log(JSON.stringify({ @@ -89,8 +88,13 @@ The agent should then: serverPort: serverInfo.port, serverToken: serverInfo.token, pageFile: checkResult.config.file, - hasContext: !!context, - context, + hasProduct: ctx.hasProduct, + product: ctx.product, + productPath: ctx.productPath, + hasDesign: ctx.hasDesign, + design: ctx.design, + designPath: ctx.designPath, + migrated: ctx.migrated, }, null, 2)); } diff --git a/.opencode/skills/impeccable/scripts/load-context.mjs b/.opencode/skills/impeccable/scripts/load-context.mjs new file mode 100644 index 000000000..ab3be08f1 --- /dev/null +++ b/.opencode/skills/impeccable/scripts/load-context.mjs @@ -0,0 +1,93 @@ +/** + * Shared context loader for every impeccable command that needs to know + * "who is this for" and "what does this look like". + * + * Input: project root (process.cwd()). + * + * Output (JSON to stdout): + * { + * hasProduct: boolean, // PRODUCT.md found (or auto-migrated) + * product: string | null, // PRODUCT.md contents + * productPath: string | null, // relative path + * hasDesign: boolean, // DESIGN.md found + * design: string | null, // DESIGN.md contents + * designPath: string | null, + * migrated: boolean, // true if we auto-renamed .impeccable.md -> PRODUCT.md + * } + * + * Filename matching is case-insensitive for PRODUCT.md and DESIGN.md. The + * Google DESIGN.md convention is uppercase at repo root; Kiro-style and + * lowercase variants are also matched so users don't get punished for case. + */ + +import fs from 'node:fs'; +import path from 'node:path'; + +const PRODUCT_NAMES = ['PRODUCT.md', 'Product.md', 'product.md']; +const DESIGN_NAMES = ['DESIGN.md', 'Design.md', 'design.md']; +const LEGACY_NAMES = ['.impeccable.md']; + +export function loadContext(cwd = process.cwd()) { + let migrated = false; + + // 1. Look for PRODUCT.md (case-insensitive) + let productPath = firstExisting(cwd, PRODUCT_NAMES); + + // 2. Legacy: if no PRODUCT.md but .impeccable.md exists, rename in place + if (!productPath) { + const legacyPath = firstExisting(cwd, LEGACY_NAMES); + if (legacyPath) { + const newPath = path.join(cwd, 'PRODUCT.md'); + try { + fs.renameSync(legacyPath, newPath); + productPath = newPath; + migrated = true; + } catch { + // Rename failed (permissions, etc.) — fall back to reading legacy in place + productPath = legacyPath; + } + } + } + + // 3. DESIGN.md (case-insensitive) + const designPath = firstExisting(cwd, DESIGN_NAMES); + + const product = productPath ? safeRead(productPath) : null; + const design = designPath ? safeRead(designPath) : null; + + return { + hasProduct: !!product, + product, + productPath: productPath ? path.relative(cwd, productPath) : null, + hasDesign: !!design, + design, + designPath: designPath ? path.relative(cwd, designPath) : null, + migrated, + }; +} + +function firstExisting(cwd, names) { + for (const name of names) { + const abs = path.join(cwd, name); + if (fs.existsSync(abs)) return abs; + } + return null; +} + +function safeRead(p) { + try { return fs.readFileSync(p, 'utf-8'); } catch { return null; } +} + +// --------------------------------------------------------------------------- +// CLI mode — print the context as JSON +// --------------------------------------------------------------------------- + +function cli() { + const result = loadContext(process.cwd()); + console.log(JSON.stringify(result, null, 2)); +} + +const _running = process.argv[1]; +if (_running?.endsWith('load-context.mjs') || _running?.endsWith('load-context.mjs/')) { + cli(); +} diff --git a/.opencode/skills/impeccable/scripts/pin.mjs b/.opencode/skills/impeccable/scripts/pin.mjs index 89a6babeb..ba02783fb 100644 --- a/.opencode/skills/impeccable/scripts/pin.mjs +++ b/.opencode/skills/impeccable/scripts/pin.mjs @@ -27,7 +27,7 @@ const HARNESS_DIRS = [ // Valid sub-command names const VALID_COMMANDS = [ - 'craft', 'teach', 'extract', 'shape', + 'craft', 'teach', 'extract', 'document', 'shape', 'critique', 'audit', 'polish', 'bolder', 'quieter', 'distill', 'harden', 'onboard', 'live', 'animate', 'colorize', 'typeset', 'layout', 'delight', 'overdrive', diff --git a/.pi/skills/impeccable/SKILL.md b/.pi/skills/impeccable/SKILL.md index d3806155c..ea013a9bb 100644 --- a/.pi/skills/impeccable/SKILL.md +++ b/.pi/skills/impeccable/SKILL.md @@ -29,10 +29,17 @@ After running the script, delete this entire section (from ` **Build & Plan** > `/impeccable craft [feature]` - Shape, then build a feature end-to-end > `/impeccable shape [feature]` - Plan UX/UI before writing code -> `/impeccable teach` - Set up design context for this project (one-time) +> `/impeccable teach` - Set up PRODUCT.md and DESIGN.md context for this project +> `/impeccable document` - Generate DESIGN.md from existing project code > `/impeccable extract [target]` - Pull reusable tokens and components into design system > > **Evaluate** @@ -347,6 +355,7 @@ When a sub-command is matched, load the linked reference and follow its instruct | `craft` | [craft](reference/craft.md) | Full shape-then-build flow with visual iteration | | `teach` | [teach](reference/teach.md) | One-time setup: gather design context for the project | | `extract` | [extract](reference/extract.md) | Pull reusable tokens and components into design system | +| `document` | [document](reference/document.md) | Generate DESIGN.md from existing project code (visual design system doc) | | `shape` | [shape](reference/shape.md) | Plan UX and UI before writing code (produces a design brief) | | `critique` | [critique](reference/critique.md) | UX design review with heuristic scoring and persona testing | | `audit` | [audit](reference/audit.md) | Technical quality checks across a11y, perf, theming, responsive, anti-patterns | diff --git a/.pi/skills/impeccable/reference/audit.md b/.pi/skills/impeccable/reference/audit.md index bbba2401b..c2258ac54 100644 --- a/.pi/skills/impeccable/reference/audit.md +++ b/.pi/skills/impeccable/reference/audit.md @@ -95,7 +95,7 @@ For each issue, document: - **Impact**: How it affects users - **WCAG/Standard**: Which standard it violates (if applicable) - **Recommendation**: How to fix it -- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) ### Patterns & Systemic Issues @@ -114,7 +114,7 @@ List recommended commands in priority order (P0 first, then P1, then P2): 1. **[P?] `/command-name`** — Brief description (specific context from audit findings) 2. **[P?] `/command-name`** — Brief description (specific context) -**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. +**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. After presenting the summary, tell the user: diff --git a/.pi/skills/impeccable/reference/critique.md b/.pi/skills/impeccable/reference/critique.md index f59217dea..8da3afebb 100644 --- a/.pi/skills/impeccable/reference/critique.md +++ b/.pi/skills/impeccable/reference/critique.md @@ -132,7 +132,7 @@ For each issue, tag with **P0-P3 severity** (consult [heuristics-scoring](heuris - **[P?] What**: Name the problem clearly - **Why it matters**: How this hurts users or undermines goals - **Fix**: What to do about it (be concrete) -- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) #### Persona Red Flags > *Consult [personas](personas.md)* @@ -197,7 +197,7 @@ List recommended commands in priority order, based on the user's answers: ... **Rules for recommendations**: -- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset +- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset - Order by the user's stated priorities first, then by impact - Each item's description should carry enough context that the command knows what to focus on - Map each Priority Issue to the appropriate command diff --git a/.pi/skills/impeccable/reference/document.md b/.pi/skills/impeccable/reference/document.md new file mode 100644 index 000000000..ebf90bbf3 --- /dev/null +++ b/.pi/skills/impeccable/reference/document.md @@ -0,0 +1,126 @@ +Generate a DESIGN.md file in the project root that captures the current visual design system, so AI agents generating new screens stay on-brand. + +DESIGN.md follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/): a single markdown file at the project root with five fixed sections describing colors, typography, components, layout, and overall atmosphere. Keep section headers exactly as specified so the file stays compatible with other DESIGN.md-aware tools. + +## When to run + +- The user just ran `/impeccable teach` and needs the visual side documented. +- The skill noticed no `DESIGN.md` exists and nudged the user to create one. +- An existing `DESIGN.md` is stale (the design has drifted). +- Before a large redesign, to capture the current state as a reference. + +If a `DESIGN.md` already exists, **do not silently overwrite it**. Show the user the existing file and ask the user directly to clarify what you cannot infer. whether to refresh it, overwrite it, or merge into it. + +## Process (approach C: auto-extract, then confirm descriptive language) + +### Step 1: Find the design assets + +Search the codebase in priority order: + +1. **CSS custom properties** — grep for `--color-`, `--font-`, `--spacing-`, `--radius-`, `--shadow-`, `--ease-`, `--duration-` declarations in CSS files (usually `src/styles/`, `public/css/`, `app/globals.css`, etc.). Record name, value, and the file it's defined in. +2. **Tailwind config** — if `tailwind.config.{js,ts,mjs}` exists, read the `theme.extend` block for colors, fontFamily, spacing, borderRadius, boxShadow. +3. **CSS-in-JS theme files** — if the project uses styled-components, emotion, vanilla-extract, stitches, etc., look for `theme.ts`, `tokens.ts`, or equivalent. +4. **Design token files** — `tokens.json`, `design-tokens.json`, Style Dictionary output, W3C token community group format. +5. **Component library** — scan the main button, card, input, navigation, dialog components. Note their variant APIs and default styles. +6. **Global stylesheet** — the root CSS file usually has the base typography and color assignments. +7. **Visible rendered output** — if browser automation tools are available, load the live site and sample computed styles from key elements (body, h1, a, button, .card). This catches values that tokens miss. + +### Step 2: Auto-extract what can be auto-extracted + +Build a structured draft from the discovered tokens. For each token class: + +- **Colors**: Group by hue family. Convert hex → OKLCH to infer lightness/chroma. Identify background vs. text vs. accent by usage patterns in CSS (`background`, `color`, `border`, `fill`). Flag any that are only used once (possibly one-off, not system tokens). +- **Typography**: Extract font families and their declared stacks. Extract the scale (all `font-size` values used in CSS custom props + component styles). Extract weights actually used. Detect the scale ratio (1.125, 1.2, 1.25, 1.333, 1.5, golden). +- **Spacing**: Extract the scale, detect the base unit (4px, 8px, other). +- **Radii & shadows**: List the values used. +- **Components**: For each common component (button, card, input, nav, dialog), extract shape (radius), color assignment, hover/focus treatment, internal padding. + +### Step 3: Ask the user for qualitative language + +The following sections require creative input that cannot be auto-extracted reliably. ask the user directly to clarify what you cannot infer. for each (group them into one interaction if possible): + +- **Visual Theme & Atmosphere**: mood adjectives (airy/dense, minimal/maximalist, editorial/utilitarian, warm/clinical), aesthetic philosophy in 2-3 sentences, key characteristics as a bullet list. +- **Color character** (for auto-extracted colors): descriptive names ("Deep Muted Teal-Navy", not "blue-800"). Suggest 2-3 options per color based on the hue/saturation, let the user pick. +- **Typographic character**: describe the font pairing ("Modern geometric sans-serif with humanist warmth" > "Manrope 500"). Describe letter-spacing strategy. +- **Spacing philosophy**: 1-2 sentences on whitespace strategy ("generous breathing room that prioritizes photography"). +- **Component philosophy**: brief description of the feel of buttons, cards, inputs ("refined and understated" vs. "tactile and confident"). + +If the user has a `PRODUCT.md` that covers brand personality, quote a line from it so they see their own strategic language carry over. + +### Step 4: Write DESIGN.md + +Use this exact structure (section headers must match the Google spec character-for-character): + +```markdown +# Design System: [Project Title] +**Project ID:** [optional — only if a Stitch project ID exists] + +## 1. Visual Theme & Atmosphere + +[2-3 paragraph description using evocative adjectives. Start with the overall sanctuary/laboratory/workshop/stage analogy if one fits. End with a short **Key Characteristics:** bullet list.] + +## 2. Color Palette & Roles + +### [Semantic group name: Primary Foundation, Accent & Interactive, Typography & Text Hierarchy, Functional States, etc.] +- **[Descriptive Name]** (#HEX) – [Functional role. Where/why it's used.] + +## 3. Typography Rules + +**Primary Font Family:** [Name] +**Character:** [1-sentence personality description.] + +### Hierarchy & Weights +- **[Role (e.g. Display Headlines H1)]:** [Weight] weight ([num]), [letter-spacing], [size]. [Purpose.] + +### Spacing Principles +[Short list of rules about leading, letter-spacing, vertical rhythm.] + +## 4. Component Stylings + +### Buttons +- **Shape:** [radius description with px value in parens] +- **Primary CTA:** [color assignment + padding] +- **Hover State:** [transition description] +- **Focus State:** [accessibility treatment] +- **Secondary CTA (if applicable):** [description] + +### Cards & Containers +- **Corner Style:** [description] +- **Background:** [colors used] +- **Shadow Strategy:** [flat / soft / heavy] +- **Border:** [if any] +- **Internal Padding:** [scale] +- **Image Treatment:** [if relevant] + +### Navigation +- [Style, typography, default/hover/active states, mobile treatment] + +### Inputs/Forms +- [Stroke style, background, focus treatment] + +## 5. Layout Principles + +[Paragraph or short list describing whitespace strategy, margin scale, grid system, responsive breakpoints. Include px/rem values in parens.] +``` + +### Step 5: Write & confirm + +1. Write the file to `PROJECT_ROOT/DESIGN.md` (uppercase, at root). +2. Show the user the full DESIGN.md you wrote, briefly highlighting the non-obvious creative choices (descriptive color names, atmosphere language). +3. Offer to refine any section: "Want me to revise a section, add component patterns I missed, or adjust the atmosphere language?" + +## Style guidelines + +- **Descriptive > technical**: "Gently curved edges (8px radius)" > "rounded-lg". Include the technical value in parens, lead with the description. +- **Functional > decorative**: for each token, explain WHERE and WHY it's used, not just WHAT it is. +- **Exact values in parens**: hex codes, px/rem values, font weights — always the number in parens alongside the description. +- **Group colors semantically**: Foundation (backgrounds), Accent (interactive), Typography (text hierarchy), States (success/warning/error), not hex-sorted. +- **Reference the user's domain**: if the project is a DEX, say "trading-focused"; if it's a CMS, say "editorial". Domain-aware language helps agents pick sensible defaults. + +## Pitfalls + +- Don't paste raw CSS class names. Translate to descriptive language. +- Don't extract every token. Stop at what's actually reused — one-offs pollute the system. +- Don't invent components that don't exist. If the project only has buttons and cards, only document those. +- Don't overwrite an existing DESIGN.md without asking. +- Don't duplicate content from PRODUCT.md. DESIGN.md is strictly visual. diff --git a/.pi/skills/impeccable/reference/live.md b/.pi/skills/impeccable/reference/live.md index 3388e1897..19c16fa38 100644 --- a/.pi/skills/impeccable/reference/live.md +++ b/.pi/skills/impeccable/reference/live.md @@ -21,12 +21,21 @@ Output JSON: "serverPort": 8400, "serverToken": "...", "pageFile": "public/index.html", - "hasContext": true, - "context": "...full .impeccable.md contents..." + "hasProduct": true, + "product": "...full PRODUCT.md contents...", + "productPath": "PRODUCT.md", + "hasDesign": true, + "design": "...full DESIGN.md contents...", + "designPath": "DESIGN.md", + "migrated": false } ``` -Keep the `context` in mind for variant generation. If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. +Keep **PRODUCT.md** (strategic: users, brand, principles) and **DESIGN.md** (visual: colors, typography, components) in mind for variant generation. **DESIGN.md wins on visual decisions; PRODUCT.md wins on strategic/voice decisions.** + +If `migrated` is true, the loader auto-renamed legacy `.impeccable.md` to `PRODUCT.md` — mention this once to the user and suggest running `/impeccable document` to also generate a `DESIGN.md`. + +If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. ### First-time setup (config missing) diff --git a/.pi/skills/impeccable/reference/teach.md b/.pi/skills/impeccable/reference/teach.md index 2d9f768f1..b436efa20 100644 --- a/.pi/skills/impeccable/reference/teach.md +++ b/.pi/skills/impeccable/reference/teach.md @@ -1,8 +1,31 @@ # Teach Flow -One-time setup that gathers design context for a project. Design without context produces generic output, so every other command reads this file before doing any work. +Gathers design context for a project and writes two complementary files at the project root: -## Step 1: Explore the Codebase +- **PRODUCT.md** (strategic): target users, product purpose, brand personality, anti-references, strategic design principles. Answers "who/what/why". +- **DESIGN.md** (visual): visual theme, color palette, typography, components, layout. Follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/). Answers "how it looks". + +Every other impeccable command reads these files before doing any work. + +## Step 1: Load current state + +Run the shared loader first so you know what already exists: + +```bash +node {{scripts_path}}/load-context.mjs +``` + +The output tells you whether PRODUCT.md and/or DESIGN.md already exist. If `migrated: true`, legacy `.impeccable.md` was auto-renamed to `PRODUCT.md`. Mention this once to the user. + +Decision tree: +- **Neither file exists (empty project or no context yet)**: do Steps 2-4 (write PRODUCT.md), then decide on DESIGN.md based on whether there's code to analyze. +- **PRODUCT.md exists, DESIGN.md missing**: skip to Step 5 — offer to run `/impeccable document` for DESIGN.md. +- **Both exist**: ask the user directly to clarify what you cannot infer. which to refresh. Skip the one the user doesn't want changed. +- **Just DESIGN.md exists (unusual)**: do Steps 2-4 to produce PRODUCT.md. + +Never silently overwrite an existing file. Always confirm first. + +## Step 2: Explore the codebase Before asking questions, thoroughly scan the project to discover what you can: @@ -13,9 +36,9 @@ Before asking questions, thoroughly scan the project to discover what you can: - **Design tokens / CSS variables**: Existing color palettes, font stacks, spacing scales - **Any style guides or brand documentation** -Note what you've learned and what remains unclear. +Note what you've learned and what remains unclear. This exploration feeds both PRODUCT.md and DESIGN.md. -## Step 2: Ask UX-Focused Questions +## Step 3: Ask strategic questions (for PRODUCT.md) ask the user directly to clarify what you cannot infer. Focus only on what you couldn't infer from the codebase: @@ -29,39 +52,53 @@ ask the user directly to clarify what you cannot infer. Focus only on what you c - Any reference sites or apps that capture the right feel? What specifically about them? - What should this explicitly NOT look like? Any anti-references? -### Aesthetic Preferences -- Any strong preferences for visual direction? (minimal, bold, elegant, playful, technical, organic, etc.) -- Light mode, dark mode, or both? -- Any colors that must be used or avoided? - ### Accessibility & Inclusion - Specific accessibility requirements? (WCAG level, known user needs) - Considerations for reduced motion, color blindness, or other accommodations? -Skip questions where the answer is already clear from the codebase exploration. +Skip questions where the answer is already clear. **Do NOT ask about colors, fonts, radii, or visual styling here** — those belong in DESIGN.md, not PRODUCT.md. -## Step 3: Write Design Context +## Step 4: Write PRODUCT.md -Synthesize your findings and the user's answers into a `## Design Context` section: +Synthesize into a strategic document: ```markdown -## Design Context +# Product -### Users +## Users [Who they are, their context, the job to be done] -### Brand Personality +## Product Purpose +[What this product does, why it exists, what success looks like] + +## Brand Personality [Voice, tone, 3-word personality, emotional goals] -### Aesthetic Direction -[Visual tone, references, anti-references, theme] +## Anti-references +[What this should NOT look like. Specific bad-example sites or patterns to avoid.] -### Design Principles -[3-5 principles derived from the conversation that should guide all design decisions] +## Design Principles +[3-5 strategic principles derived from the conversation. Principles like "practice what you preach", "editorial over marketing", "expert confidence" — NOT visual rules like "use OKLCH" or "magenta accent".] + +## Accessibility & Inclusion +[WCAG level, known user needs, considerations] ``` -Write this section to `.impeccable.md` in the project root. If the file already exists, update the Design Context section in place. +Write to `PROJECT_ROOT/PRODUCT.md`. If `.impeccable.md` existed, the loader already renamed it — merge into that content rather than starting from scratch. -Then ask the user directly to clarify what you cannot infer. whether they'd also like the Design Context appended to AGENTS.md. If yes, append or update the section there as well. +## Step 5: Decide on DESIGN.md -Confirm completion and summarize the key design principles that will now guide all future work. +If the project has meaningful code to analyze (CSS tokens, components, a running site), **offer to run `/impeccable document`** next: "I can also generate a DESIGN.md that captures your visual design system (colors, typography, components) so variants stay on-brand. Want to do that now?" + +If the user agrees, delegate to `/impeccable document` (load its reference and follow that flow). + +If the project is empty (no code yet, pre-implementation), skip DESIGN.md — there's nothing visual to document yet. Mention: "Once you've built some of the interface, run `/impeccable document` to generate a DESIGN.md." + +## Step 6: Confirm and wrap up + +Summarize: +- What was written (PRODUCT.md, DESIGN.md, or both) +- The 3-5 strategic principles from PRODUCT.md that will guide future work +- If DESIGN.md is pending, remind the user how to generate it later + +Optionally ask the user directly to clarify what you cannot infer. whether they'd like a brief summary of PRODUCT.md appended to AGENTS.md for easier agent reference. If yes, append a short **Design Context** pointer section there. diff --git a/.pi/skills/impeccable/scripts/command-metadata.json b/.pi/skills/impeccable/scripts/command-metadata.json index 2974e08f6..d8282689a 100644 --- a/.pi/skills/impeccable/scripts/command-metadata.json +++ b/.pi/skills/impeccable/scripts/command-metadata.json @@ -4,7 +4,11 @@ "argumentHint": "[feature description]" }, "teach": { - "description": "One-time setup that gathers design context for a project. Runs a short discovery interview and writes the answers to .impeccable.md. Every other command reads this file before doing work. Use once per project.", + "description": "Gathers design context for a project. Runs a short discovery interview and writes PRODUCT.md (strategic: users, brand, principles) and, when code exists to analyze, DESIGN.md (visual: colors, typography, components). Every other command reads these files before doing work. Use once per project.", + "argumentHint": "" + }, + "document": { + "description": "Generate a DESIGN.md file that captures the current visual design system. Auto-extracts colors, typography, spacing, radii, and component patterns from the codebase, then asks the user to confirm descriptive language for atmosphere and color character. Follows the Google Stitch DESIGN.md format so the file is tool-compatible. Use when you need a visual design spec an AI agent can follow to stay on-brand.", "argumentHint": "" }, "extract": { diff --git a/.pi/skills/impeccable/scripts/live.mjs b/.pi/skills/impeccable/scripts/live.mjs index 93f05456e..37b6f8997 100644 --- a/.pi/skills/impeccable/scripts/live.mjs +++ b/.pi/skills/impeccable/scripts/live.mjs @@ -21,10 +21,10 @@ import { execSync } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { loadContext } from './load-context.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const PID_FILE = path.join(process.cwd(), '.impeccable-live.json'); -const CONTEXT_FILE = path.join(process.cwd(), '.impeccable.md'); async function liveCli() { const args = process.argv.slice(2); @@ -79,9 +79,8 @@ The agent should then: process.exit(1); } - // 4. Load design context if available - let context = null; - try { context = fs.readFileSync(CONTEXT_FILE, 'utf-8'); } catch { /* optional */ } + // 4. Load PRODUCT.md + DESIGN.md context (auto-migrates legacy .impeccable.md) + const ctx = loadContext(process.cwd()); // 5. Emit everything the agent needs console.log(JSON.stringify({ @@ -89,8 +88,13 @@ The agent should then: serverPort: serverInfo.port, serverToken: serverInfo.token, pageFile: checkResult.config.file, - hasContext: !!context, - context, + hasProduct: ctx.hasProduct, + product: ctx.product, + productPath: ctx.productPath, + hasDesign: ctx.hasDesign, + design: ctx.design, + designPath: ctx.designPath, + migrated: ctx.migrated, }, null, 2)); } diff --git a/.pi/skills/impeccable/scripts/load-context.mjs b/.pi/skills/impeccable/scripts/load-context.mjs new file mode 100644 index 000000000..ab3be08f1 --- /dev/null +++ b/.pi/skills/impeccable/scripts/load-context.mjs @@ -0,0 +1,93 @@ +/** + * Shared context loader for every impeccable command that needs to know + * "who is this for" and "what does this look like". + * + * Input: project root (process.cwd()). + * + * Output (JSON to stdout): + * { + * hasProduct: boolean, // PRODUCT.md found (or auto-migrated) + * product: string | null, // PRODUCT.md contents + * productPath: string | null, // relative path + * hasDesign: boolean, // DESIGN.md found + * design: string | null, // DESIGN.md contents + * designPath: string | null, + * migrated: boolean, // true if we auto-renamed .impeccable.md -> PRODUCT.md + * } + * + * Filename matching is case-insensitive for PRODUCT.md and DESIGN.md. The + * Google DESIGN.md convention is uppercase at repo root; Kiro-style and + * lowercase variants are also matched so users don't get punished for case. + */ + +import fs from 'node:fs'; +import path from 'node:path'; + +const PRODUCT_NAMES = ['PRODUCT.md', 'Product.md', 'product.md']; +const DESIGN_NAMES = ['DESIGN.md', 'Design.md', 'design.md']; +const LEGACY_NAMES = ['.impeccable.md']; + +export function loadContext(cwd = process.cwd()) { + let migrated = false; + + // 1. Look for PRODUCT.md (case-insensitive) + let productPath = firstExisting(cwd, PRODUCT_NAMES); + + // 2. Legacy: if no PRODUCT.md but .impeccable.md exists, rename in place + if (!productPath) { + const legacyPath = firstExisting(cwd, LEGACY_NAMES); + if (legacyPath) { + const newPath = path.join(cwd, 'PRODUCT.md'); + try { + fs.renameSync(legacyPath, newPath); + productPath = newPath; + migrated = true; + } catch { + // Rename failed (permissions, etc.) — fall back to reading legacy in place + productPath = legacyPath; + } + } + } + + // 3. DESIGN.md (case-insensitive) + const designPath = firstExisting(cwd, DESIGN_NAMES); + + const product = productPath ? safeRead(productPath) : null; + const design = designPath ? safeRead(designPath) : null; + + return { + hasProduct: !!product, + product, + productPath: productPath ? path.relative(cwd, productPath) : null, + hasDesign: !!design, + design, + designPath: designPath ? path.relative(cwd, designPath) : null, + migrated, + }; +} + +function firstExisting(cwd, names) { + for (const name of names) { + const abs = path.join(cwd, name); + if (fs.existsSync(abs)) return abs; + } + return null; +} + +function safeRead(p) { + try { return fs.readFileSync(p, 'utf-8'); } catch { return null; } +} + +// --------------------------------------------------------------------------- +// CLI mode — print the context as JSON +// --------------------------------------------------------------------------- + +function cli() { + const result = loadContext(process.cwd()); + console.log(JSON.stringify(result, null, 2)); +} + +const _running = process.argv[1]; +if (_running?.endsWith('load-context.mjs') || _running?.endsWith('load-context.mjs/')) { + cli(); +} diff --git a/.pi/skills/impeccable/scripts/pin.mjs b/.pi/skills/impeccable/scripts/pin.mjs index 89a6babeb..ba02783fb 100644 --- a/.pi/skills/impeccable/scripts/pin.mjs +++ b/.pi/skills/impeccable/scripts/pin.mjs @@ -27,7 +27,7 @@ const HARNESS_DIRS = [ // Valid sub-command names const VALID_COMMANDS = [ - 'craft', 'teach', 'extract', 'shape', + 'craft', 'teach', 'extract', 'document', 'shape', 'critique', 'audit', 'polish', 'bolder', 'quieter', 'distill', 'harden', 'onboard', 'live', 'animate', 'colorize', 'typeset', 'layout', 'delight', 'overdrive', diff --git a/.rovodev/skills/impeccable/SKILL.md b/.rovodev/skills/impeccable/SKILL.md index 191747dd8..e7bf70350 100644 --- a/.rovodev/skills/impeccable/SKILL.md +++ b/.rovodev/skills/impeccable/SKILL.md @@ -3,7 +3,7 @@ name: impeccable description: Use when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a frontend interface. Covers websites, landing pages, dashboards, product UI, app shells, components, forms, settings, onboarding, and empty states. Handles UX review, visual hierarchy, information architecture, cognitive load, accessibility, performance, responsive behavior, theming, anti-patterns, typography, fonts, spacing, layout, alignment, color, motion, micro-interactions, UX copy, error states, edge cases, i18n, and reusable design systems or tokens. Also use for bland designs that need to become bolder or more delightful, loud designs that should become quieter, live browser iteration on UI elements, or ambitious visual effects that should feel technically extraordinary. Not for backend-only or non-UI tasks. version: 3.0.0 user-invocable: true -argument-hint: "[craft|shape · audit|critique · animate|bolder|colorize|delight|layout|overdrive|quieter|typeset · adapt|clarify|distill · harden|onboard|optimize|polish · teach|extract|live] [target]" +argument-hint: "[craft|shape · audit|critique · animate|bolder|colorize|delight|layout|overdrive|quieter|typeset · adapt|clarify|distill · harden|onboard|optimize|polish · teach|document|extract|live] [target]" license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. allowed-tools: - Bash(npx impeccable *) @@ -31,10 +31,17 @@ After running the script, delete this entire section (from ` **Build & Plan** > `/impeccable craft [feature]` - Shape, then build a feature end-to-end > `/impeccable shape [feature]` - Plan UX/UI before writing code -> `/impeccable teach` - Set up design context for this project (one-time) +> `/impeccable teach` - Set up PRODUCT.md and DESIGN.md context for this project +> `/impeccable document` - Generate DESIGN.md from existing project code > `/impeccable extract [target]` - Pull reusable tokens and components into design system > > **Evaluate** @@ -349,6 +357,7 @@ When a sub-command is matched, load the linked reference and follow its instruct | `craft` | [craft](reference/craft.md) | Full shape-then-build flow with visual iteration | | `teach` | [teach](reference/teach.md) | One-time setup: gather design context for the project | | `extract` | [extract](reference/extract.md) | Pull reusable tokens and components into design system | +| `document` | [document](reference/document.md) | Generate DESIGN.md from existing project code (visual design system doc) | | `shape` | [shape](reference/shape.md) | Plan UX and UI before writing code (produces a design brief) | | `critique` | [critique](reference/critique.md) | UX design review with heuristic scoring and persona testing | | `audit` | [audit](reference/audit.md) | Technical quality checks across a11y, perf, theming, responsive, anti-patterns | diff --git a/.rovodev/skills/impeccable/reference/audit.md b/.rovodev/skills/impeccable/reference/audit.md index bbba2401b..c2258ac54 100644 --- a/.rovodev/skills/impeccable/reference/audit.md +++ b/.rovodev/skills/impeccable/reference/audit.md @@ -95,7 +95,7 @@ For each issue, document: - **Impact**: How it affects users - **WCAG/Standard**: Which standard it violates (if applicable) - **Recommendation**: How to fix it -- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) ### Patterns & Systemic Issues @@ -114,7 +114,7 @@ List recommended commands in priority order (P0 first, then P1, then P2): 1. **[P?] `/command-name`** — Brief description (specific context from audit findings) 2. **[P?] `/command-name`** — Brief description (specific context) -**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. +**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. After presenting the summary, tell the user: diff --git a/.rovodev/skills/impeccable/reference/critique.md b/.rovodev/skills/impeccable/reference/critique.md index f59217dea..8da3afebb 100644 --- a/.rovodev/skills/impeccable/reference/critique.md +++ b/.rovodev/skills/impeccable/reference/critique.md @@ -132,7 +132,7 @@ For each issue, tag with **P0-P3 severity** (consult [heuristics-scoring](heuris - **[P?] What**: Name the problem clearly - **Why it matters**: How this hurts users or undermines goals - **Fix**: What to do about it (be concrete) -- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) #### Persona Red Flags > *Consult [personas](personas.md)* @@ -197,7 +197,7 @@ List recommended commands in priority order, based on the user's answers: ... **Rules for recommendations**: -- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset +- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset - Order by the user's stated priorities first, then by impact - Each item's description should carry enough context that the command knows what to focus on - Map each Priority Issue to the appropriate command diff --git a/.rovodev/skills/impeccable/reference/document.md b/.rovodev/skills/impeccable/reference/document.md new file mode 100644 index 000000000..ebf90bbf3 --- /dev/null +++ b/.rovodev/skills/impeccable/reference/document.md @@ -0,0 +1,126 @@ +Generate a DESIGN.md file in the project root that captures the current visual design system, so AI agents generating new screens stay on-brand. + +DESIGN.md follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/): a single markdown file at the project root with five fixed sections describing colors, typography, components, layout, and overall atmosphere. Keep section headers exactly as specified so the file stays compatible with other DESIGN.md-aware tools. + +## When to run + +- The user just ran `/impeccable teach` and needs the visual side documented. +- The skill noticed no `DESIGN.md` exists and nudged the user to create one. +- An existing `DESIGN.md` is stale (the design has drifted). +- Before a large redesign, to capture the current state as a reference. + +If a `DESIGN.md` already exists, **do not silently overwrite it**. Show the user the existing file and ask the user directly to clarify what you cannot infer. whether to refresh it, overwrite it, or merge into it. + +## Process (approach C: auto-extract, then confirm descriptive language) + +### Step 1: Find the design assets + +Search the codebase in priority order: + +1. **CSS custom properties** — grep for `--color-`, `--font-`, `--spacing-`, `--radius-`, `--shadow-`, `--ease-`, `--duration-` declarations in CSS files (usually `src/styles/`, `public/css/`, `app/globals.css`, etc.). Record name, value, and the file it's defined in. +2. **Tailwind config** — if `tailwind.config.{js,ts,mjs}` exists, read the `theme.extend` block for colors, fontFamily, spacing, borderRadius, boxShadow. +3. **CSS-in-JS theme files** — if the project uses styled-components, emotion, vanilla-extract, stitches, etc., look for `theme.ts`, `tokens.ts`, or equivalent. +4. **Design token files** — `tokens.json`, `design-tokens.json`, Style Dictionary output, W3C token community group format. +5. **Component library** — scan the main button, card, input, navigation, dialog components. Note their variant APIs and default styles. +6. **Global stylesheet** — the root CSS file usually has the base typography and color assignments. +7. **Visible rendered output** — if browser automation tools are available, load the live site and sample computed styles from key elements (body, h1, a, button, .card). This catches values that tokens miss. + +### Step 2: Auto-extract what can be auto-extracted + +Build a structured draft from the discovered tokens. For each token class: + +- **Colors**: Group by hue family. Convert hex → OKLCH to infer lightness/chroma. Identify background vs. text vs. accent by usage patterns in CSS (`background`, `color`, `border`, `fill`). Flag any that are only used once (possibly one-off, not system tokens). +- **Typography**: Extract font families and their declared stacks. Extract the scale (all `font-size` values used in CSS custom props + component styles). Extract weights actually used. Detect the scale ratio (1.125, 1.2, 1.25, 1.333, 1.5, golden). +- **Spacing**: Extract the scale, detect the base unit (4px, 8px, other). +- **Radii & shadows**: List the values used. +- **Components**: For each common component (button, card, input, nav, dialog), extract shape (radius), color assignment, hover/focus treatment, internal padding. + +### Step 3: Ask the user for qualitative language + +The following sections require creative input that cannot be auto-extracted reliably. ask the user directly to clarify what you cannot infer. for each (group them into one interaction if possible): + +- **Visual Theme & Atmosphere**: mood adjectives (airy/dense, minimal/maximalist, editorial/utilitarian, warm/clinical), aesthetic philosophy in 2-3 sentences, key characteristics as a bullet list. +- **Color character** (for auto-extracted colors): descriptive names ("Deep Muted Teal-Navy", not "blue-800"). Suggest 2-3 options per color based on the hue/saturation, let the user pick. +- **Typographic character**: describe the font pairing ("Modern geometric sans-serif with humanist warmth" > "Manrope 500"). Describe letter-spacing strategy. +- **Spacing philosophy**: 1-2 sentences on whitespace strategy ("generous breathing room that prioritizes photography"). +- **Component philosophy**: brief description of the feel of buttons, cards, inputs ("refined and understated" vs. "tactile and confident"). + +If the user has a `PRODUCT.md` that covers brand personality, quote a line from it so they see their own strategic language carry over. + +### Step 4: Write DESIGN.md + +Use this exact structure (section headers must match the Google spec character-for-character): + +```markdown +# Design System: [Project Title] +**Project ID:** [optional — only if a Stitch project ID exists] + +## 1. Visual Theme & Atmosphere + +[2-3 paragraph description using evocative adjectives. Start with the overall sanctuary/laboratory/workshop/stage analogy if one fits. End with a short **Key Characteristics:** bullet list.] + +## 2. Color Palette & Roles + +### [Semantic group name: Primary Foundation, Accent & Interactive, Typography & Text Hierarchy, Functional States, etc.] +- **[Descriptive Name]** (#HEX) – [Functional role. Where/why it's used.] + +## 3. Typography Rules + +**Primary Font Family:** [Name] +**Character:** [1-sentence personality description.] + +### Hierarchy & Weights +- **[Role (e.g. Display Headlines H1)]:** [Weight] weight ([num]), [letter-spacing], [size]. [Purpose.] + +### Spacing Principles +[Short list of rules about leading, letter-spacing, vertical rhythm.] + +## 4. Component Stylings + +### Buttons +- **Shape:** [radius description with px value in parens] +- **Primary CTA:** [color assignment + padding] +- **Hover State:** [transition description] +- **Focus State:** [accessibility treatment] +- **Secondary CTA (if applicable):** [description] + +### Cards & Containers +- **Corner Style:** [description] +- **Background:** [colors used] +- **Shadow Strategy:** [flat / soft / heavy] +- **Border:** [if any] +- **Internal Padding:** [scale] +- **Image Treatment:** [if relevant] + +### Navigation +- [Style, typography, default/hover/active states, mobile treatment] + +### Inputs/Forms +- [Stroke style, background, focus treatment] + +## 5. Layout Principles + +[Paragraph or short list describing whitespace strategy, margin scale, grid system, responsive breakpoints. Include px/rem values in parens.] +``` + +### Step 5: Write & confirm + +1. Write the file to `PROJECT_ROOT/DESIGN.md` (uppercase, at root). +2. Show the user the full DESIGN.md you wrote, briefly highlighting the non-obvious creative choices (descriptive color names, atmosphere language). +3. Offer to refine any section: "Want me to revise a section, add component patterns I missed, or adjust the atmosphere language?" + +## Style guidelines + +- **Descriptive > technical**: "Gently curved edges (8px radius)" > "rounded-lg". Include the technical value in parens, lead with the description. +- **Functional > decorative**: for each token, explain WHERE and WHY it's used, not just WHAT it is. +- **Exact values in parens**: hex codes, px/rem values, font weights — always the number in parens alongside the description. +- **Group colors semantically**: Foundation (backgrounds), Accent (interactive), Typography (text hierarchy), States (success/warning/error), not hex-sorted. +- **Reference the user's domain**: if the project is a DEX, say "trading-focused"; if it's a CMS, say "editorial". Domain-aware language helps agents pick sensible defaults. + +## Pitfalls + +- Don't paste raw CSS class names. Translate to descriptive language. +- Don't extract every token. Stop at what's actually reused — one-offs pollute the system. +- Don't invent components that don't exist. If the project only has buttons and cards, only document those. +- Don't overwrite an existing DESIGN.md without asking. +- Don't duplicate content from PRODUCT.md. DESIGN.md is strictly visual. diff --git a/.rovodev/skills/impeccable/reference/live.md b/.rovodev/skills/impeccable/reference/live.md index 3388e1897..19c16fa38 100644 --- a/.rovodev/skills/impeccable/reference/live.md +++ b/.rovodev/skills/impeccable/reference/live.md @@ -21,12 +21,21 @@ Output JSON: "serverPort": 8400, "serverToken": "...", "pageFile": "public/index.html", - "hasContext": true, - "context": "...full .impeccable.md contents..." + "hasProduct": true, + "product": "...full PRODUCT.md contents...", + "productPath": "PRODUCT.md", + "hasDesign": true, + "design": "...full DESIGN.md contents...", + "designPath": "DESIGN.md", + "migrated": false } ``` -Keep the `context` in mind for variant generation. If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. +Keep **PRODUCT.md** (strategic: users, brand, principles) and **DESIGN.md** (visual: colors, typography, components) in mind for variant generation. **DESIGN.md wins on visual decisions; PRODUCT.md wins on strategic/voice decisions.** + +If `migrated` is true, the loader auto-renamed legacy `.impeccable.md` to `PRODUCT.md` — mention this once to the user and suggest running `/impeccable document` to also generate a `DESIGN.md`. + +If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. ### First-time setup (config missing) diff --git a/.rovodev/skills/impeccable/reference/teach.md b/.rovodev/skills/impeccable/reference/teach.md index 2d9f768f1..b436efa20 100644 --- a/.rovodev/skills/impeccable/reference/teach.md +++ b/.rovodev/skills/impeccable/reference/teach.md @@ -1,8 +1,31 @@ # Teach Flow -One-time setup that gathers design context for a project. Design without context produces generic output, so every other command reads this file before doing any work. +Gathers design context for a project and writes two complementary files at the project root: -## Step 1: Explore the Codebase +- **PRODUCT.md** (strategic): target users, product purpose, brand personality, anti-references, strategic design principles. Answers "who/what/why". +- **DESIGN.md** (visual): visual theme, color palette, typography, components, layout. Follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/). Answers "how it looks". + +Every other impeccable command reads these files before doing any work. + +## Step 1: Load current state + +Run the shared loader first so you know what already exists: + +```bash +node {{scripts_path}}/load-context.mjs +``` + +The output tells you whether PRODUCT.md and/or DESIGN.md already exist. If `migrated: true`, legacy `.impeccable.md` was auto-renamed to `PRODUCT.md`. Mention this once to the user. + +Decision tree: +- **Neither file exists (empty project or no context yet)**: do Steps 2-4 (write PRODUCT.md), then decide on DESIGN.md based on whether there's code to analyze. +- **PRODUCT.md exists, DESIGN.md missing**: skip to Step 5 — offer to run `/impeccable document` for DESIGN.md. +- **Both exist**: ask the user directly to clarify what you cannot infer. which to refresh. Skip the one the user doesn't want changed. +- **Just DESIGN.md exists (unusual)**: do Steps 2-4 to produce PRODUCT.md. + +Never silently overwrite an existing file. Always confirm first. + +## Step 2: Explore the codebase Before asking questions, thoroughly scan the project to discover what you can: @@ -13,9 +36,9 @@ Before asking questions, thoroughly scan the project to discover what you can: - **Design tokens / CSS variables**: Existing color palettes, font stacks, spacing scales - **Any style guides or brand documentation** -Note what you've learned and what remains unclear. +Note what you've learned and what remains unclear. This exploration feeds both PRODUCT.md and DESIGN.md. -## Step 2: Ask UX-Focused Questions +## Step 3: Ask strategic questions (for PRODUCT.md) ask the user directly to clarify what you cannot infer. Focus only on what you couldn't infer from the codebase: @@ -29,39 +52,53 @@ ask the user directly to clarify what you cannot infer. Focus only on what you c - Any reference sites or apps that capture the right feel? What specifically about them? - What should this explicitly NOT look like? Any anti-references? -### Aesthetic Preferences -- Any strong preferences for visual direction? (minimal, bold, elegant, playful, technical, organic, etc.) -- Light mode, dark mode, or both? -- Any colors that must be used or avoided? - ### Accessibility & Inclusion - Specific accessibility requirements? (WCAG level, known user needs) - Considerations for reduced motion, color blindness, or other accommodations? -Skip questions where the answer is already clear from the codebase exploration. +Skip questions where the answer is already clear. **Do NOT ask about colors, fonts, radii, or visual styling here** — those belong in DESIGN.md, not PRODUCT.md. -## Step 3: Write Design Context +## Step 4: Write PRODUCT.md -Synthesize your findings and the user's answers into a `## Design Context` section: +Synthesize into a strategic document: ```markdown -## Design Context +# Product -### Users +## Users [Who they are, their context, the job to be done] -### Brand Personality +## Product Purpose +[What this product does, why it exists, what success looks like] + +## Brand Personality [Voice, tone, 3-word personality, emotional goals] -### Aesthetic Direction -[Visual tone, references, anti-references, theme] +## Anti-references +[What this should NOT look like. Specific bad-example sites or patterns to avoid.] -### Design Principles -[3-5 principles derived from the conversation that should guide all design decisions] +## Design Principles +[3-5 strategic principles derived from the conversation. Principles like "practice what you preach", "editorial over marketing", "expert confidence" — NOT visual rules like "use OKLCH" or "magenta accent".] + +## Accessibility & Inclusion +[WCAG level, known user needs, considerations] ``` -Write this section to `.impeccable.md` in the project root. If the file already exists, update the Design Context section in place. +Write to `PROJECT_ROOT/PRODUCT.md`. If `.impeccable.md` existed, the loader already renamed it — merge into that content rather than starting from scratch. -Then ask the user directly to clarify what you cannot infer. whether they'd also like the Design Context appended to AGENTS.md. If yes, append or update the section there as well. +## Step 5: Decide on DESIGN.md -Confirm completion and summarize the key design principles that will now guide all future work. +If the project has meaningful code to analyze (CSS tokens, components, a running site), **offer to run `/impeccable document`** next: "I can also generate a DESIGN.md that captures your visual design system (colors, typography, components) so variants stay on-brand. Want to do that now?" + +If the user agrees, delegate to `/impeccable document` (load its reference and follow that flow). + +If the project is empty (no code yet, pre-implementation), skip DESIGN.md — there's nothing visual to document yet. Mention: "Once you've built some of the interface, run `/impeccable document` to generate a DESIGN.md." + +## Step 6: Confirm and wrap up + +Summarize: +- What was written (PRODUCT.md, DESIGN.md, or both) +- The 3-5 strategic principles from PRODUCT.md that will guide future work +- If DESIGN.md is pending, remind the user how to generate it later + +Optionally ask the user directly to clarify what you cannot infer. whether they'd like a brief summary of PRODUCT.md appended to AGENTS.md for easier agent reference. If yes, append a short **Design Context** pointer section there. diff --git a/.rovodev/skills/impeccable/scripts/command-metadata.json b/.rovodev/skills/impeccable/scripts/command-metadata.json index 2974e08f6..d8282689a 100644 --- a/.rovodev/skills/impeccable/scripts/command-metadata.json +++ b/.rovodev/skills/impeccable/scripts/command-metadata.json @@ -4,7 +4,11 @@ "argumentHint": "[feature description]" }, "teach": { - "description": "One-time setup that gathers design context for a project. Runs a short discovery interview and writes the answers to .impeccable.md. Every other command reads this file before doing work. Use once per project.", + "description": "Gathers design context for a project. Runs a short discovery interview and writes PRODUCT.md (strategic: users, brand, principles) and, when code exists to analyze, DESIGN.md (visual: colors, typography, components). Every other command reads these files before doing work. Use once per project.", + "argumentHint": "" + }, + "document": { + "description": "Generate a DESIGN.md file that captures the current visual design system. Auto-extracts colors, typography, spacing, radii, and component patterns from the codebase, then asks the user to confirm descriptive language for atmosphere and color character. Follows the Google Stitch DESIGN.md format so the file is tool-compatible. Use when you need a visual design spec an AI agent can follow to stay on-brand.", "argumentHint": "" }, "extract": { diff --git a/.rovodev/skills/impeccable/scripts/live.mjs b/.rovodev/skills/impeccable/scripts/live.mjs index 93f05456e..37b6f8997 100644 --- a/.rovodev/skills/impeccable/scripts/live.mjs +++ b/.rovodev/skills/impeccable/scripts/live.mjs @@ -21,10 +21,10 @@ import { execSync } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { loadContext } from './load-context.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const PID_FILE = path.join(process.cwd(), '.impeccable-live.json'); -const CONTEXT_FILE = path.join(process.cwd(), '.impeccable.md'); async function liveCli() { const args = process.argv.slice(2); @@ -79,9 +79,8 @@ The agent should then: process.exit(1); } - // 4. Load design context if available - let context = null; - try { context = fs.readFileSync(CONTEXT_FILE, 'utf-8'); } catch { /* optional */ } + // 4. Load PRODUCT.md + DESIGN.md context (auto-migrates legacy .impeccable.md) + const ctx = loadContext(process.cwd()); // 5. Emit everything the agent needs console.log(JSON.stringify({ @@ -89,8 +88,13 @@ The agent should then: serverPort: serverInfo.port, serverToken: serverInfo.token, pageFile: checkResult.config.file, - hasContext: !!context, - context, + hasProduct: ctx.hasProduct, + product: ctx.product, + productPath: ctx.productPath, + hasDesign: ctx.hasDesign, + design: ctx.design, + designPath: ctx.designPath, + migrated: ctx.migrated, }, null, 2)); } diff --git a/.rovodev/skills/impeccable/scripts/load-context.mjs b/.rovodev/skills/impeccable/scripts/load-context.mjs new file mode 100644 index 000000000..ab3be08f1 --- /dev/null +++ b/.rovodev/skills/impeccable/scripts/load-context.mjs @@ -0,0 +1,93 @@ +/** + * Shared context loader for every impeccable command that needs to know + * "who is this for" and "what does this look like". + * + * Input: project root (process.cwd()). + * + * Output (JSON to stdout): + * { + * hasProduct: boolean, // PRODUCT.md found (or auto-migrated) + * product: string | null, // PRODUCT.md contents + * productPath: string | null, // relative path + * hasDesign: boolean, // DESIGN.md found + * design: string | null, // DESIGN.md contents + * designPath: string | null, + * migrated: boolean, // true if we auto-renamed .impeccable.md -> PRODUCT.md + * } + * + * Filename matching is case-insensitive for PRODUCT.md and DESIGN.md. The + * Google DESIGN.md convention is uppercase at repo root; Kiro-style and + * lowercase variants are also matched so users don't get punished for case. + */ + +import fs from 'node:fs'; +import path from 'node:path'; + +const PRODUCT_NAMES = ['PRODUCT.md', 'Product.md', 'product.md']; +const DESIGN_NAMES = ['DESIGN.md', 'Design.md', 'design.md']; +const LEGACY_NAMES = ['.impeccable.md']; + +export function loadContext(cwd = process.cwd()) { + let migrated = false; + + // 1. Look for PRODUCT.md (case-insensitive) + let productPath = firstExisting(cwd, PRODUCT_NAMES); + + // 2. Legacy: if no PRODUCT.md but .impeccable.md exists, rename in place + if (!productPath) { + const legacyPath = firstExisting(cwd, LEGACY_NAMES); + if (legacyPath) { + const newPath = path.join(cwd, 'PRODUCT.md'); + try { + fs.renameSync(legacyPath, newPath); + productPath = newPath; + migrated = true; + } catch { + // Rename failed (permissions, etc.) — fall back to reading legacy in place + productPath = legacyPath; + } + } + } + + // 3. DESIGN.md (case-insensitive) + const designPath = firstExisting(cwd, DESIGN_NAMES); + + const product = productPath ? safeRead(productPath) : null; + const design = designPath ? safeRead(designPath) : null; + + return { + hasProduct: !!product, + product, + productPath: productPath ? path.relative(cwd, productPath) : null, + hasDesign: !!design, + design, + designPath: designPath ? path.relative(cwd, designPath) : null, + migrated, + }; +} + +function firstExisting(cwd, names) { + for (const name of names) { + const abs = path.join(cwd, name); + if (fs.existsSync(abs)) return abs; + } + return null; +} + +function safeRead(p) { + try { return fs.readFileSync(p, 'utf-8'); } catch { return null; } +} + +// --------------------------------------------------------------------------- +// CLI mode — print the context as JSON +// --------------------------------------------------------------------------- + +function cli() { + const result = loadContext(process.cwd()); + console.log(JSON.stringify(result, null, 2)); +} + +const _running = process.argv[1]; +if (_running?.endsWith('load-context.mjs') || _running?.endsWith('load-context.mjs/')) { + cli(); +} diff --git a/.rovodev/skills/impeccable/scripts/pin.mjs b/.rovodev/skills/impeccable/scripts/pin.mjs index 89a6babeb..ba02783fb 100644 --- a/.rovodev/skills/impeccable/scripts/pin.mjs +++ b/.rovodev/skills/impeccable/scripts/pin.mjs @@ -27,7 +27,7 @@ const HARNESS_DIRS = [ // Valid sub-command names const VALID_COMMANDS = [ - 'craft', 'teach', 'extract', 'shape', + 'craft', 'teach', 'extract', 'document', 'shape', 'critique', 'audit', 'polish', 'bolder', 'quieter', 'distill', 'harden', 'onboard', 'live', 'animate', 'colorize', 'typeset', 'layout', 'delight', 'overdrive', diff --git a/.trae-cn/skills/impeccable/SKILL.md b/.trae-cn/skills/impeccable/SKILL.md index a2097f9fb..85d38949c 100644 --- a/.trae-cn/skills/impeccable/SKILL.md +++ b/.trae-cn/skills/impeccable/SKILL.md @@ -3,7 +3,7 @@ name: impeccable description: Use when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a frontend interface. Covers websites, landing pages, dashboards, product UI, app shells, components, forms, settings, onboarding, and empty states. Handles UX review, visual hierarchy, information architecture, cognitive load, accessibility, performance, responsive behavior, theming, anti-patterns, typography, fonts, spacing, layout, alignment, color, motion, micro-interactions, UX copy, error states, edge cases, i18n, and reusable design systems or tokens. Also use for bland designs that need to become bolder or more delightful, loud designs that should become quieter, live browser iteration on UI elements, or ambitious visual effects that should feel technically extraordinary. Not for backend-only or non-UI tasks. version: 3.0.0 user-invocable: true -argument-hint: "[craft|shape · audit|critique · animate|bolder|colorize|delight|layout|overdrive|quieter|typeset · adapt|clarify|distill · harden|onboard|optimize|polish · teach|extract|live] [target]" +argument-hint: "[craft|shape · audit|critique · animate|bolder|colorize|delight|layout|overdrive|quieter|typeset · adapt|clarify|distill · harden|onboard|optimize|polish · teach|document|extract|live] [target]" license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. --- @@ -29,10 +29,17 @@ After running the script, delete this entire section (from ` **Build & Plan** > `/impeccable craft [feature]` - Shape, then build a feature end-to-end > `/impeccable shape [feature]` - Plan UX/UI before writing code -> `/impeccable teach` - Set up design context for this project (one-time) +> `/impeccable teach` - Set up PRODUCT.md and DESIGN.md context for this project +> `/impeccable document` - Generate DESIGN.md from existing project code > `/impeccable extract [target]` - Pull reusable tokens and components into design system > > **Evaluate** @@ -347,6 +355,7 @@ When a sub-command is matched, load the linked reference and follow its instruct | `craft` | [craft](reference/craft.md) | Full shape-then-build flow with visual iteration | | `teach` | [teach](reference/teach.md) | One-time setup: gather design context for the project | | `extract` | [extract](reference/extract.md) | Pull reusable tokens and components into design system | +| `document` | [document](reference/document.md) | Generate DESIGN.md from existing project code (visual design system doc) | | `shape` | [shape](reference/shape.md) | Plan UX and UI before writing code (produces a design brief) | | `critique` | [critique](reference/critique.md) | UX design review with heuristic scoring and persona testing | | `audit` | [audit](reference/audit.md) | Technical quality checks across a11y, perf, theming, responsive, anti-patterns | diff --git a/.trae-cn/skills/impeccable/reference/audit.md b/.trae-cn/skills/impeccable/reference/audit.md index bbba2401b..c2258ac54 100644 --- a/.trae-cn/skills/impeccable/reference/audit.md +++ b/.trae-cn/skills/impeccable/reference/audit.md @@ -95,7 +95,7 @@ For each issue, document: - **Impact**: How it affects users - **WCAG/Standard**: Which standard it violates (if applicable) - **Recommendation**: How to fix it -- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) ### Patterns & Systemic Issues @@ -114,7 +114,7 @@ List recommended commands in priority order (P0 first, then P1, then P2): 1. **[P?] `/command-name`** — Brief description (specific context from audit findings) 2. **[P?] `/command-name`** — Brief description (specific context) -**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. +**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. After presenting the summary, tell the user: diff --git a/.trae-cn/skills/impeccable/reference/critique.md b/.trae-cn/skills/impeccable/reference/critique.md index 2ced96a7c..e9ae4e71e 100644 --- a/.trae-cn/skills/impeccable/reference/critique.md +++ b/.trae-cn/skills/impeccable/reference/critique.md @@ -132,7 +132,7 @@ For each issue, tag with **P0-P3 severity** (consult [heuristics-scoring](heuris - **[P?] What**: Name the problem clearly - **Why it matters**: How this hurts users or undermines goals - **Fix**: What to do about it (be concrete) -- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) #### Persona Red Flags > *Consult [personas](personas.md)* @@ -197,7 +197,7 @@ List recommended commands in priority order, based on the user's answers: ... **Rules for recommendations**: -- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset +- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset - Order by the user's stated priorities first, then by impact - Each item's description should carry enough context that the command knows what to focus on - Map each Priority Issue to the appropriate command diff --git a/.trae-cn/skills/impeccable/reference/document.md b/.trae-cn/skills/impeccable/reference/document.md new file mode 100644 index 000000000..ebf90bbf3 --- /dev/null +++ b/.trae-cn/skills/impeccable/reference/document.md @@ -0,0 +1,126 @@ +Generate a DESIGN.md file in the project root that captures the current visual design system, so AI agents generating new screens stay on-brand. + +DESIGN.md follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/): a single markdown file at the project root with five fixed sections describing colors, typography, components, layout, and overall atmosphere. Keep section headers exactly as specified so the file stays compatible with other DESIGN.md-aware tools. + +## When to run + +- The user just ran `/impeccable teach` and needs the visual side documented. +- The skill noticed no `DESIGN.md` exists and nudged the user to create one. +- An existing `DESIGN.md` is stale (the design has drifted). +- Before a large redesign, to capture the current state as a reference. + +If a `DESIGN.md` already exists, **do not silently overwrite it**. Show the user the existing file and ask the user directly to clarify what you cannot infer. whether to refresh it, overwrite it, or merge into it. + +## Process (approach C: auto-extract, then confirm descriptive language) + +### Step 1: Find the design assets + +Search the codebase in priority order: + +1. **CSS custom properties** — grep for `--color-`, `--font-`, `--spacing-`, `--radius-`, `--shadow-`, `--ease-`, `--duration-` declarations in CSS files (usually `src/styles/`, `public/css/`, `app/globals.css`, etc.). Record name, value, and the file it's defined in. +2. **Tailwind config** — if `tailwind.config.{js,ts,mjs}` exists, read the `theme.extend` block for colors, fontFamily, spacing, borderRadius, boxShadow. +3. **CSS-in-JS theme files** — if the project uses styled-components, emotion, vanilla-extract, stitches, etc., look for `theme.ts`, `tokens.ts`, or equivalent. +4. **Design token files** — `tokens.json`, `design-tokens.json`, Style Dictionary output, W3C token community group format. +5. **Component library** — scan the main button, card, input, navigation, dialog components. Note their variant APIs and default styles. +6. **Global stylesheet** — the root CSS file usually has the base typography and color assignments. +7. **Visible rendered output** — if browser automation tools are available, load the live site and sample computed styles from key elements (body, h1, a, button, .card). This catches values that tokens miss. + +### Step 2: Auto-extract what can be auto-extracted + +Build a structured draft from the discovered tokens. For each token class: + +- **Colors**: Group by hue family. Convert hex → OKLCH to infer lightness/chroma. Identify background vs. text vs. accent by usage patterns in CSS (`background`, `color`, `border`, `fill`). Flag any that are only used once (possibly one-off, not system tokens). +- **Typography**: Extract font families and their declared stacks. Extract the scale (all `font-size` values used in CSS custom props + component styles). Extract weights actually used. Detect the scale ratio (1.125, 1.2, 1.25, 1.333, 1.5, golden). +- **Spacing**: Extract the scale, detect the base unit (4px, 8px, other). +- **Radii & shadows**: List the values used. +- **Components**: For each common component (button, card, input, nav, dialog), extract shape (radius), color assignment, hover/focus treatment, internal padding. + +### Step 3: Ask the user for qualitative language + +The following sections require creative input that cannot be auto-extracted reliably. ask the user directly to clarify what you cannot infer. for each (group them into one interaction if possible): + +- **Visual Theme & Atmosphere**: mood adjectives (airy/dense, minimal/maximalist, editorial/utilitarian, warm/clinical), aesthetic philosophy in 2-3 sentences, key characteristics as a bullet list. +- **Color character** (for auto-extracted colors): descriptive names ("Deep Muted Teal-Navy", not "blue-800"). Suggest 2-3 options per color based on the hue/saturation, let the user pick. +- **Typographic character**: describe the font pairing ("Modern geometric sans-serif with humanist warmth" > "Manrope 500"). Describe letter-spacing strategy. +- **Spacing philosophy**: 1-2 sentences on whitespace strategy ("generous breathing room that prioritizes photography"). +- **Component philosophy**: brief description of the feel of buttons, cards, inputs ("refined and understated" vs. "tactile and confident"). + +If the user has a `PRODUCT.md` that covers brand personality, quote a line from it so they see their own strategic language carry over. + +### Step 4: Write DESIGN.md + +Use this exact structure (section headers must match the Google spec character-for-character): + +```markdown +# Design System: [Project Title] +**Project ID:** [optional — only if a Stitch project ID exists] + +## 1. Visual Theme & Atmosphere + +[2-3 paragraph description using evocative adjectives. Start with the overall sanctuary/laboratory/workshop/stage analogy if one fits. End with a short **Key Characteristics:** bullet list.] + +## 2. Color Palette & Roles + +### [Semantic group name: Primary Foundation, Accent & Interactive, Typography & Text Hierarchy, Functional States, etc.] +- **[Descriptive Name]** (#HEX) – [Functional role. Where/why it's used.] + +## 3. Typography Rules + +**Primary Font Family:** [Name] +**Character:** [1-sentence personality description.] + +### Hierarchy & Weights +- **[Role (e.g. Display Headlines H1)]:** [Weight] weight ([num]), [letter-spacing], [size]. [Purpose.] + +### Spacing Principles +[Short list of rules about leading, letter-spacing, vertical rhythm.] + +## 4. Component Stylings + +### Buttons +- **Shape:** [radius description with px value in parens] +- **Primary CTA:** [color assignment + padding] +- **Hover State:** [transition description] +- **Focus State:** [accessibility treatment] +- **Secondary CTA (if applicable):** [description] + +### Cards & Containers +- **Corner Style:** [description] +- **Background:** [colors used] +- **Shadow Strategy:** [flat / soft / heavy] +- **Border:** [if any] +- **Internal Padding:** [scale] +- **Image Treatment:** [if relevant] + +### Navigation +- [Style, typography, default/hover/active states, mobile treatment] + +### Inputs/Forms +- [Stroke style, background, focus treatment] + +## 5. Layout Principles + +[Paragraph or short list describing whitespace strategy, margin scale, grid system, responsive breakpoints. Include px/rem values in parens.] +``` + +### Step 5: Write & confirm + +1. Write the file to `PROJECT_ROOT/DESIGN.md` (uppercase, at root). +2. Show the user the full DESIGN.md you wrote, briefly highlighting the non-obvious creative choices (descriptive color names, atmosphere language). +3. Offer to refine any section: "Want me to revise a section, add component patterns I missed, or adjust the atmosphere language?" + +## Style guidelines + +- **Descriptive > technical**: "Gently curved edges (8px radius)" > "rounded-lg". Include the technical value in parens, lead with the description. +- **Functional > decorative**: for each token, explain WHERE and WHY it's used, not just WHAT it is. +- **Exact values in parens**: hex codes, px/rem values, font weights — always the number in parens alongside the description. +- **Group colors semantically**: Foundation (backgrounds), Accent (interactive), Typography (text hierarchy), States (success/warning/error), not hex-sorted. +- **Reference the user's domain**: if the project is a DEX, say "trading-focused"; if it's a CMS, say "editorial". Domain-aware language helps agents pick sensible defaults. + +## Pitfalls + +- Don't paste raw CSS class names. Translate to descriptive language. +- Don't extract every token. Stop at what's actually reused — one-offs pollute the system. +- Don't invent components that don't exist. If the project only has buttons and cards, only document those. +- Don't overwrite an existing DESIGN.md without asking. +- Don't duplicate content from PRODUCT.md. DESIGN.md is strictly visual. diff --git a/.trae-cn/skills/impeccable/reference/live.md b/.trae-cn/skills/impeccable/reference/live.md index 3388e1897..19c16fa38 100644 --- a/.trae-cn/skills/impeccable/reference/live.md +++ b/.trae-cn/skills/impeccable/reference/live.md @@ -21,12 +21,21 @@ Output JSON: "serverPort": 8400, "serverToken": "...", "pageFile": "public/index.html", - "hasContext": true, - "context": "...full .impeccable.md contents..." + "hasProduct": true, + "product": "...full PRODUCT.md contents...", + "productPath": "PRODUCT.md", + "hasDesign": true, + "design": "...full DESIGN.md contents...", + "designPath": "DESIGN.md", + "migrated": false } ``` -Keep the `context` in mind for variant generation. If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. +Keep **PRODUCT.md** (strategic: users, brand, principles) and **DESIGN.md** (visual: colors, typography, components) in mind for variant generation. **DESIGN.md wins on visual decisions; PRODUCT.md wins on strategic/voice decisions.** + +If `migrated` is true, the loader auto-renamed legacy `.impeccable.md` to `PRODUCT.md` — mention this once to the user and suggest running `/impeccable document` to also generate a `DESIGN.md`. + +If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. ### First-time setup (config missing) diff --git a/.trae-cn/skills/impeccable/reference/teach.md b/.trae-cn/skills/impeccable/reference/teach.md index 972ca25be..aef07b2be 100644 --- a/.trae-cn/skills/impeccable/reference/teach.md +++ b/.trae-cn/skills/impeccable/reference/teach.md @@ -1,8 +1,31 @@ # Teach Flow -One-time setup that gathers design context for a project. Design without context produces generic output, so every other command reads this file before doing any work. +Gathers design context for a project and writes two complementary files at the project root: -## Step 1: Explore the Codebase +- **PRODUCT.md** (strategic): target users, product purpose, brand personality, anti-references, strategic design principles. Answers "who/what/why". +- **DESIGN.md** (visual): visual theme, color palette, typography, components, layout. Follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/). Answers "how it looks". + +Every other impeccable command reads these files before doing any work. + +## Step 1: Load current state + +Run the shared loader first so you know what already exists: + +```bash +node {{scripts_path}}/load-context.mjs +``` + +The output tells you whether PRODUCT.md and/or DESIGN.md already exist. If `migrated: true`, legacy `.impeccable.md` was auto-renamed to `PRODUCT.md`. Mention this once to the user. + +Decision tree: +- **Neither file exists (empty project or no context yet)**: do Steps 2-4 (write PRODUCT.md), then decide on DESIGN.md based on whether there's code to analyze. +- **PRODUCT.md exists, DESIGN.md missing**: skip to Step 5 — offer to run `/impeccable document` for DESIGN.md. +- **Both exist**: ask the user directly to clarify what you cannot infer. which to refresh. Skip the one the user doesn't want changed. +- **Just DESIGN.md exists (unusual)**: do Steps 2-4 to produce PRODUCT.md. + +Never silently overwrite an existing file. Always confirm first. + +## Step 2: Explore the codebase Before asking questions, thoroughly scan the project to discover what you can: @@ -13,9 +36,9 @@ Before asking questions, thoroughly scan the project to discover what you can: - **Design tokens / CSS variables**: Existing color palettes, font stacks, spacing scales - **Any style guides or brand documentation** -Note what you've learned and what remains unclear. +Note what you've learned and what remains unclear. This exploration feeds both PRODUCT.md and DESIGN.md. -## Step 2: Ask UX-Focused Questions +## Step 3: Ask strategic questions (for PRODUCT.md) ask the user directly to clarify what you cannot infer. Focus only on what you couldn't infer from the codebase: @@ -29,39 +52,53 @@ ask the user directly to clarify what you cannot infer. Focus only on what you c - Any reference sites or apps that capture the right feel? What specifically about them? - What should this explicitly NOT look like? Any anti-references? -### Aesthetic Preferences -- Any strong preferences for visual direction? (minimal, bold, elegant, playful, technical, organic, etc.) -- Light mode, dark mode, or both? -- Any colors that must be used or avoided? - ### Accessibility & Inclusion - Specific accessibility requirements? (WCAG level, known user needs) - Considerations for reduced motion, color blindness, or other accommodations? -Skip questions where the answer is already clear from the codebase exploration. +Skip questions where the answer is already clear. **Do NOT ask about colors, fonts, radii, or visual styling here** — those belong in DESIGN.md, not PRODUCT.md. -## Step 3: Write Design Context +## Step 4: Write PRODUCT.md -Synthesize your findings and the user's answers into a `## Design Context` section: +Synthesize into a strategic document: ```markdown -## Design Context +# Product -### Users +## Users [Who they are, their context, the job to be done] -### Brand Personality +## Product Purpose +[What this product does, why it exists, what success looks like] + +## Brand Personality [Voice, tone, 3-word personality, emotional goals] -### Aesthetic Direction -[Visual tone, references, anti-references, theme] +## Anti-references +[What this should NOT look like. Specific bad-example sites or patterns to avoid.] -### Design Principles -[3-5 principles derived from the conversation that should guide all design decisions] +## Design Principles +[3-5 strategic principles derived from the conversation. Principles like "practice what you preach", "editorial over marketing", "expert confidence" — NOT visual rules like "use OKLCH" or "magenta accent".] + +## Accessibility & Inclusion +[WCAG level, known user needs, considerations] ``` -Write this section to `.impeccable.md` in the project root. If the file already exists, update the Design Context section in place. +Write to `PROJECT_ROOT/PRODUCT.md`. If `.impeccable.md` existed, the loader already renamed it — merge into that content rather than starting from scratch. -Then ask the user directly to clarify what you cannot infer. whether they'd also like the Design Context appended to RULES.md. If yes, append or update the section there as well. +## Step 5: Decide on DESIGN.md -Confirm completion and summarize the key design principles that will now guide all future work. +If the project has meaningful code to analyze (CSS tokens, components, a running site), **offer to run `/impeccable document`** next: "I can also generate a DESIGN.md that captures your visual design system (colors, typography, components) so variants stay on-brand. Want to do that now?" + +If the user agrees, delegate to `/impeccable document` (load its reference and follow that flow). + +If the project is empty (no code yet, pre-implementation), skip DESIGN.md — there's nothing visual to document yet. Mention: "Once you've built some of the interface, run `/impeccable document` to generate a DESIGN.md." + +## Step 6: Confirm and wrap up + +Summarize: +- What was written (PRODUCT.md, DESIGN.md, or both) +- The 3-5 strategic principles from PRODUCT.md that will guide future work +- If DESIGN.md is pending, remind the user how to generate it later + +Optionally ask the user directly to clarify what you cannot infer. whether they'd like a brief summary of PRODUCT.md appended to RULES.md for easier agent reference. If yes, append a short **Design Context** pointer section there. diff --git a/.trae-cn/skills/impeccable/scripts/command-metadata.json b/.trae-cn/skills/impeccable/scripts/command-metadata.json index 2974e08f6..d8282689a 100644 --- a/.trae-cn/skills/impeccable/scripts/command-metadata.json +++ b/.trae-cn/skills/impeccable/scripts/command-metadata.json @@ -4,7 +4,11 @@ "argumentHint": "[feature description]" }, "teach": { - "description": "One-time setup that gathers design context for a project. Runs a short discovery interview and writes the answers to .impeccable.md. Every other command reads this file before doing work. Use once per project.", + "description": "Gathers design context for a project. Runs a short discovery interview and writes PRODUCT.md (strategic: users, brand, principles) and, when code exists to analyze, DESIGN.md (visual: colors, typography, components). Every other command reads these files before doing work. Use once per project.", + "argumentHint": "" + }, + "document": { + "description": "Generate a DESIGN.md file that captures the current visual design system. Auto-extracts colors, typography, spacing, radii, and component patterns from the codebase, then asks the user to confirm descriptive language for atmosphere and color character. Follows the Google Stitch DESIGN.md format so the file is tool-compatible. Use when you need a visual design spec an AI agent can follow to stay on-brand.", "argumentHint": "" }, "extract": { diff --git a/.trae-cn/skills/impeccable/scripts/live.mjs b/.trae-cn/skills/impeccable/scripts/live.mjs index 93f05456e..37b6f8997 100644 --- a/.trae-cn/skills/impeccable/scripts/live.mjs +++ b/.trae-cn/skills/impeccable/scripts/live.mjs @@ -21,10 +21,10 @@ import { execSync } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { loadContext } from './load-context.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const PID_FILE = path.join(process.cwd(), '.impeccable-live.json'); -const CONTEXT_FILE = path.join(process.cwd(), '.impeccable.md'); async function liveCli() { const args = process.argv.slice(2); @@ -79,9 +79,8 @@ The agent should then: process.exit(1); } - // 4. Load design context if available - let context = null; - try { context = fs.readFileSync(CONTEXT_FILE, 'utf-8'); } catch { /* optional */ } + // 4. Load PRODUCT.md + DESIGN.md context (auto-migrates legacy .impeccable.md) + const ctx = loadContext(process.cwd()); // 5. Emit everything the agent needs console.log(JSON.stringify({ @@ -89,8 +88,13 @@ The agent should then: serverPort: serverInfo.port, serverToken: serverInfo.token, pageFile: checkResult.config.file, - hasContext: !!context, - context, + hasProduct: ctx.hasProduct, + product: ctx.product, + productPath: ctx.productPath, + hasDesign: ctx.hasDesign, + design: ctx.design, + designPath: ctx.designPath, + migrated: ctx.migrated, }, null, 2)); } diff --git a/.trae-cn/skills/impeccable/scripts/load-context.mjs b/.trae-cn/skills/impeccable/scripts/load-context.mjs new file mode 100644 index 000000000..ab3be08f1 --- /dev/null +++ b/.trae-cn/skills/impeccable/scripts/load-context.mjs @@ -0,0 +1,93 @@ +/** + * Shared context loader for every impeccable command that needs to know + * "who is this for" and "what does this look like". + * + * Input: project root (process.cwd()). + * + * Output (JSON to stdout): + * { + * hasProduct: boolean, // PRODUCT.md found (or auto-migrated) + * product: string | null, // PRODUCT.md contents + * productPath: string | null, // relative path + * hasDesign: boolean, // DESIGN.md found + * design: string | null, // DESIGN.md contents + * designPath: string | null, + * migrated: boolean, // true if we auto-renamed .impeccable.md -> PRODUCT.md + * } + * + * Filename matching is case-insensitive for PRODUCT.md and DESIGN.md. The + * Google DESIGN.md convention is uppercase at repo root; Kiro-style and + * lowercase variants are also matched so users don't get punished for case. + */ + +import fs from 'node:fs'; +import path from 'node:path'; + +const PRODUCT_NAMES = ['PRODUCT.md', 'Product.md', 'product.md']; +const DESIGN_NAMES = ['DESIGN.md', 'Design.md', 'design.md']; +const LEGACY_NAMES = ['.impeccable.md']; + +export function loadContext(cwd = process.cwd()) { + let migrated = false; + + // 1. Look for PRODUCT.md (case-insensitive) + let productPath = firstExisting(cwd, PRODUCT_NAMES); + + // 2. Legacy: if no PRODUCT.md but .impeccable.md exists, rename in place + if (!productPath) { + const legacyPath = firstExisting(cwd, LEGACY_NAMES); + if (legacyPath) { + const newPath = path.join(cwd, 'PRODUCT.md'); + try { + fs.renameSync(legacyPath, newPath); + productPath = newPath; + migrated = true; + } catch { + // Rename failed (permissions, etc.) — fall back to reading legacy in place + productPath = legacyPath; + } + } + } + + // 3. DESIGN.md (case-insensitive) + const designPath = firstExisting(cwd, DESIGN_NAMES); + + const product = productPath ? safeRead(productPath) : null; + const design = designPath ? safeRead(designPath) : null; + + return { + hasProduct: !!product, + product, + productPath: productPath ? path.relative(cwd, productPath) : null, + hasDesign: !!design, + design, + designPath: designPath ? path.relative(cwd, designPath) : null, + migrated, + }; +} + +function firstExisting(cwd, names) { + for (const name of names) { + const abs = path.join(cwd, name); + if (fs.existsSync(abs)) return abs; + } + return null; +} + +function safeRead(p) { + try { return fs.readFileSync(p, 'utf-8'); } catch { return null; } +} + +// --------------------------------------------------------------------------- +// CLI mode — print the context as JSON +// --------------------------------------------------------------------------- + +function cli() { + const result = loadContext(process.cwd()); + console.log(JSON.stringify(result, null, 2)); +} + +const _running = process.argv[1]; +if (_running?.endsWith('load-context.mjs') || _running?.endsWith('load-context.mjs/')) { + cli(); +} diff --git a/.trae-cn/skills/impeccable/scripts/pin.mjs b/.trae-cn/skills/impeccable/scripts/pin.mjs index 89a6babeb..ba02783fb 100644 --- a/.trae-cn/skills/impeccable/scripts/pin.mjs +++ b/.trae-cn/skills/impeccable/scripts/pin.mjs @@ -27,7 +27,7 @@ const HARNESS_DIRS = [ // Valid sub-command names const VALID_COMMANDS = [ - 'craft', 'teach', 'extract', 'shape', + 'craft', 'teach', 'extract', 'document', 'shape', 'critique', 'audit', 'polish', 'bolder', 'quieter', 'distill', 'harden', 'onboard', 'live', 'animate', 'colorize', 'typeset', 'layout', 'delight', 'overdrive', diff --git a/.trae/skills/impeccable/SKILL.md b/.trae/skills/impeccable/SKILL.md index 0b2aeba42..9b91dd82c 100644 --- a/.trae/skills/impeccable/SKILL.md +++ b/.trae/skills/impeccable/SKILL.md @@ -3,7 +3,7 @@ name: impeccable description: Use when the user wants to design, redesign, shape, critique, audit, polish, clarify, distill, harden, optimize, adapt, animate, colorize, extract, or otherwise improve a frontend interface. Covers websites, landing pages, dashboards, product UI, app shells, components, forms, settings, onboarding, and empty states. Handles UX review, visual hierarchy, information architecture, cognitive load, accessibility, performance, responsive behavior, theming, anti-patterns, typography, fonts, spacing, layout, alignment, color, motion, micro-interactions, UX copy, error states, edge cases, i18n, and reusable design systems or tokens. Also use for bland designs that need to become bolder or more delightful, loud designs that should become quieter, live browser iteration on UI elements, or ambitious visual effects that should feel technically extraordinary. Not for backend-only or non-UI tasks. version: 3.0.0 user-invocable: true -argument-hint: "[craft|shape · audit|critique · animate|bolder|colorize|delight|layout|overdrive|quieter|typeset · adapt|clarify|distill · harden|onboard|optimize|polish · teach|extract|live] [target]" +argument-hint: "[craft|shape · audit|critique · animate|bolder|colorize|delight|layout|overdrive|quieter|typeset · adapt|clarify|distill · harden|onboard|optimize|polish · teach|document|extract|live] [target]" license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. --- @@ -29,10 +29,17 @@ After running the script, delete this entire section (from ` **Build & Plan** > `/impeccable craft [feature]` - Shape, then build a feature end-to-end > `/impeccable shape [feature]` - Plan UX/UI before writing code -> `/impeccable teach` - Set up design context for this project (one-time) +> `/impeccable teach` - Set up PRODUCT.md and DESIGN.md context for this project +> `/impeccable document` - Generate DESIGN.md from existing project code > `/impeccable extract [target]` - Pull reusable tokens and components into design system > > **Evaluate** @@ -347,6 +355,7 @@ When a sub-command is matched, load the linked reference and follow its instruct | `craft` | [craft](reference/craft.md) | Full shape-then-build flow with visual iteration | | `teach` | [teach](reference/teach.md) | One-time setup: gather design context for the project | | `extract` | [extract](reference/extract.md) | Pull reusable tokens and components into design system | +| `document` | [document](reference/document.md) | Generate DESIGN.md from existing project code (visual design system doc) | | `shape` | [shape](reference/shape.md) | Plan UX and UI before writing code (produces a design brief) | | `critique` | [critique](reference/critique.md) | UX design review with heuristic scoring and persona testing | | `audit` | [audit](reference/audit.md) | Technical quality checks across a11y, perf, theming, responsive, anti-patterns | diff --git a/.trae/skills/impeccable/reference/audit.md b/.trae/skills/impeccable/reference/audit.md index bbba2401b..c2258ac54 100644 --- a/.trae/skills/impeccable/reference/audit.md +++ b/.trae/skills/impeccable/reference/audit.md @@ -95,7 +95,7 @@ For each issue, document: - **Impact**: How it affects users - **WCAG/Standard**: Which standard it violates (if applicable) - **Recommendation**: How to fix it -- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command to use (prefer: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) ### Patterns & Systemic Issues @@ -114,7 +114,7 @@ List recommended commands in priority order (P0 first, then P1, then P2): 1. **[P?] `/command-name`** — Brief description (specific context from audit findings) 2. **[P?] `/command-name`** — Brief description (specific context) -**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. +**Rules**: Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset. Map findings to the most appropriate command. End with `/impeccable polish` as the final step if any fixes were recommended. After presenting the summary, tell the user: diff --git a/.trae/skills/impeccable/reference/critique.md b/.trae/skills/impeccable/reference/critique.md index 2ced96a7c..e9ae4e71e 100644 --- a/.trae/skills/impeccable/reference/critique.md +++ b/.trae/skills/impeccable/reference/critique.md @@ -132,7 +132,7 @@ For each issue, tag with **P0-P3 severity** (consult [heuristics-scoring](heuris - **[P?] What**: Name the problem clearly - **Why it matters**: How this hurts users or undermines goals - **Fix**: What to do about it (be concrete) -- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) +- **Suggested command**: Which command could address this (from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset) #### Persona Red Flags > *Consult [personas](personas.md)* @@ -197,7 +197,7 @@ List recommended commands in priority order, based on the user's answers: ... **Rules for recommendations**: -- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset +- Only recommend commands from: /impeccable adapt, /impeccable animate, /impeccable audit, /impeccable bolder, /impeccable clarify, /impeccable colorize, /impeccable critique, /impeccable delight, /impeccable distill, /impeccable document, /impeccable harden, /impeccable layout, /impeccable onboard, /impeccable optimize, /impeccable overdrive, /impeccable polish, /impeccable quieter, /impeccable shape, /impeccable typeset - Order by the user's stated priorities first, then by impact - Each item's description should carry enough context that the command knows what to focus on - Map each Priority Issue to the appropriate command diff --git a/.trae/skills/impeccable/reference/document.md b/.trae/skills/impeccable/reference/document.md new file mode 100644 index 000000000..ebf90bbf3 --- /dev/null +++ b/.trae/skills/impeccable/reference/document.md @@ -0,0 +1,126 @@ +Generate a DESIGN.md file in the project root that captures the current visual design system, so AI agents generating new screens stay on-brand. + +DESIGN.md follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/): a single markdown file at the project root with five fixed sections describing colors, typography, components, layout, and overall atmosphere. Keep section headers exactly as specified so the file stays compatible with other DESIGN.md-aware tools. + +## When to run + +- The user just ran `/impeccable teach` and needs the visual side documented. +- The skill noticed no `DESIGN.md` exists and nudged the user to create one. +- An existing `DESIGN.md` is stale (the design has drifted). +- Before a large redesign, to capture the current state as a reference. + +If a `DESIGN.md` already exists, **do not silently overwrite it**. Show the user the existing file and ask the user directly to clarify what you cannot infer. whether to refresh it, overwrite it, or merge into it. + +## Process (approach C: auto-extract, then confirm descriptive language) + +### Step 1: Find the design assets + +Search the codebase in priority order: + +1. **CSS custom properties** — grep for `--color-`, `--font-`, `--spacing-`, `--radius-`, `--shadow-`, `--ease-`, `--duration-` declarations in CSS files (usually `src/styles/`, `public/css/`, `app/globals.css`, etc.). Record name, value, and the file it's defined in. +2. **Tailwind config** — if `tailwind.config.{js,ts,mjs}` exists, read the `theme.extend` block for colors, fontFamily, spacing, borderRadius, boxShadow. +3. **CSS-in-JS theme files** — if the project uses styled-components, emotion, vanilla-extract, stitches, etc., look for `theme.ts`, `tokens.ts`, or equivalent. +4. **Design token files** — `tokens.json`, `design-tokens.json`, Style Dictionary output, W3C token community group format. +5. **Component library** — scan the main button, card, input, navigation, dialog components. Note their variant APIs and default styles. +6. **Global stylesheet** — the root CSS file usually has the base typography and color assignments. +7. **Visible rendered output** — if browser automation tools are available, load the live site and sample computed styles from key elements (body, h1, a, button, .card). This catches values that tokens miss. + +### Step 2: Auto-extract what can be auto-extracted + +Build a structured draft from the discovered tokens. For each token class: + +- **Colors**: Group by hue family. Convert hex → OKLCH to infer lightness/chroma. Identify background vs. text vs. accent by usage patterns in CSS (`background`, `color`, `border`, `fill`). Flag any that are only used once (possibly one-off, not system tokens). +- **Typography**: Extract font families and their declared stacks. Extract the scale (all `font-size` values used in CSS custom props + component styles). Extract weights actually used. Detect the scale ratio (1.125, 1.2, 1.25, 1.333, 1.5, golden). +- **Spacing**: Extract the scale, detect the base unit (4px, 8px, other). +- **Radii & shadows**: List the values used. +- **Components**: For each common component (button, card, input, nav, dialog), extract shape (radius), color assignment, hover/focus treatment, internal padding. + +### Step 3: Ask the user for qualitative language + +The following sections require creative input that cannot be auto-extracted reliably. ask the user directly to clarify what you cannot infer. for each (group them into one interaction if possible): + +- **Visual Theme & Atmosphere**: mood adjectives (airy/dense, minimal/maximalist, editorial/utilitarian, warm/clinical), aesthetic philosophy in 2-3 sentences, key characteristics as a bullet list. +- **Color character** (for auto-extracted colors): descriptive names ("Deep Muted Teal-Navy", not "blue-800"). Suggest 2-3 options per color based on the hue/saturation, let the user pick. +- **Typographic character**: describe the font pairing ("Modern geometric sans-serif with humanist warmth" > "Manrope 500"). Describe letter-spacing strategy. +- **Spacing philosophy**: 1-2 sentences on whitespace strategy ("generous breathing room that prioritizes photography"). +- **Component philosophy**: brief description of the feel of buttons, cards, inputs ("refined and understated" vs. "tactile and confident"). + +If the user has a `PRODUCT.md` that covers brand personality, quote a line from it so they see their own strategic language carry over. + +### Step 4: Write DESIGN.md + +Use this exact structure (section headers must match the Google spec character-for-character): + +```markdown +# Design System: [Project Title] +**Project ID:** [optional — only if a Stitch project ID exists] + +## 1. Visual Theme & Atmosphere + +[2-3 paragraph description using evocative adjectives. Start with the overall sanctuary/laboratory/workshop/stage analogy if one fits. End with a short **Key Characteristics:** bullet list.] + +## 2. Color Palette & Roles + +### [Semantic group name: Primary Foundation, Accent & Interactive, Typography & Text Hierarchy, Functional States, etc.] +- **[Descriptive Name]** (#HEX) – [Functional role. Where/why it's used.] + +## 3. Typography Rules + +**Primary Font Family:** [Name] +**Character:** [1-sentence personality description.] + +### Hierarchy & Weights +- **[Role (e.g. Display Headlines H1)]:** [Weight] weight ([num]), [letter-spacing], [size]. [Purpose.] + +### Spacing Principles +[Short list of rules about leading, letter-spacing, vertical rhythm.] + +## 4. Component Stylings + +### Buttons +- **Shape:** [radius description with px value in parens] +- **Primary CTA:** [color assignment + padding] +- **Hover State:** [transition description] +- **Focus State:** [accessibility treatment] +- **Secondary CTA (if applicable):** [description] + +### Cards & Containers +- **Corner Style:** [description] +- **Background:** [colors used] +- **Shadow Strategy:** [flat / soft / heavy] +- **Border:** [if any] +- **Internal Padding:** [scale] +- **Image Treatment:** [if relevant] + +### Navigation +- [Style, typography, default/hover/active states, mobile treatment] + +### Inputs/Forms +- [Stroke style, background, focus treatment] + +## 5. Layout Principles + +[Paragraph or short list describing whitespace strategy, margin scale, grid system, responsive breakpoints. Include px/rem values in parens.] +``` + +### Step 5: Write & confirm + +1. Write the file to `PROJECT_ROOT/DESIGN.md` (uppercase, at root). +2. Show the user the full DESIGN.md you wrote, briefly highlighting the non-obvious creative choices (descriptive color names, atmosphere language). +3. Offer to refine any section: "Want me to revise a section, add component patterns I missed, or adjust the atmosphere language?" + +## Style guidelines + +- **Descriptive > technical**: "Gently curved edges (8px radius)" > "rounded-lg". Include the technical value in parens, lead with the description. +- **Functional > decorative**: for each token, explain WHERE and WHY it's used, not just WHAT it is. +- **Exact values in parens**: hex codes, px/rem values, font weights — always the number in parens alongside the description. +- **Group colors semantically**: Foundation (backgrounds), Accent (interactive), Typography (text hierarchy), States (success/warning/error), not hex-sorted. +- **Reference the user's domain**: if the project is a DEX, say "trading-focused"; if it's a CMS, say "editorial". Domain-aware language helps agents pick sensible defaults. + +## Pitfalls + +- Don't paste raw CSS class names. Translate to descriptive language. +- Don't extract every token. Stop at what's actually reused — one-offs pollute the system. +- Don't invent components that don't exist. If the project only has buttons and cards, only document those. +- Don't overwrite an existing DESIGN.md without asking. +- Don't duplicate content from PRODUCT.md. DESIGN.md is strictly visual. diff --git a/.trae/skills/impeccable/reference/live.md b/.trae/skills/impeccable/reference/live.md index 3388e1897..19c16fa38 100644 --- a/.trae/skills/impeccable/reference/live.md +++ b/.trae/skills/impeccable/reference/live.md @@ -21,12 +21,21 @@ Output JSON: "serverPort": 8400, "serverToken": "...", "pageFile": "public/index.html", - "hasContext": true, - "context": "...full .impeccable.md contents..." + "hasProduct": true, + "product": "...full PRODUCT.md contents...", + "productPath": "PRODUCT.md", + "hasDesign": true, + "design": "...full DESIGN.md contents...", + "designPath": "DESIGN.md", + "migrated": false } ``` -Keep the `context` in mind for variant generation. If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. +Keep **PRODUCT.md** (strategic: users, brand, principles) and **DESIGN.md** (visual: colors, typography, components) in mind for variant generation. **DESIGN.md wins on visual decisions; PRODUCT.md wins on strategic/voice decisions.** + +If `migrated` is true, the loader auto-renamed legacy `.impeccable.md` to `PRODUCT.md` — mention this once to the user and suggest running `/impeccable document` to also generate a `DESIGN.md`. + +If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. ### First-time setup (config missing) diff --git a/.trae/skills/impeccable/reference/teach.md b/.trae/skills/impeccable/reference/teach.md index 972ca25be..aef07b2be 100644 --- a/.trae/skills/impeccable/reference/teach.md +++ b/.trae/skills/impeccable/reference/teach.md @@ -1,8 +1,31 @@ # Teach Flow -One-time setup that gathers design context for a project. Design without context produces generic output, so every other command reads this file before doing any work. +Gathers design context for a project and writes two complementary files at the project root: -## Step 1: Explore the Codebase +- **PRODUCT.md** (strategic): target users, product purpose, brand personality, anti-references, strategic design principles. Answers "who/what/why". +- **DESIGN.md** (visual): visual theme, color palette, typography, components, layout. Follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/). Answers "how it looks". + +Every other impeccable command reads these files before doing any work. + +## Step 1: Load current state + +Run the shared loader first so you know what already exists: + +```bash +node {{scripts_path}}/load-context.mjs +``` + +The output tells you whether PRODUCT.md and/or DESIGN.md already exist. If `migrated: true`, legacy `.impeccable.md` was auto-renamed to `PRODUCT.md`. Mention this once to the user. + +Decision tree: +- **Neither file exists (empty project or no context yet)**: do Steps 2-4 (write PRODUCT.md), then decide on DESIGN.md based on whether there's code to analyze. +- **PRODUCT.md exists, DESIGN.md missing**: skip to Step 5 — offer to run `/impeccable document` for DESIGN.md. +- **Both exist**: ask the user directly to clarify what you cannot infer. which to refresh. Skip the one the user doesn't want changed. +- **Just DESIGN.md exists (unusual)**: do Steps 2-4 to produce PRODUCT.md. + +Never silently overwrite an existing file. Always confirm first. + +## Step 2: Explore the codebase Before asking questions, thoroughly scan the project to discover what you can: @@ -13,9 +36,9 @@ Before asking questions, thoroughly scan the project to discover what you can: - **Design tokens / CSS variables**: Existing color palettes, font stacks, spacing scales - **Any style guides or brand documentation** -Note what you've learned and what remains unclear. +Note what you've learned and what remains unclear. This exploration feeds both PRODUCT.md and DESIGN.md. -## Step 2: Ask UX-Focused Questions +## Step 3: Ask strategic questions (for PRODUCT.md) ask the user directly to clarify what you cannot infer. Focus only on what you couldn't infer from the codebase: @@ -29,39 +52,53 @@ ask the user directly to clarify what you cannot infer. Focus only on what you c - Any reference sites or apps that capture the right feel? What specifically about them? - What should this explicitly NOT look like? Any anti-references? -### Aesthetic Preferences -- Any strong preferences for visual direction? (minimal, bold, elegant, playful, technical, organic, etc.) -- Light mode, dark mode, or both? -- Any colors that must be used or avoided? - ### Accessibility & Inclusion - Specific accessibility requirements? (WCAG level, known user needs) - Considerations for reduced motion, color blindness, or other accommodations? -Skip questions where the answer is already clear from the codebase exploration. +Skip questions where the answer is already clear. **Do NOT ask about colors, fonts, radii, or visual styling here** — those belong in DESIGN.md, not PRODUCT.md. -## Step 3: Write Design Context +## Step 4: Write PRODUCT.md -Synthesize your findings and the user's answers into a `## Design Context` section: +Synthesize into a strategic document: ```markdown -## Design Context +# Product -### Users +## Users [Who they are, their context, the job to be done] -### Brand Personality +## Product Purpose +[What this product does, why it exists, what success looks like] + +## Brand Personality [Voice, tone, 3-word personality, emotional goals] -### Aesthetic Direction -[Visual tone, references, anti-references, theme] +## Anti-references +[What this should NOT look like. Specific bad-example sites or patterns to avoid.] -### Design Principles -[3-5 principles derived from the conversation that should guide all design decisions] +## Design Principles +[3-5 strategic principles derived from the conversation. Principles like "practice what you preach", "editorial over marketing", "expert confidence" — NOT visual rules like "use OKLCH" or "magenta accent".] + +## Accessibility & Inclusion +[WCAG level, known user needs, considerations] ``` -Write this section to `.impeccable.md` in the project root. If the file already exists, update the Design Context section in place. +Write to `PROJECT_ROOT/PRODUCT.md`. If `.impeccable.md` existed, the loader already renamed it — merge into that content rather than starting from scratch. -Then ask the user directly to clarify what you cannot infer. whether they'd also like the Design Context appended to RULES.md. If yes, append or update the section there as well. +## Step 5: Decide on DESIGN.md -Confirm completion and summarize the key design principles that will now guide all future work. +If the project has meaningful code to analyze (CSS tokens, components, a running site), **offer to run `/impeccable document`** next: "I can also generate a DESIGN.md that captures your visual design system (colors, typography, components) so variants stay on-brand. Want to do that now?" + +If the user agrees, delegate to `/impeccable document` (load its reference and follow that flow). + +If the project is empty (no code yet, pre-implementation), skip DESIGN.md — there's nothing visual to document yet. Mention: "Once you've built some of the interface, run `/impeccable document` to generate a DESIGN.md." + +## Step 6: Confirm and wrap up + +Summarize: +- What was written (PRODUCT.md, DESIGN.md, or both) +- The 3-5 strategic principles from PRODUCT.md that will guide future work +- If DESIGN.md is pending, remind the user how to generate it later + +Optionally ask the user directly to clarify what you cannot infer. whether they'd like a brief summary of PRODUCT.md appended to RULES.md for easier agent reference. If yes, append a short **Design Context** pointer section there. diff --git a/.trae/skills/impeccable/scripts/command-metadata.json b/.trae/skills/impeccable/scripts/command-metadata.json index 2974e08f6..d8282689a 100644 --- a/.trae/skills/impeccable/scripts/command-metadata.json +++ b/.trae/skills/impeccable/scripts/command-metadata.json @@ -4,7 +4,11 @@ "argumentHint": "[feature description]" }, "teach": { - "description": "One-time setup that gathers design context for a project. Runs a short discovery interview and writes the answers to .impeccable.md. Every other command reads this file before doing work. Use once per project.", + "description": "Gathers design context for a project. Runs a short discovery interview and writes PRODUCT.md (strategic: users, brand, principles) and, when code exists to analyze, DESIGN.md (visual: colors, typography, components). Every other command reads these files before doing work. Use once per project.", + "argumentHint": "" + }, + "document": { + "description": "Generate a DESIGN.md file that captures the current visual design system. Auto-extracts colors, typography, spacing, radii, and component patterns from the codebase, then asks the user to confirm descriptive language for atmosphere and color character. Follows the Google Stitch DESIGN.md format so the file is tool-compatible. Use when you need a visual design spec an AI agent can follow to stay on-brand.", "argumentHint": "" }, "extract": { diff --git a/.trae/skills/impeccable/scripts/live.mjs b/.trae/skills/impeccable/scripts/live.mjs index 93f05456e..37b6f8997 100644 --- a/.trae/skills/impeccable/scripts/live.mjs +++ b/.trae/skills/impeccable/scripts/live.mjs @@ -21,10 +21,10 @@ import { execSync } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { loadContext } from './load-context.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const PID_FILE = path.join(process.cwd(), '.impeccable-live.json'); -const CONTEXT_FILE = path.join(process.cwd(), '.impeccable.md'); async function liveCli() { const args = process.argv.slice(2); @@ -79,9 +79,8 @@ The agent should then: process.exit(1); } - // 4. Load design context if available - let context = null; - try { context = fs.readFileSync(CONTEXT_FILE, 'utf-8'); } catch { /* optional */ } + // 4. Load PRODUCT.md + DESIGN.md context (auto-migrates legacy .impeccable.md) + const ctx = loadContext(process.cwd()); // 5. Emit everything the agent needs console.log(JSON.stringify({ @@ -89,8 +88,13 @@ The agent should then: serverPort: serverInfo.port, serverToken: serverInfo.token, pageFile: checkResult.config.file, - hasContext: !!context, - context, + hasProduct: ctx.hasProduct, + product: ctx.product, + productPath: ctx.productPath, + hasDesign: ctx.hasDesign, + design: ctx.design, + designPath: ctx.designPath, + migrated: ctx.migrated, }, null, 2)); } diff --git a/.trae/skills/impeccable/scripts/load-context.mjs b/.trae/skills/impeccable/scripts/load-context.mjs new file mode 100644 index 000000000..ab3be08f1 --- /dev/null +++ b/.trae/skills/impeccable/scripts/load-context.mjs @@ -0,0 +1,93 @@ +/** + * Shared context loader for every impeccable command that needs to know + * "who is this for" and "what does this look like". + * + * Input: project root (process.cwd()). + * + * Output (JSON to stdout): + * { + * hasProduct: boolean, // PRODUCT.md found (or auto-migrated) + * product: string | null, // PRODUCT.md contents + * productPath: string | null, // relative path + * hasDesign: boolean, // DESIGN.md found + * design: string | null, // DESIGN.md contents + * designPath: string | null, + * migrated: boolean, // true if we auto-renamed .impeccable.md -> PRODUCT.md + * } + * + * Filename matching is case-insensitive for PRODUCT.md and DESIGN.md. The + * Google DESIGN.md convention is uppercase at repo root; Kiro-style and + * lowercase variants are also matched so users don't get punished for case. + */ + +import fs from 'node:fs'; +import path from 'node:path'; + +const PRODUCT_NAMES = ['PRODUCT.md', 'Product.md', 'product.md']; +const DESIGN_NAMES = ['DESIGN.md', 'Design.md', 'design.md']; +const LEGACY_NAMES = ['.impeccable.md']; + +export function loadContext(cwd = process.cwd()) { + let migrated = false; + + // 1. Look for PRODUCT.md (case-insensitive) + let productPath = firstExisting(cwd, PRODUCT_NAMES); + + // 2. Legacy: if no PRODUCT.md but .impeccable.md exists, rename in place + if (!productPath) { + const legacyPath = firstExisting(cwd, LEGACY_NAMES); + if (legacyPath) { + const newPath = path.join(cwd, 'PRODUCT.md'); + try { + fs.renameSync(legacyPath, newPath); + productPath = newPath; + migrated = true; + } catch { + // Rename failed (permissions, etc.) — fall back to reading legacy in place + productPath = legacyPath; + } + } + } + + // 3. DESIGN.md (case-insensitive) + const designPath = firstExisting(cwd, DESIGN_NAMES); + + const product = productPath ? safeRead(productPath) : null; + const design = designPath ? safeRead(designPath) : null; + + return { + hasProduct: !!product, + product, + productPath: productPath ? path.relative(cwd, productPath) : null, + hasDesign: !!design, + design, + designPath: designPath ? path.relative(cwd, designPath) : null, + migrated, + }; +} + +function firstExisting(cwd, names) { + for (const name of names) { + const abs = path.join(cwd, name); + if (fs.existsSync(abs)) return abs; + } + return null; +} + +function safeRead(p) { + try { return fs.readFileSync(p, 'utf-8'); } catch { return null; } +} + +// --------------------------------------------------------------------------- +// CLI mode — print the context as JSON +// --------------------------------------------------------------------------- + +function cli() { + const result = loadContext(process.cwd()); + console.log(JSON.stringify(result, null, 2)); +} + +const _running = process.argv[1]; +if (_running?.endsWith('load-context.mjs') || _running?.endsWith('load-context.mjs/')) { + cli(); +} diff --git a/.trae/skills/impeccable/scripts/pin.mjs b/.trae/skills/impeccable/scripts/pin.mjs index 89a6babeb..ba02783fb 100644 --- a/.trae/skills/impeccable/scripts/pin.mjs +++ b/.trae/skills/impeccable/scripts/pin.mjs @@ -27,7 +27,7 @@ const HARNESS_DIRS = [ // Valid sub-command names const VALID_COMMANDS = [ - 'craft', 'teach', 'extract', 'shape', + 'craft', 'teach', 'extract', 'document', 'shape', 'critique', 'audit', 'polish', 'bolder', 'quieter', 'distill', 'harden', 'onboard', 'live', 'animate', 'colorize', 'typeset', 'layout', 'delight', 'overdrive', diff --git a/NOTICE.md b/NOTICE.md index 1e501cc6e..4a0fe1a81 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -13,5 +13,5 @@ The `impeccable` skill in this project builds on Anthropic's original frontend-d This project extends the original with: - 7 domain-specific reference files (typography, color-and-contrast, spatial-design, motion-design, interaction-design, responsive-design, ux-writing) -- 22 commands +- 23 commands - Expanded patterns and anti-patterns diff --git a/README.md b/README.md index 81b8e54b3..b32345c58 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Impeccable -The vocabulary you didn't know you needed. 1 skill, 22 commands, and curated anti-patterns for impeccable frontend design. +The vocabulary you didn't know you needed. 1 skill, 23 commands, and curated anti-patterns for impeccable frontend design. > **Quick start:** Visit [impeccable.style](https://impeccable.style) to download ready-to-use bundles. @@ -12,7 +12,7 @@ Every LLM learned from the same generic templates. Without guidance, you get the Impeccable fights that bias with: - **An expanded skill** with 7 domain-specific reference files ([view source](source/skills/impeccable/)) -- **22 commands** to audit, review, polish, distill, animate, and more +- **23 commands** to audit, review, polish, distill, animate, and more - **Curated anti-patterns** that explicitly tell the AI what NOT to do ## What's Included @@ -31,14 +31,15 @@ A comprehensive design skill with 7 domain-specific references ([view skill](sou | [responsive-design](source/skills/impeccable/reference/responsive-design.md) | Mobile-first, fluid design, container queries | | [ux-writing](source/skills/impeccable/reference/ux-writing.md) | Button labels, error messages, empty states | -### 22 Commands +### 23 Commands All commands are accessed through `/impeccable`: | Command | What it does | |---------|--------------| | `/impeccable craft` | Full shape-then-build flow with visual iteration | -| `/impeccable teach` | One-time setup: gather design context, save to config | +| `/impeccable teach` | One-time setup: gather design context, write PRODUCT.md and DESIGN.md | +| `/impeccable document` | Generate DESIGN.md from existing project code | | `/impeccable extract` | Pull reusable components and tokens into the design system | | `/impeccable shape` | Plan UX/UI before writing code | | `/impeccable critique` | UX design review: hierarchy, clarity, emotional resonance | diff --git a/public/index.html b/public/index.html index 68bac36f0..905fd69b3 100644 --- a/public/index.html +++ b/public/index.html @@ -13,7 +13,7 @@ Impeccable: The missing upgrade to Anthropic's impeccable skill - + @@ -21,7 +21,7 @@ - + @@ -29,7 +29,7 @@ - + @@ -89,13 +89,13 @@

Impeccable

Design fluency for AI harnesses

-

Great design prompts require design vocabulary. Most people don't have it. Impeccable teaches your AI deep design knowledge and gives you 22 commands to steer the result.

-

Impeccable teaches your AI real design and gives you 22 commands to steer the result.

+

Great design prompts require design vocabulary. Most people don't have it. Impeccable teaches your AI deep design knowledge and gives you 23 commands to steer the result.

+

Impeccable teaches your AI real design and gives you 23 commands to steer the result.

What's included
- Impeccable agent skill with 22 design commands + Impeccable agent skill with 23 design commands · Optional CLI + Chrome extension
@@ -118,7 +118,7 @@
- + @@ -204,7 +204,7 @@

The Language

-

22 commands form a shared vocabulary between you and your AI. Each one encodes a specific design discipline, so you can steer with precision.

+

23 commands form a shared vocabulary between you and your AI. Each one encodes a specific design discipline, so you can steer with precision.

@@ -333,7 +333,7 @@

1Install the skill and CLI

-

One agent skill that teaches your AI to design, with 22 commands bundled inside. Plus the CLI that powers visual mode and scans files outside the skill.

+

One agent skill that teaches your AI to design, with 23 commands bundled inside. Plus the CLI that powers visual mode and scans files outside the skill.

@@ -411,7 +411,7 @@

2Use it

-

Impeccable gives you a shared design vocabulary with your AI. 22 commands (polish, audit, critique, typeset, and more) that each encode a specific design discipline, so you can steer with precision.

+

Impeccable gives you a shared design vocabulary with your AI. 23 commands (polish, audit, critique, typeset, and more) that each encode a specific design discipline, so you can steer with precision.

  1. @@ -510,7 +510,7 @@ April 10, 2026
    -
  • 18 skills became 1 skill with 22 commands. Every command now lives under /impeccable: /impeccable audit, /impeccable polish, /impeccable critique, and the rest. One entry in your / menu instead of 18, a shared design vocabulary between you and your AI, and far less namespace pollution as the plugin ecosystem grows. The autocomplete shows the full list the moment you type /impeccable.
  • +
  • 18 skills became 1 skill with 23 commands. Every command now lives under /impeccable: /impeccable audit, /impeccable polish, /impeccable critique, and the rest. One entry in your / menu instead of 18, a shared design vocabulary between you and your AI, and far less namespace pollution as the plugin ecosystem grows. The autocomplete shows the full list the moment you type /impeccable.
  • Pin your favorites back as shortcuts. Run /impeccable pin audit and /audit becomes a standalone command again, without reversing the consolidation. Under the hood it writes a lightweight redirect skill that delegates to /impeccable audit, so updates to the parent skill flow through automatically. /impeccable unpin audit removes it.
diff --git a/public/js/components/framework-viz.js b/public/js/components/framework-viz.js index e9bb4e652..1caf03d55 100644 --- a/public/js/components/framework-viz.js +++ b/public/js/components/framework-viz.js @@ -46,6 +46,7 @@ const commandSymbols = { 'harden': 'Ha', 'onboard': 'On', 'teach': 'Te', + 'document': 'Dc', 'extract': 'Ex', 'live': 'Li' }; @@ -57,7 +58,7 @@ const commandNumbers = { 'delight': 10, 'bolder': 11, 'quieter': 12, 'overdrive': 13, 'distill': 14, 'clarify': 15, 'adapt': 16, 'polish': 17, 'optimize': 18, 'harden': 19, 'onboard': 20, - 'teach': 21, 'extract': 22, 'live': 23 + 'teach': 21, 'document': 22, 'extract': 23, 'live': 24 }; // After the v3.0 consolidation, all commands except the root "impeccable" are diff --git a/public/js/data.js b/public/js/data.js index e5ac46729..9c66d7d27 100644 --- a/public/js/data.js +++ b/public/js/data.js @@ -74,6 +74,7 @@ export const commandProcessSteps = { 'harden': ['Assess', 'Implement', 'Test', 'Verify'], 'onboard': ['Identify', 'Design', 'Guide', 'Measure'], 'teach': ['Explore', 'Interview', 'Synthesize', 'Save'], + 'document': ['Scan', 'Extract', 'Describe', 'Write'], 'extract': ['Identify', 'Abstract', 'Migrate', 'Document'], 'live': ['Start', 'Select', 'Generate', 'Accept'] }; @@ -106,6 +107,7 @@ export const commandCategories = { 'onboard': 'harden', // SYSTEM - setup and tooling 'teach': 'system', + 'document': 'system', 'extract': 'system', 'live': 'system' }; diff --git a/public/js/generated/counts.js b/public/js/generated/counts.js index 7737740f5..e2d1a00d8 100644 --- a/public/js/generated/counts.js +++ b/public/js/generated/counts.js @@ -1,3 +1,3 @@ // GENERATED by build.js — do not edit -export const COMMAND_COUNT = 22; +export const COMMAND_COUNT = 23; export const DETECTION_COUNT = 25; diff --git a/scripts/lib/sub-pages-data.js b/scripts/lib/sub-pages-data.js index 6d95f2a0c..69250a242 100644 --- a/scripts/lib/sub-pages-data.js +++ b/scripts/lib/sub-pages-data.js @@ -71,6 +71,7 @@ export const SKILL_CATEGORIES = { onboard: 'harden', // SYSTEM - setup and tooling teach: 'system', + document: 'system', extract: 'system', live: 'system', }; @@ -129,8 +130,9 @@ export const COMMAND_RELATIONSHIPS = { harden: { combinesWith: ['optimize'] }, onboard: { combinesWith: ['clarify', 'delight'] }, // System - teach: {}, - extract: {}, + teach: { combinesWith: ['document'] }, + document: { combinesWith: ['teach', 'extract'] }, + extract: { combinesWith: ['document'] }, live: {}, }; diff --git a/scripts/lib/utils.js b/scripts/lib/utils.js index 476a7c8f2..b839957ac 100644 --- a/scripts/lib/utils.js +++ b/scripts/lib/utils.js @@ -394,8 +394,8 @@ const EXCLUDED_FROM_SUGGESTIONS = new Set([ // These are the commands that audit/critique/etc. reference when suggesting next steps. const IMPECCABLE_SUB_COMMANDS = [ 'adapt', 'animate', 'audit', 'bolder', 'clarify', 'colorize', - 'critique', 'delight', 'distill', 'harden', 'layout', 'onboard', - 'optimize', 'overdrive', 'polish', 'quieter', 'shape', 'typeset', + 'critique', 'delight', 'distill', 'document', 'harden', 'layout', + 'onboard', 'optimize', 'overdrive', 'polish', 'quieter', 'shape', 'typeset', ]; export function replacePlaceholders(content, provider, commandNames = [], allSkillNames = []) { diff --git a/source/skills/impeccable/SKILL.md b/source/skills/impeccable/SKILL.md index e95bbbda6..2398361a6 100644 --- a/source/skills/impeccable/SKILL.md +++ b/source/skills/impeccable/SKILL.md @@ -30,10 +30,17 @@ After running the script, delete this entire section (from ` **Build & Plan** > `{{command_prefix}}impeccable craft [feature]` - Shape, then build a feature end-to-end > `{{command_prefix}}impeccable shape [feature]` - Plan UX/UI before writing code -> `{{command_prefix}}impeccable teach` - Set up design context for this project (one-time) +> `{{command_prefix}}impeccable teach` - Set up PRODUCT.md and DESIGN.md context for this project +> `{{command_prefix}}impeccable document` - Generate DESIGN.md from existing project code > `{{command_prefix}}impeccable extract [target]` - Pull reusable tokens and components into design system > > **Evaluate** @@ -348,6 +356,7 @@ When a sub-command is matched, load the linked reference and follow its instruct | `craft` | [craft](reference/craft.md) | Full shape-then-build flow with visual iteration | | `teach` | [teach](reference/teach.md) | One-time setup: gather design context for the project | | `extract` | [extract](reference/extract.md) | Pull reusable tokens and components into design system | +| `document` | [document](reference/document.md) | Generate DESIGN.md from existing project code (visual design system doc) | | `shape` | [shape](reference/shape.md) | Plan UX and UI before writing code (produces a design brief) | | `critique` | [critique](reference/critique.md) | UX design review with heuristic scoring and persona testing | | `audit` | [audit](reference/audit.md) | Technical quality checks across a11y, perf, theming, responsive, anti-patterns | diff --git a/source/skills/impeccable/reference/document.md b/source/skills/impeccable/reference/document.md new file mode 100644 index 000000000..0a3b2073c --- /dev/null +++ b/source/skills/impeccable/reference/document.md @@ -0,0 +1,126 @@ +Generate a DESIGN.md file in the project root that captures the current visual design system, so AI agents generating new screens stay on-brand. + +DESIGN.md follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/): a single markdown file at the project root with five fixed sections describing colors, typography, components, layout, and overall atmosphere. Keep section headers exactly as specified so the file stays compatible with other DESIGN.md-aware tools. + +## When to run + +- The user just ran `{{command_prefix}}impeccable teach` and needs the visual side documented. +- The skill noticed no `DESIGN.md` exists and nudged the user to create one. +- An existing `DESIGN.md` is stale (the design has drifted). +- Before a large redesign, to capture the current state as a reference. + +If a `DESIGN.md` already exists, **do not silently overwrite it**. Show the user the existing file and {{ask_instruction}} whether to refresh it, overwrite it, or merge into it. + +## Process (approach C: auto-extract, then confirm descriptive language) + +### Step 1: Find the design assets + +Search the codebase in priority order: + +1. **CSS custom properties** — grep for `--color-`, `--font-`, `--spacing-`, `--radius-`, `--shadow-`, `--ease-`, `--duration-` declarations in CSS files (usually `src/styles/`, `public/css/`, `app/globals.css`, etc.). Record name, value, and the file it's defined in. +2. **Tailwind config** — if `tailwind.config.{js,ts,mjs}` exists, read the `theme.extend` block for colors, fontFamily, spacing, borderRadius, boxShadow. +3. **CSS-in-JS theme files** — if the project uses styled-components, emotion, vanilla-extract, stitches, etc., look for `theme.ts`, `tokens.ts`, or equivalent. +4. **Design token files** — `tokens.json`, `design-tokens.json`, Style Dictionary output, W3C token community group format. +5. **Component library** — scan the main button, card, input, navigation, dialog components. Note their variant APIs and default styles. +6. **Global stylesheet** — the root CSS file usually has the base typography and color assignments. +7. **Visible rendered output** — if browser automation tools are available, load the live site and sample computed styles from key elements (body, h1, a, button, .card). This catches values that tokens miss. + +### Step 2: Auto-extract what can be auto-extracted + +Build a structured draft from the discovered tokens. For each token class: + +- **Colors**: Group by hue family. Convert hex → OKLCH to infer lightness/chroma. Identify background vs. text vs. accent by usage patterns in CSS (`background`, `color`, `border`, `fill`). Flag any that are only used once (possibly one-off, not system tokens). +- **Typography**: Extract font families and their declared stacks. Extract the scale (all `font-size` values used in CSS custom props + component styles). Extract weights actually used. Detect the scale ratio (1.125, 1.2, 1.25, 1.333, 1.5, golden). +- **Spacing**: Extract the scale, detect the base unit (4px, 8px, other). +- **Radii & shadows**: List the values used. +- **Components**: For each common component (button, card, input, nav, dialog), extract shape (radius), color assignment, hover/focus treatment, internal padding. + +### Step 3: Ask the user for qualitative language + +The following sections require creative input that cannot be auto-extracted reliably. {{ask_instruction}} for each (group them into one interaction if possible): + +- **Visual Theme & Atmosphere**: mood adjectives (airy/dense, minimal/maximalist, editorial/utilitarian, warm/clinical), aesthetic philosophy in 2-3 sentences, key characteristics as a bullet list. +- **Color character** (for auto-extracted colors): descriptive names ("Deep Muted Teal-Navy", not "blue-800"). Suggest 2-3 options per color based on the hue/saturation, let the user pick. +- **Typographic character**: describe the font pairing ("Modern geometric sans-serif with humanist warmth" > "Manrope 500"). Describe letter-spacing strategy. +- **Spacing philosophy**: 1-2 sentences on whitespace strategy ("generous breathing room that prioritizes photography"). +- **Component philosophy**: brief description of the feel of buttons, cards, inputs ("refined and understated" vs. "tactile and confident"). + +If the user has a `PRODUCT.md` that covers brand personality, quote a line from it so they see their own strategic language carry over. + +### Step 4: Write DESIGN.md + +Use this exact structure (section headers must match the Google spec character-for-character): + +```markdown +# Design System: [Project Title] +**Project ID:** [optional — only if a Stitch project ID exists] + +## 1. Visual Theme & Atmosphere + +[2-3 paragraph description using evocative adjectives. Start with the overall sanctuary/laboratory/workshop/stage analogy if one fits. End with a short **Key Characteristics:** bullet list.] + +## 2. Color Palette & Roles + +### [Semantic group name: Primary Foundation, Accent & Interactive, Typography & Text Hierarchy, Functional States, etc.] +- **[Descriptive Name]** (#HEX) – [Functional role. Where/why it's used.] + +## 3. Typography Rules + +**Primary Font Family:** [Name] +**Character:** [1-sentence personality description.] + +### Hierarchy & Weights +- **[Role (e.g. Display Headlines H1)]:** [Weight] weight ([num]), [letter-spacing], [size]. [Purpose.] + +### Spacing Principles +[Short list of rules about leading, letter-spacing, vertical rhythm.] + +## 4. Component Stylings + +### Buttons +- **Shape:** [radius description with px value in parens] +- **Primary CTA:** [color assignment + padding] +- **Hover State:** [transition description] +- **Focus State:** [accessibility treatment] +- **Secondary CTA (if applicable):** [description] + +### Cards & Containers +- **Corner Style:** [description] +- **Background:** [colors used] +- **Shadow Strategy:** [flat / soft / heavy] +- **Border:** [if any] +- **Internal Padding:** [scale] +- **Image Treatment:** [if relevant] + +### Navigation +- [Style, typography, default/hover/active states, mobile treatment] + +### Inputs/Forms +- [Stroke style, background, focus treatment] + +## 5. Layout Principles + +[Paragraph or short list describing whitespace strategy, margin scale, grid system, responsive breakpoints. Include px/rem values in parens.] +``` + +### Step 5: Write & confirm + +1. Write the file to `PROJECT_ROOT/DESIGN.md` (uppercase, at root). +2. Show the user the full DESIGN.md you wrote, briefly highlighting the non-obvious creative choices (descriptive color names, atmosphere language). +3. Offer to refine any section: "Want me to revise a section, add component patterns I missed, or adjust the atmosphere language?" + +## Style guidelines + +- **Descriptive > technical**: "Gently curved edges (8px radius)" > "rounded-lg". Include the technical value in parens, lead with the description. +- **Functional > decorative**: for each token, explain WHERE and WHY it's used, not just WHAT it is. +- **Exact values in parens**: hex codes, px/rem values, font weights — always the number in parens alongside the description. +- **Group colors semantically**: Foundation (backgrounds), Accent (interactive), Typography (text hierarchy), States (success/warning/error), not hex-sorted. +- **Reference the user's domain**: if the project is a DEX, say "trading-focused"; if it's a CMS, say "editorial". Domain-aware language helps agents pick sensible defaults. + +## Pitfalls + +- Don't paste raw CSS class names. Translate to descriptive language. +- Don't extract every token. Stop at what's actually reused — one-offs pollute the system. +- Don't invent components that don't exist. If the project only has buttons and cards, only document those. +- Don't overwrite an existing DESIGN.md without asking. +- Don't duplicate content from PRODUCT.md. DESIGN.md is strictly visual. diff --git a/source/skills/impeccable/reference/live.md b/source/skills/impeccable/reference/live.md index 3388e1897..19c16fa38 100644 --- a/source/skills/impeccable/reference/live.md +++ b/source/skills/impeccable/reference/live.md @@ -21,12 +21,21 @@ Output JSON: "serverPort": 8400, "serverToken": "...", "pageFile": "public/index.html", - "hasContext": true, - "context": "...full .impeccable.md contents..." + "hasProduct": true, + "product": "...full PRODUCT.md contents...", + "productPath": "PRODUCT.md", + "hasDesign": true, + "design": "...full DESIGN.md contents...", + "designPath": "DESIGN.md", + "migrated": false } ``` -Keep the `context` in mind for variant generation. If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. +Keep **PRODUCT.md** (strategic: users, brand, principles) and **DESIGN.md** (visual: colors, typography, components) in mind for variant generation. **DESIGN.md wins on visual decisions; PRODUCT.md wins on strategic/voice decisions.** + +If `migrated` is true, the loader auto-renamed legacy `.impeccable.md` to `PRODUCT.md` — mention this once to the user and suggest running `/impeccable document` to also generate a `DESIGN.md`. + +If browser automation tools are available, navigate to the page so the user can see it. Then proceed directly to the poll loop — no other setup steps needed. ### First-time setup (config missing) diff --git a/source/skills/impeccable/reference/teach.md b/source/skills/impeccable/reference/teach.md index b56a55e19..2d0c1488c 100644 --- a/source/skills/impeccable/reference/teach.md +++ b/source/skills/impeccable/reference/teach.md @@ -1,8 +1,31 @@ # Teach Flow -One-time setup that gathers design context for a project. Design without context produces generic output, so every other command reads this file before doing any work. +Gathers design context for a project and writes two complementary files at the project root: -## Step 1: Explore the Codebase +- **PRODUCT.md** (strategic): target users, product purpose, brand personality, anti-references, strategic design principles. Answers "who/what/why". +- **DESIGN.md** (visual): visual theme, color palette, typography, components, layout. Follows the [Google Stitch DESIGN.md format](https://stitch.withgoogle.com/docs/design-md/format/). Answers "how it looks". + +Every other impeccable command reads these files before doing any work. + +## Step 1: Load current state + +Run the shared loader first so you know what already exists: + +```bash +node {{scripts_path}}/load-context.mjs +``` + +The output tells you whether PRODUCT.md and/or DESIGN.md already exist. If `migrated: true`, legacy `.impeccable.md` was auto-renamed to `PRODUCT.md`. Mention this once to the user. + +Decision tree: +- **Neither file exists (empty project or no context yet)**: do Steps 2-4 (write PRODUCT.md), then decide on DESIGN.md based on whether there's code to analyze. +- **PRODUCT.md exists, DESIGN.md missing**: skip to Step 5 — offer to run `/impeccable document` for DESIGN.md. +- **Both exist**: {{ask_instruction}} which to refresh. Skip the one the user doesn't want changed. +- **Just DESIGN.md exists (unusual)**: do Steps 2-4 to produce PRODUCT.md. + +Never silently overwrite an existing file. Always confirm first. + +## Step 2: Explore the codebase Before asking questions, thoroughly scan the project to discover what you can: @@ -13,9 +36,9 @@ Before asking questions, thoroughly scan the project to discover what you can: - **Design tokens / CSS variables**: Existing color palettes, font stacks, spacing scales - **Any style guides or brand documentation** -Note what you've learned and what remains unclear. +Note what you've learned and what remains unclear. This exploration feeds both PRODUCT.md and DESIGN.md. -## Step 2: Ask UX-Focused Questions +## Step 3: Ask strategic questions (for PRODUCT.md) {{ask_instruction}} Focus only on what you couldn't infer from the codebase: @@ -29,39 +52,53 @@ Note what you've learned and what remains unclear. - Any reference sites or apps that capture the right feel? What specifically about them? - What should this explicitly NOT look like? Any anti-references? -### Aesthetic Preferences -- Any strong preferences for visual direction? (minimal, bold, elegant, playful, technical, organic, etc.) -- Light mode, dark mode, or both? -- Any colors that must be used or avoided? - ### Accessibility & Inclusion - Specific accessibility requirements? (WCAG level, known user needs) - Considerations for reduced motion, color blindness, or other accommodations? -Skip questions where the answer is already clear from the codebase exploration. +Skip questions where the answer is already clear. **Do NOT ask about colors, fonts, radii, or visual styling here** — those belong in DESIGN.md, not PRODUCT.md. -## Step 3: Write Design Context +## Step 4: Write PRODUCT.md -Synthesize your findings and the user's answers into a `## Design Context` section: +Synthesize into a strategic document: ```markdown -## Design Context +# Product -### Users +## Users [Who they are, their context, the job to be done] -### Brand Personality +## Product Purpose +[What this product does, why it exists, what success looks like] + +## Brand Personality [Voice, tone, 3-word personality, emotional goals] -### Aesthetic Direction -[Visual tone, references, anti-references, theme] +## Anti-references +[What this should NOT look like. Specific bad-example sites or patterns to avoid.] -### Design Principles -[3-5 principles derived from the conversation that should guide all design decisions] +## Design Principles +[3-5 strategic principles derived from the conversation. Principles like "practice what you preach", "editorial over marketing", "expert confidence" — NOT visual rules like "use OKLCH" or "magenta accent".] + +## Accessibility & Inclusion +[WCAG level, known user needs, considerations] ``` -Write this section to `.impeccable.md` in the project root. If the file already exists, update the Design Context section in place. +Write to `PROJECT_ROOT/PRODUCT.md`. If `.impeccable.md` existed, the loader already renamed it — merge into that content rather than starting from scratch. -Then {{ask_instruction}} whether they'd also like the Design Context appended to {{config_file}}. If yes, append or update the section there as well. +## Step 5: Decide on DESIGN.md -Confirm completion and summarize the key design principles that will now guide all future work. +If the project has meaningful code to analyze (CSS tokens, components, a running site), **offer to run `/impeccable document`** next: "I can also generate a DESIGN.md that captures your visual design system (colors, typography, components) so variants stay on-brand. Want to do that now?" + +If the user agrees, delegate to `/impeccable document` (load its reference and follow that flow). + +If the project is empty (no code yet, pre-implementation), skip DESIGN.md — there's nothing visual to document yet. Mention: "Once you've built some of the interface, run `/impeccable document` to generate a DESIGN.md." + +## Step 6: Confirm and wrap up + +Summarize: +- What was written (PRODUCT.md, DESIGN.md, or both) +- The 3-5 strategic principles from PRODUCT.md that will guide future work +- If DESIGN.md is pending, remind the user how to generate it later + +Optionally {{ask_instruction}} whether they'd like a brief summary of PRODUCT.md appended to {{config_file}} for easier agent reference. If yes, append a short **Design Context** pointer section there. diff --git a/source/skills/impeccable/scripts/command-metadata.json b/source/skills/impeccable/scripts/command-metadata.json index 2974e08f6..d8282689a 100644 --- a/source/skills/impeccable/scripts/command-metadata.json +++ b/source/skills/impeccable/scripts/command-metadata.json @@ -4,7 +4,11 @@ "argumentHint": "[feature description]" }, "teach": { - "description": "One-time setup that gathers design context for a project. Runs a short discovery interview and writes the answers to .impeccable.md. Every other command reads this file before doing work. Use once per project.", + "description": "Gathers design context for a project. Runs a short discovery interview and writes PRODUCT.md (strategic: users, brand, principles) and, when code exists to analyze, DESIGN.md (visual: colors, typography, components). Every other command reads these files before doing work. Use once per project.", + "argumentHint": "" + }, + "document": { + "description": "Generate a DESIGN.md file that captures the current visual design system. Auto-extracts colors, typography, spacing, radii, and component patterns from the codebase, then asks the user to confirm descriptive language for atmosphere and color character. Follows the Google Stitch DESIGN.md format so the file is tool-compatible. Use when you need a visual design spec an AI agent can follow to stay on-brand.", "argumentHint": "" }, "extract": { diff --git a/source/skills/impeccable/scripts/live.mjs b/source/skills/impeccable/scripts/live.mjs index 93f05456e..37b6f8997 100644 --- a/source/skills/impeccable/scripts/live.mjs +++ b/source/skills/impeccable/scripts/live.mjs @@ -21,10 +21,10 @@ import { execSync } from 'node:child_process'; import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; +import { loadContext } from './load-context.mjs'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const PID_FILE = path.join(process.cwd(), '.impeccable-live.json'); -const CONTEXT_FILE = path.join(process.cwd(), '.impeccable.md'); async function liveCli() { const args = process.argv.slice(2); @@ -79,9 +79,8 @@ The agent should then: process.exit(1); } - // 4. Load design context if available - let context = null; - try { context = fs.readFileSync(CONTEXT_FILE, 'utf-8'); } catch { /* optional */ } + // 4. Load PRODUCT.md + DESIGN.md context (auto-migrates legacy .impeccable.md) + const ctx = loadContext(process.cwd()); // 5. Emit everything the agent needs console.log(JSON.stringify({ @@ -89,8 +88,13 @@ The agent should then: serverPort: serverInfo.port, serverToken: serverInfo.token, pageFile: checkResult.config.file, - hasContext: !!context, - context, + hasProduct: ctx.hasProduct, + product: ctx.product, + productPath: ctx.productPath, + hasDesign: ctx.hasDesign, + design: ctx.design, + designPath: ctx.designPath, + migrated: ctx.migrated, }, null, 2)); } diff --git a/source/skills/impeccable/scripts/load-context.mjs b/source/skills/impeccable/scripts/load-context.mjs new file mode 100644 index 000000000..ab3be08f1 --- /dev/null +++ b/source/skills/impeccable/scripts/load-context.mjs @@ -0,0 +1,93 @@ +/** + * Shared context loader for every impeccable command that needs to know + * "who is this for" and "what does this look like". + * + * Input: project root (process.cwd()). + * + * Output (JSON to stdout): + * { + * hasProduct: boolean, // PRODUCT.md found (or auto-migrated) + * product: string | null, // PRODUCT.md contents + * productPath: string | null, // relative path + * hasDesign: boolean, // DESIGN.md found + * design: string | null, // DESIGN.md contents + * designPath: string | null, + * migrated: boolean, // true if we auto-renamed .impeccable.md -> PRODUCT.md + * } + * + * Filename matching is case-insensitive for PRODUCT.md and DESIGN.md. The + * Google DESIGN.md convention is uppercase at repo root; Kiro-style and + * lowercase variants are also matched so users don't get punished for case. + */ + +import fs from 'node:fs'; +import path from 'node:path'; + +const PRODUCT_NAMES = ['PRODUCT.md', 'Product.md', 'product.md']; +const DESIGN_NAMES = ['DESIGN.md', 'Design.md', 'design.md']; +const LEGACY_NAMES = ['.impeccable.md']; + +export function loadContext(cwd = process.cwd()) { + let migrated = false; + + // 1. Look for PRODUCT.md (case-insensitive) + let productPath = firstExisting(cwd, PRODUCT_NAMES); + + // 2. Legacy: if no PRODUCT.md but .impeccable.md exists, rename in place + if (!productPath) { + const legacyPath = firstExisting(cwd, LEGACY_NAMES); + if (legacyPath) { + const newPath = path.join(cwd, 'PRODUCT.md'); + try { + fs.renameSync(legacyPath, newPath); + productPath = newPath; + migrated = true; + } catch { + // Rename failed (permissions, etc.) — fall back to reading legacy in place + productPath = legacyPath; + } + } + } + + // 3. DESIGN.md (case-insensitive) + const designPath = firstExisting(cwd, DESIGN_NAMES); + + const product = productPath ? safeRead(productPath) : null; + const design = designPath ? safeRead(designPath) : null; + + return { + hasProduct: !!product, + product, + productPath: productPath ? path.relative(cwd, productPath) : null, + hasDesign: !!design, + design, + designPath: designPath ? path.relative(cwd, designPath) : null, + migrated, + }; +} + +function firstExisting(cwd, names) { + for (const name of names) { + const abs = path.join(cwd, name); + if (fs.existsSync(abs)) return abs; + } + return null; +} + +function safeRead(p) { + try { return fs.readFileSync(p, 'utf-8'); } catch { return null; } +} + +// --------------------------------------------------------------------------- +// CLI mode — print the context as JSON +// --------------------------------------------------------------------------- + +function cli() { + const result = loadContext(process.cwd()); + console.log(JSON.stringify(result, null, 2)); +} + +const _running = process.argv[1]; +if (_running?.endsWith('load-context.mjs') || _running?.endsWith('load-context.mjs/')) { + cli(); +} diff --git a/source/skills/impeccable/scripts/pin.mjs b/source/skills/impeccable/scripts/pin.mjs index 89a6babeb..ba02783fb 100644 --- a/source/skills/impeccable/scripts/pin.mjs +++ b/source/skills/impeccable/scripts/pin.mjs @@ -27,7 +27,7 @@ const HARNESS_DIRS = [ // Valid sub-command names const VALID_COMMANDS = [ - 'craft', 'teach', 'extract', 'shape', + 'craft', 'teach', 'extract', 'document', 'shape', 'critique', 'audit', 'polish', 'bolder', 'quieter', 'distill', 'harden', 'onboard', 'live', 'animate', 'colorize', 'typeset', 'layout', 'delight', 'overdrive',