mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-11 21:57:14 +03:00
cli-v4.0.3
99
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
87d8f6d686 |
Track the rule registry as a generated artifact (#728)
* Track the rule registry as a generated artifact `cargo xtask bundle` already wrote the registry to `dist/antipatterns.json` and into `extension/detector/`, but neither is tracked, so a consumer reading this repo from a source checkout or a tarball had no way to get the rule list without a Rust toolchain. The Rust swap made that concrete: impeccable.style imported `cli/engine/registry/antipatterns.mjs` for its rule count and its Slop catalog, and that file is gone. Write the same JSON to `crates/live/assets/antipatterns.json`, next to the in-page bundle and tracked like it, and extend `cargo xtask bundle --check` to fail when either asset is stale. The build's rule-count check now reads the tracked copy first and falls back to the extension copy, so a fresh checkout validates counts instead of skipping the check. Co-Authored-By: Claude Code <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vau2X53xGTjjTCXWMVBoNY * Registry: wire the staleness gate into CI, harden the count read Two review findings on the tracked-registry change. `cargo xtask bundle --check` was never run by CI, so a rule whose name, category, or description changed without changing the rule count could ship a stale `crates/live/assets/antipatterns.json`. The extension job already runs `bun run build:extension` (and so `cargo xtask bundle`) and then asserts a clean tree; adding that file to the path list covers it with the gate that is already there. The bundle beside it stays out: its bytes carry a wasm module built by whatever wasm-pack and wasm-opt the runner installed, so diffing it would fail on toolchain drift rather than on a real change. `readDetectionRuleCount` counted `new Set(rules.map(r => r.id))`, so a shape change would collapse to a set of one `undefined` and read as a one-rule registry, flagging every count claim as stale. Count only non-empty string ids, and say "no readable antipatterns.json" when the file is present but unparseable. Co-Authored-By: Claude Code <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vau2X53xGTjjTCXWMVBoNY * Registry gate: make the trigger honest, name the real count condition The tracked-registry diff check ran on every PR, but the step that regenerates the registry (`bun run build:extension`, which is `cargo xtask bundle`) only runs when the detector trigger fires, and that trigger did not list `crates/bundle`. A PR that changed how the registry is serialized therefore never rebuilt it, and the check compared the committed file against an untouched tree and passed on stale bytes. Two changes. The detector trigger now covers every input the bundle reads: `crates/(bundle|core|foundation|wasm|xtask)/` plus `crates/live/assets/` so a hand-edit of a tracked artifact is regenerated over. And the registry check moved into its own step carrying the same condition as the build it validates, so it no longer claims to check something that was never regenerated; the provider-output check stays unconditional, because `bun run build` runs on every PR. Separately, `readDetectionRuleCount` returns the reason it found no count. "no antipatterns.json" covered three different conditions, and a registry that is present but unparseable sends anyone debugging a count failure to the wrong place. It now reports the paths it looked at, or names the file that is not readable as JSON, or names the file that carries no rule ids. Co-Authored-By: Claude Code <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vau2X53xGTjjTCXWMVBoNY --------- Co-authored-by: Claude Code <noreply@anthropic.com> |
||
|
|
e2ff625b63 |
The Rust engine: one binary replaces every script and the JS detector, fully open (#714)
* Add oracle harness: verb goldens and function-level vectors
Records stdout/stderr/exit/files for every impeccable verb over a fixed
corpus and replays them against an alternate implementation. Adds a loader
hook that captures per-function call vectors from the pure engine modules.
Prepared with AI assistance (Claude Code).
* Oracle: hook, hook-before-edit, hook-admin cases and goldens
Prepared with AI assistance (Claude Code).
* Add docs/CLI-CONTRACT.md: observable behavior of every impeccable verb
Prepared with AI assistance (Claude Code).
* Oracle: context/doctor/pin/surface-brief/critique/palette/embed/signals/csp/seed/genimg/question cases and goldens
Prepared with AI assistance (Claude Code).
* Oracle: live-mode cases and goldens (roots, inject, wrap, insert, accept, session, manual edits, daemon)
Prepared with AI assistance (Claude Code).
* Oracle: mask the binary path before HOME; export launcher env to the binary
Prepared with AI assistance (Claude Code).
* detect: set process.exitCode instead of exiting after the final write
process.exit() right after a large piped stdout write truncated JSON output
at the pipe buffer boundary; found by the oracle harness. Re-record the six
directory-scan goldens that had captured the truncation.
Prepared with AI assistance (Claude Code).
* Oracle: normalize the hook-admin command in both runtimes' forms and audit chars
Prepared with AI assistance (Claude Code).
* Skill text: invoke the impeccable launcher instead of node scripts
Every `node {{scripts_path}}/<name>.mjs` becomes `{{scripts_path}}/impeccable <verb>`
(context-signals -> signals, hook-admin -> hooks). Setup step 1 drops Node, points
Windows shells without sh at impeccable.cmd, and says the launcher runs a
self-contained binary. allowed-tools follows.
Prepared with AI assistance (Claude Code).
* Scripts dir: replace the Node scripts with the impeccable launcher
skill/scripts keeps command-metadata.json and the page JS; every .mjs entry
point, lib/, and live/ are gone (the binary owns those verbs). Adds the POSIX
launcher, impeccable.cmd, VERSION (copied from the new root ENGINE_VERSION),
scripts/fetch-engine.mjs (bun run fetch:engine) to pull the pinned binary
into skill/scripts/bin/<os>-<arch>/, and gitignores that bin dir.
Prepared with AI assistance (Claude Code).
* Build: ship the launcher instead of bundling the JS engine
readSourceFiles no longer copies cli/engine into the skill; the scripts
payload is the launcher (executable bit preserved through dist, plugin/, and
universal.zip), impeccable.cmd, VERSION (synced from ENGINE_VERSION on every
build), the page JS, and command-metadata.json. Hook manifests call
`<scripts>/impeccable hook` behind an existence guard (Codex adds a
commandWindows sibling calling impeccable.cmd; Cursor runs hook-before-edit;
GitHub keeps the git rev-parse form; Grok mirrors Claude); the Node probe and
systemMessage notice are gone. build:release fetches the pinned engine for
every target (lenient) and stages bin/<os-arch>/ into the dist skill copies
after root harness dirs and plugin/ were synced, so git-delivered trees stay
launcher-only. The detection-rule count check reads the vendored
extension/detector/antipatterns.json and is skipped when absent.
build:browser is a stub; the codex prefix rewrite leaves
`{{scripts_path}}/impeccable` alone.
Prepared with AI assistance (Claude Code).
* CLI: turn the impeccable npm package into a platform-binary shim
cli/engine, cli/lib, and cli/bin/commands are gone; their behavior lives in
the engine binary. cli/bin/cli.js now resolves the binary from IMPECCABLE_BIN,
the @impeccable/cli-<os>-<arch> optional dependency (templates under
cli/platform-packages/, published by the engine release), the
~/.impeccable/bin/<version>/ cache, or a checksum-verified download, and
execs it. package.json drops the engine dependencies and the library
exports; puppeteer moves to devDependencies for the icon scripts.
README.npm.md describes the shim.
Prepared with AI assistance (Claude Code).
* Tests: gate behavior on the oracle and the engine binary
Unit tests of the deleted Node scripts and the JS detector are removed;
their behavior is pinned by tests/oracle goldens (frozen JS behavior plus
reviewed deltas) and the engine's own tests. tests/oracle.test.mjs replays
the corpus against the binary (IMPECCABLE_BIN or skill/scripts/bin/<target>/,
via tests/lib/engine-bin.mjs) and skips cleanly without one; the framework
fixture sweep drives live-inject, live-wrap, and detect-csp through the
binary the same way. record.mjs learns --bin. The function-level vectors
under tests/oracle/vectors/calls are committed as the frozen snapshot they
can no longer be regenerated from. Suites: core trimmed to build and
transformer tests, oracle added to the default run, detector/live reduced to
packaging and reference checks, the live-e2e helper tests move to the opt-in
live-e2e lane pending its retarget, cli-remote-e2e is an empty placeholder.
Prepared with AI assistance (Claude Code).
* Docs: describe the launcher, the engine pin, and the oracle gate
CLAUDE.md gains an Engine binary section (launcher lookup order, ENGINE_VERSION,
untracked binaries, how tests get one, the oracle as behavior gate, what stays
JavaScript) and drops the Node-script and JS-detector descriptions; the CLI
and detection-rule sections point at the shim and the engine repo. README.md
states the skill needs no runtime and lists the launcher-based hook commands;
AGENTS.md follows. CLI-CONTRACT.md's intro notes the scripts it quotes are
the recorded source, not the tree.
Prepared with AI assistance (Claude Code).
* Tests: tighten the hook command guard assertion
Prepared with AI assistance (Claude Code).
* Oracle: re-golden 46 cases for the engine's own command names; record them in DELTAS.md
Prepared with AI assistance (Claude Code).
* Build: ship launcher-only release zips by default
IMPECCABLE_BUNDLE_ENGINE=1 opts in to staging the engine binaries into the
dist skill copies. Bundling every target into every provider copy put
dist/universal.zip near 340 MB, past the 25 MB Cloudflare Pages file cap
that impeccable install downloads through.
Prepared with AI assistance (Claude Code).
* Tests: drive the live-e2e orchestrator through the engine binary
The session, fake-agent loop, steer test, and manual-edit probe spawn
<binary> <verb> (live-server, live, live-inject, live-wrap, live-insert,
live-accept, live-poll, live-complete) resolved by tests/lib/engine-bin.mjs
instead of node skill/scripts/live-*.mjs; the completion typing the agent
imported from the deleted live/completion.mjs is a small local helper. The
live-e2e helper unit tests move back into the default live suite (the steer
loop skips without a binary).
Prepared with AI assistance (Claude Code).
* Tests: run new-work-e2e through the engine's serve-question and generate-image verbs
Prepared with AI assistance (Claude Code).
* Tests: point the skill-behavior harness at the launcher and engine binary
The bash tool exports IMPECCABLE_BIN so the staged skill's launcher runs
without a download; scenarios assert on 'impeccable context' instead of
context.mjs and skip without a binary.
Prepared with AI assistance (Claude Code).
* Tests: note what plugin-e2e validates before and after the generated-output sync
Prepared with AI assistance (Claude Code).
* Oracle: record the engine's 'wasm-unsafe-eval' CSP meta patch as a reviewed delta
Prepared with AI assistance (Claude Code).
* Rebase reconciliation: fold main's post-freeze work into the swapped tree
The rebase onto origin/main brought changes whose JS engine halves left the
tree with the swap. This commit reconciles what survives:
- Suite map: register main's comp-fidelity unit tests (build-phase,
comp-diff, font-match, hero-checks) in the core suite and
live-browser-ignores in the live suite.
- Payload guard: the skill scripts payload now allowlists the comp-fidelity
build pipeline (comp-spec/comp-diff/build-phase/font-match and their libs),
the one Node toolchain that has not moved into the engine.
- Drop skill/scripts/live/project-ignores.mjs, lib/live-path-globs.mjs, and
their test: they import hook-lib/live-inject/impeccable-paths, which the
swap deleted, and their consumer (the JS live server) is the engine now.
- skill text: the comp pipeline's calls to engine verbs (generate-image,
embed-prompt) use the launcher spelling.
- Oracle: re-record 17 detect goldens over the fixture set main changed
(oklch #592, color-mix #578, 1D grid #615, the two comp-fidelity rules)
and record the gap in DELTAS.md; those JS rule changes are not yet ported
to the engine, and the goldens pin its current behavior.
bun run test (oracle included) and bun run build are green on this tree.
AI-assisted change: implemented with Claude Code.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WaJv2c4oN8wS7Ttq4XRqyx
* Launcher: engine-probe PATH validation, working .cmd download path; CI: drop stale path, add oracle job
Byte-identical copies of the engine repo's launchers (engine main
af7572c): the retired 3.x npm CLI on PATH or in ~/.impeccable/bin is
rejected by the engine-probe handshake instead of hijacking every verb;
impeccable.cmd's download path is rewritten as straight-line goto flow
(the parenthesized blocks expanded %url%/%cached% at parse time, making
it dead code) with certutil sha256 verification and a windows-arm64 ->
x64 asset fallback; the final error points at the release download
instead of npm i -g (npm still serves the 3.x CLI).
ci.yml: the generated-output check no longer diffs the deleted
cli/engine/detect-antipatterns-browser.js, and a new oracle job fetches
the pinned engine (bun run fetch:engine) and replays tests/oracle/
against it. The job is continue-on-error with a loud warning until the
first engine release exists; flipping it to required is a release-time
toggle, documented in the workflow.
Verified here: sh -n on both launcher copies, bun run build green, full
oracle replay against the rebuilt engine binary green (770 pass, 0
fail), and a launcher behavior test proving a fake 3.x CLI on PATH is
skipped while the download + checksum chain completes against a local
file server.
Prepared with AI assistance (Claude Code).
* Oracle: restore detector goldens to post-fix behavior after the engine ports
The Aug 17-31 detector fixes (oklch parsing, color-mix nested hex, 1D grid
pass, comment stripping, root-relative linked stylesheets, URL userinfo
redaction, inert ignore-value refusal) and the comp-fidelity rules
organic-clip-path / buried-raster are ported to the engine. Re-records the
gap-pinning detect goldens from the fixed binary (glow.html included: its
.photo-opaque-grad column now carries the buried-raster finding it was
written for), replays the frozen checkHtmlPatterns call vectors through the
last JS engine state in history (db1462b9^; args untouched, 14 of 101
results moved), and rewrites the DELTAS gap section into the landed-ports
note. Each re-recorded json fixture golden byte-matches that JS state's
output; oracle: 770 pass, 0 fail.
Prepared with AI assistance (Claude Code).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WaJv2c4oN8wS7Ttq4XRqyx
* Oracle: pin the Aug 17-31 verb fixes ported to the Rust engine
New cases: hook-session-grok-edit-then-stop (Grok Build camelCase envelope,
end_turn/shutdown/stopHookActive Stop handling,
|
||
|
|
9736a9f6e9 |
Fix OpenCode slash command bridge (#483)
Add a first-class OpenCode command bridge across builds, installs, updates, linked installs, and pinned shortcuts. Preserve current provider behavior while backfilling missing or drifted command files.\n\nAI assistance: contributor and maintainer work used AI tools as disclosed in the PR discussion and commits. |
||
|
|
bfafc7dbcb |
Fix plugin script path resolution (#535)
Makes plugin instructions execute the installed plugin copy, safely quotes paths containing spaces, removes the broad Node pre-approval, and ships guarded generated plugin output.\n\nAI-assisted maintainer conflict resolution, review, and validation by Codex under maintainer direction. |
||
|
|
f3df3ffe40 |
Add Veto harness support (#675)
Adds Veto detection, provider transforms, installation paths, documentation, and regression coverage.\n\nAI-assisted maintainer repair, review, and validation by Codex under maintainer direction. |
||
|
|
d4e1b0902f |
Enforce the ask_instruction sentence-initial contract
Review on #576 caught document.md:71 splicing {{ask_instruction}} after "then", which is the same defect this branch set out to fix. Rendered for Codex it produced "Show the user the existing file, then STOP and use Codex's structured user-input/question tool...". The line now starts a new sentence. The comment added to PROVIDER_PLACEHOLDERS asserted the contract without enforcing it, which is exactly how four reference files shipped the splice in the first place. validateAskInstructionSites() in build.js now checks every call site and fails the build on a mid-sentence interpolation, and the comment points at the gate instead of asking authors to remember. Prepared with AI assistance (Claude Code). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
5ce4a5c6b5 |
Add Hermes Agent as a supported provider
Impeccable now ships a Hermes-compatible bundle under dist/hermes/.hermes/skills/. Hermes reads the Agent Skills spec as-is, so the bundle uses the four spec frontmatter fields (name, description, version, license) plus metadata/compatibility and drops the Claude/Codex-specific extensions Hermes would silently ignore. The .hermes/skills/ tracked root and the regenerated pin.mjs mirrors will be produced by .github/workflows/sync-generated-output.yml after this lands; per AGENTS.md, generated harness churn stays out of feature PRs. What a Hermes user gets: - npx impeccable install --providers=hermes --scope=project writes .hermes/skills/impeccable/ into the cwd. - npx impeccable install --providers=hermes --scope=user honors $HERMES_HOME, so a profile-scoped install (HERMES_HOME=~/.hermes/profiles/forge) lands in the active profile's skills dir, not the default ~/.hermes/. Cross-home HERMES_HOME inheritance is ignored so test isolation holds. - /impeccable registers as a Hermes slash command and routes sub-commands via the Commands table in the skill body, since user-invocable / argument-hint are not honored by Hermes' skill loader. What a Hermes user does NOT get, and why: - No hook surface. Impeccable's PostToolUse/Stop anti-pattern detector on Claude/Codex/Cursor/Grok/GitHub does not translate to Hermes, which has no equivalent tool event lifecycle. The skill body still ships. - No writeOpenAIMetadata, agentFormat, or emitHooks. Hermes has no per-skill tool ACL, no subagent on-disk format, and no hooks.json equivalent. Verified end-to-end with hermes-agent v0.18.2: /impeccable polish and /impeccable critique both load reference/<command>.md and return the documented first step. parse_frontmatter accepts the generated SKILL.md, scan_skill_commands registers /impeccable, and the full default test suite passes (267/267 in the critical files; 0 fail across all suites). |
||
|
|
6d2af3f800 |
Guard the plugin loader contract that PR #494 exposed (#499)
* test: guard the plugin loader contract that PR #494 exposed The agents manifest key shipped for months and silently loaded zero of the four subagents; no validator looked at the generated plugin manifest's shape and claude plugin validate never checks it. Three layers now do: - scripts/lib/validate-plugin-manifest.js pins the verified loader contract (KNOWN_LOADER_KEYS allowlist, no agents key, trailing-slash skills path from issue #86, every skill/agents/*.md shipped in plugin/agents/), unit-tested in tests/validate-plugin-manifest.test.js including a check of the real committed subtree. - The same check gates bun run build next to the version-drift guard. - tests/plugin-e2e.test.mjs installs the committed ./plugin subtree into a real Claude Code (sandboxed via CLAUDE_CONFIG_DIR in a temp dir) and asserts the component inventory: skill parses, all agents visible, hooks discovered. In the default suite; runs in about a second and skips cleanly when the claude CLI is absent, so CI is unaffected. All three failed against the pre-#494 tree for the shipped reason (Agents 0 of 4) and pass against current main. AI-assisted via Claude Code under maintainer direction. Co-Authored-By: Claude Code <noreply@anthropic.com> * fix: address PR review bot findings - Copilot: guard collectPluginManifestFindings against valid JSON that is not an object (null, string, number, array) so a broken manifest is a finding instead of a build crash; unit test added - Copilot: update the plugin-e2e header comment, the suite is in the default lineup rather than opt-in AI-assisted via Claude Code under maintainer direction. Co-Authored-By: Claude Code <noreply@anthropic.com> * fix: harden plugin E2E sandbox isolation Bugbot: create the sandbox CLAUDE_CONFIG_DIR up front and redirect HOME and USERPROFILE into the temp workDir too, so a CLI code path that derives config or cache locations from the home directory instead of CLAUDE_CONFIG_DIR still cannot touch the developer's real Claude config when the default suite runs. AI-assisted via Claude Code under maintainer direction. Co-Authored-By: Claude Code <noreply@anthropic.com> * fix: agent parity check mirrors the build's emit rules Bugbot: the shipped filename is `${claude-name || name}.md` and a providers: list may exclude claude-code, so comparing raw source basenames could fail the build on a renamed or provider-scoped agent with a build:release hint that cannot fix it. The validator now derives expected filenames the same way the transformer factory does (shared parseFrontmatter, same providers gate) with unit coverage for renames, name overrides, and provider-scoped agents. AI-assisted via Claude Code under maintainer direction. Co-Authored-By: Claude Code <noreply@anthropic.com> * fix: run the plugin E2E through a shell on Windows Bugbot: the claude CLI is a .cmd shim on Windows and Node refuses to spawn those via execFile without a shell, so the availability probe always failed and the suite silently skipped there. Windows now invokes through a shell with every argument double-quoted (temp paths routinely contain spaces); the POSIX path is unchanged. AI-assisted via Claude Code under maintainer direction. Co-Authored-By: Claude Code <noreply@anthropic.com> --------- Co-authored-by: Claude Code <noreply@anthropic.com> |
||
|
|
baa76cfd05 |
fix: stop emitting the "agents" key so the four subagents actually load (#494)
build.js derives plugin/.claude-plugin/plugin.json from the root manifest and injects an `agents` array built from the generated agent files. In Claude Code that array is exactly what stops them loading. Verified on a throwaway local marketplace, across the plausible shapes: array of file paths (what build.js emits) -> 0 agents load, skills fine a string, e.g. "./agents" -> whole plugin fails to load array containing a directory -> whole plugin fails to load key omitted -> all agents load, skills fine Claude Code discovers agents/*.md on its own, and the identifier it uses is the file name rather than the frontmatter `name`. So the key is not needed, and any present form of it is worse than its absence. Confirmed end to end on this repo: with the key emitted, `claude plugin details impeccable` reports "Agents (0)"; with it omitted it reports "Agents (4) impeccable-asset-producer, impeccable-documenter, impeccable-finish-reviewer, impeccable-manual-edit-applier". The agent files themselves are still copied by the existing copyDirSync a few lines below — only the manifest key goes away. Two things make this hard to notice: with a breaking shape `claude plugin details` prints "Plugin not found" instead of a validation error, and `claude plugin validate` does not catch it because it validates the marketplace manifest, not the plugin manifest. The only reliable signal is the "Agents (N)" line. The same defect is reported against another project at addyosmani/agent-skills#449, with the full reproduction. Scope note: verified on Claude Code only. plugin/ is the Claude-Code / Grok subtree, and the Grok manifest is written separately just below, so this does not touch the other harnesses. |
||
|
|
bf957452c4 | Add Google Antigravity provider support | ||
|
|
9d1b4bdfac |
Fix five stale rule counts and the validator blind spots that hid them
single-font's retirement made the detector 59 rules; both READMEs still said 60 in five places, and the count validator reported clean because 'deterministic detector rules' puts a word the regex never expected between the qualifier and the noun, and README.npm.md was never in the checked file list. The regex now tolerates the detector infix, counts qualified 'issues' claims, and README.npm.md joins the list. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
bcf354cd0c |
Fix Codex hook path so .codex-directory installs run the detector
The committed .codex/hooks.json hardcoded .agents/skills/impeccable/scripts/
hook.mjs. On a .codex-directory install the skill payload lives at .codex/
skills/..., so the guarded command ([ ! -f X ] || node X) found no file and
silently no-opped, leaving the design detector dead for those users.
Derive the hook payload path from the emitting provider's own configDir rather
than hardcoding .agents:
- buildCodexHooksManifest(skillDir) now builds `${skillDir}/skills/impeccable/
scripts/hook.mjs`; hooksJsonFor threads each provider's configDir through. The
Codex provider (configDir .codex) emits .codex/skills; the root sync and the
self-consistent dist/codex bundle both point at their own payload.
- CLI installer: project-scope hook rewriting now derives the provider's own
project-relative path instead of preserving the bundle token. The Codex bundle
ships a .codex/skills command, but the CLI lays the skill at .agents/skills, so
the installed .codex/hooks.json is rewritten to .agents/skills (Claude keeps
its ${CLAUDE_PROJECT_DIR} token; global installs keep the absolute rewrite).
Per-provider hook payload path after the fix:
Emission hook path
dist/codex/.codex/hooks.json .codex/skills/impeccable/scripts/hook.mjs
root .codex/hooks.json (build sync) .codex/skills/impeccable/scripts/hook.mjs
CLI .agents (codex) project install .agents/skills/impeccable/scripts/hook.mjs
CLI .agents (codex) global install <home>/.agents/skills/.../hook.mjs (abs)
.claude / .cursor unchanged
Tests: extended hook-build (codex-dir -> .codex/skills, agents-dir -> .agents/
skills) and skills-cli (bundle ships .codex/skills, install rewrites to .agents/
skills). Regenerated tracked .codex/hooks.json via build:release.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
||
|
|
06d21dea7d |
Add first-class Grok Build harness support
Emit .grok skills, agents, and PostToolUse/Stop hooks; wire the CLI installer and downloads; fix the plugin install path to #plugin; and document Grok in HARNESSES.md and README. AI assistance: written with Grok Build. |
||
|
|
90f9eeb99b |
Split service layer into private impeccable-site repo
The public repo keeps the OSS promise surface: skill, CLI, extension, tests, and the provider build. The site, labs, concept/composition catalogs, image pipeline, Cloudflare functions, and authoring guide move to pbakaus/impeccable-site. concept-seed tests run against a synthetic fixture catalog; the plugin icon and skill categories moved in-repo; build validation narrows to README prose and non-site counts; release notes read from a sibling impeccable-site checkout. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
b5ec969c07 |
Add world roll API and seed telemetry client
/api/roll deals deterministic challenger rolls server-side (same salts and sha256 ranking as the local seed, verified bit-for-bit); the request log is the impression record. /api/chosen takes the anonymous choice ping. Events land in Workers Analytics Engine. concept-seed.mjs resolves data in order: local catalog dir, roll API, degraded promotion-only seed. --chosen sends the choice ping; DO_NOT_TRACK and IMPECCABLE_NO_TELEMETRY disable it. API-dealt seeds carry the telemetry instruction inline. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
7557935fdb |
Expand concept system: modes, ratings, re-roll, breadth strategy
Catalog: mode-aligned staging surfaces (persuade/operate/read/experience), star ratings on approvals feeding challenger draw weights, family retirements, authoring strategy and territory guide, rework and breadth authoring rounds, composition mining from rejected worlds. Seed: six challengers (two per tier), --reroll chains, --mode staging filter, rating-weighted draws. New-work: Present/visualize/re-roll flow, image-gen requirement, register-neutral vocabulary. Pipeline: per-mode staging prompts with split frames, hero-from-board reference generation, render-safety guards. Labs: ratings UI, unrated filter, mode chips, composition approve-guard. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
2b1f36c43e |
Add concept world catalog and review workflow
AI-assisted: prepared by Codex at Paul's request. |
||
|
|
da99645a58 |
Add OpenAI plugin submission bundle (#363)
* Add OpenAI plugin submission bundle Build a Codex-native OpenAI plugin with bundled hooks, public listing metadata, submission guidance, privacy coverage, and regression tests. AI assistance: OpenAI Codex prepared and validated these changes under maintainer direction. * Fix provider script command rendering Replace heuristic rewrites across executable scripts with one explicit provider marker, render pinned shortcuts per target harness, and remove the personal email from the public publisher manifest. Addresses automated review feedback on PR #363. AI assistance: OpenAI Codex prepared and validated these changes under maintainer direction. |
||
|
|
3e38e595c7 |
Add platform axis (web / ios / android / adaptive) (#269)
* Add a platform axis (web / ios / android / adaptive) to the skill Orthogonal to register: register decides whether design IS or SERVES the product; platform decides the delivery target and which native conventions apply. Set `## Platform` in PRODUCT.md; a missing field defaults to `web`, so legacy projects are unaffected. - extractPlatform() in skill/scripts/context.mjs (mirrors extractRegister); the CLI appends a NEXT STEP directive to read the native reference(s). `adaptive` (Flutter / RN / KMP shipping both iOS and Android) loads both ios.md and android.md. - New reference/ios.md (Apple HIG distilled) and reference/android.md (Material 3 distilled); reference/web.md is a thin pointer. The native refs frame register's role as narrow: platform conformance is the bar, brand lives in the expressive layer the platform gives you, never by breaking the rails. - Setup step 5 loads the native reference(s) when platform is native. Live mode and the detect CLI stay web-only, gated off ios/android/adaptive. - init asks platform right after register; adapt/audit/animate/layout carry short platform divergence notes; all secondary spots thread `adaptive`. - a11y stays in audit.md (loading it at design time makes output timid), so the native refs carry no Accessibility section; audit.md's Platform section owns native a11y. - Tests: extractPlatform unit coverage + skill-behavior scenario 10 (PRODUCT.md platform ios -> agent loads ios.md). Source-first: only skill/, scripts/, tests/, CLAUDE.md, NOTICE.md, the changelog and version are committed; the sync workflow regenerates the provider trees and ./plugin on merge. ios.md / android.md are distilled from the MIT-licensed ehmo/platform-design-skills; attribution in NOTICE.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Address review: gate web tools on native platforms, drop version churn Maintainer-review fixes applied with AI assistance (Claude Code), on top of the rebased platform-axis commit: - Design hook (post-edit and Cursor pre-edit) now resolves the project platform via loadContext + extractPlatform and skips its web rule scan for ios / android / adaptive projects, so React Native / Flutter code never draws web-shaped findings (new hook-lib resolveProjectPlatform / isNativePlatform helpers, covered by unit and subprocess tests). - context.mjs CLI warns on an unrecognized ## Platform value (e.g. a toolchain name like `flutter`) instead of silently defaulting to web; extractRegister / extractPlatform now share extractSectionValue. - Removed reference/web.md: nothing loaded it; CLAUDE.md carries the "web has no extra rulebook" explanation. - init.md: skip live-mode config (Step 6) for native platforms; note the per-app PRODUCT.md pattern for repos shipping web + native. - android.md: Material-everywhere apps that also ship on iPhone still owe iOS OS guarantees (safe areas, Reduce Motion, edge-swipe back). - ios.md: reworded a design-time line that framed Dynamic Type as an accessibility check (a11y stays owned by audit.md). - Renumbered the new skill-behavior scenario to 14 after main's 10-13; updated CLAUDE.md scenario list; added android + unrecognized-value CLI test cases. - No version or changelog changes: versioning happens at release time. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Tighten platform reference prose Editorial pass on the platform-axis text, applied with AI assistance (Claude Code) under maintainer direction: - ios.md / android.md rewritten to house style: single-line paragraphs (no hard wraps), one-sentence scope intro, deduplicated intro/slop-test, register-compression down to two sentences. In-file attribution paragraphs removed (NOTICE.md owns attribution); "read on top of the register reference" cruft removed (SKILL step 5 and the context.mjs directive already say it). Bans sections dropped: they restated the rules above them; the two additive items (tab-bar overload, hover-dependent affordances) folded into rules. ~40% smaller each. - Sub-command Platform sections (adapt, audit, animate, layout), SKILL step 5, init.md platform prose, and the context.mjs directive trimmed the same way. Build (prose validators, counts) and both test runners green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Treat an empty PRODUCT.md section as absent, not the next heading Copilot review catch: extractSectionValue read the next `## ...` heading as the section value when a field was left empty, which made the CLI warn "value `## Product Purpose` is not recognized". Stop at the next heading and return null instead. Regression tests for extractPlatform, extractRegister, and the CLI warning path. Applied with AI assistance (Claude Code) under maintainer direction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Only read a token list of both native targets as adaptive Bugbot catch: after the exact platform tokens failed, any Platform line containing the words ios and android was classified adaptive, so negated or explanatory prose ("web only, not ios or android") silently loaded both native refs and skipped the hook, with no warning. The combo parse now accepts only list separators and the two platform words; anything else falls through to the CLI's unrecognized-value WARNING. Regression tests added. Applied with AI assistance (Claude Code) under maintainer direction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Paul Bakaus <paul.bakaus@gmail.com> |
||
|
|
793feda5a0 |
Guard plugin/skill version drift in the build (issue #274) (#278)
* Guard plugin/skill version drift in the build (issue #274) The Claude Code marketplace installs from the committed ./plugin subtree, so a version disagreement between the hand-edited manifests and the generated subtree ships stale content under a wrong version. This is the class of bug reported in #274: a version bump that doesn't regenerate ./plugin (e.g. PR #252, where root plugin.json was 3.7.0 while plugin/.claude-plugin/plugin.json was still 3.6.0) merges a drift window onto main, and marketplace/Cowork installs pull the stale subtree. Add a build-time validator that treats root .claude-plugin/plugin.json as the source of truth and fails the build if any of these disagree: - .claude-plugin/marketplace.json plugins[0].version (hand-edited; the post-merge sync workflow never bumps versions, so it can't repair a mismatch here) - plugin/.claude-plugin/plugin.json version (generated subtree) - plugin/skills/impeccable/SKILL.md frontmatter version (bundled skill) It only fires on an inconsistent bump; PRs that don't touch versions keep every file in agreement and stay silent. The pure comparison lives in scripts/lib/validate-plugin-versions.js with direct unit coverage; build.js owns the logging and the non-zero exit. Documents the regenerate-on-bump step in CLAUDE.md's Versioning section. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Harden version-drift collector against malformed/incomplete manifests Address Greptile review on #278: - Wrap every file read/parse in a sentinel helper (extractFromFile) so a half-edited manifest — the exact state during a version bump — yields a clean "could not parse (...)" diagnostic naming the file instead of a raw JSON.parse stack trace out of build(). - Report a present-but-malformed root plugin.json, or one missing its `version` field, as an explicit error. Previously `undefined` version short-circuited the build wrapper's `source == null` guard and passed silently. collectPluginVersions now returns an `errors` array; build.js fails on errors + mismatches combined, and only the genuinely-absent root manifest is a no-op skip. Adds 4 unit tests: malformed checked manifest, malformed root, missing version field, and the absent-root no-errors case. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Make SKILL.md frontmatter version read CRLF-tolerant Address Cursor Bugbot review on #278: readSkillFrontmatterVersion only matched `\n` delimiters, while the shared parseFrontmatter in scripts/lib/utils.js accepts `\r?\n`. A bundled SKILL.md saved with CRLF line endings would parse to a null version and trip a false mismatch against root plugin.json even when the version line is correct. Match the shared parser's `\r?\n` tolerance and drop the `$` anchor on the version line (it would not match before a `\r`). Adds CRLF coverage for both readSkillFrontmatterVersion and collectPluginVersions. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Re-trigger CI (no file change) CI did not fire for 5cda9f6b; force a fresh run on the current tree. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
9c0012d4e1 |
feat(hooks): package design hook in plugin, install to settings.local.json (#243)
* feat(hooks): package design hook in plugin, install to settings.local.json
Three related changes to how the Impeccable design hook is distributed,
plus an unrelated build fix discovered along the way.
Package the hook in the Claude Code plugin
- The marketplace / `/plugin install` path previously shipped the skill and
agents but no hook, so those users never got the design detector. The build
now emits `plugin/hooks/hooks.json` (auto-discovered at the plugin root),
resolving the script via `${CLAUDE_PLUGIN_ROOT}` so it works wherever Claude
Code unpacks the plugin instead of assuming a `.claude/skills/` layout.
CLI installs the hook into settings.local.json, not shared settings.json
- `npx impeccable skills install/update` now writes the Claude hook to the
gitignored `.claude/settings.local.json` (a machine-local install side
effect) rather than the team-shared `settings.json`, which could otherwise
be committed and break for teammates without the skill installed.
- Graceful handling (leave-it-never-duplicate): if our hook already lives in
the shared `settings.json` (a legacy install or a deliberate user move), it
is honored in place and never duplicated into the local override, which
would otherwise run the detector twice per edit.
- The skill's `/impeccable hooks on|off` toggle is unaffected: it only writes
`.impeccable/hook.json`, never the settings files.
Fix universal.zip build failure under archiver v8
- `archiver` was bumped to v8 (now ESM, factory function removed) but
`scripts/lib/zip.js` still used the old `archiver('zip', ...)` API, so every
build silently failed to produce `dist/universal.zip` (the skill-release
artifact). Switched to `new ZipArchive({...})`.
Also folds in a pre-existing local rename of the hook status message
("Scanning design" -> "Checking UI changes") and its regenerated provider
output.
Tests: new coverage for the plugin-packaged hook manifest and the
shared-settings honor-in-place path; existing CLI assertions moved to
settings.local.json. Full suite green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(cli): detect hook by marker, not file existence (Bugbot)
hookInstalledForProvider treated any existing settings.local.json (or
hooks.json) as proof the hook was installed. Those files commonly hold
unrelated local settings, so the already-installed `skills install` path
would skip repairing a genuinely missing hook that `update` would add.
Detect the Impeccable marker in the file instead of mere existence. Adds a
test for the exact case: a settings.local.json with only permissions still
triggers hook repair and preserves the unrelated content.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* test(build): fail loud on a broken release zip + cover the zip writer
Close the gap that let the archiver v8 break ship a 0-byte universal.zip
with a green test suite:
- createProviderZip no longer swallows failures. It throws on a missing
source, an archive with zero entries, or a 0-byte output, and build() now
exits non-zero on any such rejection. A build that can't produce its release
artifact fails instead of deploying an empty bundle.
- New tests/zip.test.mjs exercises the real zip writer and round-trips through
extract-zip (the unpacker the CLI uses): a valid bundle unpacks to the skill
tree, and the empty/missing-source cases throw. Wired into the core suite so
it runs in `bun run test`.
Why this matters: the prior CLI e2e tests stub the bundle as a local
directory, so they never built, downloaded, or unzipped a real archive. The
zip writer had no coverage and failed soft, so Dependabot's archiver 7->8
major bump merged green and the deploy shipped an unusable bundle.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(cli): scope hook marker scan to the hooks subtree + prune local dupes (Bugbot)
Two follow-ups from Bugbot:
- fileHasImpeccableHookMarker scanned the whole settings file as raw text, so
an unrelated string (e.g. a permissions allow entry that mentions the hook
path) could falsely read as an installed hook and block install/repair or
the shared-settings skip. Now it parses the JSON and scans only the `hooks`
subtree.
- When the hook is honored in the shared settings.json, copyProviderHooks
skipped the local write but left a stale hook in settings.local.json from an
earlier machine-local install, so Claude Code loaded both and ran the
detector twice per edit. It now prunes the local copy (preserving unrelated
local settings, dropping the file if only our scaffolding remained).
Adds tests for both: a permissions string mentioning the hook path still
triggers repair, and a shared hook prunes the stale local duplicate while
keeping unrelated permissions.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|
|
672517f76e |
Add automatic design hook install and exceptions (#170)
* docs: add PRD for design detector hook integration Plans a PostToolUse hook for Claude Code and Codex that runs the existing design detector after every relevant file write and feeds findings back to the agent as advisory system-reminder context. No implementation in this commit; covers UX, technical design, build pipeline changes, distribution, coverage tradeoffs, and rollout. Co-authored-by: Cursor <cursoragent@cursor.com> * docs: revise hook PRD with best-practices review Folds in the P0/P1/P2 findings from an online best-practices critique against the official Claude Code and Codex hook references plus 10+ 2026 community guides and similar prior-art tools (claw-hooks, claude-code-hooks-mastery). Key changes: - Exec form everywhere (Codex snippet was shell form), with Windows rationale. - Default timeout dropped from 10s to 5s. - Re-entrancy guard (CLAUDE_HOOK_DEPTH) and per-file edit counter. - Session-scoped finding dedup promoted from open question to v1. - Per-language inline-ignore syntax map (HTML/JSX/CSS/JS). - Hard-skip rules for sensitive paths and generated/lock files. - Honest framing about Claude Code lacking per-plugin hook disable. - Honest framing about Bash-written files being invisible in v1. - Codex Windows-not-supported call-out, feature flag note, trust ceremony detail. - Optional NDJSON audit log via IMPECCABLE_HOOK_LOG. - Findings cap lowered 8 → 5 with attention-budget rationale. - Versioned envelope ([impeccable@1]) on rendered template. - Expanded test plan, decision log, and stdin payload appendix. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(hooks): ship the design detector hook for Claude Code and Codex Implements docs/hooks-prd.md: a PostToolUse hook that runs the impeccable design detector after every Edit/Write/MultiEdit on a UI file and pushes findings into the agent's next-turn context as a short system reminder. Silent on clean files. Never blocks an edit. Why this matters: today, design slop (side-tab borders, gradient text, purple/cyan palettes, bounce easing, etc.) only gets caught when a human notices or someone explicitly runs /impeccable audit. The hook closes the loop at the moment slop is written. What ships in v1 - skill/scripts/hook.mjs: PostToolUse entry. Reads stdin, runs the detector in-process (no `npx impeccable` cold start), emits hookSpecificOutput.additionalContext when fresh findings exist. - skill/scripts/hook-lib.mjs: extracted helpers (config, cache, filter, render, audit log, runHook orchestrator). 100% unit-testable. - skill/scripts/hook-session-start.mjs: SessionStart greeting, gated by a project-scannable probe + 30-day throttle. - skill/scripts/hook-admin.mjs: backs /impeccable hooks on/off/status/ignore-rule/ignore-file/reset. Hardening built in - Re-entrancy guard (IMPECCABLE_HOOK_DEPTH) so the hook can never recursively spawn itself. - Hard-skip regexes for sensitive paths (.env, .pem, id_rsa, secrets, credentials, .git) and generated/lock/build output. These fire before the file is even read; cannot be turned off via config. - Path-traversal check on the inbound file_path. - Session-scoped dedup keyed by (session, file, rule, line) so the same finding never lands in context twice. Prevents the ~12.5K wasted tokens per chatty session called out in the PRD. - Per-(session, file) edit counter with a one-shot suppression notice on the 7th edit, silent after. - Fail-open contract: every error path returns exit 0 with no stdout. Optional NDJSON audit log via IMPECCABLE_HOOK_LOG. Three kill switches (precedence high to low): 1. IMPECCABLE_HOOK_DISABLED env var (1/true/yes/on, case-insensitive) 2. .impeccable/hook.json `enabled: false` 3. /impeccable hooks off slash command (writes the JSON) Inline ignores are language-aware. `// impeccable: ignore <rule>` for JS/TS, `<!-- impeccable: ignore <rule> -->` for HTML/Vue/Svelte/Astro, `{/* impeccable: ignore <rule> */}` for JSX/TSX, `/* impeccable: ignore <rule> */` for CSS. `*` matches any rule. Directive applies to the next non-blank line. Same shape as ESLint, Stylelint, Biome. Build pipeline - scripts/lib/transformers/hooks.js: per-provider hooks.json builders, plus the slim .codex-plugin/plugin.json manifest. - providers.js: emitHooks: 'claude' for claude-code, emitHooks: 'codex' for codex and agents. Codex also emits emitCodexPlugin. - factory.js: emits hooks/hooks.json next to the skills tree. - build.js: syncs hooks/ into harness roots and into the slim plugin/ subtree; writes .codex-plugin/plugin.json. Build is idempotent (verified: 98 staged files unchanged across two runs). Claude Code wiring uses exec form (command + args) and the ${CLAUDE_PLUGIN_ROOT} placeholder. Matcher: Edit|Write|MultiEdit. `if:` glob filters to UI extensions before spawning Node. PostToolUse timeout 5s, SessionStart timeout 3s. Codex wiring uses ${PLUGIN_ROOT} (Codex's native placeholder), matcher Edit|Write|apply_patch, no `if:` analog (the script does the extension filter). macOS and Linux only; hooks are disabled on Windows in current Codex builds. The trust ceremony and feature flag are documented in README.md. Routing - /impeccable hooks lives outside the 23-command router table on purpose: it is plumbing, not a design skill. The hidden routing slot is added to SKILL.md alongside pin/unpin so the LLM knows to dispatch it. The 23-command count and all stale-count validators remain happy. Tests - tests/hook.test.mjs: 38 unit tests covering env parsing, config load + defaults + malformed, cache round-trip + GC, ignoreRules/minSeverity/inline ignores (all four languages), globbing with **/*/{a,b}, render template with cap + clamp + 0-line prefix drop, audit log NDJSON, payload event-name parameterization, re-entrancy, kill switches, sensitive-path + generated-path + traversal skips, allowlist filter, config ignoreFiles, edit counter cycle including the 7th-edit notice, MultiEdit and apply_patch payload shapes, detector throw swallow, malformed stdin, missing file race. - tests/hook-build.test.mjs: 18 integration tests covering hook manifest shape (matcher, timeouts, exec form, if: glob, placeholders), Codex differences (${PLUGIN_ROOT}, no if:, no SessionStart), Codex plugin manifest (no inline hooks field to avoid the duplicate-file error), routing across the hooksJsonFor table, and presence of all three committed artifacts plus the bundled detector the runtime relative-import path depends on. Full suite: 175 bun tests + 186 node tests, all green. Docs - README.md: new "Design hook" section explaining default behavior, per-project / global / inline disable paths, the JSON schema knobs, the audit log debug flag, and the slop / a11y coverage split. - HARNESSES.md: flips the `hooks` row for Codex from No -> Yes (Claude was already Yes), adds a per-harness hook-surface table with the manifest location and matcher each provider uses. Open questions from the PRD intentionally deferred to v2: Bash-write blind spot, effort-aware suppression, Stop-hook session summary, per-rule severity, async hook mode. None block v1. Co-authored-by: Cursor <cursoragent@cursor.com> * Fix Codex hook scanning: apply_patch paths and co-located stylesheets Parse file targets from Codex apply_patch command bodies, co-scan imported and sibling CSS when UI components are edited, drop the git-sweep PostToolUse group, and align Codex SessionStart manifest and trust docs with the official hooks spec. Co-authored-by: Cursor <cursoragent@cursor.com> * Gitignore hook session cache and drop local test HTML Hook dedup/throttle state in .impeccable/hook.cache.json is per-project runtime data like other .impeccable/ sidecars. Remove an untracked bad-nested-flexbox scratch page from site/public/. Co-authored-by: Cursor <cursoragent@cursor.com> * Fix Claude Code hook: drop Edit-only if filter so Write/MultiEdit fire Claude's if permission rule binds to one tool name, so Edit(*.{…}) never spawned the hook on Write or MultiEdit despite the matcher listing them. Extension filtering now lives in hook-lib on both Claude and Codex. Co-authored-by: Cursor <cursoragent@cursor.com> * Surface Cursor design findings via stop-hook followup Replace dropped postToolUse additional_context with afterFileEdit recording and a one-shot stop followup_message so anti-pattern nudges reach the agent. Co-authored-by: Cursor <cursoragent@cursor.com> * Fix design hook packaging and scans * Fix Cursor hook pending bucket fallback * Fix Sass hook scan coverage * Fix Cursor hook review findings * Fix session start dead hook normalization * Fix hook config and relative scan paths * Remove SessionStart design hook * Remove redundant afterFileEdit normalization * Fix Cursor suppression and module style scans * Fix sensitive path hook filter * Fix disabled Cursor stop hook emission * Refresh hook harness artifacts * Fix Cursor hook manifest install * Add hook ignore-value support * Ignore hook runtime files locally * Fix Codex plugin hook packaging * fix: address PR review bot findings Block numeric hook depth counters from re-entering. Avoid following stylesheet imports from traversal-looking hook targets. * fix: gate ignore-value suggestions by supported rules Only render exact ignore-value commands when the same finding can be suppressed by ignoreValues. * Package Codex plugin as hook-only * Remove Codex plugin packaging * Recover hook install probe plumbing * Remove Codex hook packaging follow-up doc * Remove extra hook docs and skill wording changes * Install real design hooks via skills CLI * Add provider hook smoke runner * Fix Cursor hook delivery with preToolUse gate * Simplify Cursor hook install to preToolUse * Clarify confirmed hook exceptions * Persist hook ignores in shared config * Guard font hook exceptions * Fix hook install after main rebase * Fix hook scan target handling * fix: address hook review findings * Address hook review feedback * Stabilize DeepSeek insert live fixture * Fix Cursor hook Python shell write bypass --------- Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
324cec73a4 | Reorganize contributor docs | ||
|
|
05f9797957 | Remove deprecated cleanup migration (#240) | ||
|
|
972f5b18be | Improve generated output sync workflow | ||
|
|
4fda4a0ece |
Serve _data/api JSON in dev server
app.js fetches /_data/api/commands.json and patterns.json, but those are build artifacts written into site/public/_data/ by scripts/build.js. The plain `astro dev` server never runs that build, so the homepage 404'd on both in dev. Extract generateApiData into scripts/lib/api-data.js (shared by the build and a new scripts/gen-dev-api.mjs prebuild), and run the prebuild before astro dev so `bun run dev` serves the same payloads as production. site/public/_data/ stays gitignored. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
9ffd3211d5 |
Neo Kinpaku design system + Live Mode v3 (#169)
* Add neo kinpaku design system page * skill: rip out baked-in category recipes and saturated-default motion tropes Programmatic bias mining (impeccable-evals) traced four major defects back to specific lines in this skill that contradicted SKILL.md's own first-order-reflex warning: - brand.md "Pairing and voice" prescribed four category→aesthetic recipes (editorial → serif+sans, tech/dev/fintech → tight tracking, consumer/food/travel → script/display serif, creative → rule-break). These directly drove OpenAI's 76% extreme-negative letter-spacing on tech briefs and Anthropic/Google's 28-34% italic-serif-display slop on editorial/food briefs. Replaced with one sentence: the shape depends on the brand, not on the brand's category. - brand.md "Brand permissions" had "Typographic risk. Enormous display type, unexpected italic cuts, mixed cases, hand-drawn headlines, a single oversize word as a hero." — a four-for-one slop driver behind 97% OpenAI comically-large H1, 42% bad-SVG illustration, and the editorial-italic slop. Deleted outright. - typeset.md and teach.md repeated the same category recipes; trimmed to the principle without the recipe. - SKILL.md Typography: added a hard hero-H1 ceiling (clamp() max ≤ 6rem ≈ 96px), with a <codex> block to make it explicit since OpenAI over-indexes here (97% ≥128px vs 24% for Anthropic). - animate.md, bolder.md, brand.md: removed "staggered reveals" and "scroll-triggered transitions" as the prescribed default ambitious motion. By 2026 that's the saturated AI tell, not a choreography. Reserved stagger for legitimate list-sibling rhythm. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * skill: anti-cream + codex-specific defect bans + universal slop bans Second pass after measuring more biases against the eval corpus. - SKILL.md Color: explicit "cream/sand/beige body bg is the saturated AI default of 2026" rule. Tone down the "tint every neutral" line so it doesn't read as "default to warm-tinted near-white" (which OpenAI hits at 74% and Anthropic at 31%-47%). - SKILL.md Absolute bans: add universal bans for two slop patterns detected at 55-95% across providers — tiny uppercase tracked eyebrow above every section (the 2023-era kicker that's now AI grammar) and numbered section markers (01/02/03). Also explicit "text that overflows its container is the universal defect on tablet/mobile." - SKILL.md Absolute bans → <codex> block: ban the GPT-specific defects Paul annotated repeatedly — `border:1px solid` + soft-wide-shadow (≥16px blur) "ghost cards", `border-radius:32px+` over-rounding, hand-drawn/sketchy SVG illustrations (loose-sketch / *-sketch classes, feTurbulence paper-grain filters), repeating-linear-gradient stripes, "X theater" AI-slop copy phrases. - SKILL.md Motion → <gemini> block: the image :hover transform tell (38% Google skill-on rate). Hover effects on images add no info; the image isn't an action target. Animate card chrome, not the image. - SKILL.md Typography: hard display letter-spacing floor ≥-0.04em (OpenAI defaults to -0.075em → cramped). Existing hero ceiling <codex> block extended with the letter-spacing rule. - codex.md Step A example: stop seeding "warm-grounded (deep oxblood + cream)" as the warm-palette template, which primes the cream default. - colorize.md Tinted backgrounds: stop printing the literal cream recipe `oklch(97% 0.01 60)`; replace with brand-anchored guidance. - document.md examples: warm-ash-cream → cool-paper so the example doesn't seed cream as the canonical neutral example. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * skill: universal anti-slop bans + contrast/font-count/all-caps-body rules Third pass after measuring the rest of the cross-provider matrix: - Color: explicit "Verify contrast" rule. Low-contrast text fires at 68% across all providers skill-on (90+% off). The most common failure is muted gray body on a tinted near-white; light-gray-for- elegance is named as the single biggest cause of unreadable AI pages. - Typography: max-3-font-families rule. Overused-fonts (>4 families) fires at 28% Anthropic / 36% Google / 0% OpenAI skill-on; >50% off. Also: universal "no all-caps body copy" (moved from brand-only ban to Shared design laws since product-register also overuses caps). - Copy: anti-aphoristic-cadence ban targets Anthropic's signature "X. No Y." / "X. Just Y." voice (63% skill-on copy-slop rate, 77% off — the worst rate in the matrix). Once-is-voice / three-or-more- is-tell framing per the runner's copy-slop detector. - Copy: anti-SaaS-buzzword-string ban with the literal phrase list the detector watches for (streamline/empower/supercharge, trusted- by-leading, best-in-class/enterprise-grade/cutting-edge, etc). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * skill: strengthen anti-cream rule across full warm-neutral band Smoke validation showed the cream fix worked for Google + OpenAI but Anthropic Sonnet italian-restaurant still shipped `--paper: oklch(90% .018 88)` — cream just outside the L≥95% band the rule cited. Broaden the rule: - Band: OKLCH L 0.84-0.97, C < 0.06, hue 40-100 (was 95-97% / 60-95). - Name the token-name tells explicitly (paper / cream / sand / bone / flour / linen / parchment / wheat / biscuit / ivory) — the model defaults to one of these regardless of what hex it lands on. - Call out the specific brief patterns ("warm, traditional, family- coastal-Italian" / "editorial-restraint") that the model translates into cream by reflex. Then provide three explicit non-cream options: saturated brand color, true off-white at C=0, or darker mid-tone. Warmth in the brand is carried by accent + typography + imagery, not by body bg. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * v3.2.0: skill bias-fix release Bumps version from 3.1.1 to mark the four-commit skill cleanup that rips out baked-in category recipes (brand.md), saturated-default motion tropes (staggered reveals everywhere), the cream/sand body-bg AI tell, codex-specific defects (1px+wide-shadow, over-rounding, hand-drawn SVGs, stripes, X-theater copy), the extreme-letter-spacing default, and universal slop bans (all-caps eyebrow on every section, numbered-section markers, all-caps body, font-family-count > 3, aphoristic copy cadence, SaaS buzzword strings). Plus a hard hero-H1 ceiling (clamp() ≤6rem) and a Gemini-specific image:hover transform block. Validated against ~190 post-fix samples — see impeccable-evals biases tab for per-provider deltas. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * drop "no pure black/white" rule entirely The rule was contested in the design world and causing more damage than good — pushing every page into the tinted-near-white default which is the cream/sand AI tell we already explicitly ban elsewhere. Vercel, SVKMS, Brutalist sites, et al. use pure black/white successfully; the skill shouldn't second-guess that. Skill markdown deletions: - SKILL.md Color: drop the "Never use #000 or #fff" bullet. - color-and-contrast.md: drop the "Never Use Pure Gray or Pure Black" subsection, the "Never pure black" table-row prescription, and the "Avoid: Using pure black for large areas" bullet. - colorize.md: drop the "NEVER use pure black or pure white for large areas" bullet. - polish.md: drop the "Tinted neutrals: No pure gray or pure black" half of the bullet (the gray-on-color bullet survives). Detector code (cli/engine): - registry/antipatterns.mjs: remove the `pure-black-white` entry. - rules/checks.mjs: remove the three `findings.push({ id: 'pure-black-white', ... })` emit points (inline #000 bg, Tailwind bg-black class, plain-HTML scan path). - engines/regex/detect-text.mjs: remove the two pure-black-white regex rules (CSS `background: #000…` + Tailwind `bg-black`). - detect-antipatterns-browser.js: regenerated via scripts/build-browser-detector.js. Tests: - detect-antipatterns-fixtures.test.mjs: invert the assertion that pure-black-white fires; expect it to NOT fire post-v3.2. Drop the Tailwind bg-black-opacity edge-case test (no longer relevant). - detect-antipatterns.test.js: drop the standalone "detects pure- black-white in styled-components" test and remove pure-black-white from the multi-detector assertions in PricingCard, globals.css, and GlobalStyle.tsx tests. 166 bun tests pass; 24 node fixture tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * skill: strip example patterns from copy rules, strengthen gemini block v3.2 rerun validation surfaced two issues: 1. Copy-slop detector fires more on Gemini under v3.2 (48% → 84%) than under no-skill baseline. Root cause: the anti-aphoristic-cadence rule printed the literal "X. No Y." / "X. Just Y." patterns as examples, and Gemini imitated them as the recommended voice. Same recipe-becomes- bias trap we hit with brand.md:116's "Enormous display type, unexpected italic cuts, mixed cases, hand-drawn headlines" enumeration. Fix: describe the cadence as a rhythm ("serious statement, then punchy short negation") without printing literal patterns. Buzzword list trimmed to a single inline phrase family rather than quoted strings. 2. Gemini image:hover transform Gemini-tell hadn't dropped (31% off → 32% v3.2). Strengthen the <gemini> block: explicit "Never animate <img> elements on hover", call out the Tailwind group-hover:scale / group-hover:rotate / group-hover:translate parent-hover patterns by name (Gemini was reaching for these via Tailwind even though the prior text talked about :hover on the image directly). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * skill: simplify context loading and inline register directive Replaces load-context.mjs's JSON output with a tight markdown block from the renamed context.mjs. The script now extracts PRODUCT.md's `## Register` field and appends a `NEXT STEP:` directive naming the matching reference (brand.md / product.md), which moved Gemini from skipping the register load entirely to honoring it. Drops the `.impeccable.md` auto-migration; makes IMPECCABLE_CONTEXT_DIR a lazy escape hatch consulted only when the default paths come up empty. Setup is now four bullets in one list. The DESIGN.md nudge is gone; in its place, a "familiarize with the existing design system" step that calls out CSS / tokens / running app as authoritative sources alongside DESIGN.md. The standalone `### Register` H3 stays for the cascade rules (task cue → surface → register field). New LLM-backed test suite at tests/skill-behavior/ runs five scenarios against claude-haiku-4-5, gpt-5.4-mini, and gemini-3.1-flash-lite via Vercel AI SDK. Captures real tool traces, asserts on context.mjs calls, brand.md loads, and teach.md fallback. Skips cleanly when API keys are unset. 13-14/15 pass; only stable failure is the v3.2.0-era gpt-mini S4 "don't re-run" regression. Adds @ai-sdk/google as devDep and the test:skill-behavior npm script. Touches em-dashes in skill/SKILL.md and four reference files so `bun run build:skills` passes its skill-prose validator. teach.md and document.md drop their "re-run the loader to refresh session cache" steps since the agent's own write is now the freshest source. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * skill: merge orphan reference files into command sub-skills + inline S-tier invariants Two related restructurings: 1. SKILL.md now carries the cross-domain invariants that catch defects in any project (contrast/placeholder/gray-on-color, similar-font pairing, text-wrap, tabular-nums, centered-stack default, Flex/Grid choice, auto-fit grids, semantic z-index, reduced motion, stagger vs section-fade, premium motion materials, focus-visible, placeholders-aren't-labels, dropdown overflow trap, button/link copy). Greenfield-only rules (theme picking, color strategy, tinted neutrals) live under "New projects only". 2. Reference files merged into their command counterparts: - spatial-design.md -> layout.md - motion-design.md -> animate.md - color-and-contrast.md -> colorize.md - responsive-design.md -> adapt.md - ux-writing.md -> clarify.md - typography.md -> typeset.md (bolder.md redirected) - cognitive-load.md + heuristics-scoring.md + personas.md -> critique.md craft.md and shape.md "load references" lists updated to new file homes. interaction-design.md stays standalone (no 1:1 command verb). Net: 36 -> 27 reference files. Same content, fewer files, no orphaned reference loaded only from craft.md. Also extends the routing rules: if the user's first word doesn't match a command but the intent clearly maps to one, load that command's reference and proceed as if invoked. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * skill: add sub-command + existing-project scenarios; move sub-command load to step 2 Adds three new LLM-backed scenarios to tests/skill-behavior: - S6: `/impeccable polish` → loads polish.md - S7: `/impeccable audit` → loads audit.md - S8: existing SvelteKit project (PRODUCT.md + DESIGN.md + src/app.css + src/lib/components/*.svelte + src/routes/+page.svelte) → agent reads at least one project code file to understand the existing design system S6/S7 surface a real model-floor: gpt-5.4-mini reads brand.md, reads the target index.html, and just does the polish/audit without ever loading the sub-command reference. Stronger SKILL.md wording didn't move it. Captured in the README baseline as a known weakness. Claude and Gemini honor the load reliably. To fix Gemini on S6/S7, sub-command reference loading is now Setup step 2 (right after context.mjs), not step 4 — placing it before the model gets focused on "doing the work". Step 3 (design-system familiarization) is tightened to require at least one project code read even when a sub-command reference loads in step 2, so Claude doesn't laser-focus on the sub-command flow and skip the broader exploration. Two new fixtures: MINIMAL_LANDING_HTML (a tiny static landing page for S6/S7) and SVELTE_PROJECT_FILES (a minimal SvelteKit scaffold with tokens, components, and a routes/+page.svelte for S8). Both designed to look real enough that agents treat them as production code. Suite is now 24 tests across three providers; baseline is 21-22/24, with the stable failures being gpt-5.4-mini scenarios 6 and 7. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * skill: add reveal-animation safety rule (must enhance, not gate visibility) Class-triggered visibility transitions pause on hidden tabs and headless renderers. The italian-restaurant smoke produced a build where 2 sections shipped opacity:0 because the CSS transition never advanced past currentTime=0 (timeline paused). Added one-liner under Motion to prevent the antipattern: reveals must enhance an already-visible default, never gate content visibility on a class-triggered transition. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * skill: restore prescriptive cream/sand/beige paragraph Bisection across 5 historical skill commits on Gemini 3.5 flash fast lane n=3 found that |
||
|
|
e1d3ea0b6f |
Detector architecture v2: static engine, benchmarks, lab, and visual contrast (#156)
* Add detector benchmark lab and visual contrast fallback * Expand visual contrast fixture coverage * Add browser visual contrast fallback * Show visual contrast overlays in detector lab * Fix detector lab short viewport layout * Fix detector lab visual overlays * Add visual contrast to browser scan overlays * Avoid browser scroll jumps during visual contrast scans * Resolve visual contrast lazily on scroll * Refresh detector lab visual counts lazily * Update pnpm lockfile for static parser deps * Address Bugbot detector API comments * Report extension visual contrast errors * Refactor detector into engine modules * Address Bugbot detector comments * Fix latest Bugbot detector notes * Fix visual contrast fixture labels * Refine detector lab fixtures * Fix stale detector overlay references * Fix detector lab fixture URLs * Fix typography lab fixture highlights * Fix typography lab page-level signal * Fix visual overlay lifecycle cleanup * Remove dead spotlight timer cleanup * Make browser async APIs reject consistently |
||
|
|
e7e923c4ef |
Skill + craft cleanup, detector hardening, native subagent pipeline (#152)
* skill: drop quality tiers, keep the real brand-craft guardrails Codex's craft/brand pass introduced fast/ship/showpiece "quality bars" plus brand-specific build gates, asset ledgers, sub-agent review, and self-graded fallback labels. In practice those tiers became escape hatches rather than craft pressure: the final output should always be 10/10, and the real decision points are splashiness and maximalism, not quality. Removed: - All quality-bar / showpiece / fast / ship framing in shape.md and craft.md - Standalone Brand Direction (#4) and Asset Requirements (#10) sections in shape's brief; renumbered back to 1-10 - The Brand hard rules section in brand.md (folded its real prohibitions into the existing Imagery and Brand bans sections) - Brand-specific build-gate item, mock-fidelity bullet, production-bar bullet, present-step bullet in craft.md - Asset ledger ceremony in craft Step 4 - Review-only sub-agents and "self-reviewed fallback, not independently validated" machinery in craft.md and polish.md - The For brand surfaces, assess hard failures subsection in polish.md and the brand checklist row - tests/brand-showpiece-reference.test.mjs (and its package.json wiring) Kept (the real nuggets): - Asset-substitution prohibition: image-led briefs ship real/generated assets or canvas/SVG/WebGL, not generic CSS panels, cards, bullets, or copy - Repeated tiny uppercase tracked kicker labels as a brand ban - Detector/QA output is defect evidence only, never proof of quality - "What visual assets are real content here?" discovery question - Inspect each major section individually for brand and long-form work - repeated-section-kickers detection rule + fixture - CLI improvements (JSON to stdout, -json/-fast aliases, severity field) - critique.md: npx impeccable detect --json fix Harness output dirs refreshed via bun run build. Full test suite (186) passes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * skill: strip gate ceremony; require shape pause; allow compact briefs The setup gate table and IMPECCABLE_PREFLIGHT banner pushed every craft run through ritual restatement (PRODUCT.md → original prompt → round 1 → round 2 → 70-line "confirmed brief" → critique → summary, all saying the same thing). Replaced with imperative prose that still demands the same work but skips the user-facing telemetry. Specifically: SKILL.md - Drop the Setup gate table and IMPECCABLE_PREFLIGHT banner. - Keep the imperative steps explicitly: load context, identify register and load brand.md or product.md, AND load the matching command reference (craft.md / shape.md / etc.) when a sub-command is invoked. The command-reference step is non-negotiable; without craft.md loaded the agent skips the shape-and-confirm pause. craft.md - Drop the Build Gate / Craft Contract formal sections; replace with one paragraph stating prerequisites. - Step 1 explicitly requires ending the response after presenting the shape output; the user must confirm before any code lands. Allows a compact 3-5 bullet brief when the prompt + PRODUCT.md already pin direction (full 10-section structure reserved for genuinely ambiguous tasks). - Step 3 image gate skips silently when image generation isn't natively available; no user-facing announcement. - Step 6 explicitly legitimizes "first pass clean, shipping" as a valid endpoint and bans inventing fake defects to demonstrate iteration. shape.md - Cap discovery at 1 round by default; second round only when first leaves material gaps. - Adds an "assert-then-confirm, not menu-with-escape" rule: when PRODUCT.md and the prompt make one option obvious, name it and ask for confirm or override instead of enumerating "Restrained / Committed / Or something else?" as a real choice. - Phase 2 brief has two forms now: compact (default for clear briefs) and full structured (genuinely ambiguous). Open Questions can't double as leading-with-Recommend; if you'd write "Recommend: X", decide X. - Image gate same as craft.md. Validated end-to-end with a Haiku skill-on observability run: agent loads craft.md plus the brief's recommended implementation refs, pauses for one productive question (accent color, trace fidelity, CTA), and ships an artifact with zero side-tab violations vs. the original v1 baseline. Cost trades up modestly for that quality. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * craft.md Step 6: Reading the screenshot is the inspection, not taking it A v4 eval run took 4 targeted screenshots (hero, mobile, tablet, query-section) and then never Read any of them back. The agent treated browser_screenshot itself as "I inspected" and shipped without the multimodal feedback loop ever closing. Detector caught the resulting slop (5+ side-tab violations) on adjacent runs that did the same thing. Step 6 now spells out the pattern explicitly: take the screenshot, then Read the resulting PNG so its image content enters the conversation as multimodal input, then critique what you actually see in the image. With a check: "if your critique could have been written without looking at the image, you didn't look at the image." Validated with v5b: agent took 6 screenshots, Read all 6 back, and shipped with zero detector findings (vs the previous greenfield runs that hit 1-12 findings each). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * craft + brand: framework foundation, build-pipeline respect, image verification Three closely-linked additions surfaced by an eval-harness session investigating why the agent always shipped flat single-file HTML and zero imagery on greenfield brand briefs. 1. craft.md gains a new Step 0 "Project Foundation" before Shape. Detects existing framework / component library / icon set and uses what's there. Greenfield: ask the user via AskUserQuestion with sensible defaults framed by the brief (Astro for content/ brand sites, SvelteKit/Next/Nuxt for app surfaces, single index.html only for one-shot demos). Skipping the framework decision and writing flat HTML "to satisfy the spec" produces work that reads as a 2018 prototype regardless of visual quality. 2. craft.md Step 5 production bar gains two bullets: - Respect the build pipeline. Edit source files and run the project's `npm run build`; do not write to build/ / dist/ / .next/ directly with cat/heredoc/Bash redirects. Bypassing the pipeline skips asset hashing, image optimization, code splitting, and CSS extraction. - Verify external image URLs before referencing them. Use an image-search MCP, web-fetch tool, or browser if available; guessed photo IDs ship as broken-image placeholders. 3. brand.md "Imagery" section: - Generalizes the Unsplash URL guidance to "verify URLs before referencing them" with a hierarchy: image-search MCP > web-fetch > confidence-restricted manual selection > fewer photos. - Tightens the tech/dev-tool exception. Old line "zero imagery can be correct" gave models a permission slip. New framing keeps the underlying truth (typography + code + diagrams primarily carry voice) but raises the floor: imagery still earns its place when it serves the brief, and skipping it requires naming the typographic/diagrammatic move that's carrying the visual weight instead. "Zero imagery is the failure mode of laziness, not restraint." Eval-harness corpus that prompted this: 19/19 brand landing tasks shipped 0 images each, including ones where Opus had taste enough to break the dev-tool color default lane. The skill needs to teach both halves of the decision; the harness shouldn't have to nudge. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * detector: body-text-viewport-edge rule + OKLCH/var-resolution + anchor-inherit FP fixes New rule: body-text-viewport-edge flags body paragraphs that render flush against the left/right viewport edges (no container padding). Tested via the new tests/fixtures/antipatterns/body-text-viewport-edge.html fixture (3 flag cases, 5 pass cases) and the test in detect-antipatterns-browser. False-positive class fixes — all jsdom-mode only (real browsers resolve the cascade correctly so these gates stay inert there). Five related gaps that compounded into ~14× spurious contrast findings on Tailwind v4 pages with OKLCH color tokens: • OKLCH parser. jsdom returns the literal "oklch(...)" string from getComputedStyle; the detector now converts to sRGB via Björn Ottosson's matrices. Handles Tailwind v4's compact minified form "oklch(21.5%.02 50)" (no space after %). • var() resolution. resolveBackground + checkElementColors now accept the existing customPropMap and parse `var(--color-paper)` etc. as proper RGB via the new parseColorResolved helper. • bg-color before bg-image. The old order bailed on any gradient ancestor before checking for a solid background-color underneath, causing the body's decorative paper-grain gradient to be measured against instead of the page's actual `bg-paper` cream. • body/html-level gradient → white fallback. When the only opaque ancestor we can read is body/html with a gradient overlay (and jsdom can't decompose `background: var(--paper) gradient` to extract the solid color), return white instead of falling through to resolveGradientStops — which was picking up paper-grain noise colors and using them as the bg. • Anchor-inherit workaround for jsdom :link UA specificity. Tailwind v4's preflight declares `a { color: inherit }` (0,0,1). jsdom's UA stylesheet has `:link { color: blue }` at (0,1,1) and wins the cascade. Real Chrome wraps :link in :where() (0,0,0) so the page rule wins. When the page declares the inherit rule AND we see jsdom's default `rgb(0,0,238)` on an anchor, walk to the nearest non-anchor ancestor and use its color. • Alpha-fallback safety gate. When text has alpha<1 AND we couldn't find an opaque ancestor (effectiveBg null), skip the contrast finding. Covers any remaining FP class the deeper fixes miss. Verified end-to-end against an Opus iter-1 artifact on Tailwind v4 with 14 cream/cream FPs + 2 blue-link UA FPs before; 0 findings after, while the color.html fixture's 12 real low-contrast cases continue to flag (verified via direct detectHtml calls). cli/engine/detect-antipatterns-browser.js is the generated browser distribution — regenerated from .mjs via scripts/build-browser-detector.js (no manual edits to the generated file). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * craft.md: tighten verbose passages, de-codex Step 6, cut redundancies Cumulative reduction: 218 → 155 lines (-29%). Step 0: drop the "Why this matters" paragraph at the end. The body of Step 0 already makes the framework-pick point; the paragraph just re-explains it with extra rhetoric. Step 1: replace the 4-sentence "you must end your response" block with a single line. The original said the same thing three different ways. Step 3: trim the conditional / defensive scaffolding (Purpose subsection, "do not skip because the eventual UI is semantic..." paragraph, duplicated approval-loop guidance). Mock fidelity inventory preserved. Step 4: drop the "keep UI text semantic" sentence; it duplicates Step 5's "Semantic first" rule. The rasterized-vs-semantic decision rule stays. Step 5: tighten each production-bar bullet to bold-lead + specifics format. All 15 rules preserved (real content, mock ingredients, semantic first, spacing/alignment, typography, state coverage, interaction quality, icon set, build pipeline, image URL verification, optimized imagery, premium motion, maintainability, technical cleanliness, ask-when-uncertain). Step 6: rewrite around "look at what you built like a designer would — your eyes are whatever the harness gives you." Drops Codex-specific "In Codex, use browser-use" bias. Drops the verbose 3-step Read pattern (condensed to one sentence). Drops the 1-8 numbered checklist (replaced by a tight paragraph). Keeps the load-bearing rules: read the PNG, don't fabricate iteration, mock fidelity reference, exit bar = studio defensibility. Step 7: drop the closing "Iterate based on feedback. Good design is rarely right on the first pass" preachy filler. All em-dashes converted to semicolons / colons / periods to satisfy the skill prose validator. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * build: native subagent pipeline + Codex-only asset producer Adds an agent cross-compile pipeline alongside the existing skill pipeline. Sources live at skill/agents/*.md; providers that declare agentFormat (codex-toml, claude-md) emit native subagent files. An optional providers: <list> field on an agent gates which harnesses get a copy; default (no field) ships everywhere. The impeccable-asset-producer agent is opt-in to Codex only. It's useful for Codex's native image generation path and is untested elsewhere; Claude has no native image gen anyway. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * brand: inverse-test + cultural-symbol palette guardrail Two additions to the brand register reference: - Inverse slop test: describe the page the way a competitor would describe theirs. If that sentence fits the modal landing page in the category, restart. - Palette guardrail: when a cultural-symbol palette is the obvious pull, reach past it. Let cultural reading come from typography, imagery, and copy. Harness mirrors regenerated; some also catch up to the image- verification paragraph from |
||
|
|
e587004ee4 |
Refactor: cleaner top-level directory structure (#138)
* 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 |
||
|
|
d874af046a |
feat(live): make live sessions recoverable (#125)
* 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> |
||
|
|
ea930268a8 |
docs(skill): apply STYLE.md to source/skills/impeccable (#135)
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> |
||
|
|
122a82f715 |
docs: strip AI prose, add STYLE.md and validateProse (#134)
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>
|
||
|
|
b8f09c8142 |
Migrate site from Bun to Astro (#130)
* 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> |
||
|
|
70a9246401 |
fix(plugin): slim Claude Code install (291MB→770KB) + fix skills path
- 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> |
||
|
|
579006cda5 | fix: add missing trailing-slash redirect for /cases/neon-mirai/ | ||
|
|
ceb0ef8f67 | chore: rename all references Neon Mirai -> Neo Mirai to match site title | ||
|
|
74f16d6310 | Add Neon Mirai showcase | ||
|
|
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> |
||
|
|
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
|
||
|
|
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> |
||
|
|
66630a0ead |
chore: sync skills, live tooling, and eval ignores
- Ship design-parser and refreshed live scripts/document refs across provider skill trees; align live.mjs and live-poll with source - Update build/skills harness metadata, skills CLI test, and devDependencies (AI SDKs, zod) - Gitignore .codex/ harness artifacts and tests/evals-v2/ Made-with: Cursor |
||
|
|
59bb3d35a5 | Stop syncing repo-local Codex skill | ||
|
|
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> |
||
|
|
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> |
||
|
|
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>
|
||
|
|
7d29aaca1b |
Deprecate /gallery page, redirect to /visual-mode#try-it-live
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> |
||
|
|
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> |
||
|
|
22b7adf56f |
Strip deprecated skill stubs from local harness dirs after build sync
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> |
||
|
|
eeee5bc0aa |
Copy antipattern examples and browser detector to build output
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> |