Bump the npm package and regenerate the browser detector bundle with
the advisory tier, entity-aware em-dash counting, and the
undersized-ui-text rule.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A cheap, LLM-free E2E tier for the interactive parts of new-work, mirroring
the two-layer live-e2e pattern (deterministic now, opt-in LLM tier later).
- generate-image.mjs: IMPECCABLE_IMAGE_GEN_FAKE=1 writes a deterministic
offline image (SVG with wrapped prompt + SYNTHETIC COMP label, or a valid
palette-stripe PNG carrying the prompt/marker in a tEXt chunk). Same CLI
contract, no key, no network, $0.00 cost line.
- tests/new-work-e2e/user-bot.mjs: scripted user bot (module + CLI) that
resolves the serve-question daemon from the workspace and drives the real
page via Playwright (pick, re-roll + steer, canon, tab close).
- tests/new-work-e2e.test.mjs: node --test coverage of the serve-question
cycles (pick + CHOSEN CARD, re-roll + --update re-deal, canon + CANON
CHOSEN, tab-close exit-4, text-only card) plus fake image determinism.
- Registered as the opt-in new-work-e2e suite; added test:new-work-e2e.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The v4 repo split dropped astro/wrangler from devDependencies, which
also removed the only (transitive) source of @babel/parser. The
post-apply syntax check in live-copy-edit-agent.mjs requires it to flag
invalid JSX/TSX; without it the check silently degrades to a warning and
tests/live-copy-edit-agent.test.mjs "flags invalid JSX syntax" fails on a
fresh CI install. Production behavior is unchanged: the require stays an
optional, graceful-degrade path for end users, and @babel/parser was
never in the published package's runtime dependencies. Declaring it as a
devDependency just makes the repo's own test environment deterministic.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Bump skill to 4.0.0 (plugin.json + marketplace.json) and the CLI to
3.3.0 (package.json), then run build:release to regenerate the plugin
subtree and all provider harness output to the new versions.
Skill 4.0.0 ships external-dice direction assignment, the reviewed
world catalog dealt through the roll API with rendered quality-bar
cards, the in-browser serve-question decision page, visualize-before-
build, the rebuilt new-work flow, and the 58-rule detector under hook
enforcement. CLI 3.3.0 grows the deterministic detector to 58 rules
and adds config-declared context roots, per-file rule scoping, and
--target resolution for nested products.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
main still carries the site, so every `site/` path resolves to deleted.
`tests/docs-integrity.test.js` goes with it (it imports the site's demo
renderer), and `package.json` keeps main's `@anthropic-ai/sdk` bump while
dropping `@google/genai` and `@paper-design/shaders`, which nothing in the
product layer imports.
Real code merges:
- hook-lib: main's #391 cache fix (sync the remembered set to the live
scan so fixed findings stop being named and a reintroduced one fires
again) now runs on the immediate tier rather than the whole filtered
set. Remembering a deferred finding the per-edit pass never reported
would let the Stop deep pass dedupe it away. main's `maxFileBytes`
ceiling, `cleanAcked` once-per-file ack, and template-extensions
re-export all land alongside the tiering work.
- live-browser: main's `hasParams` gate on the Tune badge, keeping this
branch's `C.ink` badge text so it stays legible on kinpaku gold.
- detect-text: both the block-level codex-grid-background scan and main's
inset-stripe CSS check.
- test-suites: union of both trigger sets and file lists, minus the
site-only entries (`shiki-theme`, `docs-integrity`).
- Two hook tests moved off deferred-tier rules (`overused-font`,
`side-tab`) onto immediate-tier ones. They assert cache bookkeeping,
which the per-edit pass only reaches for the immediate tier.
Also drops the site waivers from `.impeccable/config.json` and stops
`build:browser` recreating a stray `site/` tree just to write a bundle
the other repo builds itself.
Co-Authored-By: Claude <noreply@anthropic.com>
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>
/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>
Update the coordinated AI SDK stack plus Anthropic, Google GenAI, Astro, and Wrangler minor/patch releases.
Validated with a frozen Bun install, full build, full test suite, and green GitHub checks.
AI assistance: Codex performed dependency review and validation under maintainer automation instructions.
Compare direct Sol execution with cold and persistent app-server paths using identical full-task quality gates, lifecycle timings, and token metrics.\n\nAI-assisted: OpenAI Codex.
Benchmark realistic bolder and polish tasks across fast, full-model, and full-context worker profiles with deterministic and independent quality gates.\n\nAI-assisted: OpenAI Codex.
Measure framework and provider latency, enforce fidelity and cleanup gates, and publish reproducible results on the dev-only Live Lab.\n\nAI-assisted: OpenAI Codex.
Eval evidence showed the per-edit PostToolUse stream fires overwhelmingly
on copy-level rules (em-dash-overuse ~97x/session) and measurably makes
models more conservative, while a full-detector pass at completion is what
actually fixes contrast/padding/glow. Split the hook accordingly:
- Per-edit (PostToolUse) now surfaces only IMMEDIATE_TIER_RULES: broken
output (broken-image, text-overflow, clipped-overflow-container,
body-text-viewport-edge), objective contrast/legibility failures
(low-contrast, gray-on-color, tiny-text), single-property mechanical
slop (gradient-text, dark-glow), and design-system drift (the four
design-system-* rules, which compound if left uncorrected). Everything
else defers. Override with hook.perEditRules: "all" in
.impeccable/config.json. Tiering is off for Cursor/Copilot harnesses,
which have no Stop pass wired, so nothing gets silently dropped there.
- Stop deep pass (runStopHook): runs the FULL rule set over every UI file
touched this session (tracked via the existing hook.cache.json session
state; deferred-only edits now mark the file touched), dedupes against
everything already surfaced per-edit, honors ignore-rule/file/value and
inline disables, reuses the [impeccable@1] envelope, and no-ops fast
when no UI files were touched. Emits hookSpecificOutput
{ hookEventName: "Stop", additionalContext } per the Claude Code SDK
Stop contract (conversation continues so the model can act on it).
Second Stop fire is silent - deep-pass findings are remembered.
- Wiring: Stop entries (timeout 30) in plugin/hooks/hooks.json, the
.claude settings + .codex hooks manifests (transformers + hook-admin
repair path). Claude Code and Codex both dispatch a native Stop event;
Cursor's stop hook is inconsistently dispatched (pre-write gate stays)
and Copilot's agentStop/sessionEnd don't inject model context, so
neither gets a Stop entry - documented in reference/hooks.md.
- Tests: tiering split/override/harness gating, Stop dedupe + silent
no-touched-files + ignore machinery + kill switches; existing per-edit
tests moved to immediate-tier rule ids. 181 tests green; smoke-tested
the built dist skill end to end (glow surfaced per-edit, em-dash only
at Stop, second Stop silent).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Lower the CLI engine floor to Node 22.12 so npx no longer falls back to stale 2.x releases for Node 22/23 users.
Add Node 22.12 CI coverage while preserving the stable required test check, and document the 3.2.1 CLI release notes including the detector and installer fixes already waiting on main.
AI-assisted-by: Codex
On Node v24.16.0 / v26.1.0+, `impeccable install` printed "Downloading
impeccable skills...", exited 0, and installed nothing. A Node streams
regression (nodejs/node#63487) made pause()/resume() no-ops on destroyed
streams, stalling extract-zip's yauzl/fd-slicer read stack partway through;
its promise never settled and the process exited clean with no error.
Swap extract-zip for fflate across both extraction call sites
(downloadAndExtractBundle, copyOrExtractLocalBundle) via a new extractZip
helper. fflate decompresses from an in-memory buffer and never touches the
fs stream path, so it is immune on every Node version. It is pure JS with
zero dependencies, so the Windows fix from #198 (no `unzip` binary) holds.
Unlike extract-zip, fflate is actively maintained.
Because extractZip writes entries itself, it guards against zip-slip (`../`
entries escaping the target dir). Tests add a many-file regression guard
(fails on partial extraction) and a zip-slip rejection test.
Verified end-to-end: the real 1,194-file universal bundle extracts and
installs completely.
Fixes#250.
Co-authored-by: Claude <noreply@anthropic.com>
* 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>
* Improve CI test coverage
* Stabilize live E2E harness
* Shard live E2E CI
* Cache live E2E CI dependencies
* Stabilize live E2E smoke CI
* Update generated live browser bundles
* Tighten live E2E smoke runtime
* Prevent live E2E smoke hangs
* Stabilize live E2E CI coverage
* Fix stale accept DOM cleanup
* Regenerate live browser outputs
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>
* Fix live preview state for framework components
* Complete stateful live preview coverage
* Record Svelte manual validation
* Fix Svelte live mode adapter
* Fix live Steer apply flow
* Fix Svelte live variant refresh recovery
* Fix live exit bar teardown
* Consolidate Svelte live DeepSeek sweep
* Reconcile Svelte live browser after main rebase
* Fix live accept review regressions
* Fix carbonize column-zero indentation
* Fix live poll lease expiry flake
* Fix Svelte shader preview capture
The `i-` prefix install option was a holdover from the multi-skill era.
With a single `impeccable` skill it only ever renamed that one skill to
`i-impeccable`, while the install message wrongly advertised `/i-audit`
style commands that never existed, and the unscoped rename could clobber
unrelated third-party skills in the same harness folder.
- Drop `--prefix=`, the interactive prompt, and all prefix machinery
(renameSkillsWithPrefix, prefixSkillContent, detectPrefix, undoPrefix,
prefixedCommandHint, isImpeccableSkillName).
- Add migrateUnprefixImpeccable: install --force and update rename any old
`<prefix>impeccable` back to canonical `impeccable` before the fresh copy
lands, scoped by name so foreign `i-*` skills are left untouched.
- Fix FAQ + editorial that wrongly described pinned commands as `i-`
prefixed (pins are bare `skills/<command>/` dirs).
- Tests now exercise the real exported migration, not a reimplementation.
- CLI 2.3.1 -> 2.3.2 with a changelog entry.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codex auto-discovers subagents bundled inside an installed skill's own
agents/ folder, so the separate .codex/agents/*.toml sidecar was redundant.
- cli: remove installCodexAgents/isCodexLikely and their install/update calls
- context.mjs: remove the CODEX_AGENT_MISSING self-heal directive
- build: drop codex agentFormat so no top-level .codex/agents is emitted; the
nested in-skill .toml bundling is the whole delivery
- remove the tracked .codex/agents/*.toml and the gitignore exception
- docs + build.test.js updated for the nested layout
- CLI patch version bump; skill version unchanged
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>