* refactor(content): merge content/site/ into site/content/
Phase 1 step 1 of the directory restructure. The dual content tree was
called out in CLAUDE.md as cleanup; both trees were already in sync
except for anti-patterns-catalog.js, which moves to site/data/.
- Delete content/site/skills/ and content/site/tutorials/ (duplicates of
site/content/, which is what Astro's content collection actually reads).
- Move content/site/anti-patterns-catalog.js -> site/data/.
- Update scripts/lib/sub-pages-data.js and scripts/build.js to read from
site/content/ and site/data/.
- Drop content/site/ from validateProse target list (site/content was
already there).
- Rewrite the "Two content trees" section in CLAUDE.md as a single-tree
pointer; update stale dev-server text mentioning the deleted
server/index.js.
Tests: 186/186 pass. Skills build: clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(skill): rename source/skills/impeccable/ -> skill/
Phase 1 step 2 of the directory restructure. The path was redundantly
nested ("source/" wrapper plus "skills/impeccable/" — singular content
hidden behind the plural). Collapses to flat skill/SKILL.md +
skill/reference/ + skill/scripts/.
- Move source/skills/impeccable/ -> skill/.
- Rewrite scripts/lib/utils.js readSourceFiles(): drop the multi-skill
iteration (CLAUDE.md commits to a single user-invocable skill); read
skill/SKILL.md directly.
- Update scripts/build.js, scripts/generate-og-image.js, and the
sub-pages data layer to point at skill/.
- Update tests/lib/utils.test.js: drop the "multi-skill" and "dir-name
fallback" cases, update single-skill paths to skill/.
- Update tests/build.test.js similarly: drop "multiple skills"
integration test, update paths.
- Update non-glob path joins in tests/framework-fixtures.test.mjs,
tests/live-e2e/session.mjs, tests/live-e2e/agents/llm-agent.mjs,
tools/live-loop.mjs.
- Update prose/text references in CLAUDE.md, AGENTS.md, DEVELOP.md,
README.md, scripts/lib/sub-pages-data.js, bin/commands/skills.mjs,
site/data/anti-patterns-catalog.js, site/pages/docs/[...slug].astro,
docs/adr-live-variant-mode.md, docs/plans/.
Eval framework note: the separate impeccable-evals repo reads
../impeccable/source/skills/impeccable/ and needs a coordinated
rename to ../impeccable/skill/.
Tests: 186/186 pass. Skills build: clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor: rename docs/ -> notes/
Phase 1 step 3 of the directory restructure. The internal docs/ dir
(ADRs and plans) clashed with the site's /docs route. Renaming it
"notes/" makes the difference unambiguous: notes/ is project-internal
process, /docs is the user-facing route under site/pages/docs/.
No code references the dir; the rename is a clean git mv.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(site): move public/ under site/public/
Phase 2 step 4 of the directory restructure. Public assets and the
Astro publicDir now live alongside the rest of the site, so site/
is fully self-contained for static content.
- git mv public site/public.
- astro.config.mjs: add publicDir: './site/public'. Astro defaults to
./public at the project root, so the override is required.
- scripts/build.js: write generated _data, _headers, _redirects,
_routes.json, and js/detect-antipatterns-browser.js into
site/public/. Also delete the dead _REMOVED() Bun static-site
builder (replaced by Astro at #130; the placeholder no longer earns
its keep).
- scripts/build.js validateProse: replace the stale public/index.html
reference (deleted at the Astro migration) with site/pages/index.astro
in the count-validation file list, restoring homepage drift detection.
- scripts/generate-og-image.js: write OG image into site/public/.
- scripts/screenshot-antipatterns.js: read examples from + write
screenshots to site/public/antipattern-{examples,images}/.
- scripts/lib/sub-pages-data.js: load command demos from
site/public/js/demos/commands.
- .gitignore: rename the public/* generator-output entries to
site/public/*.
- CLAUDE.md: refresh CSS/data-file paths (still pointing at the old
pre-Astro public/css/ + public/js/ tree), point the changelog and
command-add checklists at site/pages/index.astro and
site/scripts/data.js + site/scripts/components/framework-viz.js.
Cloudflare Pages note: functions/ stays at the repo root because
CF Pages auto-discovers it there with no configuration knob to
relocate. Moving it under site/ would either break deployment or
require a build-time copy step that adds more complexity than the
cleanup is worth.
Tests: 186/186 pass. Skills + site build clean. _headers,
_redirects, _routes.json, _data/ all land in build/ correctly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(cli): consolidate bin/ + src/ + lib/ under cli/
Phase 2 step 5 of the directory restructure. The CLI surface was split
across three top-level dirs whose names were easy to mistake for each
other (especially src/ vs source/ pre-step-2). Consolidates under cli/.
- git mv bin -> cli/bin (CLI entry + skills sub-command)
- git mv src -> cli/engine (detect-antipatterns engine + browser variant)
- git mv lib -> cli/lib (download-providers helper)
Update package.json:
- bin.impeccable: cli/bin/cli.js
- main + exports: cli/engine/detect-antipatterns.mjs and the
./browser variant
- files: ["cli/", "LICENSE"]
Update internal references:
- cli/bin/cli.js: dynamic import points at ../engine/, package.json
read goes one level deeper (../../package.json).
- functions/api/download/[type]/[provider]/[id].js + bundle/[provider].js:
cli/lib/download-providers.js path.
- scripts/build.js, scripts/build-browser-detector.js,
scripts/build-extension.js: cli/engine path constants.
- scripts/lib/sub-pages-data.js, scripts/lib/utils.js, skill/scripts/
live-server.mjs: comment refs.
- tests/detect-antipatterns{,-browser,-fixtures}.test.{js,mjs},
tests/windows-path-fix.test.js: import + read paths.
- AGENTS.md, CLAUDE.md: doc paths.
Verified:
- npx node cli/bin/cli.js --version, --help, detect --help all work.
- bun run build, bun run build:browser, bun run build:extension all
clean. Browser detector lands at cli/engine/detect-antipatterns-browser.js;
extension/detector/detect.js still emits to the same location.
- bun run test: 186/186 pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: update browser-detector paths missed in cli/ rename
Bugbot caught two runtime path leaks where the comment got renamed
to cli/engine/ but the actual code still used the old src/ segment.
- skill/scripts/live-server.mjs: detectPaths array now joins cli, engine,
detect-antipatterns-browser.js for both the repo-relative lookup
(4 dirs up from .claude/skills/impeccable/scripts/ to repo root) and
the npm node_modules fallback. Without this fix, the detection
overlay would silently not load during live-server sessions.
- scripts/build.js: the post-build copy of the browser detector into
site/public/js/ was reading from src/. The if (fs.existsSync(...))
guard meant the copy was silently skipping, so antipattern-examples
pages would 404 on /js/detect-antipatterns-browser.js once the site
was deployed.
Tests: 186/186 pass. Build clean. site/public/js/detect-antipatterns-browser.js
re-emits as expected.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix: cleanup-deprecated import path missed an extra .. in cli/ rename
Bugbot caught three call sites in cli/bin/commands/skills.mjs that
import '../../skill/scripts/cleanup-deprecated.mjs'. Pre-rename, that
was correct from bin/commands/ (one parent to bin/, one to repo root).
After moving the file from bin/commands/ to cli/bin/commands/, the
path is one directory deeper, so it needs three .. segments to reach
the repo root. Without the fix, every cleanup invocation throws on
import and gets swallowed by the surrounding try/catch — silent skip.
cli/bin/cli.js's package.json read already uses '../../package.json'
(the same depth pattern), confirming three levels is correct.
Verified: dynamic import resolves and exports the expected functions.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore: sweep stale path/file references missed in the restructure
Same root cause as the two bugbot finds: some references in moved or
related files weren't tracked because they didn't match a simple
sed pattern. Caught the rest by walking each moved dir's depth and
each Astro-migration deletion.
Stale path references (post-Astro migration, missed earlier):
- CLAUDE.md: legacy URL redirects "live in server/index.js" -> point
at the actual sources (scripts/build.js generateCFConfig +
site/public/_redirects).
- AGENTS.md: counts.js path (public/ -> site/public/), changelog file
(public/index.html -> site/pages/index.astro), screenshots note
(public/ -> site/), source-of-truth dirs (source/, src/ -> skill/,
cli/).
- tests/detect-antipatterns-browser.test.mjs: comment about routes
"in server/index.js".
- skill/reference/live.md: workflow.css example for "this repo" was
pre-Astro (public/css/) -> site/styles/. (User-project Vite/Next
example unchanged.)
Stale path that pointed at moved files:
- tests/skills-cli.test.js: CLI path was '..', 'bin', 'cli.js'; now
'..', 'cli', 'bin', 'cli.js'. Test isn't wired into bun run test
but it would have failed if invoked.
Dead files (orphaned by Astro migration, never cleaned up):
- tests/server/download-validation.test.js: imported from
../../server/lib/{validation,api-handlers}.js which were deleted in
b8f09c8. Test was a silent failure waiting to happen.
- scripts/lib/render-markdown.js: 156-line module with zero consumers
(the only caller, scripts/lib/render-page.js, was deleted in the
Astro cleanup).
- scripts/build.js: dead commented-out generateSubPages import.
Tests: 186/186 pass. Build clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(build): remove invalid Corepack packageManager spec
Cloudflare Pages rejects the build with `Unsupported package manager
specification (bun@1.3.11)`. The packageManager field follows
Corepack's syntax which only validates npm/pnpm/yarn — `bun@X.Y.Z`
parses as a malformed Corepack directive even though Bun itself
treats it as a hint.
Pre-existing on main since d874af0 (CF Pages deploy on main also
failing); just surfaces here because the PR triggers a fresh deploy.
CF Pages auto-detects Bun anyway (the build log confirms:
"Detected the following tools from environment: bun@1.3.11,
pnpm@10.11.1, nodejs@22.16.0"). Removing the field unblocks the
deploy without changing local dev behavior.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Paul Bakaus <paulbakaus@pauls-mbp-3.lan>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(live): make live sessions recoverable
tired of live mode losing the plot when the browser moved faster than the agent.
now the state is boring: journal it, resume it, finish it.
---
- add durable live-session journal, checkpoint events, and status/resume/complete commands
- split browser session storage into a testable helper and harden accept/discard completion
- fix Astro live CSS preview mode and add recovery/live E2E coverage
- declare Bun as the package manager and add a Bun-native audit script
* fix(live): acknowledge fallback recovery states
* fix(live): flush recoverable handoffs promptly
* fix(live): keep recovery handoffs accurate
* fix(live): preserve poll reply metadata
* fix(live): treat event HTTP failures as failed sends
* fix(live): acknowledge manual completion through helper
* Add .impeccable project state paths
* Fix live disconnect recovery phase
* Refine live CSS authoring contract
* Test live CSS authoring guidance
* Harden live LLM E2E recovery
* Fix live recovery review issues
---------
Co-authored-by: Paul Bakaus <paulbakaus@pauls-mbp-3.lan>
Follow-up to #134, which scoped validateProse to user-facing copy and
left the LLM-facing skill files alone. Bring those to the same bar,
phased so hardening repetition stays intact.
- Em dashes: 419 → 0 across SKILL.md and 35 reference files. Each
replacement picks the right relationship (colon, semicolon, period,
or parens) instead of letting the dash hide the choice.
- Closer cleanup: deleted or rewrote the "Remember:" sermonettes that
were pure adjective chants (bolder/quieter/clarify/delight/extract/
colorize/layout/typeset/audit/adapt). Survivors that load-bear an
instruction now hand off to /impeccable polish instead of summarizing.
- Opener taglines: rewrote the "[Verb] [object] to [outcome]" brochure
openers in 12 older files to lead with the failure mode, the
strongest claim, or a directive. Newer files (live, brand, product,
audit, critique, harden) kept their existing openers.
- data-driven: rephrased the two technical hits in live.md so the
validator can stay strict on this term.
- validateSkillProse: narrow validator scoped to source/skills/impeccable/.
Em-dash check + the small denylist of phrases with no technical
reading. Hardening repetition and structural-prose rules are
deliberately not enforced — those need human judgment.
Test failure on detectUrl is pre-existing (puppeteer needs --no-sandbox
when running as root); unrelated to these changes.
https://claude.ai/code/session_013zZY6rbB1bS8z3D63rX5hW
Co-authored-by: Claude <noreply@anthropic.com>
Site copy was being called out as AI slop (specifically the word
"load-bearing"). Five-pass cleanup with a build validator to keep it
from creeping back.
Pass 1 — mechanical purge:
- Remove "load-bearing" from impeccable.md, brand.md, live.md,
iterate-live.md
- Remove "highest-leverage" from critique.md, typeset.md, designing
- Remove em dashes from all 9 slop-page rule cards
- Replace "leverage" verb in personas.md
Pass 2 — rewrite the worst offenders:
- Changelog v2.0 "Data-driven skill rewrite" entry: drop "data-driven",
"frontier models", "collapses into monoculture", "biggest unlock",
"reflex defaults"; name the actual mechanism
- README opener: drop "deeper expertise and more control"; replace with
three concrete differentiators (7 reference files, 23 commands, 27
detection rules)
- Neo Mirai case study opener: action-first, name the image model used
Pass 3 — editorials:
- Fix negation pivot in distill.md ("simplicity is not about ... It is
about ...")
Pass 4 — homepage why-panels:
- Foundation lead: name the 7 reference files specifically
- Language lead: show the discipline mapping with real command names
- Production-codebases panel: drop "Impeccable isn't a sketchpad"
negation pivot
- Ships-code panel: replace "is native to that world" with "runs there"
Pass 5 — STYLE.md and validator:
- New STYLE.md at root: editorial brief with 12 principles and the
enforced denylist (each rule with a rationale and a suggested
replacement)
- scripts/build.js: validateNoEmDashes becomes validateProse. Adds 21
phrase rules with rationales, catches the \`--\` em-dash substitute,
expands target list to site/pages, site/content, README.md,
README.npm.md
- CLAUDE.md: replace the em-dash section with a STYLE.md pointer and
document the two-content-tree footgun (content/site/ vs site/content/
must be edited in lockstep until they're unified)
Co-authored-by: Claude <noreply@anthropic.com>
* feat(site): scaffold Astro migration, convert 3 pages
Phase 1+2 of the Astro migration:
- Astro v6.2.1 installed, srcDir: 'site', static output to build/
- Shared layout: Base.astro (head, fonts, meta, slots), Header.astro
(star count in one place: 23k), Footer.astro
- CSS moved from public/css/ to site/styles/ (9 files, @import chains
resolve via Vite)
- Three pages converted: privacy, cases/neo-mirai, live-mode
(all return 200 on astro dev)
Remaining: designing, slop, homepage, content collections (docs),
JS migration, server/index.js deletion, build.js cleanup.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(site): migrate all 6 main pages to Astro
Converts the remaining pages:
- designing/index.html → site/pages/designing/index.astro (551 lines)
- slop/index.html → site/pages/slop/index.astro (909 lines)
- index.html → site/pages/index.astro (1278 lines, the homepage)
Base.astro gains OG meta tag props, before-header/after-header
slots (for grain overlay and section nav), and configurable mainId.
Homepage uses link tags to public/css/ instead of frontmatter CSS
imports to avoid esbuild choking on :has() in main.css. Curly
braces inside <code> elements (CSS snippets in changelog) escaped
with HTML entities to prevent Astro JSX expression parsing.
All 6 pages return 200 on astro dev. Branch: feat/astro-migration.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(site): content collections for docs and tutorials
Replaces the 1532-line build-sub-pages.js generator with Astro v6
content collections:
- 24 skill editorial files move to site/content/skills/
- 4 tutorial files move to site/content/tutorials/
- site/content.config.ts defines both collections with glob loaders
- site/pages/docs/[...slug].astro reads skills collection + command
metadata from source/skills/ at build time
- site/pages/docs/index.astro renders the command grid grouped by
category (create, evaluate, refine, simplify, harden, system)
- site/pages/tutorials/ mirrors the pattern with ordered index
- Doc.astro layout provides sidebar nav, breadcrumbs, and related-
command chips from the COMMAND_RELATIONSHIPS data
- Category/relationship data extracted to site/data/sub-pages-data.ts
All 15 tested pages return 200: 6 main pages + 5 docs + 2 tutorials
+ 2 index pages. The old generator is not yet deleted (Task #6).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(site): move JS source from public/js/ to site/scripts/
Moves all 49 JS files (app.js + 48 in js/) into site/scripts/.
Vite now processes them through its module bundler instead of
serving them raw from public/.
app.js import paths updated from ./js/X to ./X (the js/ nesting
is gone since app.js now lives alongside the subdirectories).
Homepage and live-mode page switch from <script is:inline src="/app.js">
to Vite-processed <script> imports, so tree-shaking, bundling,
and minification happen automatically at build time.
public/js/ still exists for now (cleanup in Task #6) and the
generated/counts.js build output path needs updating there too.
@paper-design/shaders added to npm dependencies (was missing).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(site): delete old Bun server, generator, and duplicated files
Cleanup after the Astro migration:
Deleted:
- server/index.js (233 lines, replaced by `astro dev`)
- scripts/build-sub-pages.js (1532 lines, replaced by content collections)
- scripts/lib/render-page.js (247 lines, replaced by Base.astro layout)
- content/site/partials/header.html (replaced by Header.astro component)
- public/index.html, privacy.html, designing/, live-mode/, cases/
(replaced by .astro pages in site/pages/)
- public/css/ (moved to site/styles/)
- public/js/ old source files (moved to site/scripts/)
- public/app.js (moved to site/scripts/app.js)
Kept in public/:
- antipattern-examples/ (standalone HTML demos, not Astro pages)
- antipattern-images/, assets/, neo-mirai/ (static assets)
- js/detect-antipatterns-browser.js (referenced by antipattern examples)
- js/generated/counts.js (build output from scripts/build.js)
- _data/api/ (generated API data, now written to public/ so Astro
passes it through to build/)
Updated:
- astro.config.mjs: added redirects (skills->docs, cheatsheet->docs,
gallery->slop, neon-mirai->neo-mirai, etc.)
- package.json: dev->astro dev, build->build:skills+build:site,
preview->astro preview
- scripts/build.js: removed buildStaticSite(), generateSubPages(),
static-asset copying. API data writes to public/_data/ instead of
build/_data/. Site-header validator is a no-op (shared component).
Em-dash validator scans site/components + site/layouts, not pages
(pages contain content from other sources like detector descriptions).
- .gitignore: removed public/slop/ entry
Tests: 186/186 pass. Skills build: clean.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(site): fix redirect config for Astro compatibility
Move the dynamic /skills/:id -> /docs/:id redirect to public/_redirects
(Cloudflare Pages native format) since Astro's redirect config can't
handle dynamic routes that don't match existing page patterns.
Remove duplicate trailing-slash redirect entries that caused warnings.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(site): switch remaining pages from /css/ link tags to frontmatter imports
Doc.astro, docs/index, tutorials/index, and tutorials/[slug] were
still using <link href="/css/sub-pages.css"> which pointed at the
deleted public/css/ directory. Switched to frontmatter CSS imports
(import '../../styles/sub-pages.css') which Vite resolves from
site/styles/.
Homepage also switches from link tags to frontmatter imports for
main.css and sub-pages.css — the esbuild error that originally
forced the link-tag workaround was caused by unescaped curly braces
in the HTML content (since fixed), not by the CSS itself.
All pages verified visually in Chrome: homepage hero, foundation
grid, docs index (card grid with categories), docs detail (sidebar +
editorial content + visual mockups), designing (core loop diagram),
privacy, tutorials. Header renders with 23k stars on every page.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(site): fix edge-to-edge sections, broken API paths, CSS links
Three fixes:
1. Homepage sections sat on the viewport edge because Base.astro's
<main> lacked the site-content class (provides max-width + padding).
Added mainClass prop to Base.astro; homepage sets mainClass="site-content".
2. "Failed to load commands" because app.js fetched /api/commands
which only existed in the old Bun server's routing. Updated to
fetch from /_data/api/commands.json (the static JSON files that
build:skills writes to public/_data/).
3. CSS reference fix (previous commit was incomplete): Doc.astro,
docs/index, tutorials pages all used <link href="/css/sub-pages.css">
pointing at deleted public/css/. Switched to frontmatter imports.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(site): add sidebar to docs index page
The docs index was using Base.astro directly without the skills-layout
grid, so it rendered without a sidebar. Added the same sidebar structure
from Doc.astro (category-grouped command list) and wrapped the content
in the skills-layout grid.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(site): extract footer CSS to shared file, import in Base.astro
Footer was unstyled on sub-pages because footer CSS lived only in
main.css (loaded by the homepage) not in sub-pages.css. Extracted
the 95 lines of footer rules into site/styles/footer.css and
imported it in Base.astro so every page gets footer styles regardless
of which page-specific CSS it loads.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(demos): move landing-demo into repo, add as slop specimens
Moves ~/code/landing-demo/ into demos/landing-demo/ (without
node_modules or the redundant .claude/.agents skill copies — the
repo root's skill is found by walking up). PRODUCT.md, DESIGN.md,
DESIGN.json, PROMPT.md, and SCRIPT.md stay in place so running
Claude from demos/landing-demo/ picks up the project context.
Also copies both pages as slop specimens to public/antipattern-examples/
with the detector script baked in:
- new-slop-2026.html (Fraunces + warm cream editorial monoculture)
- old-slop-2022.html (purple gradient + glassmorphism + neon glow)
These can be linked from the slop page gallery alongside the
existing 11 synthetic specimens.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(slop): replace single demo iframe with Then vs Now comparison
The "See it" section (01) on the slop page now shows two side-by-side
browser frames: 2022 slop (purple gradients, glassmorphism, neon glow)
and 2026 slop (Fraunces, warm cream, editorial restraint). Both run
the detector overlay live — hover either to see which rules fire.
Replaces the single visual-mode-demo.html iframe. Responsive: stacks
vertically on viewports below 900px.
Caption: "Same engine, different decade, both flagged."
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(slop): switch to single-frame era toggle, center the section
Replaces the side-by-side dual-iframe layout with a single large
frame and a segmented 2022/2026 toggle. Clicking the toggle swaps
which iframe is visible (both pre-loaded, instant switch). Browser
chrome title updates to match the active era.
Centers the lede text and toggle above the frame for visual
cohesion with the full-width iframe below.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(slop): left-align See It section, toggle inline with lede
Moves the era toggle to the right of the lede paragraph using a
flex row (align-items: flex-end). Left-aligned text + right-docked
toggle matches the rest of the page's flow instead of standing out
as a centered island. Stacks vertically on narrow viewports.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(slop): left-align iframe, remove max-width and auto margin
The visual-mode-preview had max-width: 1040px + margin: 0 auto
which centered it within the column. Override both in the
.slop-then-now context so the frame fills the full content width
flush with the text above. Caption left-aligned to match.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(site): update star count to 24k (24,062)
One file, one edit. The Astro migration working as intended.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(build): regenerate pnpm-lock.yaml for astro + shaders deps
Cloudflare Pages uses pnpm with frozen-lockfile. The lockfile was
stale after adding astro, @astrojs/cloudflare, and
@paper-design/shaders via npm.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(build): resolve 3 bugbot review issues
1. Restore public/slop/ to .gitignore — prevents accidental legacy
generator output from conflicting with the Astro page.
2. Move astro and @paper-design/shaders to devDependencies — these
are site-build tools, not CLI runtime deps. Removes @astrojs/cloudflare
entirely (unused; static output mode needs no adapter).
3. Fix Astro wiping build:skills output — CF config (_headers,
_redirects, _routes.json) and API data now write to public/ so
Astro copies them through. Dist ZIPs copy to build/_data/dist/
as a post-build step (after Astro finishes).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(build): merge duplicate devDependencies, use npx for astro CLI
The previous commit created a second devDependencies key in
package.json. JSON doesn't support duplicate keys — pnpm ignored
the first block (with astro), so `astro build` wasn't found.
Merged astro and @paper-design/shaders into the existing
devDependencies block. Changed `astro build/dev/preview` to
`npx astro build/dev/preview` so pnpm finds the local binary
on Cloudflare Pages (which doesn't add node_modules/.bin to PATH
by default).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(demos): remove private demo script and prompt from public repo
SCRIPT.md contained a detailed conference talk script with personal
delivery strategies, rehearsed Q&A answers, and venue details.
PROMPT.md contained the origin brief for the demo page. Neither
belongs in a public repo.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(build): gitignore generated public/ artifacts, consolidate redirects
1. Generated files written to public/ by build:skills (API data,
CF config, browser detector, counts.js) are now gitignored.
Prevents noisy diffs and merge conflicts from committed build
artifacts.
2. Removed duplicate redirects from astro.config.mjs. All redirects
now live in one place: the _redirects file generated by
scripts/build.js (which Cloudflare Pages processes natively).
Eliminates the dual-maintenance risk where the two sources
could drift apart.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Marketplace source moved from "./" to "./plugin", a thin generated
subtree containing only the plugin manifest and the impeccable skill.
Per-version plugin cache shrinks ~378× (~770 KB instead of ~291 MB),
and the lockfile is no longer included in the source path so the
cache extraction never runs bun install. (#107)
- skills field in plugin.json now ends with a trailing slash to match
the documented schema (code.claude.com/docs/en/plugins-reference,
every directory example uses ./path/). Three reporters converged on
this fix because Claude Code's plugin loader skips command
registration on some setups when the slash is missing. (#86)
- Anti-patterns maintenance agent moved out of .claude/agents/ into
CLAUDE.md / AGENTS.md as concise inline guidance, since it is
repo-internal dev workflow, not user-facing. The plugin was also
the only place this agent was exposed to install users.
- Skills version bumped to 3.0.2 so existing users pick up the new
install path on next /plugin update.
- Top-level harness directories (.claude/skills/, .cursor/skills/, ...)
intentionally stay where they are; npx skills add reads them
directly from the GitHub repo and that path is unaffected.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
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>
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>
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>
- 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>
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>
The gallery page had broken styling and missing images. The visual
mode page already has the same specimen gallery in a better layout.
- Removed public/gallery.html and its build entry point
- Updated homepage links to point to /visual-mode#try-it-live
- Added 301 redirect from /gallery to /visual-mode#try-it-live
- Added id="try-it-live" anchor to the visual-mode gallery section
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 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>
The build still generates deprecated stubs in dist/ (so the cleanup
script can redirect users), but now removes them from the repo's own
harness directories so they don't clutter the local skill list.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
These self-contained HTML files and the detector script were served
by the dev server from public/ but never made it into the Cloudflare
Pages build directory, causing 404s on the deployed site.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cloudflare Pages merges headers from all matching rules rather than
overriding, so the path-specific SAMEORIGIN conflicted with the global
DENY. Switch the global rule to SAMEORIGIN since the site only frames
its own antipattern example pages.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The global _headers rule set DENY for all paths, preventing the
/visual-mode/ page from embedding /antipattern-examples/ in an iframe.
Add a path-specific SAMEORIGIN override for /antipattern-examples/*.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Bun shipped with Cloudflare Pages doesn't dedupe shared CSS chunks
across HTML entrypoints — each entry tries to emit its own copy. With
chunk: '[name]-[hash].[ext]', three sub-pages all named index.html
(skills/, tutorials/, anti-patterns/) plus shared CSS content end up
producing chunks with identical name+hash and the build aborts on
'Multiple files share the same output path'.
Including [dir] in the chunk and asset templates scopes each chunk to
its entry's source directory, so the per-entry copies land in unique
paths even when dedupe is off. Local Bun (1.3.x) still emits a single
shared chunk because [dir] is only used when there are multiple chunk
candidates.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cloudflare Pages ships an older Bun than the one used locally. That
version emits shared CSS chunks via the default 'chunk-[hash]' naming
template, but the [hash] token isn't always populated when the chunk
is shared across multiple HTML entrypoints — every sub-page that
imports sub-pages.css ends up wanting the same './chunk-' filename
and the build aborts with 'Multiple files share the same output path'.
Pin the chunk and asset naming explicitly so [hash] is always present
regardless of Bun version.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When Bun.build aggregates resolution failures, the thrown error keeps the
real causes on error.errors (an array). The previous handler only printed
error.message and error.stack, both of which are generic / undefined for
this kind of failure, so CI logs read as 'Bundle failed / undefined' with
no clue what was unresolved. Walk error.errors first so the actual file +
import that failed shows up in CI output.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
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 — 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.
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.
Every hand-authored HTML page now carries the same sticky top nav:
Home / Skills / Anti-Patterns / Tutorials / Gallery / GitHub. The three
future sections (skills, anti-patterns, tutorials) will land behind
these links in subsequent commits.
- Add <header class="site-header"> with a <!-- site-header v1 --> marker
to index, cheatsheet, gallery, privacy
- Each page links public/css/sub-pages.css so it picks up the shared
header styling (sticky, backdrop blur, accent-underlined current item)
- Gallery: drop the inline .site-header/.header-brand/.header-nav
definitions that predate the shared component (class names conflicted)
- Cheatsheet: restructure the page title into .cheatsheet-page-header
so it doesn't collide with the new <header class="site-header">; move
the page container max-width/padding off <body> onto .cheatsheet-page-header,
main, and footer so the shared sticky header spans the full viewport
- Privacy: full styling refresh using sub-pages.css tokens + a small
inline block for the page body typography
- Add a validateSiteHeader step to scripts/build.js that fails the build
if any of the four pages drops the marker
- Add /privacy route to server/index.js so extensionless URLs work
All four built pages pass the marker check; dev server serves all four
with 200 and the shared header.
Tailwind was wired into the build but the project didn't actually use it:
no @tailwind/@theme/@apply directives in source CSS, no utility classes
in any HTML or JS, no tailwindcss dependency in package.json, and no
HTML page linked to the compiled styles.css output.
Bun's HTML loader already handles main.css's @import chain transparently
in both `bun run dev` and `bun run build`. Removing the Tailwind step:
- Deletes buildTailwindCSS() from scripts/build.js (and the now-unused
execSync import)
- Removes public/css/styles.css (dead compiled output that nothing read)
- Updates CLAUDE.md to drop the "must rebuild Tailwind after CSS edits"
instruction
Verified: `bun run build` produces the same 104 KB CSS chunk linked from
index.html via Bun's HTML loader. No more rebuild step after CSS edits.
A new icon-tile-stack detection (the canonical AI feature-card with a
small rounded-square icon container above a heading), backed by a
two-column TDD fixture, plus a single-source-of-truth design that ties
the engine to the impeccable skill so they can no longer drift silently.
Detection
- New icon-tile-stack rule (slop): heading's previousElementSibling is
a 32–128px rounded-square element with a non-transparent background
or border, contains an svg/icon-i child, and sits above (not next to)
the heading. Excludes round avatars, wide thumbnails, side-by-side
layouts, tiny icons, and hero images.
- Two-column fixture convention: a single icon-tile-stack.html with a
flag column (4 cases) and pass column (6 cases), with snippet-text
matching used by the fixture test.
Single source of truth
- Each ANTIPATTERNS entry can now declare skillSection + skillGuideline.
18 of 25 rules carry these fields; the build's new
validateAntipatternRules() in scripts/build.js fails if any declared
skillGuideline isn't found verbatim in the right SKILL.md section.
- scripts/build-extension.js now includes the description field in
extension/detector/antipatterns.json (it was previously dropped).
- The existing count validator was promoted from warn to error so
command count drift fails the build the same way detection drift does.
Impeccable skill DON'Ts
- Added 4 new top-level DON'Ts that target real default AI behavior:
single-font, flat-type-hierarchy, all-caps-body, line-length.
- Cut 7 new DON'Ts I had drafted (tight-leading, tiny-text, wide-tracking,
justified-text, low-contrast, cramped-padding, skipped-heading) because
they teach things every model already knows from CSS/a11y basics. The
detector still catches all of them.
Stale count cleanup
- 22 commands → 21 across 17 references in HTML, README, NOTICE, AGENTS,
plugin.json, marketplace.json (left over from the validate skill removal).
- Dropped the hand-coded "212 design guidelines" marketing copy on the
homepage, which never mapped to any real count.
Sub-agent
- New private .claude/agents/anti-patterns.md captures the full TDD
recipe, schema, plug-in points, jsdom constraints, and pre-commit
checklist so future sessions can add rules end-to-end without
re-investigating the wiring.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Merges the impeccable-detect CLI repo (pbakaus/impeccable-cli@831a6cc)
into this repo. The BSL-1.1 license that motivated the split is gone;
everything is now Apache 2.0.
- Add bin/, src/, detection tests and fixtures from CLI repo
- Merge package.json: name → "impeccable", add bin/exports/files fields
- Internal refs now read from local src/ instead of node_modules/
- Update SPDX headers, NOTICE.md, CLAUDE.md, FAQ, npm README
- Add prepack/postpack scripts for CLI-focused README on npm
- Remove terminal license labels (no longer needed)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The CLI and detection engine now live in pbakaus/impeccable-detect
(published as 'impeccable' on npm, BSL-1.1). This repo is purely
Apache 2.0: skills, prompts, website, and build system.
- Remove bin/ (CLI moved to CLI repo)
- Remove README.npm.md (moved to CLI repo)
- Remove @impeccable/detect dependency, add impeccable dependency
- Set package.json to private (no longer published to npm)
- Update all references from @impeccable/detect to impeccable
- Update CLAUDE.md, NOTICE.md, FAQ, and changelog
- Rebuild all provider skill distributions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Build system now computes authoritative counts from source (22 commands,
24 detection rules) and warns about mismatches in HTML, README, plugin
configs. Generates public/js/generated/counts.js for frontend use.
Fixed 15 stale references across index.html, cheatsheet.html, README.md,
NOTICE.md, AGENTS.md, plugin.json, and marketplace.json. Changed all
"20 commands" to "22", "25 rules" to "24". Fixed v1.6.0 changelog date
(was March 24, after v2.0.0's March 20; now March 18).
Changelog entries are excluded from validation since historical counts
were correct at time of release.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
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>
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>
Previously only .claude/skills/ was synced from dist after build. Now
all 8 provider directories are synced (.claude, .cursor, .gemini, .codex,
.agents, .kiro, .opencode, .pi) so each provider's output can be tested
directly in this repo.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
- Output skills to both .trae-cn/ and .trae/ directories
- Update README with installation instructions for both versions
- Update DEVELOP.md with dual-variant documentation
- Add trae.js transformer with full metadata support (same as Claude Code)
- Update build.js to include Trae in provider transformations
- Update README.md with Trae installation instructions
- Update DEVELOP.md with Trae transformer documentation
Trae uses ~/.trae-cn/builtin_skills/ for skills installation.
The skill sync wipes .claude/skills/ and re-copies from dist, deleting
the generated browser script. Moved build-browser-detector.js to run
AFTER the sync. Dev server's /js/* route now falls through to
.claude/skills/critique/scripts/ for built artifacts. All fixture HTML
references use /js/detect-antipatterns-browser.js (clean URL).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DRY refactor:
- detect-antipatterns-core.mjs (297 lines): shared constants (SAFE_TAGS,
OVERUSED_FONTS, GENERIC_FONTS, ANTIPATTERNS), color utilities (parseRgb,
relativeLuminance, contrastRatio, hasChroma, getHue, colorToHex,
isNeutralColor), and pure detection functions (checkBorders, checkColors,
isCardLikeFromProps).
- CLI (889 lines, was 1212): imports from core, keeps jsdom-specific
resolveBackground, page-level analyzers, regex fallback, and CLI logic.
- Browser wrapper (335 lines): template with browser-specific DOM adapters,
highlighting, scan loop. Core is injected at build time.
- build-browser-detector.js: reads core, strips exports, injects into
wrapper, writes to public/js/detect-antipatterns-browser.js (generated).
- Build step added to scripts/build.js (runs before Bun bundling).
Source of truth for detection logic is now the core module. Browser script
is generated — do not edit public/js/detect-antipatterns-browser.js directly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Anti-pattern detector script (source/skills/critique/scripts/detect-antipatterns.mjs):
CLI tool that scans files/dirs for UI anti-patterns via regex. Detects side-tab
accent borders and border-accent-on-rounded patterns across Tailwind, CSS, JSX.
Context-aware: skips safe elements (blockquotes, nav, inputs, code), neutral
colors, and adjusts thresholds based on border-radius co-occurrence.
- Browser visualizer (public/js/detect-antipatterns-browser.js):
Drop-in script that highlights anti-patterns directly in the browser with
labeled overlays. Two modes: "static" (regex, matches CLI) and "computed"
(getComputedStyle, catches CSS cascade). Scans both inline styles and
<style> blocks.
- Gallery of Shame (public/gallery.html):
Standalone page showcasing 11 AI anti-pattern examples with thumbnails
and links. Anti-pattern example pages updated from 1080x1080 Twitter
format to responsive layouts, labels removed, screenshots retaken at 16:10.
- Critique skill updated to run detector before manual review.
- Build system: skills now support scripts/ directories alongside reference/.
All 8 provider transformers refactored to use shared.js (DRY).
- 58 new tests covering detection logic, fixtures, CLI integration.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add first-class Pi (pi.dev) provider with transformer, tests, and build integration
- Fix CODEOWNERS username (@paulbakaus → @pbakaus)
- Add missing providers to issue/PR templates (Copilot, Kiro, OpenCode, Pi)
- Add Pi and OpenCode logos to homepage hero and install sections
- Move /onboard from "system" to "enhancement" category
- Update README and DEVELOP.md with all supported providers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>