mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-11 21:57:14 +03:00
695df68a5860da4d25cd629fc3727ec8f3c0991b
8
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2cfd60765a |
Fix: do not flag Roboto in system font stacks (#678)
Treat the leading system face as primary so later Roboto fallbacks do not trigger overused-font, while named web-font primaries still flag. AI-assisted merge: reviewed and executed by Codex under maintainer direction. |
||
|
|
5444031942 |
Fix: skip hex nested in color-mix when measuring gradient contrast (#578)
parseGradientColors treated #000 inside color-mix() as a stop, so low-contrast scored text against phantom black. Prepared with AI assistance. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|
|
ac0416b655 |
Stop assuming white when a background cannot be read (#541)
* Stop assuming white when a background cannot be read Dark themes came back from a scan buried in low-contrast findings that all claimed the light text sat on #ffffff. Two live runs against impeccable.style produced 102 and 95 of them. Two causes, both fixed here. Parsing. Browsers keep the authored color space in getComputedStyle output: oklch() stayed oklch, but color-mix results come back as color(srgb 1.04 0.72 -0.21), wide-gamut authors get color(display-p3 ...), and lch()/lab() survive verbatim. The parser read none of those, so those surfaces registered as unset. parseGradientColors was worse: it matched only rgba() and #hex, so a ground painted as linear-gradient(oklch(...), oklch(...)) counted as a gradient with no stops at all. Guessing. When the ancestor walk ran out of readable color it returned white, and on a body-level gradient it returned white without even looking. Light copy on a lacquer-black page then measured 1.3:1 against a canvas the visitor never sees. resolveBackgroundInfo now separates three outcomes: a resolved surface, a gradient the caller should fall back to stops for, and an unreadable layer. The last one makes both color adapters skip their contrast checks entirely. White survives in exactly one case, the one that earns it: every layer up to the document root was genuinely transparent. Color conversions moved to cli/engine/shared/color.mjs and gained lab, lch, and color() for srgb, srgb-linear, and display-p3. Spaces outside that set return null, which now routes to abstention rather than to a color nobody painted. Every conversion is pinned against what Chrome itself paints for the same string. Rescanning impeccable.style: 102 low-contrast findings down to 30, none of them on an invented white ground. Assisted-by: Claude Code * fix: address PR review bot findings on background resolution - Treat a url() image layer stacked above a gradient as an occluding, unreadable surface: resolveBackgroundInfo now returns unresolved so the gradient-stop fallback never measures stops the image hides (greptile-apps finding, reproduced in Chrome). - Route the glow and AI-palette DOM adapters through resolveBackgroundInfo so an unresolved surface makes them abstain instead of hunting gradient ancestors past an unreadable layer (Cursor Bugbot finding). - Resolve background-color keywords jsdom hands through verbatim: inherit now reads as no-paint (the ancestor walk IS its resolution) and currentcolor substitutes the element's own computed text color instead of forcing an abstention (Copilot finding). - Regression coverage in the dark-theme fixture for all three, asserted in both the jsdom and real-Chrome suites; browser detector regenerated. AI-assisted: prepared with Claude Code at the maintainer's direction. Co-Authored-By: Claude <noreply@anthropic.com> * fix: keep zero-offset glow findings when the surface is unreadable The browser glow adapter abstained from the whole element when resolveBackgroundInfo reported an unreadable surface, which also dropped zero-offset chromatic halo findings that do not depend on the background at all. It now skips only the gradient hunt past the unreadable layer and scores the halo tell against a null surface, matching what the static loop already did. Fixture cases pin both sides: the halo over a url() image ancestor flags in both engines, and an offset chromatic shadow on the same unknown surface stays abstained. Also hardens the currentcolor background substitution with the parseColorResolved fallback used by the text-color path, and adds fixture coverage proving tokenized currentcolor surfaces already resolve through the static cascade (flag when knowable, abstain when the token is undefined). Addresses Cursor Bugbot review findings on PR #541. AI-assisted-by: Claude Code Co-Authored-By: Claude <noreply@anthropic.com> * fix: abstain on translucent gradients over images, drop phantom color-mix stops Two follow-up review findings on the merge with main. A gradient leading a url() layer was treated as a resolvable surface even when its stops are translucent, so the glow and AI-palette hunts averaged wash stops (a 20% black wash reads as pure black) while the real surface blends with image pixels the engine cannot read. resolveBackgroundInfo now marks gradient-over-image unresolved unless every readable stop of the leading gradient is opaque, in which case the gradient provably covers the image and remains the scorable surface. parseGradientColorsModern predated this branch's parseGradientColors rewrite: its second regex pass re-extracted color tokens nested inside color-mix() stops that the shared parser already captures whole via balanced-paren tokens, appending ingredient colors that are never painted. The worst-case stop ratio then invented low-contrast findings against a color nobody sees. The helper is removed; all callers use the shared parser, which covers the modern syntaxes it existed for. Fixture coverage pins both: the translucent-wash-over-image glow abstains in both engines, an opaque gradient over an image still flags in the browser, and the color-mix wash case stays clean in the static engine. Each new assertion was verified to fail against the previous engine. Addresses Greptile and Cursor Bugbot review findings on PR #541. AI-assisted-by: Claude Code Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
270f4d20aa |
Make em-dash-overuse an advisory rule with browser parity
Em-dashes are used legitimately by humans, so em-dash-overuse fired far too often. Reclassify it as the first advisory-tier rule: detected, but never a failure. Engine - Add `advisory: true` to the rule metadata schema (em-dash-overuse is the first). findings.mjs stamps `advisory: true` on advisory findings so every consumer can partition without a registry lookup. Rule count stays 58. - Raise the firing threshold from a flat 5 dashes to two gates: an absolute floor of 8 and a density of about one dash per 500 characters of body text. A long article that uses a few em-dashes no longer trips; a short, dash-per-clause page still does. Entity decoding (mdash, numeric, hex) is unchanged. Thresholds live in shared/constants.mjs so every engine agrees. Browser parity - The browser bundle carried a registry entry but no logic, so the overlay and extension could never flag it. Add checkEmDashOveruse / checkEmDashOveruseDOM in rules/checks.mjs (reads rendered text, no entity decoding needed), wire it into the injected page-level pass, and carry the advisory flag through serializeFindings so the overlay/extension can render it with the mildest affordance. CLI - Advisory findings print under a separate dimmed "Advisory" section, are excluded from the failure count, and never change the exit code (an advisory-only scan exits 0). JSON keeps them with `"advisory": true`. `--no-advisory` suppresses them entirely. Hook - Advisory rules are skipped by default in both the per-edit and Stop deep-pass hooks, so the hook never nags about them. Opt in with `.impeccable/config.json` -> `detector.advisoryRules: "include"`. Tests - Fixture + threshold + browser-adapter coverage; advisory-skip default and opt-in for the hook; formatFindings partitioning. The em-dash-overuse stand for a deferred copy rule in the tier tests is swapped to marketing-buzzword. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
9f49cb85cc | Fix Google Fonts css2 family parsing (#349) | ||
|
|
776c019041 |
Add inline, in-file ignore comments for the detector (#283) (#285)
* Add inline, in-file ignore comments for the detector (issue #283) Complement config ignores with eslint-disable-style waivers that live where they apply and travel with the file when it leaves the repo. The motivating case is a generated/exported standalone document that legitimately uses a first-party brand typeface (on the overused-font list) and is later scanned without .impeccable/config.json present. Marker is comment-syntax-agnostic (works in //, /* */, <!-- -->, #, {/* */}): impeccable-disable <rule>[, <rule>...] [-- reason | : reason] whole file impeccable-disable-line <rule>... same line impeccable-disable-next-line <rule>... next line Bare directive or * means every rule; reason is optional and discarded at scan time. Behavior is suppression, for parity with config ignores. Implementation: - New pure module cli/engine/shared/inline-ignores.mjs (parser + filter, no Node deps). Static-HTML findings have no line number, so only whole-file directives apply there -- exactly the standalone-document case; the regex/text engine additionally honors the line-scoped forms. - Wired into detectText and detectHtml, gated by options.inlineIgnores. - detect CLI applies inline ignores by default; --no-inline-ignores skips just them, --no-config skips config and inline ignores together. Docs: config.md (new section), detector.md, README. skill/reference/hooks.md reversed its prior "inline comments are not supported" guidance and now points the agent to inline waivers for the travels-with-the-file case. Changelog 3.x. Tests: tests/inline-ignores.test.mjs (parser units, detectText/detectHtml integration, CLI end-to-end), registered in the detector suite. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Reconcile design hook wording with inline ignores Two hook-side fixes prompted by review of the new inline-ignore feature: 1. Clean-ack steer line. The old line ("Keep typography hierarchy, spacing rhythm, and color contrast intentional on the next change.") read as an odd non-sequitur after "No anti-patterns." Reworded the whole clean ack to say what it means: a clean scan only clears the deterministic rule set, not overall design quality, so keep following the design system and skill guidance. Now: "Design hook scanned X. No deterministic design-quality issues found. That does not mean the design is good: keep following the project design system and the impeccable skill guidance." 2. Directive footer. It still told the agent "Do not add source comments such as `impeccable: ignore`; those pollute the code and do not suppress hook findings." That is now misleading: the hook runs the same detector engine as the CLI, which honors inline `impeccable-disable` waivers, so they DO suppress hook findings (consistent with config ignores, which filterFindings already honors). Reworded to: don't silence a real finding to skip fixing it; suppress only after the user confirms intent; prefer a config ignore, and reach for an inline `impeccable-disable <rule>` comment only when the waiver must travel with a file that leaves the repo. Added a hook test asserting an inline `impeccable-disable-line` comment makes the hook scan the file clean (locks in the cross-cutting behavior), and updated the clean-ack / footer assertions to the new wording. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Address review on inline-ignores parser - Case-insensitive fast-path bail-out (Cursor): the cheap substring guard was lowercase-only while DIRECTIVE_RE has the `i` flag, so a mixed-case marker like `Impeccable-Disable` skipped parsing entirely and never suppressed. Switched the guard to `/impeccable-disable/i.test(...)`. Added a regression test. - Removed the unreachable `-->` branch from TRAILING_CLOSER_RE (Greptile): `--+>` already matches `-->` and any longer dash run. - Replaced the always-truthy lazy-match + `if (sep)` reason strip with an explicit first-separator slice (Greptile): clearer and drops the dead branch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Align inline-ignore line numbering with the detector (CRLF/CR endings) parseInlineIgnores split lines with /\r\n|\r|\n/, but detectText numbers lines with split('\n'). On classic `\r`-only endings the two diverged, so a disable-line / disable-next-line directive could key a different line than the finding it should waive (Cursor review). Split on '\n' only, matching the detector exactly; the directive regex already excludes '\r', so a trailing '\r' on CRLF files is never captured into the rule list. Added a CRLF regression test through the real detectText. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- 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 |