diff --git a/.agents/skills/impeccable/SKILL.md b/.agents/skills/impeccable/SKILL.md index 14acacac2..3763c7471 100644 --- a/.agents/skills/impeccable/SKILL.md +++ b/.agents/skills/impeccable/SKILL.md @@ -1,7 +1,7 @@ --- name: impeccable description: "Design fluency for frontend interfaces. Build distinctive, production-grade web components, pages, artifacts, posters, and applications with high design quality. Also handles: critique/review/evaluate designs, audit accessibility/performance/responsive, polish finishing touches, improve typography/fonts/readability, fix layout/spacing/hierarchy, add animation/transitions/motion, adapt for mobile/tablet/responsive, simplify/declutter/distill, amplify bland/generic/safe designs, tone down loud/overwhelming designs, add color to gray/monochromatic interfaces, improve UX copy/labels/error messages, harden for production with edge cases/i18n/errors/empty states, optimize slow/laggy performance, plan UX before coding, extract design tokens, or push boundaries with shaders/physics/scroll effects. Commands: craft, teach, extract, pin, audit, critique, polish, shape, adapt, animate, bolder, quieter, colorize, clarify, delight, distill, harden, layout, optimize, overdrive, typeset." -version: 2.1.1 +version: 3.0.0 user-invocable: true argument-hint: "[command] [target]" license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 7fcd222d2..15754b175 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -12,7 +12,7 @@ { "name": "impeccable", "description": "Design fluency for frontend development. 1 skill with 20 commands (/impeccable polish, /impeccable audit, /impeccable critique, etc.) and curated anti-pattern detection.", - "version": "2.1.1", + "version": "3.0.0", "author": { "name": "Paul Bakaus", "email": "paul@paulbakaus.com" diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 25dce892c..a42ac27a3 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "impeccable", "description": "Design fluency for frontend development. 1 skill with 20 commands (/impeccable polish, /impeccable audit, /impeccable critique, etc.) and curated anti-pattern detection.", - "version": "2.1.1", + "version": "3.0.0", "author": { "name": "Paul Bakaus", "email": "paul@paulbakaus.com" diff --git a/.claude/skills/impeccable/SKILL.md b/.claude/skills/impeccable/SKILL.md index 5c0676008..182c33604 100644 --- a/.claude/skills/impeccable/SKILL.md +++ b/.claude/skills/impeccable/SKILL.md @@ -1,7 +1,7 @@ --- name: impeccable description: "Design fluency for frontend interfaces. Build distinctive, production-grade web components, pages, artifacts, posters, and applications with high design quality. Also handles: critique/review/evaluate designs, audit accessibility/performance/responsive, polish finishing touches, improve typography/fonts/readability, fix layout/spacing/hierarchy, add animation/transitions/motion, adapt for mobile/tablet/responsive, simplify/declutter/distill, amplify bland/generic/safe designs, tone down loud/overwhelming designs, add color to gray/monochromatic interfaces, improve UX copy/labels/error messages, harden for production with edge cases/i18n/errors/empty states, optimize slow/laggy performance, plan UX before coding, extract design tokens, or push boundaries with shaders/physics/scroll effects. Commands: craft, teach, extract, pin, audit, critique, polish, shape, adapt, animate, bolder, quieter, colorize, clarify, delight, distill, harden, layout, optimize, overdrive, typeset." -version: 2.1.1 +version: 3.0.0 user-invocable: true argument-hint: "[command] [target]" license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. diff --git a/.codex/skills/impeccable/SKILL.md b/.codex/skills/impeccable/SKILL.md index b96bef77e..f49846747 100644 --- a/.codex/skills/impeccable/SKILL.md +++ b/.codex/skills/impeccable/SKILL.md @@ -1,7 +1,7 @@ --- name: impeccable description: "Design fluency for frontend interfaces. Build distinctive, production-grade web components, pages, artifacts, posters, and applications with high design quality. Also handles: critique/review/evaluate designs, audit accessibility/performance/responsive, polish finishing touches, improve typography/fonts/readability, fix layout/spacing/hierarchy, add animation/transitions/motion, adapt for mobile/tablet/responsive, simplify/declutter/distill, amplify bland/generic/safe designs, tone down loud/overwhelming designs, add color to gray/monochromatic interfaces, improve UX copy/labels/error messages, harden for production with edge cases/i18n/errors/empty states, optimize slow/laggy performance, plan UX before coding, extract design tokens, or push boundaries with shaders/physics/scroll effects. Commands: craft, teach, extract, pin, audit, critique, polish, shape, adapt, animate, bolder, quieter, colorize, clarify, delight, distill, harden, layout, optimize, overdrive, typeset." -version: 2.1.1 +version: 3.0.0 argument-hint: "[command] [target]" license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. --- diff --git a/.cursor/skills/impeccable/SKILL.md b/.cursor/skills/impeccable/SKILL.md index 79ed6debb..f3baccb6a 100644 --- a/.cursor/skills/impeccable/SKILL.md +++ b/.cursor/skills/impeccable/SKILL.md @@ -1,7 +1,7 @@ --- name: impeccable description: "Design fluency for frontend interfaces. Build distinctive, production-grade web components, pages, artifacts, posters, and applications with high design quality. Also handles: critique/review/evaluate designs, audit accessibility/performance/responsive, polish finishing touches, improve typography/fonts/readability, fix layout/spacing/hierarchy, add animation/transitions/motion, adapt for mobile/tablet/responsive, simplify/declutter/distill, amplify bland/generic/safe designs, tone down loud/overwhelming designs, add color to gray/monochromatic interfaces, improve UX copy/labels/error messages, harden for production with edge cases/i18n/errors/empty states, optimize slow/laggy performance, plan UX before coding, extract design tokens, or push boundaries with shaders/physics/scroll effects. Commands: craft, teach, extract, pin, audit, critique, polish, shape, adapt, animate, bolder, quieter, colorize, clarify, delight, distill, harden, layout, optimize, overdrive, typeset." -version: 2.1.1 +version: 3.0.0 license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. --- diff --git a/.gemini/skills/impeccable/SKILL.md b/.gemini/skills/impeccable/SKILL.md index 49b489705..ed6950695 100644 --- a/.gemini/skills/impeccable/SKILL.md +++ b/.gemini/skills/impeccable/SKILL.md @@ -1,7 +1,7 @@ --- name: impeccable description: "Design fluency for frontend interfaces. Build distinctive, production-grade web components, pages, artifacts, posters, and applications with high design quality. Also handles: critique/review/evaluate designs, audit accessibility/performance/responsive, polish finishing touches, improve typography/fonts/readability, fix layout/spacing/hierarchy, add animation/transitions/motion, adapt for mobile/tablet/responsive, simplify/declutter/distill, amplify bland/generic/safe designs, tone down loud/overwhelming designs, add color to gray/monochromatic interfaces, improve UX copy/labels/error messages, harden for production with edge cases/i18n/errors/empty states, optimize slow/laggy performance, plan UX before coding, extract design tokens, or push boundaries with shaders/physics/scroll effects. Commands: craft, teach, extract, pin, audit, critique, polish, shape, adapt, animate, bolder, quieter, colorize, clarify, delight, distill, harden, layout, optimize, overdrive, typeset." -version: 2.1.1 +version: 3.0.0 --- This skill guides creation and editing/iteration of distinctive, production-grade frontend interfaces. Implement real working code with exceptional attention to aesthetic details and creative choices. diff --git a/.kiro/skills/impeccable/SKILL.md b/.kiro/skills/impeccable/SKILL.md index 80efc2f9a..e06824c74 100644 --- a/.kiro/skills/impeccable/SKILL.md +++ b/.kiro/skills/impeccable/SKILL.md @@ -1,7 +1,7 @@ --- name: impeccable description: "Design fluency for frontend interfaces. Build distinctive, production-grade web components, pages, artifacts, posters, and applications with high design quality. Also handles: critique/review/evaluate designs, audit accessibility/performance/responsive, polish finishing touches, improve typography/fonts/readability, fix layout/spacing/hierarchy, add animation/transitions/motion, adapt for mobile/tablet/responsive, simplify/declutter/distill, amplify bland/generic/safe designs, tone down loud/overwhelming designs, add color to gray/monochromatic interfaces, improve UX copy/labels/error messages, harden for production with edge cases/i18n/errors/empty states, optimize slow/laggy performance, plan UX before coding, extract design tokens, or push boundaries with shaders/physics/scroll effects. Commands: craft, teach, extract, pin, audit, critique, polish, shape, adapt, animate, bolder, quieter, colorize, clarify, delight, distill, harden, layout, optimize, overdrive, typeset." -version: 2.1.1 +version: 3.0.0 license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. --- diff --git a/.opencode/skills/impeccable/SKILL.md b/.opencode/skills/impeccable/SKILL.md index 219cb7402..6d274ae73 100644 --- a/.opencode/skills/impeccable/SKILL.md +++ b/.opencode/skills/impeccable/SKILL.md @@ -1,7 +1,7 @@ --- name: impeccable description: "Design fluency for frontend interfaces. Build distinctive, production-grade web components, pages, artifacts, posters, and applications with high design quality. Also handles: critique/review/evaluate designs, audit accessibility/performance/responsive, polish finishing touches, improve typography/fonts/readability, fix layout/spacing/hierarchy, add animation/transitions/motion, adapt for mobile/tablet/responsive, simplify/declutter/distill, amplify bland/generic/safe designs, tone down loud/overwhelming designs, add color to gray/monochromatic interfaces, improve UX copy/labels/error messages, harden for production with edge cases/i18n/errors/empty states, optimize slow/laggy performance, plan UX before coding, extract design tokens, or push boundaries with shaders/physics/scroll effects. Commands: craft, teach, extract, pin, audit, critique, polish, shape, adapt, animate, bolder, quieter, colorize, clarify, delight, distill, harden, layout, optimize, overdrive, typeset." -version: 2.1.1 +version: 3.0.0 user-invocable: true argument-hint: "[command] [target]" license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. diff --git a/.pi/skills/impeccable/SKILL.md b/.pi/skills/impeccable/SKILL.md index ea2f01ccd..be8ec284a 100644 --- a/.pi/skills/impeccable/SKILL.md +++ b/.pi/skills/impeccable/SKILL.md @@ -1,7 +1,7 @@ --- name: impeccable description: "Design fluency for frontend interfaces. Build distinctive, production-grade web components, pages, artifacts, posters, and applications with high design quality. Also handles: critique/review/evaluate designs, audit accessibility/performance/responsive, polish finishing touches, improve typography/fonts/readability, fix layout/spacing/hierarchy, add animation/transitions/motion, adapt for mobile/tablet/responsive, simplify/declutter/distill, amplify bland/generic/safe designs, tone down loud/overwhelming designs, add color to gray/monochromatic interfaces, improve UX copy/labels/error messages, harden for production with edge cases/i18n/errors/empty states, optimize slow/laggy performance, plan UX before coding, extract design tokens, or push boundaries with shaders/physics/scroll effects. Commands: craft, teach, extract, pin, audit, critique, polish, shape, adapt, animate, bolder, quieter, colorize, clarify, delight, distill, harden, layout, optimize, overdrive, typeset." -version: 2.1.1 +version: 3.0.0 license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. allowed-tools: - Bash(npx impeccable *) diff --git a/.rovodev/skills/impeccable/SKILL.md b/.rovodev/skills/impeccable/SKILL.md index 5a380eafa..b42e08bfb 100644 --- a/.rovodev/skills/impeccable/SKILL.md +++ b/.rovodev/skills/impeccable/SKILL.md @@ -1,7 +1,7 @@ --- name: impeccable description: "Design fluency for frontend interfaces. Build distinctive, production-grade web components, pages, artifacts, posters, and applications with high design quality. Also handles: critique/review/evaluate designs, audit accessibility/performance/responsive, polish finishing touches, improve typography/fonts/readability, fix layout/spacing/hierarchy, add animation/transitions/motion, adapt for mobile/tablet/responsive, simplify/declutter/distill, amplify bland/generic/safe designs, tone down loud/overwhelming designs, add color to gray/monochromatic interfaces, improve UX copy/labels/error messages, harden for production with edge cases/i18n/errors/empty states, optimize slow/laggy performance, plan UX before coding, extract design tokens, or push boundaries with shaders/physics/scroll effects. Commands: craft, teach, extract, pin, audit, critique, polish, shape, adapt, animate, bolder, quieter, colorize, clarify, delight, distill, harden, layout, optimize, overdrive, typeset." -version: 2.1.1 +version: 3.0.0 user-invocable: true argument-hint: "[command] [target]" license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. diff --git a/.trae-cn/skills/impeccable/SKILL.md b/.trae-cn/skills/impeccable/SKILL.md index 5ef54ec67..177238ebb 100644 --- a/.trae-cn/skills/impeccable/SKILL.md +++ b/.trae-cn/skills/impeccable/SKILL.md @@ -1,7 +1,7 @@ --- name: impeccable description: "Design fluency for frontend interfaces. Build distinctive, production-grade web components, pages, artifacts, posters, and applications with high design quality. Also handles: critique/review/evaluate designs, audit accessibility/performance/responsive, polish finishing touches, improve typography/fonts/readability, fix layout/spacing/hierarchy, add animation/transitions/motion, adapt for mobile/tablet/responsive, simplify/declutter/distill, amplify bland/generic/safe designs, tone down loud/overwhelming designs, add color to gray/monochromatic interfaces, improve UX copy/labels/error messages, harden for production with edge cases/i18n/errors/empty states, optimize slow/laggy performance, plan UX before coding, extract design tokens, or push boundaries with shaders/physics/scroll effects. Commands: craft, teach, extract, pin, audit, critique, polish, shape, adapt, animate, bolder, quieter, colorize, clarify, delight, distill, harden, layout, optimize, overdrive, typeset." -version: 2.1.1 +version: 3.0.0 user-invocable: true argument-hint: "[command] [target]" license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. diff --git a/.trae/skills/impeccable/SKILL.md b/.trae/skills/impeccable/SKILL.md index 005f325c3..d97a8e5ce 100644 --- a/.trae/skills/impeccable/SKILL.md +++ b/.trae/skills/impeccable/SKILL.md @@ -1,7 +1,7 @@ --- name: impeccable description: "Design fluency for frontend interfaces. Build distinctive, production-grade web components, pages, artifacts, posters, and applications with high design quality. Also handles: critique/review/evaluate designs, audit accessibility/performance/responsive, polish finishing touches, improve typography/fonts/readability, fix layout/spacing/hierarchy, add animation/transitions/motion, adapt for mobile/tablet/responsive, simplify/declutter/distill, amplify bland/generic/safe designs, tone down loud/overwhelming designs, add color to gray/monochromatic interfaces, improve UX copy/labels/error messages, harden for production with edge cases/i18n/errors/empty states, optimize slow/laggy performance, plan UX before coding, extract design tokens, or push boundaries with shaders/physics/scroll effects. Commands: craft, teach, extract, pin, audit, critique, polish, shape, adapt, animate, bolder, quieter, colorize, clarify, delight, distill, harden, layout, optimize, overdrive, typeset." -version: 2.1.1 +version: 3.0.0 user-invocable: true argument-hint: "[command] [target]" license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md for attribution. diff --git a/AGENTS.md b/AGENTS.md index 6252f0cb8..954bc3df1 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,250 +1,32 @@ -# Impeccable +# Repository Guidelines -The vocabulary you didn't know you needed. 1 skill, 20 commands, and curated anti-patterns for impeccable style. Works with Cursor, Claude Code, Gemini CLI, and Codex CLI. +## Project Structure & Module Organization -## Repository Purpose +`source/` is the source of truth. Author skills in `source/skills/impeccable/` and keep provider output in `dist/` generated, not hand-edited. Build logic lives in `scripts/`, with provider configs in `scripts/lib/transformers/`. Runtime detection code ships from `src/`. The website lives in `public/`, local API/dev serving lives in `server/`, and regression coverage lives in `tests/` with fixtures under `tests/fixtures/`. -Maintain a **single source of truth** for design-focused skills and commands, then automatically transform them into provider-specific formats. Each provider has different capabilities (frontmatter, arguments, modular files), so we use a build system to generate appropriate outputs. +## Build, Test, and Development Commands -## Architecture: Option A (Feature-Rich Source) +- `bun run dev` - start the local Bun server. +- `bun run build` - regenerate `dist/`, derived site assets, and validation output. +- `bun run rebuild` - clean and rebuild everything from scratch. +- `bun test tests/build.test.js` - run a focused Bun test. +- `bun run test` - run the full Bun + Node test suite. +- `bun run build:browser` / `bun run build:extension` - rebuild browser-specific bundles. -We use a **feature-rich source format** that gets transformed for each provider: +Run `bun run build` after changing anything in `source/`, transformer code, or user-facing counts. -- **Source files** (`source/`): Full metadata with YAML frontmatter, args, descriptions -- **Build system** (`scripts/`): Transforms source → provider-specific formats -- **Distribution** (`dist/`): Committed output files for 4 providers +## Coding Style & Naming Conventions -### Why Option A? +Use ESM, semicolons, and the existing two-space indentation style in JS, HTML, and CSS. Prefer small, single-purpose modules over large abstractions. Keep filenames descriptive and lowercase with hyphens where needed; skill entrypoints stay as `SKILL.md`, helper scripts use `.js` or `.mjs`. In source frontmatter, use clear kebab-case names and concise descriptions. There is no dedicated formatter or linter configured here, so match surrounding code closely. -Cursor doesn't support frontmatter or arguments (lowest common denominator). Instead of limiting all providers, we: -1. Author with full metadata in source files -2. Generate full-featured versions for providers that support it (Claude Code, Gemini, Codex) -3. Generate downgraded versions for Cursor (strip frontmatter, rely on appending) +## Testing Guidelines -## Repository Structure +Tests use Bun’s test runner plus Node’s built-in `--test`. Name tests `*.test.js` or `*.test.mjs` and place new fixtures near the behavior they cover, usually under `tests/fixtures/`. Prefer targeted test runs while iterating, then finish with `bun run test`. If you change generated outputs or provider transforms, verify both source parsing and at least one affected provider path in `dist/`. -``` -impeccable/ -├── source/ # EDIT THESE! Single source of truth -│ ├── commands/ # Command definitions with frontmatter -│ │ └── normalize.md -│ └── skills/ # Skill definitions with frontmatter -│ └── impeccable/ -├── dist/ # Generated outputs (committed for users) -│ ├── cursor/ # Commands + Agent Skills -│ │ └── .cursor/ -│ │ ├── commands/*.md -│ │ └── skills/*/SKILL.md -│ ├── claude-code/ # Full featured -│ │ └── .claude/ -│ │ ├── commands/*.md -│ │ └── skills/*/SKILL.md -│ ├── gemini/ # TOML commands + modular skills -│ │ ├── .gemini/ -│ │ │ └── commands/*.toml -│ │ ├── GEMINI.md -│ │ └── GEMINI.*.md -│ └── codex/ # Custom prompts + Agent Skills -│ └── .codex/ -│ ├── prompts/*.md -│ └── skills/*/SKILL.md -├── api/ # Vercel Functions (production) -│ ├── skills.js # GET /api/skills -│ ├── commands.js # GET /api/commands -│ └── download/ -│ ├── [type]/[provider]/[id].js # Individual downloads -│ └── bundle/[provider].js # Bundle downloads -├── public/ # Website for impeccable.style -│ ├── index.html # Main page -│ ├── css/ # Modular CSS (9 files) -│ │ ├── main.css # Entry point with imports -│ │ ├── tokens.css # Design system -│ │ └── ... # Component styles -│ └── app.js # Vanilla JS -├── server/ # Bun server (local dev only) -│ ├── index.js # Serves website + API routes -│ └── lib/ -│ └── api-handlers.js # Shared API logic (used by both server & functions) -├── scripts/ # Build system (Bun) -│ ├── build.js # Main orchestrator -│ ├── lib/ -│ │ ├── utils.js # Shared utilities -│ │ ├── zip.js # ZIP generation -│ │ └── transformers/ # Provider-specific transformers -│ │ ├── cursor.js -│ │ ├── claude-code.js -│ │ ├── gemini.js -│ │ └── codex.js -├── README.md # End user documentation -├── DEVELOP.md # Contributor documentation -└── package.json # Bun scripts -``` +## Commit & Pull Request Guidelines -## Website (impeccable.style) +Recent history favors short, imperative subjects such as `Fix: ...`, `Add ...`, `Improve ...`, or `Bump ...`. Keep commits focused and explain the user-facing impact when it is not obvious. PRs should summarize what changed, list validation performed, and call out regenerated artifacts like `dist/` or `build/`. Include screenshots for visible `public/` changes and mention affected providers when transform behavior changes. -**Tech Stack:** -- Vanilla JavaScript (no frameworks) -- Modern CSS with Bun's bundler (nesting, OKLCH colors, @import) -- **Local Development**: Bun server with native routes (`server/index.js`) -- **Production**: Vercel Functions with Bun runtime (`/api` directory) -- Deployed on Vercel with Bun runtime - -**Dual Setup:** -- `/api` directory contains individual Vercel Functions for production -- `/server` directory contains monolithic Bun server for local development -- `/server/lib/api-handlers.js` contains shared logic used by both -- Zero duplication: API functions and dev server import the same handlers - -**Design:** -- Editorial precision aesthetic -- Cormorant Garamond (display) + Instrument Sans (body) -- OKLCH color space for vibrant, perceptually uniform colors -- Editorial sidebar layout (title left, content right) -- Modular CSS architecture (9 files) - -**API Endpoints** (Vercel Functions): -- `/` - Homepage (static HTML) -- `/api/skills` - JSON list of all skills -- `/api/commands` - JSON list of all commands -- `/api/download/[type]/[provider]/[id]` - Individual file download -- `/api/download/bundle/[provider]` - ZIP bundle download - -## Source File Format - -### Commands (`source/commands/*.md`) - -```yaml ---- -name: command-name -description: Clear description of what this command does -args: - - name: argname - description: Argument description - required: false ---- - -Command prompt here. Use {{argname}} placeholders for arguments. -``` - -### Skills (`source/skills/*.md`) - -```yaml ---- -name: skill-name -description: Clear description of what this skill provides -license: License info (optional) ---- - -Skill instructions for the LLM here. -``` - -## Build System - -Uses **Bun** for fast builds. Modular architecture: - -- **`utils.js`**: Shared functions (parseFrontmatter, readSourceFiles, writeFile, etc.) -- **Transformer pattern**: Each provider has one focused file -- **Registry**: `transformers/index.js` exports all transformers -- **Main script**: `build.js` orchestrates everything (~50 lines) - -Run: `bun run build` - -## Provider Transformations - -### 1. Cursor (Agent Skills Standard) -- **Commands**: Body only → `dist/cursor/.cursor/commands/*.md` (no frontmatter support) -- **Skills**: Agent Skills standard → `dist/cursor/.cursor/skills/{name}/SKILL.md` - - Full YAML frontmatter with name/description - - Reference files in skill subdirectories -- **Installation**: Extract ZIP into your project root, creates `.cursor/` folder -- **Note**: Agent Skills require Cursor nightly channel - -### 2. Claude Code (Full Featured) -- **Commands**: Full YAML frontmatter → `dist/claude-code/.claude/commands/*.md` -- **Skills**: Full YAML frontmatter → `dist/claude-code/.claude/skills/{name}/SKILL.md` -- **Preserves**: All metadata, all args -- **Format**: Matches [Anthropic Skills spec](https://github.com/anthropics/skills) -- **Installation**: Extract ZIP into your project root, creates `.claude/` folder - -### 3. Gemini CLI (Full Featured) -- **Commands**: TOML format → `dist/gemini/.gemini/commands/*.toml` - - Uses `description` and `prompt` keys - - Transforms `{{argname}}` → `{{args}}` (Gemini uses single args string) -- **Skills**: Modular with imports → `dist/gemini/GEMINI.{name}.md` (root level) - - Main `GEMINI.md` uses `@./GEMINI.{name}.md` import syntax - - Gemini automatically loads imported files -- **Installation**: Extract ZIP into your project root, creates `.gemini/` folder + skill files - -### 4. Codex CLI (Full Featured) -- **Commands**: Custom prompt format → `dist/codex/.codex/prompts/*.md` - - Uses `description` and `argument-hint` in frontmatter - - Transforms `{{argname}}` → `$ARGNAME` (uppercase variables) - - Invoked as `/prompts:` -- **Skills**: Agent Skills standard → `dist/codex/.codex/skills/{name}/SKILL.md` - - Same SKILL.md format as Claude Code with YAML frontmatter - - Reference files in skill subdirectories -- **Installation**: Extract ZIP into your project root, creates `.codex/` folder - -## Key Design Decisions - -### Why commit dist/? -End users can copy files directly without needing build tools. - -### Why separate transformers? -- Each provider ~30-85 lines, easy to understand -- Can modify one without affecting others -- Easy to add new providers - -### Why Bun? -- Much faster than Node.js (2-4x) -- All-in-one toolkit (runtime + package manager) -- Zero config, TypeScript native -- Node.js compatible (works with existing code) - -### Why modular skills for Gemini/Codex? -- Better context management (load only what's needed) -- Cleaner file organization -- Gemini: Uses native `@file.md` import feature -- Codex: Uses routing pattern with AGENTS.md guide - -### Why vanilla JS for website? -- No build complexity -- Bun handles everything natively -- Modern features (ES6+, CSS nesting, OKLCH colors) -- Fast, lean, maintainable - -## Adding New Content - -1. **Create source file** in `source/commands/` or `source/skills/` -2. **Add frontmatter** with name, description, args (for commands) or license (for skills) -3. **Write body** with instructions/prompt -4. **Build**: `bun run build` -5. **Test** with your provider -6. **Commit** both source and dist files - -## Important Notes - -- **Source is truth**: Always edit `source/`, never edit `dist/` directly -- **Test across providers**: Changes affect 4 different outputs -- **Argument handling**: Write prompts that work with both placeholders and appending -- **Cursor limitations**: No frontmatter/args, so design for graceful degradation - -## Documentation - -- **README.md**: End user guide (installation, usage, quick dev setup) -- **DEVELOP.md**: Contributor guide (architecture, build system, adding content) -- **This file (AGENTS.md)**: Context for AI assistants and new developers - -## Provider Documentation Links - -- [Agent Skills Specification](https://agentskills.io/specification) - Open standard -- [Cursor Commands](https://cursor.com/docs/agent/chat/commands) -- [Cursor Rules](https://cursor.com/docs/context/rules) -- [Cursor Skills](https://cursor.com/docs/context/skills) -- [Claude Code Slash Commands](https://code.claude.com/docs/en/slash-commands) -- [Anthropic Skills](https://github.com/anthropics/skills) -- [Gemini CLI Custom Commands](https://cloud.google.com/blog/topics/developers-practitioners/gemini-cli-custom-slash-commands) -- [Gemini CLI GEMINI.md](https://github.com/google-gemini/gemini-cli/blob/main/docs/cli/gemini-md.md) -- [Codex CLI Slash Commands](https://developers.openai.com/codex/guides/slash-commands) -- [Codex CLI Skills](https://developers.openai.com/codex/skills/) +## Contributor Notes +Do not edit generated provider files directly unless you are intentionally patching generated output as part of a build-system change. Prefer fixing the root source in `source/`, `scripts/`, or `src/`, then regenerate artifacts. diff --git a/CLAUDE.md b/CLAUDE.md index 87349124c..c89f6ed1a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,17 +1,39 @@ # Project Instructions for Claude +## Architecture (v3.0+) + +There is **one** user-invocable skill, `impeccable`, with **20 commands** underneath it. Users type `/impeccable polish`, `/impeccable audit`, etc. The skill is defined in `source/skills/impeccable/`: + +- `SKILL.md` — frontmatter (with the auto-trigger-optimized description and the `allowed-tools` list), shared design principles, and the **Command Router** section that dispatches sub-commands via argument matching. +- `reference/` — one `.md` per command (`audit.md`, `polish.md`, `critique.md`, etc.) plus the domain reference files (`typography.md`, `color-and-contrast.md`, etc.). When a sub-command is matched, the router loads its reference file. +- `scripts/command-metadata.json` — single source of truth for each command's description, argument hint, and (eventually) category. Both the build and `pin.mjs` read from this. +- `scripts/pin.mjs` — creates/removes lightweight redirect shims so users can have `/audit` as a standalone shortcut that delegates to `/impeccable audit`. +- `scripts/cleanup-deprecated.mjs` — runs once after an update to remove leftover files from renamed/merged commands. + +**Do not add standalone skills** unless there's a strong reason. The consolidation was deliberate: the `/` menu pollution problem is real and gets worse as users install more plugins. + ## CSS -Plain hand-written CSS, no Tailwind, no build step. Bun's HTML loader resolves -`` and inlines `@import` chains automatically for both -`bun run dev` and `bun run build`. +Plain hand-written CSS, no Tailwind, no build step. Bun's HTML loader resolves `` and inlines `@import` chains automatically for both `bun run dev` and `bun run build`. The CSS architecture: -- `public/css/main.css` - Main entry point, imports the partials and defines tokens/reset -- `public/css/workflow.css` - Commands section, glass terminal, case studies styles -- `public/css/gallery.css`, `skill-demos.css`, `problem-section.css` - section partials +- `public/css/main.css` — Main entry point, imports the partials and defines tokens/reset +- `public/css/workflow.css` — Commands section, glass terminal, magazine spread styles +- `public/css/sub-pages.css` — `/docs`, `/anti-patterns`, `/tutorials`, detail pages +- `public/css/tokens.css` — OKLCH color tokens (ink, charcoal, ash, mist, cream, accent) -Edit any of these directly and reload — no rebuild needed. +Edit any of these directly and reload. No rebuild needed for CSS changes. + +## Color token rule + +- **`--color-ink`** (10% lightness) is for body copy. Use it even for small text. +- **`--color-charcoal`** (25% lightness) reads as washed-out gray in small text. Only use for headings or larger body copy at ≥16px. +- **`--color-ash`** (55%) is for secondary labels, captions, relationship meta lines. +- **Never use pure black or pure white.** Use the tinted tokens. + +## No em dashes, no `--` either + +CLAUDE.md feedback from multiple sessions: "no em dashes in project copy" does NOT mean "replace with `--`". It means **use actual punctuation**: commas, colons, semicolons, periods, parentheses. The `--` substitution makes the problem worse. The build validator (`validateNoEmDashes` in `scripts/build.js`) catches real em dashes but not the `--` double-hyphen habit, so you have to catch yourself. ## Development Server @@ -20,6 +42,10 @@ bun run dev # Bun dev server at http://localhost:3000 bun run preview # Build + Cloudflare Pages local preview ``` +The dev server (in `server/index.js`) runs `generateSubPages` at module load, so editing source files in `content/site/skills/`, `source/skills/impeccable/`, or the sub-page generator requires a **server restart** (not just a browser reload) to see the change. CSS hot-reloads fine without a restart. + +**Legacy URL redirects** live in `server/index.js` and must stay in sync with `scripts/build.js` `_redirects` generation. Current redirects: `/skills` → `/docs`, `/skills/:id` → `/docs/:id`, `/cheatsheet` → `/docs`, `/gallery` → `/visual-mode#try-it-live`. + ## Deployment Hosted on Cloudflare Pages. Static assets served from `build/`, API routes handled via `_redirects` rewrites (JSON) and Pages Functions (downloads). @@ -30,7 +56,7 @@ bun run deploy # Build + deploy to Cloudflare Pages ## Build System -The build system compiles skills and commands from `source/` to provider-specific formats in `dist/`: +The build system compiles the impeccable skill from `source/` to provider-specific formats in `dist/`: ```bash bun run build # Build all providers @@ -38,9 +64,22 @@ bun run rebuild # Clean and rebuild ``` Source files use placeholders that get replaced per-provider: -- `{{model}}` - Model name (Claude, Gemini, GPT, etc.) -- `{{config_file}}` - Config file name (CLAUDE.md, .cursorrules, etc.) -- `{{ask_instruction}}` - How to ask user questions +- `{{model}}` — Model name (Claude, Gemini, GPT, etc.) +- `{{config_file}}` — Config file name (CLAUDE.md, .cursorrules, etc.) +- `{{ask_instruction}}` — How to ask user questions +- `{{command_prefix}}` — `/` or `$` depending on provider +- `{{available_commands}}` — auto-populated list of commands (from `IMPECCABLE_SUB_COMMANDS` in `scripts/lib/utils.js`) +- `{{scripts_path}}` — provider-aware path to the skill's scripts directory + +### Harness output directories are tracked + +`.claude/skills/`, `.cursor/skills/`, `.agents/skills/`, and the other 8 harness directories are **intentionally committed to the repo**. `npx skills` reads them directly from this repo at install time, and they enable clean submodule use. Do not gitignore them. Run `bun run build` to refresh them after editing `source/skills/`. + +Local state files inside harness directories (e.g. `.claude/scheduled_tasks.lock`, `.claude/settings.local.json`) ARE gitignored. + +### Generated sub-pages are gitignored + +`public/docs/`, `public/anti-patterns/`, `public/tutorials/`, `public/visual-mode/` are generated by `scripts/build-sub-pages.js` on dev server startup and during `bun run build`. They're gitignored because the production site (Cloudflare Pages) runs its own build and nobody consumes them directly from git. ## Testing @@ -48,7 +87,9 @@ Source files use placeholders that get replaced per-provider: bun run test # Run all tests ``` -Unit tests (build, detector logic) run via `bun test`. Fixture tests (jsdom-based HTML detection) run via `node --test` because bun is too slow with jsdom. The `test` script handles this split automatically. +Unit tests (build orchestration, detector logic) run via `bun test`. Fixture tests (jsdom-based HTML detection) run via `node --test` because bun is too slow with jsdom. The `test` script handles this split automatically. + +**Important:** `tests/build.test.js` uses `spyOn(transformers, 'transformCursor')` with the named exports from `scripts/lib/transformers/index.js`. Those named exports (`transformCursor`, `transformClaudeCode`, etc.) are kept specifically for test spying, even though `build.js` itself uses `createTransformer + PROVIDERS` directly. **Do not delete them as "dead code"** — I made that mistake once and broke 8 tests. ## CLI @@ -81,37 +122,57 @@ There are three independently versioned components. Only bump the one(s) that ac **Skills** (Claude Code plugin / skill definitions): - `.claude-plugin/plugin.json` → `version` - `.claude-plugin/marketplace.json` → `plugins[0].version` -- Bump when: skill content changes (`source/skills/`, skill count changes, etc.) +- Bump when: skill content changes (`source/skills/`, reference files, command metadata, etc.) **Chrome extension**: - `extension/manifest.json` → `version` - Bump when: extension code changes (`extension/`) **Website changelog** (`public/index.html`): -- Hero version link text + new changelog entry +- Hero version link text + new changelog entry in the changelog section - Update for user-facing changes only, not internal build/tooling details -- Use the most prominent version that changed (e.g. skills version for skill consolidation) +- Use the most prominent version that changed (skills version is usually the right one) -## Adding New Sub-commands +## Adding New Commands -All commands are accessed through `/impeccable`. To add a new one: +All commands live under `/impeccable`. To add a new one: -1. Create `source/skills/impeccable/reference/.md` with the command's instructions +1. Create `source/skills/impeccable/reference/.md` with the command's instructions (this is what the LLM loads when the command is invoked) 2. Add a row to the **Sub-command reference table** in `source/skills/impeccable/SKILL.md` 3. Add an entry to the **Command menu** section in the same file 4. Add the command name to `IMPECCABLE_SUB_COMMANDS` in `scripts/lib/utils.js` 5. Add it to `VALID_COMMANDS` in `source/skills/impeccable/scripts/pin.mjs` -6. Add its metadata to `source/skills/impeccable/scripts/command-metadata.json` +6. Add its metadata (description + argumentHint) to `source/skills/impeccable/scripts/command-metadata.json` +7. Add its category to `SKILL_CATEGORIES` in `scripts/lib/sub-pages-data.js` +8. Add its relationships (leadsTo / pairs / combinesWith) to `COMMAND_RELATIONSHIPS` in the same file +9. Add the same category entry to `public/js/data.js` `commandCategories` and `commandProcessSteps` (for the homepage carousel) +10. Add symbol + number to `commandSymbols` and `commandNumbers` in `public/js/components/framework-viz.js` (periodic table) +11. Optional: write an editorial wrapper at `content/site/skills/.md` with a short `tagline` and expanded body (When to use it / How it works / Try it / Pitfalls) -The build system counts commands from the router table automatically. Update the command count in **all** of these locations: +The build system counts commands from the router table automatically. Update the command count in **all** of these locations when the total changes: -- `public/index.html` -- meta descriptions, hero box, section lead -- `public/cheatsheet.html` -- meta description, subtitle -- `README.md` -- intro, command count, commands table -- `NOTICE.md` -- command count -- `AGENTS.md` -- intro command count -- `.claude-plugin/plugin.json` -- description -- `.claude-plugin/marketplace.json` -- metadata description + plugin description +- `public/index.html` — meta descriptions, hero box, section lead +- `public/cheatsheet.html` does not exist anymore; `/cheatsheet` redirects to `/docs` +- `README.md` — intro, command count, commands table +- `NOTICE.md` — command count +- `AGENTS.md` — intro command count +- `.claude-plugin/plugin.json` — description +- `.claude-plugin/marketplace.json` — metadata description + plugin description + +The build validator (`generateCounts` in `scripts/build.js`) checks these files for stale numeric counts and fails the build if any disagree with the router table. + +## Adding editorial content for existing commands + +Editorial files live at `content/site/skills/.md` and have a `tagline` frontmatter plus a body with the standard four sections: + +- **When to use it** — the specific scenarios this command owns +- **How it works** — the internal process, phases, or approach +- **Try it** — one or two concrete examples with expected output +- **Pitfalls** — real failure modes, with alternatives to reach for instead + +The tagline is used by UI surfaces (magazine spread, docs cards) that need a short human-friendly label. The long description in `command-metadata.json` stays optimized for auto-trigger keyword matching in the AI harness. + +Every command should have an editorial file eventually, but the build does not require one: commands without editorials fall back to the frontmatter description. ## Evals Framework (private, gitignored) @@ -119,6 +180,16 @@ There is a controlled eval framework at `evals/` that measures whether the `/imp **If you're picking up eval work in a new session, read `evals/AGENT.md` first.** It captures everything we've learned: model choices, sample size policy, lessons learned, common workflows, and gotchas. Don't try to reinvent the workflow from scratch — there's significant prior context. +### After structural skill changes, update `evals/runner/inline-skill.ts` + +The eval harness inlines `SKILL.md` into the system prompt for the "skill-on" condition, stripping sections that are irrelevant to an API-driven craft run. The stripped sections list (`sectionsToStrip` in `inline-skill.ts`) needs to stay in sync with `SKILL.md`'s top-level `##` headings. As of v3.0, it strips: + +- `## Context Gathering Protocol` — references a `.impeccable.md` file that doesn't exist in the test harness +- `## Command Router` — sub-command dispatch is meaningless for a single API call +- `## Pin / Unpin` — harness tooling, not design instruction + +If you add or rename a top-level section in `SKILL.md`, check whether `inline-skill.ts` needs updating. A stale strip list either leaves noise in the prompt or accidentally strips useful content. + ### Quick orientation - **Primary baseline model**: `gpt-5.4` with `--reasoning-effort medium`. Frontier intelligence at ~5-10× lower cost than high reasoning. **Do NOT use `--reasoning-effort high`** unless you specifically need it — reasoning tokens count against `max_completion_tokens` and burn ~$1-2/file with no quality benefit for our use case. diff --git a/DEVELOP.md b/DEVELOP.md index 96627c70c..ba594cf06 100644 --- a/DEVELOP.md +++ b/DEVELOP.md @@ -68,7 +68,7 @@ source/ -> dist/ skills/{name}/SKILL.md {provider}/{configDir}/skills/{name}/SKILL.md ``` -Each provider gets its own output directory. Two variants are generated per provider: unprefixed and prefixed (with `i-` prefix for skill names). +Each provider gets its own output directory. ## Build System Details @@ -130,7 +130,6 @@ scripts/ - `readSourceFiles()`: Reads all skill directories from `source/skills/` - `replacePlaceholders()`: Substitutes `{{model}}`, `{{config_file}}`, etc. per provider - `generateYamlFrontmatter()`: Serializes objects to YAML frontmatter (auto-quotes values starting with `[` or `{`) -- `prefixSkillReferences()`: Replaces `/skillname` with `/i-skillname` for prefixed variants ## Best Practices diff --git a/lib/download-providers.js b/lib/download-providers.js index b7f6917cd..cca47b27a 100644 --- a/lib/download-providers.js +++ b/lib/download-providers.js @@ -15,7 +15,6 @@ export const FILE_DOWNLOAD_PROVIDERS = Object.freeze( export const BUNDLE_DOWNLOAD_PROVIDERS = Object.freeze([ 'universal', - 'universal-prefixed', ]); export const DOWNLOAD_PROVIDERS = Object.freeze([ diff --git a/public/app.js b/public/app.js index 280189f5b..1b54a7054 100644 --- a/public/app.js +++ b/public/app.js @@ -170,8 +170,8 @@ function renderPatternsWithTabs(patterns, antipatterns) { // ============================================ // Handle bundle download clicks via event delegation. -// Each download button carries the full bundle name in data-bundle (e.g. -// "universal" or "universal-prefixed") so the handler is just a redirect. +// Each download button carries the full bundle name in data-bundle +// (currently just "universal") so the handler is just a redirect. document.addEventListener("click", (e) => { const bundleBtn = e.target.closest("[data-bundle]"); if (bundleBtn) { diff --git a/public/css/main.css b/public/css/main.css index d2c15a660..43dfa0fc0 100644 --- a/public/css/main.css +++ b/public/css/main.css @@ -2785,59 +2785,46 @@ code { } .install-primary-alts { - display: flex; - flex-direction: column; - gap: var(--spacing-lg); min-width: 0; } -/* Collapsible "other install methods" under the main install card. */ -.install-alts-collapse { - margin-top: var(--spacing-md); - border-top: 1px solid var(--color-mist); +/* "Other install methods" is a collapsed
panel that sits + directly under the main install card. The alternatives are worth + keeping discoverable but don't need to be visible by default. */ +.install-primary-main > .install-primary-alts { + margin-top: var(--spacing-lg); padding-top: var(--spacing-md); + border-top: 1px solid var(--color-mist); } -.install-alts-collapse[open] { - padding-bottom: var(--spacing-sm); +.install-primary-alts[open] > .install-alts-summary > .install-alts-arrow { + transform: rotate(90deg); } .install-alts-summary { display: flex; align-items: center; - justify-content: space-between; - gap: var(--spacing-sm); - cursor: pointer; + gap: var(--spacing-xs); list-style: none; - padding: 0.25rem 0; - user-select: none; + cursor: pointer; + padding: 2px 0; } .install-alts-summary::-webkit-details-marker { display: none; } -.install-alts-summary-label { - font-family: var(--font-body); - font-size: 0.6875rem; - font-weight: 600; - text-transform: uppercase; - letter-spacing: 0.08em; +.install-alts-arrow { color: var(--color-ash); + transition: transform var(--duration-fast) var(--ease-out, ease); } -.install-alts-chevron { - color: var(--color-ash); - transition: transform 0.2s ease; - flex-shrink: 0; +.install-primary-alts[open] > .install-alts-summary { + margin-bottom: var(--spacing-md); } -.install-alts-collapse[open] .install-alts-chevron { - transform: rotate(180deg); -} - -.install-alts-collapse[open] .install-primary-alts { - margin-top: var(--spacing-md); +.install-primary-alts[open] > .install-alt-method + .install-alt-method { + margin-top: var(--spacing-lg); } /* Editorial "How to use" step list on the right side of the install row. @@ -2956,6 +2943,42 @@ code { min-width: 0; } +/* Solo install-tool (no grid wrapper) — used when step 3 is Chrome-only. + The preview screenshot sits to the left of the CTA button so neither + dominates vertical space. Collapses to a stack on narrow screens. */ +.install-tool--solo { + flex-direction: row; + align-items: center; + gap: var(--spacing-lg); + margin-top: var(--spacing-md); + width: 100%; +} + +.install-tool--solo .install-tool-preview { + flex: 0 1 260px; + min-width: 0; + margin-top: 0; +} + +.install-tool--solo .install-tool-cta { + flex: 1 1 auto; + margin-top: 0; + width: auto; + white-space: nowrap; +} + +@media (max-width: 640px) { + .install-tool--solo { + flex-direction: column; + align-items: stretch; + } + + .install-tool--solo .install-tool-preview, + .install-tool--solo .install-tool-cta { + flex: 1 1 auto; + } +} + .install-tool-label { font-family: var(--font-body); font-size: 0.9375rem; @@ -2969,10 +2992,50 @@ code { .install-tool-desc { margin: 0; font-size: 0.8125rem; - color: var(--color-charcoal); + color: var(--color-ink); line-height: 1.55; } +/* Chrome extension screenshot preview inside the install-tool column */ +.install-tool-preview { + display: block; + margin-top: var(--spacing-sm); + border: 1px solid var(--color-mist); + border-radius: 8px; + overflow: hidden; + text-decoration: none; + background: var(--color-paper); + transition: border-color var(--duration-fast) var(--ease-out, ease), + transform var(--duration-fast) var(--ease-out, ease); +} + +.install-tool-preview:hover { + border-color: var(--color-accent); + transform: translateY(-1px); +} + +.install-tool-preview img { + display: block; + width: 100%; + height: auto; +} + +.install-tool-preview-caption { + display: block; + padding: 0.4rem 0.75rem; + font-family: var(--font-body); + font-size: 0.75rem; + color: var(--color-ash); + border-top: 1px solid var(--color-mist); +} + +/* "Install from Chrome Web Store" uses the standard .btn .btn-primary + styles; this modifier only adds layout (full width + top spacing). */ +.install-tool-cta { + margin-top: var(--spacing-sm); + width: 100%; +} + .install-alts-label { display: block; font-family: var(--font-mono); diff --git a/public/index.html b/public/index.html index 387083c39..867da43d8 100644 --- a/public/index.html +++ b/public/index.html @@ -117,7 +117,7 @@ - + @@ -329,10 +329,10 @@
- +
-

1Install the skill Recommended

-

One agent skill that teaches your AI to design, with 20 commands bundled inside.

+

1Install the skill and CLI

+

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

@@ -355,51 +355,54 @@
Works with Cursor, Claude Code, Gemini CLI, Codex CLI, and more.
+
+
+ $ + npm i -g impeccable + +
+ Recommended for visual mode and anti-pattern scans. +
-
+
- Other install methods - + Other install methods + -
-
- Claude Code plugin -
- $ - /plugin marketplace add pbakaus/impeccable - -
- Then open /plugin in Claude Code -
-
- Manual download all 11 providers - +
+ Claude Code plugin +
+ $ + /plugin marketplace add pbakaus/impeccable +
+ Then open /plugin in Claude Code +
+ +
+ Manual download all 11 providers +
@@ -433,40 +436,23 @@
- +
-

3Add the anti-pattern tools Optional

+

3Add the Chrome extension Optional

-

Two ways to catch AI slop outside the skill: a CLI for the terminal and a Chrome extension for any webpage. Both catch gradient text, AI color palettes, nested cards, low contrast, and 20+ more rules.

+

Click the toolbar icon on any page and every anti-pattern lights up right where it lives. Catches gradient text, AI color palettes, nested cards, low contrast, and 20+ more rules. Works on localhost, staging, production, or anyone else's site.

-
-
-
CLI Beta
-

Scan files, directories, or live URLs from the terminal. Drop into CI pipelines, pre-commit hooks, or one-off audits.

-
-
- $ - npm i -g impeccable - -
- Or use npx impeccable detect src/ without installing. -
- -
- -
-
Chrome extension
-

Click the toolbar icon on any page and every anti-pattern lights up right where it lives. Works on localhost, staging, production, or anyone else's site.

- -
+
@@ -519,36 +505,49 @@
- v2.1 - April 9, 2026 + v3.0 + April 10, 2026
    -
  • Streamlined from 21 to 18 commands. Removed overlap and confusion: /arrange renamed to /layout, /normalize merged into /polish (design system alignment is now part of the final pass), /onboard merged into /harden (empty states and first-run experiences are part of production readiness), and /extract became /impeccable extract (a sub-mode alongside craft and teach). Every remaining command has a clearly distinct job.
  • -
  • Automatic cleanup of deprecated skills. On first load after updating, the skill detects and removes leftover files from renamed or merged commands. No manual cleanup needed.
  • -
-
- -
-
- v2.0 - April 8, 2026 -
-
    -
  • Renamed frontend-design to impeccable. The core skill now shares its name with the project, and the teach subcommand moved from /teach-impeccable to /impeccable teach. One skill, one namespace.
  • -
  • Data-driven skill rewrite. The core skill was rebuilt against an internal eval framework that runs the same brief through frontier models with and without the skill loaded, then measures how much the output collapses into monoculture. The result: dramatically more font and color diversity, sharper overall design quality, and much stronger Codex support. The biggest unlock was an anti-attractor procedure that forces the model to enumerate and reject its reflex defaults before picking. Validated on gpt-5.4 and Qwen 3.6 Plus across 15 niches.
  • -
  • Anti-pattern detection engine. 25 deterministic rules across typography, color, layout, motion, and quality. Handles oklch, oklab, lch, and lab color formats, CSS variables inside border shorthands, gradient-backed text, and emoji-only nodes.
  • -
  • CLI: npx impeccable detect. Scans HTML, CSS, JSX/TSX, Vue, Svelte, and CSS-in-JS. Framework detection, multi-file import tracking, Puppeteer-backed live URL scanning, CI-ready JSON output, and a --fast regex mode for huge codebases.
  • -
  • Chrome DevTools extension. One-click detection on any page: yours, staging, production, or someone else's. Reads live computed styles, surfaces findings in an interactive panel, and highlights elements on the page. In Chrome Web Store review.
  • -
  • /critique got teeth. Persona sub-agents review in parallel, score against Nielsen's heuristics, run the detector automatically, and open a live browser overlay so you can walk each finding in place.
  • -
  • New ways to create with Impeccable. /shape runs a structured discovery interview about purpose, audience, and goals, then produces a design brief before any code is written. /impeccable craft chains that brief straight into the full implementation flow so you ship a designed feature instead of a reflex card grid.
  • -
  • New docs site. Top-level Docs, Anti-Patterns, and Visual Mode sections. 18 per-skill pages with before/after demos and the canonical SKILL.md inline, two tutorials, and 38 rule cards with inline visual examples.
  • -
  • New harness: Rovo Dev. 11 supported AI tools total.
  • +
  • 18 skills became 1 skill with 20 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.
  • +
  • Rewritten docs site. New /docs home with a featured home command card, dense cheatsheet-style command rows by category, and per-command detail pages. The standalone /cheatsheet was merged into /docs. URL renamed from /skills to /docs with permanent redirects so existing links keep working. The homepage install section was rebuilt 50/50 with a proper "how to use" panel explaining the mixture-of-experts model in plain language.
  • +
  • Teach runs automatically on first use. You no longer have to run /impeccable teach before anything else. Invoke any command in a fresh project and the Context Gathering Protocol kicks off the discovery interview mid-flight, then saves .impeccable.md so every future command reads it silently.
View older releases
+
+
+ v2.1 + April 9, 2026 +
+
    +
  • Streamlined from 21 to 18 commands. Removed overlap and confusion: /arrange renamed to /layout, /normalize merged into /polish (design system alignment is now part of the final pass), /onboard merged into /harden (empty states and first-run experiences are part of production readiness), and /extract became /impeccable extract (a sub-mode alongside craft and teach). Every remaining command has a clearly distinct job.
  • +
  • Automatic cleanup of deprecated skills. On first load after updating, the skill detects and removes leftover files from renamed or merged commands. No manual cleanup needed.
  • +
+
+ +
+
+ v2.0 + April 8, 2026 +
+
    +
  • Renamed frontend-design to impeccable. The core skill now shares its name with the project, and the teach subcommand moved from /teach-impeccable to /impeccable teach. One skill, one namespace.
  • +
  • Data-driven skill rewrite. The core skill was rebuilt against an internal eval framework that runs the same brief through frontier models with and without the skill loaded, then measures how much the output collapses into monoculture. The result: dramatically more font and color diversity, sharper overall design quality, and much stronger Codex support. The biggest unlock was an anti-attractor procedure that forces the model to enumerate and reject its reflex defaults before picking. Validated on gpt-5.4 and Qwen 3.6 Plus across 15 niches.
  • +
  • Anti-pattern detection engine. 25 deterministic rules across typography, color, layout, motion, and quality. Handles oklch, oklab, lch, and lab color formats, CSS variables inside border shorthands, gradient-backed text, and emoji-only nodes.
  • +
  • CLI: npx impeccable detect. Scans HTML, CSS, JSX/TSX, Vue, Svelte, and CSS-in-JS. Framework detection, multi-file import tracking, Puppeteer-backed live URL scanning, CI-ready JSON output, and a --fast regex mode for huge codebases.
  • +
  • Chrome DevTools extension. One-click detection on any page: yours, staging, production, or someone else's. Reads live computed styles, surfaces findings in an interactive panel, and highlights elements on the page. In Chrome Web Store review.
  • +
  • /critique got teeth. Persona sub-agents review in parallel, score against Nielsen's heuristics, run the detector automatically, and open a live browser overlay so you can walk each finding in place.
  • +
  • New ways to create with Impeccable. /shape runs a structured discovery interview about purpose, audience, and goals, then produces a design brief before any code is written. /impeccable craft chains that brief straight into the full implementation flow so you ship a designed feature instead of a reflex card grid.
  • +
  • New docs site. Top-level Docs, Anti-Patterns, and Visual Mode sections. 18 per-skill pages with before/after demos and the canonical SKILL.md inline, two tutorials, and 38 rule cards with inline visual examples.
  • +
  • New harness: Rovo Dev. 11 supported AI tools total.
  • +
+
+
v1.6.0 diff --git a/scripts/build.js b/scripts/build.js index 6636eec54..345f03f58 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -377,8 +377,8 @@ async function buildStaticSite(extraEntrypoints = []) { /** * Assemble universal directory from all provider outputs */ -function assembleUniversal(distDir, suffix = '') { - const universalDir = path.join(distDir, `universal${suffix}`); +function assembleUniversal(distDir) { + const universalDir = path.join(distDir, 'universal'); // Clean and recreate if (fs.existsSync(universalDir)) { @@ -388,7 +388,7 @@ function assembleUniversal(distDir, suffix = '') { const providerConfigs = Object.values(PROVIDERS); for (const { provider, configDir } of providerConfigs) { - const src = path.join(distDir, `${provider}${suffix}`, configDir); + const src = path.join(distDir, provider, configDir); const dest = path.join(universalDir, configDir); if (fs.existsSync(src)) { copyDirSync(src, dest); @@ -397,30 +397,28 @@ function assembleUniversal(distDir, suffix = '') { // Add a visible README so macOS users don't see an empty folder // (all provider dirs are dotfiles, hidden by default in Finder) - const prefixNote = suffix ? '\nSkills in this bundle are prefixed with i- (e.g. /i-audit) to avoid conflicts.\n' : ''; fs.writeFileSync(path.join(universalDir, 'README.txt'), -`Impeccable — Design fluency for AI harnesses +`Impeccable. Design fluency for AI harnesses. https://impeccable.style -${prefixNote} + This folder contains skills for all supported tools: - .cursor/ → Cursor - .claude/ → Claude Code - .gemini/ → Gemini CLI - .codex/ → Codex CLI - .agents/ → VS Code Copilot, Antigravity - .kiro/ → Kiro - .opencode/ → OpenCode - .pi/ → Pi - .trae-cn/ → Trae China - .trae/ → Trae International + .cursor/ -> Cursor + .claude/ -> Claude Code + .gemini/ -> Gemini CLI + .codex/ -> Codex CLI + .agents/ -> VS Code Copilot, Antigravity + .kiro/ -> Kiro + .opencode/ -> OpenCode + .pi/ -> Pi + .trae-cn/ -> Trae China + .trae/ -> Trae International To install, copy the relevant folder(s) into your project root. -These are hidden folders (dotfiles) — press Cmd+Shift+. in Finder to see them. +These are hidden folders (dotfiles). Press Cmd+Shift+. in Finder to see them. `); - const label = suffix ? ' (prefixed)' : ''; - console.log(`✓ Assembled universal${label} directory (${providerConfigs.length} providers)`); + console.log(`✓ Assembled universal directory (${providerConfigs.length} providers)`); } /** @@ -644,16 +642,14 @@ async function build() { const pluginJson = JSON.parse(fs.readFileSync(path.join(ROOT_DIR, '.claude-plugin/plugin.json'), 'utf-8')); const skillsVersion = pluginJson.version; - // Transform for each provider (unprefixed + prefixed) + // Transform for each provider for (const config of Object.values(PROVIDERS)) { const transform = createTransformer(config); transform(skills, DIST_DIR, { skillsVersion }); - transform(skills, DIST_DIR, { prefix: 'i-', outputSuffix: '-prefixed', skillsVersion }); } - // Assemble universal directory (unprefixed and prefixed) + // Assemble universal directory assembleUniversal(DIST_DIR); - assembleUniversal(DIST_DIR, '-prefixed'); // Create ZIP bundles (individual + universal) await createAllZips(DIST_DIR); diff --git a/scripts/lib/transformers/factory.js b/scripts/lib/transformers/factory.js index 5e13a4a4d..eeb1036a6 100644 --- a/scripts/lib/transformers/factory.js +++ b/scripts/lib/transformers/factory.js @@ -1,5 +1,5 @@ import path from 'path'; -import { cleanDir, ensureDir, writeFile, generateYamlFrontmatter, replacePlaceholders, prefixSkillReferences, PROVIDER_PLACEHOLDERS } from '../utils.js'; +import { cleanDir, ensureDir, writeFile, generateYamlFrontmatter, replacePlaceholders } from '../utils.js'; /** * Map from frontmatter field name to extraction spec. @@ -54,8 +54,8 @@ export function createTransformer(config) { .filter(Boolean); return function transform(skills, distDir, options = {}) { - const { prefix = '', outputSuffix = '', skillsVersion = '' } = options; - const providerDir = path.join(distDir, `${provider}${outputSuffix}`); + const { skillsVersion = '' } = options; + const providerDir = path.join(distDir, provider); const skillsDir = path.join(providerDir, `${configDir}/skills`); cleanDir(providerDir); @@ -64,13 +64,13 @@ export function createTransformer(config) { const allSkillNames = skills.map((s) => s.name); const commandNames = skills .filter((s) => s.userInvocable) - .map((s) => `${prefix}${s.name}`); + .map((s) => s.name); let refCount = 0; let scriptCount = 0; for (const skill of skills) { - const skillName = `${prefix}${skill.name}`; + const skillName = skill.name; const skillDir = path.join(skillsDir, skillName); // Build frontmatter @@ -89,13 +89,11 @@ export function createTransformer(config) { const frontmatter = generateYamlFrontmatter(frontmatterObj); // Build body - const cmdPrefix = (PROVIDER_PLACEHOLDERS[placeholderKey] || {}).command_prefix || '/'; let skillBody = replacePlaceholders(skill.body, placeholderKey, commandNames, allSkillNames); // Replace {{scripts_path}} with provider-aware path to skill's scripts directory const scriptsPath = `${configDir}/skills/${skillName}/scripts`; skillBody = skillBody.replace(/\{\{scripts_path\}\}/g, scriptsPath); - if (prefix) skillBody = prefixSkillReferences(skillBody, prefix, allSkillNames, cmdPrefix); if (bodyTransform) skillBody = bodyTransform(skillBody, skill); const content = `${frontmatter}\n\n${skillBody}`; @@ -126,7 +124,6 @@ export function createTransformer(config) { const skillWord = skills.length === 1 ? 'skill' : 'skills'; const refInfo = refCount > 0 ? ` (${refCount} reference files)` : ''; const scriptInfo = scriptCount > 0 ? ` (${scriptCount} script files)` : ''; - const prefixInfo = prefix ? ` [${prefix}prefixed]` : ''; - console.log(`✓ ${displayName}${prefixInfo}: ${skills.length} ${skillWord}${refInfo}${scriptInfo}`); + console.log(`✓ ${displayName}: ${skills.length} ${skillWord}${refInfo}${scriptInfo}`); }; } diff --git a/scripts/lib/utils.js b/scripts/lib/utils.js index 9ed835a30..1965a1f27 100644 --- a/scripts/lib/utils.js +++ b/scripts/lib/utils.js @@ -380,50 +380,14 @@ export const PROVIDER_PLACEHOLDERS = { /** * Replace all {{placeholder}} tokens with provider-specific values */ -/** - * Prefix skill cross-references in body text. - * Replaces patterns like `/skillname` and `the skillname skill` with prefixed versions. - * - * @param {string} content - The skill body text - * @param {string} prefix - The prefix to add (e.g., 'i-') - * @param {string[]} skillNames - Array of all skill names - * @param {string} commandPrefix - The command invocation prefix (e.g., '/' or '$') - */ -export function prefixSkillReferences(content, prefix, skillNames, commandPrefix = '/') { - if (!prefix || !skillNames || skillNames.length === 0) return content; - - let result = content; - // Sort by length descending to avoid partial matches (e.g. 'teach-impeccable' before 'teach') - const sorted = [...skillNames].sort((a, b) => b.length - a.length); - - for (const name of sorted) { - const prefixed = `${prefix}${name}`; - - // Replace command invocations (e.g., `/skillname` or `$skillname`) with prefixed versions - const escapedPrefix = escapeRegex(commandPrefix); - result = result.replace( - new RegExp(`${escapedPrefix}(?=${escapeRegex(name)}(?:[^a-zA-Z0-9_-]|$))`, 'g'), - `${commandPrefix}${prefix}` - ); - - // Replace `the skillname skill` references - result = result.replace( - new RegExp(`(the) ${escapeRegex(name)} skill`, 'gi'), - (_, article) => `${article} ${prefixed} skill` - ); - } - - return result; -} - function escapeRegex(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } const EXCLUDED_FROM_SUGGESTIONS = new Set([ - 'impeccable', 'i-impeccable', // foundational skill, not a steering command - 'teach-impeccable', 'i-teach-impeccable', // deprecated shim - 'frontend-design', 'i-frontend-design', // deprecated shim + 'impeccable', // foundational skill, not a steering command + 'teach-impeccable', // deprecated shim + 'frontend-design', // deprecated shim ]); // Sub-commands of /impeccable that should appear in {{available_commands}}. diff --git a/scripts/lib/zip.js b/scripts/lib/zip.js index 35a834272..6f563112f 100644 --- a/scripts/lib/zip.js +++ b/scripts/lib/zip.js @@ -58,5 +58,4 @@ export async function createAllZips(distDir) { console.log('\n📦 Creating ZIP bundles...'); await createProviderZip(path.join(distDir, 'universal'), distDir, 'universal'); - await createProviderZip(path.join(distDir, 'universal-prefixed'), distDir, 'universal-prefixed'); } diff --git a/tests/lib/utils.test.js b/tests/lib/utils.test.js index 7a0664005..38bfe9f0c 100644 --- a/tests/lib/utils.test.js +++ b/tests/lib/utils.test.js @@ -10,8 +10,7 @@ import { writeFile, generateYamlFrontmatter, readPatterns, - replacePlaceholders, - prefixSkillReferences + replacePlaceholders } from '../../scripts/lib/utils.js'; // Temporary test directory @@ -687,58 +686,3 @@ describe('replacePlaceholders', () => { }); }); -describe('prefixSkillReferences', () => { - test('should prefix /skillname command references', () => { - const result = prefixSkillReferences('Run /audit to check.', 'i-', ['audit', 'polish']); - expect(result).toBe('Run /i-audit to check.'); - }); - - test('should prefix "the skillname skill" references', () => { - const result = prefixSkillReferences('Use the audit skill for checks.', 'i-', ['audit', 'polish']); - expect(result).toBe('Use the i-audit skill for checks.'); - }); - - test('should prefix multiple different references', () => { - const result = prefixSkillReferences('Run /audit then /polish. The audit skill is great.', 'i-', ['audit', 'polish']); - expect(result).toContain('/i-audit'); - expect(result).toContain('/i-polish'); - expect(result).toContain('The i-audit skill'); - }); - - test('should not partially match longer skill names', () => { - const result = prefixSkillReferences('Run /teach-impeccable command.', 'i-', ['teach', 'teach-impeccable']); - expect(result).toBe('Run /i-teach-impeccable command.'); - }); - - test('should handle case-insensitive "the X skill" matching', () => { - const result = prefixSkillReferences('The audit skill is useful.', 'i-', ['audit']); - expect(result).toBe('The i-audit skill is useful.'); - }); - - test('should return content unchanged with empty prefix', () => { - const result = prefixSkillReferences('Run /audit.', '', ['audit']); - expect(result).toBe('Run /audit.'); - }); - - test('should return content unchanged with empty skill names', () => { - const result = prefixSkillReferences('Run /audit.', 'i-', []); - expect(result).toBe('Run /audit.'); - }); - - test('should not match /skillname inside longer words', () => { - const result = prefixSkillReferences('The /auditing process.', 'i-', ['audit']); - // 'auditing' starts with 'audit' but has trailing letters — should NOT match - expect(result).toBe('The /auditing process.'); - }); - - test('should match /skillname at end of string', () => { - const result = prefixSkillReferences('Run /audit', 'i-', ['audit']); - expect(result).toBe('Run /i-audit'); - }); - - test('should match /skillname before punctuation', () => { - const result = prefixSkillReferences('Try /audit, /polish.', 'i-', ['audit', 'polish']); - expect(result).toContain('/i-audit,'); - expect(result).toContain('/i-polish.'); - }); -});