Bump skills to 3.0, remove prefixed bundle, redesign install section

- Bump skills plugin version 2.1.1 -> 3.0.0 (plugin.json, marketplace.json,
  harness SKILL.md files). CLI and Chrome extension unchanged.
- Remove prefixed universal zip bundle and all related code:
  factory.js prefix/outputSuffix options, zip.js variant pass, utils.js
  prefixSkillReferences, the "universal-prefixed" entry in
  download-providers.js, and the matching test suite in utils.test.js.
- Redesign Get Started step 1 "Install the skill and CLI": two terminal
  rows (npx skills + npm i -g impeccable) with paired notes, drop the
  Recommended badge.
- Collapse "Other install methods" back into a <details> element so the
  primary install path is the first thing users see.
- Simplify step 3 to "Add the Chrome extension": remove the CLI tool
  block (now in step 1), use standard .btn .btn-primary for the CTA so
  it matches other primary buttons (square corners, accent slide-up
  hover), and lay out the preview screenshot next to the button instead
  of stacked so the screenshot no longer dominates vertical space.
- CLAUDE.md: rewrite with v3.0 architecture, the "no em dash also means
  no --" rule, the harness-dirs-are-tracked gotcha, the named-export
  test-spy warning, and the evals inline-skill.ts sync note.
- AGENTS.md, DEVELOP.md: drop prefixed variant references.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Paul Bakaus
2026-04-10 20:28:07 -07:00
co-authored by Claude Opus 4.6
parent b0f44f83c6
commit 2233d82f3a
25 changed files with 345 additions and 532 deletions
+98 -27
View File
@@ -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 `<command>.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
`<link rel="stylesheet">` 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 `<link rel="stylesheet">` 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/<command>.md` with the command's instructions
1. Create `source/skills/impeccable/reference/<command>.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/<command>.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/<command>.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.