Commit Graph
78 Commits
Author SHA1 Message Date
18fa503d44 fix: normalize quoted user-invocable frontmatter (#87)
* fix: normalize quoted user-invokable frontmatter

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

* fix: preserve quoted non-boolean frontmatter values

Only normalize quoted booleans for the user-invocable frontmatter flag so other quoted fields like argument-hint and description continue to round-trip as plain strings.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>

---------

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-04-28 18:19:50 -07:00
VinaywhoandClaude Opus 4.7 7cfa7759f5 fix: parseFrontmatter handles CRLF line endings
On Windows checkouts, SKILL.md may have CRLF line endings, which caused
parseFrontmatter to fall back to {} and the build to prepend a fresh
frontmatter block while leaving the original one in the body. The result
was the dist Qoder SKILL.md shipping with two frontmatter blocks and
losing user-invocable / argument-hint / license / allowed-tools metadata.

Make the regex and YAML line split CRLF-tolerant. Regenerated tracked
.qoder/skills/impeccable/SKILL.md is now a single, well-formed
frontmatter block.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 16:00:19 +05:30
VinaywhoandClaude Opus 4.7 4f66eb9c08 feat: add Qoder harness support (closes #76)
Qoder ships an Agent Skills system at .qoder/skills/{name}/SKILL.md with
slash-command invocation, mapping cleanly onto the existing transformer
pipeline. Adds Qoder as a 13th first-class harness:

- PROVIDER_PLACEHOLDERS entry in scripts/lib/utils.js (model, config_file,
  ask_instruction, command_prefix) mirroring the Pi/Rovo Dev shape.
- PROVIDERS entry in scripts/lib/transformers/providers.js with
  configDir=.qoder and the OpenCode/Claude Code frontmatter field set
  (user-invocable, argument-hint, license, compatibility, metadata,
  allowed-tools), since Qoder docs explicitly support those.
- transformQoder named export in scripts/lib/transformers/index.js for
  test-spy parity (kept per CLAUDE.md guidance, even though build.js uses
  PROVIDERS directly).
- .qoder added to PROVIDER_DIRS in bin/commands/skills.mjs so the CLI
  detects existing Qoder installs.
- HARNESSES.md updated: official docs row, frontmatter support column,
  directory structure row, and "Last verified" date bumped.
- DEVELOP.md reference link added.
- .github/ISSUE_TEMPLATE/feature_request.md and PULL_REQUEST_TEMPLATE.md
  extended with Qoder in the provider checklists.
- Built .qoder/skills/impeccable/ tree committed (per CLAUDE.md harness
  output dirs are tracked so npx skills can read them at install time).

The dynamic providers.test.js loop picks up Qoder automatically; all
non-prefix Qoder cases pass. The pre-existing Windows-only prefix-test
flake affects every provider equally and is out of scope for this PR.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-28 15:16:12 +05:30
Paul Bakaus 54f6ccf6f0 codex in auto-review became way too autonomous - significantly harden craft/shape flows 2026-04-27 23:41:23 -07:00
Paul BakausandClaude Opus 4.7 5316809139 feat(site): merge /anti-patterns and /visual-mode into /slop
Top nav was at six items and growing. The anti-patterns catalog and the
visual-mode overlay demo were always two views of the same subject (the
rule set and seeing it caught in place), so collapsing them into one page
reduces nav weight and puts the catalog + live demo next to each other.

Four sections in one scroll: See it (iframe demo), Try it live (specimen
gallery), The catalog (full rule list), Run it yourself (invocation
methods). Sidebar TOC nests the catalog sections under "The catalog" for
deep linking. 301s from the old URLs preserve external links.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 13:13:56 -07:00
Paul BakausandClaude Opus 4.7 c160ffc38d feat(live): v2 sidecar upgrade + preserve per-project config on build
Unify the design-system panel's data shape around DESIGN.md frontmatter
as the primary source of truth; the sidecar carries only what Stitch's
frontmatter schema can't (extensions + live component HTML + narrative).
Also fix a long-standing build bug that destroyed per-project config.

Shape changes:
- Server /design-system.json now returns { parsed, sidecar, hasMd,
  hasSidecar, mdNewerThanJson, parseError?, sidecarError? }. No more
  mode switching; both layers ship when present and the panel merges.
- Panel consolidates renderSidecarVisual + renderParsedMdVisual into a
  single renderDesignVisual that merges frontmatter primitives with
  sidecar extensions.colorMeta / typographyMeta. Helpers for color,
  typography, radii model-building. Parsed-md narrative synthesis
  survives as a fallback when no sidecar.
- DESIGN.json rewritten at schemaVersion 2: extensions.{colorMeta,
  typographyMeta, shadows, motion, breakpoints} + components (with
  refersTo pointing back to frontmatter component keys) + narrative.
  Token primitives no longer duplicated in the sidecar.

Build fix:
- scripts/build.js:634 wiped .claude/skills/ (and every other harness
  dir) on each rebuild, then recopied from dist. After commit b0feed0
  unbundled per-project config.json from dist, the sync destroyed the
  user's live-mode config on every build without replacing it.
- Added stashPerProjectArtifacts / restorePerProjectArtifacts in
  scripts/lib/utils.js. Hoisted PER_PROJECT_SCRIPT_ARTIFACTS to a
  module-level export so build.js and readSourceFiles share one
  source of truth. Build now preserves config.json across the sync.

Verified in browser: panel renders 10 colors, 9 typography roles, 3
shadows, 6 grouped components, 9 rules, 25 do/don't items, all merged
correctly from frontmatter + v2 sidecar with zero console errors.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 12:09:55 -07:00
Paul BakausandClaude Opus 4.7 b0feed06c9 feat(live): config globs + drift-heal warning for multi-page projects
Config drift was a real tripwire for projects with static generators: new
HTML files get added, never make it into config.files, silently skip
injection. Two additions.

config.files entries now accept glob patterns (**, *, ?) expanded via
fs.globSync in live-inject. Multi-page projects can write
["public/**/*.html"] once and never maintain the list again. New optional
exclude field filters out matched files (email templates, demo fixtures).
HARD_EXCLUDES of node_modules and .git are enforced regardless of user
config so vendor trees can never receive a tracking script.

live.mjs now runs a drift scan after inject: walks common page-source
roots (public/, src/, app/, pages/) and reports HTML files not covered
by the resolved inject targets. Respects user excludes so intentional
omissions aren't flagged. Output JSON carries configDrift: { orphans,
orphanCount, hint } or null. live.md documents the agent flow for
surfacing drift to users without auto-mutating the config.

Unbundle config.json from the distributable skill: it's a per-project
artifact, not skill code. readSourceFiles now skips any PER_PROJECT_ARTIFACTS
during source scan so build output to .claude/ .cursor/ etc never ships
one project's inject targets to another's install. The per-harness
copies stay gitignored via the existing **/skills/impeccable/scripts/config.json
rule; each consuming project writes its own on first /impeccable live.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-23 09:12:56 -07:00
Paul Bakaus d03dca1209 fix(site): restore Antidote section with curated anti-pattern list
The DO/DONT extractor in readPatterns stopped finding anything after
the skill went human-authored (new SKILL.md uses plain bullets, one-word
section headings, no DO:/DON'T: prefixes). Replace the extractor with
a hand-curated category list: six categories, three or four DOs and
DON'Ts each. Editorial tone, tight, deliberately a teaser — the full
catalog still lives on /anti-patterns.

The legacy SKILL.md parser is retained in the file as _legacyReadPatterns
in case we want to revive it later with a different format.

Small CSS fix: .faq-question was display:flex with justify-content:
space-between, so inline <code> in a summary got treated as its own
flex item and pushed apart. Switched to relative+absolute positioning
so the + icon sits in the right margin and text flows naturally.

Changelog font size reduced to 0.9375rem for the expanded v3.0 entry.
New FAQ entry on pinning standalone commands back. Pin section added
to /docs/impeccable editorial.
2026-04-22 11:52:40 -07:00
Paul BakausandClaude Opus 4.7 1ba75a820e fix(skill): 3 review-bot findings from EAC PR
1. cleanup-deprecated: strip `i-` prefix before fingerprint lookup so
   `i-harden` / `i-optimize` classify correctly (regression from the
   prefixed-naming migration).

2. build: substitute `{{scripts_path}}` in reference/*.md the same way
   it's substituted in SKILL.md. Previously the placeholder survived
   unresolved in built reference files, so any reference that told the
   agent to run a scripts path emitted a literal `{{scripts_path}}` to
   the shell.

3. live-poll: drop the `undici` import. Node's built-in fetch enforces a
   300s headers timeout that can't be lowered per-request, so we now cap
   each poll slice at 270s and loop internally until a real event or the
   caller's total timeout. Removes the hard `ERR_MODULE_NOT_FOUND`
   failure when undici isn't transitively hoisted.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 09:32:31 -07:00
Paul BakausandClaude Opus 4.7 4daabe5232 feat(skill): register split, color strategy, and pre-design intake
Splits the skill into two register references (editorial, product),
replaces category-based theme selection with a forced physical-scene
inference, and introduces a four-step color strategy axis (Restrained /
Committed / Full palette / Drenched) with editorial permission for the
bold three.

Adds a seed mode to /impeccable document for pre-implementation
projects, updates /impeccable teach Step 5 to offer the seed path, and
grows /impeccable shape with Design Direction + Scope intake
(fidelity, breadth, interactivity, time). Extends live-mode variant
distinctness to forbid three variants sharing theme and dominant hue.

Also drops the anti-pattern validator coupling, consolidates a11y into
audit.md, and updates CLAUDE.md with the register architecture.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 14:13:29 -07:00
Paul BakausandClaude Opus 4.6 af2d6e1194 Support PRODUCT.md + DESIGN.md as canonical context files
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) <noreply@anthropic.com>
2026-04-13 18:14:13 -07:00
Paul BakausandClaude Opus 4.6 4092ee5f22 Move PID file to project root (.impeccable-live.json)
os.tmpdir() returns /var/folders/.../T/ on macOS, not /tmp/. The skill
reference was telling the agent to cat /tmp/impeccable-live.json which
didn't exist. Moving the PID file to the project root makes it
predictable across platforms and project-scoped (multiple projects can
run independent live sessions).

Changed in: live-server.mjs, live-poll.mjs, live.md reference.
Added .impeccable-live.json to .gitignore.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 12:32:42 -07:00
Paul BakausandClaude Opus 4.6 e4d1d96926 Auto-generate argument hint with all commands grouped by category
The static "[command] [target]" hint didn't help users discover available
commands. The build now reads command-metadata.json and groups commands
by category (from SKILL_CATEGORIES) with middle-dot separators for
natural line-breaking in the prompt bar.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 09:22:09 -07:00
Paul BakausandClaude Opus 4.6 bb94dadda0 Add live variant mode: element picker, action panel, poll/reply bridge (22 commands)
New feature: /impeccable live starts an interactive visual iteration server.
Users select elements in the browser, pick a design action (bolder, quieter,
etc.), and the agent generates HTML+CSS variants written directly to source.
The dev server's HMR hot-swaps them in, and MutationObserver progressively
reveals each variant in a cycler UI as it arrives.

Architecture:
- src/live/server.mjs: HTTP + WebSocket server with session token auth,
  long-poll /poll endpoint for the agent, WebSocket for the browser
- src/live/poll.mjs: CLI client (npx impeccable poll / poll --reply)
- src/live/browser.js: element picker with keyboard nav (arrows=siblings,
  shift+arrows=parent/child), action panel (12 commands, freeform input,
  variant count), variant cycler with progressive reveal via MutationObserver
- src/live/protocol.mjs: shared message types and event validation
- source/skills/impeccable/reference/live.md: agent loop instructions
  (inject script, poll loop, generate variants, accept/discard, cleanup)

CLI changes:
- bin/cli.js: added "poll" top-level command
- src/detect-antipatterns.mjs: liveCli() now delegates to src/live/server.mjs
- package.json: added ws dependency

Registered /impeccable live as command #22 across all standard locations.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 17:13:53 -07:00
Paul BakausandClaude Opus 4.6 e58cbc432f Split /onboard back out as its own command (21 commands total)
Pre-3.0, onboard was folded into /harden when we were trying to reduce
namespace pollution. In the single-skill model that tradeoff is gone,
so the weakest of the old merges is the first to undo.

Harden and onboard live in different mental modes. Harden is defensive
(edge cases, i18n, overflow, errors). Onboard is activation (first-run
flows, empty states as CTAs, progressive disclosure). A user thinking
"design the onboarding flow" was never going to type /impeccable harden.

Changes:
- New reference file at source/skills/impeccable/reference/onboard.md,
  restored from the pre-merge version in git history rather than the
  condensed 33-line summary that was in harden.md.
- Removed the "Onboarding & First-Run Experience" section from
  source/skills/impeccable/reference/harden.md.
- Updated harden description/editorial/process-steps to drop onboarding
  keywords; split commandProcessSteps so harden stays focused on
  production resilience and onboard gets its own phases.
- Registered onboard in: SKILL.md description + command menu + router
  table, command-metadata.json, IMPECCABLE_SUB_COMMANDS, pin.mjs
  VALID_COMMANDS, SKILL_CATEGORIES, COMMAND_RELATIONSHIPS, data.js
  commandCategories + commandProcessSteps + commandRelationships,
  framework-viz commandSymbols + commandNumbers.
- Reused the existing content/site/skills/onboard.md editorial wrapper
  (it was orphaned by the merge but never deleted), updating it to use
  /impeccable onboard.
- Bumped all user-facing count references 20 -> 21: public/index.html,
  CLAUDE.md, README.md, NOTICE.md, plugin.json, marketplace.json,
  sitemap.xml, build-sub-pages.js.
- Harness dir audit.md and critique.md changes are the
  {{available_commands}} placeholder expanding to include onboard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 19:21:45 -07:00
Paul BakausandClaude Opus 4.6 2233d82f3a 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>
2026-04-10 20:28:07 -07:00
Paul BakausandClaude Opus 4.6 b0f44f83c6 Consolidate 18 skills into 1 /impeccable skill with 20 commands
Biggest change in a while. Users previously had 18 standalone skill
entries cluttering their /menu; now they have one entry (/impeccable)
that routes to 20 specialized commands via argument dispatch. The pin
mechanism (/impeccable pin audit) restores standalone shortcuts on
demand for commands users hit all the time.

## Architecture

- Single /impeccable skill with command router section in SKILL.md
- 20 commands served via reference files under source/skills/impeccable/reference/
- /impeccable pin <command> creates a lightweight redirect shim so users
  who prefer /audit, /polish, etc. can still have them
- Context gathering (teach) auto-runs on first use
- command-metadata.json is the single source of truth for command
  descriptions, argument hints, and relationships

## Site rewrite

- Docs URL: /skills renamed to /docs (with /skills permanent redirects)
- Homepage hero frames Impeccable as "one skill with 20 commands"
- "Get Started" split into 50/50 install + how-to-use with editorial
  numbered steps, /impeccable shown as the home command with three modes
- New /docs overview: home command hero card + dense category rows
  matching the old cheatsheet density, with leads-to/pairs-with/
  combines-with relationship metadata served from a shared source
- Cheatsheet merged into /docs, /cheatsheet redirects
- Magazine spread and mobile cards show /impeccable as a stacked
  namespace label above the command name at full display size
- Periodic table updated with craft/teach/extract as first-class cells
- Skill detail pages generate from reference files, with an editorial
  wrapper per command for tagline + body
- Tutorials and anti-patterns pages updated to use /impeccable <cmd>

## Build system

- Dead code removed (scripts/lib/transformers/shared.js)
- Build log wording fixed ("1 skill" not "1 skills (1 user-invocable)")
- generateApiData fallback branch removed (throws loudly if metadata
  missing instead of silently degrading)
- Commands API includes editorial tagline alongside the long description;
  UI surfaces prefer tagline for human display, description for auto-
  trigger keyword matching

## Gitignore

- Added .claude/scheduled_tasks.lock, .claude/settings.local.json to
  ignore list (local Claude Code state that should not be tracked).
- Harness skill directories (.claude/skills/, .agents/skills/, etc.)
  remain tracked by design: npx skills reads them from this repo at
  install time and they enable clean submodule use.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 19:45:17 -07:00
Paul BakausandClaude Opus 4.6 f957fcad20 Fix: quote YAML scalars that contain colon-space in frontmatter
generateYamlFrontmatter only re-quoted values starting with `[` or `{`,
but parseFrontmatter strips surrounding quotes on input. Descriptions
containing `: ` (e.g. "Also handles: critique...") round-tripped into
unquoted plain scalars that YAML parsers reject. Added a yamlNeedsQuoting
check covering colon-space, space-hash, YAML indicator chars, reserved
keywords, and number-like strings, plus regression tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 19:09:55 -07:00
Paul BakausandClaude Opus 4.6 7670d1325a Show actual skills version, not CLI version; normalize version for hash
- Build system now injects skills version (from plugin.json) into
  every SKILL.md frontmatter as a version field
- CLI reads the version from the local impeccable SKILL.md and
  displays it in check/update output
- Hash comparison normalizes the version field (so a version bump
  alone doesn't trigger a full re-download)
- Removed misleading CLI version display from skills commands

CLI bumped to v2.1.5.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 11:18:06 -07:00
Paul BakausandClaude Opus 4.6 c2b72b9d44 Fix: factory transformer was not copying skill scripts to dist
The refactored factory.js transformer dropped script file support that
existed in the old shared.js version. Scripts were read from source
but never written to dist/, so npx skills installed skills without the
cleanup-deprecated.mjs script, causing errors on first load.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-10 09:43:50 -07:00
Paul BakausandClaude Opus 4.6 faa7453db7 Consolidate skills from 21 to 18: rename, merge, and fold
- Rename /arrange to /layout for clarity
- Merge /normalize into /polish (design system discovery + cleanup phases)
- Merge /onboard into /harden (onboarding, empty states, progressive disclosure)
- Fold /extract into /impeccable extract sub-mode (reference file, sidebar link)
- Update all counts, cross-references, data files, demos, and metadata
- Remove System category (now empty)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 20:39:02 -07:00
Paul BakausandClaude Opus 4.6 0567d1954d Fix scroll anchors for /impeccable craft and /impeccable teach
Use h3 headings with custom IDs instead of inline spans so the browser
scrolls to the right position. Added {#id} syntax support to the
markdown heading renderer.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 16:48:22 -07:00
Paul Bakaus ebe07cbae5 Merge gallery into /anti-patterns, hide rule ids
Two fixes from the review.

1. Rule id chip hidden. The internal slugs (e.g. 'border-accent-on-rounded')
   are not useful to readers, only to detector code. Drop the
   .rule-card-id element from the card head entirely. The DOM id on
   the article stays so rules can still be anchor-linked.

2. Merge /gallery into /anti-patterns and drop 'Gallery' from the nav.
   'Gallery' in the top nav reads as 'things built with impeccable'
   when it is actually a curated collection of AI-generated UI in the
   wild — the complement to the rule catalog above.

   - Add GALLERY_ITEMS to content/site/anti-patterns-catalog.js
     (11 entries, same ids and copy as the old gallery.html)
   - Render a new 'In the wild' section at the bottom of
     /anti-patterns with a card grid of the 11 specimens, each linking
     to its standalone live example under /antipattern-examples/{id}.html
   - New .gallery-card CSS: square thumbnail, italic display title,
     charcoal body, hover lifts the card and tints the title accent
   - Add an 'In the wild' entry to the anti-patterns TOC sidebar so
     readers can jump to it
   - Drop the 'Gallery' link from the top-level nav in the shared
     header partial and the 4 hand-authored HTML pages. The old
     /gallery route still serves its page directly (for bookmarked
     links), but the nav no longer advertises it and the gallery page
     itself now marks Anti-Patterns as the active nav item.
2026-04-08 12:48:24 -07:00
Paul Bakaus 0d87b5afb5 Overhaul /anti-patterns with visuals, detection layers, and LLM rules
Three additions to the anti-patterns catalog page, all sourced from a
new content/site/anti-patterns-catalog.js file so the user's parallel
edits to src/detect-antipatterns.mjs don't conflict with display metadata.

1. Detection layer badge per rule. Three layers:
     cli     - static analysis or jsdom. Runs from `npx impeccable detect`
               on files, no browser required. 23 of 25 current rules.
     browser - needs real browser layout (getBoundingClientRect).
               Runs via the browser extension or Puppeteer, not the
               plain CLI. Only 2 rules: cramped-padding and line-length,
               as documented in tests/detect-antipatterns-browser.test.mjs.
     llm     - no deterministic detector. Flagged by /critique's LLM
               review pass. 13 rules live only in the skill's DON'T list.
   Each card renders a mono pill with the layer label, color-coded per
   layer (neutral mist for CLI, blue tint for browser, amber tint for LLM).
   The How-to-read legend grows a dl explaining what each layer means.

2. Inline visual example per detected rule. All 25 detection rules get
   a ~140px tall preview area at the top of the card showing the bad
   pattern as live HTML (cream background, self-contained inline styles).
   Visuals for side-tab, gradient-text, dark-glow, nested-cards, and the
   rest let you see what the detector is actually flagging. LLM-only
   rules ship without visuals for now; their card bodies take the full
   card height.

3. LLM-only rules merged into the sections. Parsed out from
   source/skills/impeccable/SKILL.md DON'T lines that the detector
   doesn't cover: Syne, monospace-as-technical, dark-mode-default,
   everything-in-cards, identical-card-grids, hero-metric-layout,
   glassmorphism, sparkline-decoration, generic-drop-shadows,
   modal-reflex, every-button-primary, redundant-headers,
   mobile-amputation. Each renders like a detection rule card but
   shows the 'LLM only' layer badge and has no rule id chip. They
   slot into the same section groups as detected rules (Interaction
   and Responsive sections added to the section order so these get
   real headings).

- scripts/lib/sub-pages-data.js: imports the catalog, enriches
  detected rules with { layer, visual }, appends LLM_ONLY_RULES with
  layer: 'llm'. Re-exports LAYER_LABELS and LAYER_DESCRIPTIONS for
  the generator.
- scripts/build-sub-pages.js: renderRuleCard adds the visual block
  and the layer badge; LLM rules drop the rule id chip since their id
  is just an internal slug. groupRulesBySection now extends the
  primary order with whatever extra sections rules reference.
- public/css/sub-pages.css: .rule-card now has a .rule-card-visual
  preview area on top with border-bottom, body section below. New
  .rule-card-layer pill styling per layer. Layer legend dl using a
  2-column grid for badge -> description.

Dev server serves 38 total cards (25 detected + 13 LLM) across 8
sections: Visual Details, Typography, Color & Contrast, Layout & Space,
Motion, Interaction, Responsive, General quality.
2026-04-08 12:05:12 -07:00
Paul Bakaus 648eb036ea Mobile collapsible sidebar + more breathing room on active state
Three docs sidebar improvements.

1. Collapsible mobile menu. The sidebar on narrow viewports used to
   dump 21 skill links and 2 tutorial links inline above the content,
   forcing a long scroll past the nav. Add a toggle button at the top
   of the sidebar that shows the current page label (e.g. "/overdrive"
   or "Getting started") plus a chevron, and collapses the menu behind
   it on mobile. Click the button to open/close. On desktop (>=920px)
   the toggle is hidden and the menu shows unconditionally as before.
   Pure aria-expanded state driven by a small delegated click handler
   in render-page.js.

2. Active-state breathing room. The left-border accent on the current
   sidebar item used to sit 2px from the text, which felt cramped. Pull
   the border 14px to the left via margin-left and push the text 12px
   to the right via padding-left. The net result: the accent bar sits
   in the layout gutter, the text keeps its alignment with the brand
   logo in the header, and there's now 12px of comfortable space
   between the border and the text.

3. Active state visibility. The same change makes the accent bar more
   visible on desktop, since it no longer hugs the text. 'aria-current'
   was already being set correctly on /skills/* and /tutorials/* pages;
   the bar just looked too subtle at 2px of clearance.
2026-04-08 11:47:47 -07:00
Paul BakausandClaude Opus 4.6 0728eaadea Allow XML-block prose form in SKILL.md DON'T parser
Recognize "DO NOT" / "DO" lines (with optional colon) inside <rules>
and <absolute_bans> blocks, and make skillGuideline substring matching
case-insensitive so the validator handles the new XML-structured
SKILL.md without rejecting the refactored prose.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-08 11:38:26 -07:00
Paul Bakaus 71f46ef20f Add invisible hover buffer around the before/after demo
Ported the homepage's padding-margin trick: .split-comparison now has
20px of padding around the visible box, with a matching negative
top/bottom margin so the padding does not affect layout flow. The
pointer event listeners move from .split-container to .split-comparison
so the hover tracking engages inside the buffer and only resets when
the mouse leaves the full padded area. Percentage math still reads
.split-container.getBoundingClientRect() so the divider position stays
aligned with the visible box.

This matches how the landing-page split demo feels: graze the edge
and the divider holds; leave the box entirely and it eases back.
2026-04-08 11:09:05 -07:00
Paul Bakaus ac710d5ec1 Fix before/after demo layout, labels, and interaction
Four issues reported on /skills/overdrive (and every other skill demo):

1. The demo block was centered inside the content column, looking odd
   against the otherwise left-aligned page. Drop 'margin: 0 auto' from
   both .split-comparison and .split-container, and remove the nested
   max-width so the whole demo left-aligns at 500px max-width with no
   centering.

2. The BEFORE and AFTER labels were stretching beyond the demo box
   because .split-comparison (560px) was wider than .split-container
   (500px) and .split-labels was using justify-content: space-between
   across the wider parent. Collapse the two max-widths to a single
   500px cap so the labels now sit flush with the container edges.

3. The label row was sitting way below the demo (16px margin-top plus
   the height-stretched container). Tighten margin-top to 10px.

4. The inline split-compare handler only supported click-and-drag. The
   homepage effect also tracks hover on devices with hover:hover, so
   the mouse sweeps the divider and leaving the box eases it back to
   the default. Port that behavior: matchMedia('(hover: hover)') to
   detect, pointerenter/leave to toggle a hovering flag, pointerdown/up
   for drag, and a tiny lerp on requestAnimationFrame so the return to
   center feels smooth. Eyebrow text now reads 'Drag or hover to
   compare' to signal both modes.

Also drop text-align: center on .skill-demo-eyebrow and .skill-demo-caption
for the same left-align consistency.
2026-04-08 11:04:35 -07:00
Paul Bakaus 7d7f77d2ba Before/after split demos on skill pages + sidebar reorder
Two changes bundled:

1. Before/after split demos on every skill detail page.
   - loadCommandDemos() in sub-pages-data.js: dynamically imports each
     module in public/js/demos/commands (the same files the homepage
     uses), returning a { skillId: { id, caption, before, after } } map.
     Falls back to a warn-and-continue if a demo file can't be loaded
     so one bad demo doesn't break the whole generator.
   - buildSubPageData becomes async; caller in build-sub-pages.js
     awaits it.
   - Each skill object gets a .demo field (may be null for /shape).
   - renderSkillDemo() produces the .split-comparison markup matching
     the homepage: .split-container with .split-before + .split-after
     + .split-divider, plus Before/After labels and the caption. The
     block sits between the detail header and the editorial wrapper
     so readers see the visual before reading any prose.
   - sub-pages.css ports the core .split-* layout from main.css (the
     .slop-* and .impeccable-* helpers are homepage-specific and not
     copied). Height is 360px to match the docs column.
   - render-page.js grows a lightweight inline split-compare init
     script (60 lines of vanilla JS) that handles drag and the skewed
     clip-path without depending on the homepage's full lerp/ResizeObserver
     module. Runs only on pages that actually have .split-container.

2. Sidebar reorder: Tutorials first, then skills.
   Walk-throughs are the on-ramp; they belong at the top of the sidebar
   where a new visitor will find them. Add <hr class="skills-sidebar-divider">
   between the Tutorials group and the first skill category so the two
   sections read as distinct.

Verified: /skills/polish, /skills/bolder, /skills/critique all render
the demo block. /skills/shape correctly has none. Sidebar on any /skills
or /tutorials page shows Tutorials first, then a thin mist divider,
then Create / Evaluate / Refine / Simplify / Harden / System skill
categories.
2026-04-08 10:54:18 -07:00
Paul Bakaus eb130c4af9 Copy buttons on code blocks + merge Skills and Tutorials under Docs
Two small-to-medium improvements bundled together.

1. Copy buttons on every rendered code block.
   - render-markdown.js: wrap each fenced code block in a .code-block-wrap
     container and emit a <button class="code-block-copy" data-copy="...">
     alongside it. Button text is set via CSS ::before content so the
     'Copy' / 'Copied' label is a single toggle class (.is-copied).
   - render-page.js: 12-line inline script at the end of the body wires
     a delegated click handler that calls navigator.clipboard.writeText
     and flips .is-copied for 1.5s.
   - sub-pages.css: button styles matching the dark terminal palette,
     hidden until you hover the code block, accent-colored success state.

2. Merge Skills and Tutorials under a single Docs nav item.
   - Rename the Skills nav link to 'Docs' in every header (partial +
     4 hand-authored pages). Drop the separate Tutorials nav item; it
     now lives inside Docs. Anti-patterns stays as its own top-level.
   - scripts/build-sub-pages.js: replace renderSkillsSidebar and
     renderTutorialsSidebar with a unified renderDocsSidebar that shows
     every skill category followed by a Tutorials group. Takes a
     current descriptor of shape { kind: 'skill'|'tutorial', id|slug }
     so both skill detail and tutorial detail pages can mark the active
     row. activeNav on every /skills/* and /tutorials/* page is now
     'docs'; the shared site header's data-nav matches.

Verified: /skills/polish and /tutorials/getting-started both render
with the unified Docs sidebar (all 21 skills grouped by category +
both tutorials as a final group). The Docs nav item is aria-current
on both. Copy buttons appear on every fenced code block and toggle
to 'Copied' when clicked.
2026-04-08 10:50:23 -07:00
Paul Bakaus a89f7f5040 Polish pass on editorial wrappers and skill detail layout
Feedback round from first review of the skill pages. Six concrete fixes:

1. Contain the auto-rendered SKILL.md in a distinct card.
   The "skill itself" section was flowing straight into the editorial
   wrapper above, making the two blocks read as one long mixed
   document. Wrap the canonical body in .skill-source-card: white
   paper background, mist border, rounded, with a small "SKILL.md"
   badge header and an italic subtitle. Drop the old full-width
   divider treatment; the card does the visual separation work.

2. Rewrite the /impeccable "do not fight the opinion" pitfall.
   The old text said "fighting the opinion usually produces worse
   output", which discouraged informed pushback. Replace with language
   that explicitly encourages users with real reasons (brand guideline,
   accessibility, user research) to push back; the skill raises the
   floor, not overrules your judgment when you have evidence.

3. Move /onboard from create to refine.
   Onboarding is refinement of empty states and first-run experiences,
   not greenfield creation. Fixed in:
   - scripts/lib/sub-pages-data.js SKILL_CATEGORIES
   - public/js/data.js commandCategories
   Both locations now list onboard under 'refine'.

4. De-dupe overdrive and animate.
   - overdrive: "how it works" listed 7 techniques as bullets and then
     "try it" listed 5 concrete examples using the same 7 techniques.
     Collapse "how it works" into a tight paragraph and make "try it"
     a specific scenario instead of a laundry list.
   - animate: pitfalls repeated the "no layout properties" rule that
     was already stated in "how it works". Drop the duplicate.

5. Remove outdated tutorial guidance.
   getting-started.md said "Cursor needs Nightly channel plus Agent
   Skills in Settings. Gemini CLI needs the preview version." Neither
   is true anymore. Replace with a generic pointer to check the
   harness's own skill docs.

6. Embed the live visual overlay in critique-with-overlay tutorial.
   The tutorial now renders the same demo iframe the homepage uses
   (/antipattern-examples/visual-mode-demo.html) inside step 2, with
   a mac-window chrome frame that mirrors the homepage preview. New
   .tutorial-embed CSS in sub-pages.css defines the header with
   traffic-light dots + mono title, the iframe body (520px tall),
   and an optional caption. The user now sees the overlay in action
   before being asked to run it locally.
2026-04-08 10:26:01 -07:00
Paul Bakaus 80d7502737 Extend docs-browser shell to detail pages, tighten sidebar, ban em dashes
Builds on the /skills overview landing. Every skill detail page now lives
inside the same sticky-sidebar shell, with the active skill marked via
aria-current and pulled out of the list with a 2px accent border.

- scripts/build-sub-pages.js: detail pages now wrap the .skill-detail
  body in wrapInDocsLayout() and pass currentSkillId into the sidebar
  renderer so the active row is marked
- public/css/sub-pages.css sidebar pass:
  - Narrow from 260px to 200px (was way too wide for the content)
  - Drop the redundant "Skills" label at the top (it was visually
    competing with the category titles); keep the node for a11y via
    visually-hidden styling
  - Group titles shrink to 0.625rem mono uppercase in --color-ash so
    they read as quiet signposts, not headings
  - Tighten item line-height to 1.5 and vertical padding to 3px
  - Replace the box-shadow inset accent with a border-left accent on
    the active item, leaving it visually pulled left
  - Simplify .skill-detail sizing so it works inside .skills-main
    without its own max-width / padding
- Ban em dashes in user-facing copy everywhere:
  - Rewrite 9 copy lines in index.html, 2 title tags in gallery.html,
    inline category descriptions, the /skills overview lede + how-to,
    two skills-generator comments, one aria-label, and the page titles
    for Skills and skill detail pages
  - New validateNoEmDashes step in scripts/build.js scans content/site,
    public/*.html, and the sub-page generator sources. Build fails on
    any — or &mdash; in user-facing copy. Uses commas, colons, periods,
    or parentheses instead

Build green: all 26 HTML entrypoints bundle cleanly, all four hand-authored
pages retain the shared site header, anti-pattern rules still match
SKILL.md, zero em dashes.
2026-04-08 09:45:13 -07:00
Paul Bakaus 7847daffff Generate /skills index + 21 auto-rendered skill detail pages
Ships the first new sub-page section. Every user-invocable skill now has
its own page at /skills/{id}, with the canonical SKILL.md body rendered
via marked. The index at /skills lists all 21 skills grouped by category.

Editorial wrappers are opt-in: if content/site/skills/{id}.md exists, it
renders above the canonical body (with a "The skill itself" divider).
All 21 pages currently ship with the auto-rendered body only; hand-written
wrappers land in the next few commits.

- scripts/lib/sub-pages-data.js: builds the data model. Reuses
  readSourceFiles() from lib/utils.js for skill content; parses the
  ANTIPATTERNS array out of src/detect-antipatterns.mjs; reads optional
  editorial wrappers from content/site/skills/*.md; validates that every
  user-invocable skill has a category entry (build fails loudly if not).
- scripts/build-sub-pages.js: orchestrator. Writes generated HTML into
  public/skills/*.html (gitignored). Called from both scripts/build.js
  (before buildStaticSite) and server/index.js (at module load) so dev
  and prod share the same generation code path.
- scripts/lib/render-page.js: new assetDepth parameter so generated
  pages one level deep under public/ use relative paths (../favicon.svg,
  ../css/sub-pages.css) that Bun's HTML loader can resolve on disk.
- scripts/build.js: pass generated files into Bun.build entrypoints;
  post-process to flatten build/public/* → build/* (Bun preserves the
  public/ prefix when entrypoints span multiple depths).
- server/index.js: generateSubPages() runs at module load; new routes
  /skills, /skills/:id, /anti-patterns, /tutorials, /tutorials/:slug
  serve the pre-generated files via Bun.file().
- public/css/sub-pages.css: adds sub-page layout shell, skills index
  grouped-list styling, skill detail header/meta chips/divider, collapsed
  <details> reference sections, and a .prose block for rendered markdown
  with editorial typography, code blocks, and inline code.

Verified: bun run build produces 26 HTML files (4 hand-authored + 22
generated), all flat under build/. Dev server returns 200 on /skills,
/skills/polish, /skills/impeccable, /skills/critique. Tests pass.
2026-04-08 09:16:19 -07:00
Paul Bakaus 54b687d16f Add sub-page render pipeline foundation
Groundwork for new /skills, /anti-patterns, /tutorials sections.
No user-visible changes yet — this is pure plumbing.

- Split main.css into tokens.css (design tokens + reset, ~100 lines) and
  main.css (everything else, imports tokens.css). Lets sub-pages import
  only tokens without pulling in the landing-page component CSS.
- Add marked as a dependency.
- Add scripts/lib/render-markdown.js: marked wrapper with a custom link
  resolver (skill slugs, reference/*.md anchors, external rel=noopener),
  stable heading slugger, and terminal-style code blocks.
- Add scripts/lib/render-page.js: page shell wrapper that injects the
  shared site header partial with aria-current marking.
- Add content/site/partials/header.html: shared site header with nav
  (Home / Skills / Anti-Patterns / Tutorials / Gallery / GitHub).
- Add public/css/sub-pages.css: shared styles for generated pages, with
  .site-header styling (sticky, backdrop blur, accent-underlined active
  nav item) and mobile collapse.

Build still produces the same 104 KB landing-page CSS chunk; tests pass.
2026-04-08 08:01:34 -07:00
Paul Bakaus 50e5c9af68 Merge remote-tracking branch 'origin/main' into v2.0 2026-04-03 11:10:54 -07:00
Paul BakausandClaude Opus 4.6 f683f413c8 Rename frontend-design to impeccable, fold teach-impeccable into teach mode
Major skill consolidation for v2.0:

- Rename source/skills/frontend-design/ to source/skills/impeccable/
  with user-invocable: true and argument-hint: "[teach]"
- Fold teach-impeccable body into impeccable as "Teach Mode" section,
  activated via /impeccable teach
- Create deprecation shims:
  - frontend-design: redirects to /impeccable
  - teach-impeccable: redirects to /impeccable teach
- Update all 16 skill cross-references from {{command_prefix}}frontend-design
  to {{command_prefix}}impeccable and {{command_prefix}}teach-impeccable to
  {{command_prefix}}impeccable teach
- Update CLI sentinel detection to use 'impeccable' (with teach-impeccable
  as legacy fallback)
- Update build system readPatterns() path and EXCLUDED_FROM_SUGGESTIONS
- Update all public files (data.js, cheatsheet, index, viz, demos)
- Update all documentation (README, NOTICE, AGENTS, plugin.json)
- Update all test expectations

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 14:04:54 -07:00
Dan Minshew 4bff8086d3 Add harness support for RovoDev 2026-03-29 22:12:27 -05:00
Paul BakausandClaude Opus 4.6 efcfd5dadd Merge main into v2.0: consolidate critique skill with scoring, personas, and detection
Merges 54 commits from main including factory-based build system, Trae support,
improved skill descriptions, and security hardening. Consolidates the critique
skill to combine v2.0's sub-agent architecture and automated anti-pattern
detection with main's Nielsen heuristics scoring, cognitive load assessment,
persona-based testing, and structured follow-up workflow. Fixes browser detector
build to create target directory after skill sync.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:20:04 -07:00
Paul BakausandClaude Opus 4.6 112317fd05 Rebase Trae support onto new factory architecture
Merge main (factory refactor) and adapt Trae to use the config-driven
transformer system instead of a standalone trae.js file. Two provider
entries (trae-cn, trae) replace the custom dual-directory logic.

Also adds placeholderProvider support to the factory for providers that
share placeholder configs but need separate output directories.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:38:25 -07:00
Paul BakausandClaude Opus 4.6 7c208cdfbb Merge main and integrate command_prefix support into factory
Resolve conflict from codex.js (deleted in our branch, modified on main
for command_prefix). The command_prefix feature from main is preserved
in factory.js via PROVIDER_PLACEHOLDERS lookup.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 15:19:13 -07:00
Paul BakausandClaude Opus 4.6 2d4c7899dd Update provider configs from official docs, add HARNESSES.md reference
Research each harness's official documentation to verify and correct
provider frontmatter configs. Remove Codex/Gemini body transforms that
targeted their commands systems, not skills.

- Add compatibility + metadata to Cursor and Agents (Copilot)
- Add allowed-tools to Pi
- Remove Codex $ARGNAME and Gemini {{args}} body transforms
- Add HARNESSES.md as source of truth for harness capabilities

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 10:46:59 -07:00
Paul BakausandClaude Opus 4.6 6de73abf1b Fix invalid YAML frontmatter and consolidate build transformers
Fixes #67: argument-hint values starting with [ were parsed as YAML flow
sequences. Replace structured args arrays in source files with pre-formatted
argument-hint strings, and quote values starting with [ or { in
generateYamlFrontmatter().

Also consolidates 8 nearly-identical transformer files into a single
config-driven createTransformer() factory. Adding a new provider now
requires only a config object in providers.js instead of a full file.

- Replace args source frontmatter with argument-hint strings
- Add YAML quoting for values starting with [ or {
- Add quote stripping to parseFrontmatter() for round-trip support
- Create factory.js + providers.js, delete 8 individual transformers
- Replace 16 explicit build.js calls with a loop over PROVIDERS
- Consolidate 8 test files into 2 (factory + providers)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 09:48:42 -07:00
Gabi e97a73446d fix: repair placeholder syntax for codex prefix 2026-03-23 22:01:29 +01:00
Gabi d67d69d342 fix: Codex was showing / instead of $ for command references
The build system hardcoded `/` as the command prefix for every provider,
but Codex CLI uses `$`. Added command_prefix to PROVIDER_PLACEHOLDERS
so replacePlaceholders and prefixSkillReferences use the right one.
Now `$normalize` shows up in Codex output instead of `/normalize`.
2026-03-23 21:59:42 +01:00
Paul BakausandGitHub c878f7db5a Merge branch 'main' into add-trae-support 2026-03-21 21:29:42 -07:00
shog86 9faa690047 Fix Trae output format and add tests 2026-03-22 12:12:24 +08:00
Paul BakausandGitHub 998dd0c68a Merge pull request #52 from Gujiassh/fix/preserve-prefixed-article-casing
fix: preserve article casing in prefixed skill references
2026-03-20 23:39:37 -07:00
Paul BakausandClaude Opus 4.6 df1c26ce63 Fix user-invokable -> user-invocable spelling across entire codebase
PR #50 fixed the output SKILL.md files but the source files, build
scripts, tests, docs, and server code still used the wrong spelling.
Claude Code expects `user-invocable` (with c) for slash command
autocomplete to work.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 23:33:22 -07:00
Paul BakausandClaude Opus 4.6 4f18ddaf52 Improve critique skill: sub-agents, scripts_path, browser overlays
- Add {{scripts_path}} build placeholder that resolves per-provider
  (${CLAUDE_PLUGIN_ROOT}/scripts for Claude Code, relative paths for others)
- Restructure critique into sub-agent architecture: LLM review and
  detector run independently to avoid bias, results synthesized at end
- Browser overlay is now a visual aid for the user only -- agent reads
  findings from console via [impeccable] prefix instead of scrolling
- Add scroll-to-top instruction before overlay injection
- Add allowed-tools frontmatter for detector bash commands
- Fix YAML parser to handle simple string arrays (not just - name: objects)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 19:29:22 -07:00
shog86 3f05d8b6a7 Support both Trae China and International versions
- Output skills to both .trae-cn/ and .trae/ directories
- Update README with installation instructions for both versions
- Update DEVELOP.md with dual-variant documentation
2026-03-19 11:32:09 +08:00