agentsclimarketplace

Visual debug

Skill voidmatcha/ui-clone-skills/skills/visual-debug

Compare original site vs implementation with automated AE/SSIM diff — near-zero vision tokens. Triggers on "it looks different", "doesn't match", "compare with original", "what's wrong", "why is the impl off", "diff against ref", "verify the clone". Uses auto-diagnose to find mismatched elements from diff images without vision tokens. Falls back to reading diff images only when auto-diagnose finds nothing.From its SKILL.md

Install
npx -y skills add voidmatcha/ui-clone-skills --skill visual-debug

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • 6 stars6 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
  • runs commandsInstructs the agent to run 8 commands, including `agent-browser --session <s> eval "<script>" > tmp/ref/<name>.json` and 7 more.

SKILL.md

27.1 KB, ~6.7k tokens by cl100k_base, as published. Nobody here has run it

Visual Debug

Automated visual comparison — original vs implementation. Zero vision tokens via AE/SSIM CLI tools.

When to use

  • After implementing a section, before declaring "done"
  • When user says "it's different", "doesn't match"
  • During ui-reverse-engineering Phase C
  • Instead of Read-ing screenshots for comparison

HARD RULE: Never Read ref/impl images for comparison. For FAIL positions, use auto-diagnose.sh first (zero vision tokens). Only Read diff images as fallback if auto-diagnose finds nothing. Exception: Phase E reads ref+impl pairs — and Phase E must run inside an Agent subagent so its 44K vision tokens stay out of the main context (see Phase E section).

Browser cleanup rule (MANDATORY at end of every run): agent-browser --session <name> close for each session you opened. Never close --all — other Claude sessions may own active browsers. The detailed section near the end of this file may be clipped after auto-compaction; this one-liner is the survival copy.

Token rule

Pipe large eval output to a file, then Read only what you need:

agent-browser --session <s> eval "<script>" > tmp/ref/<name>.json

Never let large JSON print to stdout — it wastes tokens.

Dependencies — preflight (run once per session)

npx skills add installs the SKILL files but skips system tooling. Run this check at session start; if anything is missing, halt and surface the bootstrap one-liner to the user (do not auto-execute curl | bash on their behalf).

miss=""
for c in agent-browser ffmpeg dssim; do command -v "$c" >/dev/null 2>&1 || miss+=" $c"; done
{ command -v magick >/dev/null 2>&1 || command -v convert >/dev/null 2>&1; } || miss+=" imagemagick"
if [ -n "$miss" ]; then
  printf 'Missing system deps:%s\n\nFastest fix:\n  curl -LsSf https://raw.githubusercontent.com/voidmatcha/ui-clone-skills/main/install.sh | bash\n\nOr install manually:\n  brew install ffmpeg imagemagick dssim   # macOS  (Linux: apt install ffmpeg imagemagick && cargo install dssim)\n  npm i -g agent-browser\n' "$miss"
  exit 1
fi

Scripts

SCRIPTS_DIR="${CLAUDE_PLUGIN_ROOT:+$CLAUDE_PLUGIN_ROOT/skills/visual-debug/scripts}"
# -L follows symlinks (~/.claude/skills/visual-debug is often a symlink to a real path).
SCRIPTS_DIR="${SCRIPTS_DIR:-$(find -L ~/.claude/skills -name 'ae-compare.sh' -exec dirname {} \; 2>/dev/null | head -1)}"
ScriptPurpose
computed-diff.sh <session> <orig> <impl> <sel...>Run first — getComputedStyle comparison. Catches fontWeight/display/height root causes before pixel diff
batch-scroll.sh <orig> <impl> <session> [dir]Captures both at 0–100% scroll positions
ae-compare.sh <ref.png> <impl.png> [diff.png]AE comparison → `AE=<n> STATUS=PASS
batch-compare.sh <dir> [threshold]Compare all pairs. Supports dynamic thresholds
dssim-compare.sh <dir> [threshold]Structural similarity (catches what AE misses)
layout-diff.sh <session> <orig> <impl>Section bounding box comparison
section-compare.sh <orig> <impl> <session> <dir>Section-level comparison — crops each section, AE + structure diff. Catches SVG-as-text, layout mismatches. <dir> is required — pass "$(pwd)/tmp/ref/<component>"
auto-diagnose.sh <session> <orig> <impl> <diff.png>Auto-find mismatched elements from AE diff image → elementFromPoint → computed-diff with severity
layout-health-check.sh <session> <orig> <impl> <dir>Section height/total height structural check before pixel diff
stray-absolute-check.sh <session> <impl-url> [w] [h]Catches the "footer disappeared" bug class — flags position: absolute elements with no positioned ancestor (offset resolves against <body>). Single URL, no ref needed. See diagnosis.md → Root Cause H.
breakpoint-collision-check.sh <session> <impl-url> [bps]Catches the "broken at exactly 768" bug class — captures impl at every Tailwind boundary ±1 (default 640/768/1024/1280/1536) and flags widths where matchMedia(max-width) and matchMedia(min-width) both match, body overflows in isolation, or root font-size jitters. Single URL, no ref needed. Set REF_DIR=... env to write responsive/boundary-collisions.json for the boundary gate. See diagnosis.md → Root Cause J.
font-parity-check.sh <session> <ref-url> <impl-url> <ref-dir>Gates the asset-substitution decision — extracts primary font-family from both ref and impl, writes <ref-dir>/font-parity.json. The font-parity gate enforces: parity:match → PASS; parity:mismatch → must be declared in asset-substitution.json. Catches the "100% sections FAIL forever" bug when commercial fonts are silently substituted. See ui-reverse-engineering/asset-substitution.md.
paid-features-detect.sh <ref-dir>Early-detects paid font dependencies BEFORE generation — static-greps <ref-dir>/bundles/, css/, fonts.json, head.json, external-sdks.json for paid font CDN hosts (Adobe Typekit, Monotype, Hoefler, Linotype, FONTPLUS / TypeSquare in Japan). Writes <ref-dir>/paid-features.json with decision: null for each finding. The paid-features gate (between bundle and spec) refuses to pass until every entry has decision set to one of use / substitute / skip. Catches the "100% sections FAIL forever" bug class when a paid web font silently falls back to the default sans-serif at impl time. Note: GSAP plugins are no longer flagged — GSAP became 100% free (including all previously-paid Club plugins) following the Webflow acquisition.
reveal-trigger-check.sh <session> <impl-url> [w] [h]Catches the "stuck reveal" bug class — enumerates initially-hidden elements (opacity 0 / non-identity transform), scrolls each into view, fails any whose style never advances. Reports parent-chain with overflow: hidden ancestors so the IO+overflow:hidden bug class (took 12 iterations to find on 375.studio) is named on first run. See ui-reverse-engineering/transition-implementation.md → IntersectionObserver placement for masked reveals.
transition-spec-coverage.sh <component-dir> <impl-src-dir>Static gate: every spec entry has an impl artifact. Parses transition-spec.json, greps the impl source for each entry's id / selector / type-derived hooks (RevealRise, useScrollTrigger, useScroll, etc.), FAILs if any entry has zero hits. Catches the "hover transitions matched while intersection entries were never wired" failure class.
transition-compare.sh <orig> <impl> <session> [dir]Transition comparison — idle/hover screenshots + computedStyle + timing diff per element
tree-diff.sh <session> <orig> <impl> [dir]Exhaustive per-element CSS diff — walks every visible impl element (≥ MIN_SIZE px), pairs with ref via elementFromPoint, runs computed-style diff per pair. Catches mismatches AE misses (wrong font that renders identically, same-box different-style).
layout-tree-diff.sh <session> <orig> <impl> [dir]Geometry diff via signature-based pairing — pairs impl ↔ ref by stable signature (text + tag + class hash + size class), reports geometry deltas (top/left/w/h) regardless of where elements moved. Catches what tree-diff misses (right element, wrong position).
hover-tree-diff.sh <session> <orig> <impl> [dir]Per-element hover/transition diff — for each hover-capable element pair, captures idle → CDP :hover → settled style. Diffs timing (property/duration/easing/delay) + idle→hover delta. Catches missing hover rules, wrong easing, different deltas.
keyframes-diff.sh <session> <orig> <impl> [dir]@keyframes declaration diff — extracts all keyframe rules from both pages, reports keyframes only on one side and same-name rules with different steps. Catches missing entrance animations, wrong timing curves baked into keyframes.
scroll-anim-temporal-diff.sh <session> <ref> <impl> <selector> [dir]Phase/frequency diff for scroll-driven repeating animations — samples each matched element's position at N scroll progress steps on both sides, classifies as single-frequency (traveling wave) vs per-row-frequency vs mixed. Catches the "wave family wrong" bug class that AE/SSIM can't see (animation pixels match in any frozen frame, perceived motion is completely different). Advisory only — no gate. Run manually when the impl "feels off" on scroll for repeating elements; the selector arg is required so it can't be auto-invoked.

Reference selectors: common-selectors.md — ready-to-use selector sets (typography, CSS reset canaries, Tailwind preflight issues, Naver.com specific, general e-commerce)

Cost ladder — cheapest detection first

The diff tools below have a 100x cost spread (sub-second to multi-minute, plus token cost when their output gets read). The most common avoidable waste is jumping to L3/L4 when an L1/L2 check would have answered the same question. Always start at L1 and stop as soon as a tier gives you the answer.

TierCostWhatUse when
L1≤1s, ~freeRead existing summary files: tmp/ref/<c>/sections/result.txt, pipeline-state.json, _summary.json, pixel-perfect-diff.jsonA prior run already produced these — they answer "what FAILed" in 2KB instead of you re-reading 50KB per section
L2≤5s, 1 page loadStructural checks: stray-absolute-check.sh, transition-spec-coverage.sh, reveal-trigger-check.sh, layout-health-check.sh, computed-diff.shVerifying transitions, checking for whole-class bugs (footer disappeared, reveal stuck, spec entry never wired)
L330–120sTargeted runs: auto-diagnose.sh on a single FAIL diff.png, computed-diff.sh on a narrow selector listBug class is suspected universal — sample one before sweeping all
L4multi-minuteFull sweeps: full-page section-compare.sh, transition-compare.sh, tree-diff.sh, hover-tree-diff.shL1–L3 came back clean and you need exhaustive coverage
L5minutes + tokensSubagent visual review (Phase E LLM gate)All metric tools agree but you need semantic verification

Read-summary-first rule (L1 specifics): scripts that write per-section/per-element detail also write a summary. Read the summary, then drill into detail files only for entries marked FAIL.

ScriptSummary (read first)Detail (drill on FAIL only)
section-compare.sh<dir>/sections/result.txt (~2KB)<dir>/sections/<name>.json (~50KB each)
transition-compare.sh<dir>/transitions/report.json (per-element verdicts)<dir>/transitions/{ref,impl}-elements.json, hover-states.json
tree-diff.sh / layout-tree-diff.sh / hover-tree-diff.sh / keyframes-diff.shseverity-sorted markdown (<dir>/<script-name>.md)paired <dir>/<script-name>.json raw diff list
Pipeline gatespython -m ui_clone.pipeline ... statusindividual gate artifacts

Reading a 50KB per-section JSON when result.txt would have answered the question is the single most common token waste in this workflow. If you don't see a summary file, that's a sign no run has been done yet — go to L2/L3, don't manually grep raw artifacts.

Pick the right diff tool

Five computed-style/geometry diff tools exist; each answers a different question. Run the targeted tool first, then escalate if the answer is "nothing wrong" but AE still fails.

QuestionToolScopeCost
Are CSS resets / structural canaries OK? (entry-point sanity)computed-diff.shSelector list you provideCheap — first call always
Did every transition-spec entry get wired into impl code at all?transition-spec-coverage.shAll entries in transition-spec.json vs grep of impl sourceCheap — first call when verifying transitions
Hidden-init elements (opacity 0, transform offset) — do they ever trigger?reveal-trigger-check.shEvery initially-hidden element on the impl pageCheap — second call when verifying transitions
AE failed; which element on the diff image is wrong?auto-diagnose.shHotspots in the AE diff imageCheap — second call
AE keeps failing but auto-diagnose found nothing — wrong style on visually-similar rendertree-diff.shEvery visible element (≥ MIN_SIZE), paired by elementFromPointMed
Element is in the right place style-wise but at the wrong positionlayout-tree-diff.shEvery element, paired by signature (text+tag+class hash+size class) — robust to reflowMed
Hover / transition feels off (wrong easing, missing rule, different delta)hover-tree-diff.shEvery hover-capable pair, idle → CDP :hover → settledHigh — many state captures
Entrance / scroll animation timing is subtly offkeyframes-diff.shAll @keyframes declarations from both pagesLow — declarations only
Scroll-driven repeating animation "feels off" — irregular gaps where ref shows smooth interlock, or vice versascroll-anim-temporal-diff.shPer-element trajectory across N scroll progress samples (you provide the selector for the repeating set)Med — N viewport scrolls × 2 sites

Heuristics:

  • tree-diff and layout-tree-diff are siblings, not redundant — first asks "is the style right on this element?", second asks "is this element in the right place?". Run tree-diff first; if it's clean and AE still fails, run layout-tree-diff.
  • transition-compare.sh is the predefined-set hover gate (Step 8c of ui-reverse-engineering); hover-tree-diff.sh is the exhaustive escalation. Use hover-tree-diff only when transition-compare reports PASS but the impl still feels wrong.
  • transition-spec-coverage.sh and reveal-trigger-check.sh are the first two transition gates, not escalations — run them before transition-compare.sh. Coverage catches "entry never wired", reveal-trigger catches "wired but stuck". transition-compare.sh only verifies idle→hover diffs, so it can pass while intersection/scroll-driven entries are completely broken.
  • Don't run all five by default — they are slower and noisier than the standard auto-diagnose workflow.

Workflow

Step 0-pre: pass the chrome-hidden impl URL to every script

Before running ANY compare script (stray-absolute-check, section-compare, transition-compare, batch-compare, auto-diagnose), confirm the impl shell is not painting fixed-position chrome that the ref doesn't have — dev banners, attribution / "made with X" badges, Vite/Next dev-overlay buttons, devtools widgets, locale switchers, env labels. Any element with position: fixed and a non-trivial bounding box will dominate AE in its corner every frame, turning a passing clone into FAIL while the diff image points at the chrome — not at any code you wrote.

Quick scan:

agent-browser --session <s> open <impl-url>
agent-browser --session <s> wait 1500   # let chrome (dev banners, badges) mount
agent-browser --session <s> eval "
(() => {
  const fixed = [...document.querySelectorAll('*')].filter(el => {
    const st = getComputedStyle(el);
    if (st.position !== 'fixed') return false;
    const r = el.getBoundingClientRect();
    return r.width >= 40 && r.height >= 20;
  }).map(el => ({ tag: el.tagName.toLowerCase(), id: el.id, cls: (el.className && el.className.toString) ? el.className.toString().slice(0,80) : '', w: el.getBoundingClientRect().width|0, h: el.getBoundingClientRect().height|0 }));
  return JSON.stringify(fixed);
})()
" > tmp/fixed-scan.json

Pipe to a file (per the token rule) — chrome scans are small but writing through Read keeps the pattern uniform.

If the scan returns elements that don't exist on the ref, the impl needs a hide-mechanism (query flag like ?embed=true, env var like NEXT_PUBLIC_HIDE_CHROME=1, dev-only NODE_ENV guard, CSS display:none injected via a fixture stylesheet). Standardize on one and pass the hidden URL to every script. Document the flag in the impl repo's CLAUDE.md so it survives compaction.

Failure signature when you forget: AE delta image shows a clean rectangular hotspot in one corner (top-right, bottom-right, etc.); auto-diagnose.sh reports the badge element as the only mismatch; section-compare passes for every section except the one that includes the chrome's vertical band. Fix is a query-flag swap, not a code change — verify before opening any source file.

Step 0: structural checks FIRST (before AE)

Always run structural checks before pixel comparison. AE catches that something is wrong; structural checks catch why — and fix the root cause immediately without hunting through diff images.

SCRIPTS="$SCRIPTS_DIR"

# 0a. Stray absolute positioning — catches the "footer disappeared" bug class.
#     Run on EVERY viewport you care about; the bug often only manifests on shorter pages.
bash "$SCRIPTS/stray-absolute-check.sh" <session>-stray <impl> 375 812
bash "$SCRIPTS/stray-absolute-check.sh" <session>-stray <impl> 1280 800

# 0a-bis. Stuck reveals — catches the IO+overflow:hidden bug class. Mandatory if
#         the spec has any `intersection`/`inview` trigger entries.
bash "$SCRIPTS/reveal-trigger-check.sh" <session>-reveal <impl> 1280 800

# 0a-quater. Breakpoint collision — catches the "broken at exactly 768" bug class.
#            Mandatory whenever impl mixes Tailwind responsive utilities AND a
#            project-scoped @media (max-width: <bp>px) rule (root font-size,
#            container padding, mobile-only stack). One run sweeps every Tailwind
#            boundary ±1; cheap (single page load, ~15 viewport sets).
bash "$SCRIPTS/breakpoint-collision-check.sh" <session>-bp <impl>

# 0a-ter. Spec coverage — every transition-spec entry must have an impl artifact.
#         Mandatory before per-trigger verification (transition-compare etc.) so
#         entirely-missing entries are caught BEFORE you waste a hover sweep.
bash "$SCRIPTS/transition-spec-coverage.sh" tmp/ref/<component> <impl-src-dir>

# 0b. Broad sweep: CSS reset canaries + page structure
bash "$SCRIPTS/computed-diff.sh" <session> <orig> <impl> \
  "h1" "h2" "h3" "h4" \
  "img" "button" "a" \
  "body" "header" "main" "footer"

# 0c. Domain-specific selectors from common-selectors.md
# IGNORE_FONT_SIZE=1 to skip OS text-scaling false positives
IGNORE_FONT_SIZE=1 bash "$SCRIPTS/computed-diff.sh" <session> <orig> <impl> \
  "[class*=title]" "[class*=logo]" "[class*=search]" "[class*=nav]"

See common-selectors.md for ready-to-use selector sets by domain.

Full-page comparison (broad sweep)

0. Structural    stray-absolute-check.sh + computed-diff.sh (CSS reset canaries + page structure)
1. Capture        batch-scroll.sh <orig> <impl> <session>
2. AE diff        batch-compare.sh <dir>
3. DSSIM          dssim-compare.sh <dir>
4. Diagnose       auto-diagnose.sh <session> <orig> <impl> <diff.png>
                  → auto-finds mismatched elements, runs computed-diff with severity
                  → zero vision tokens. Only Read diff image if auto-diagnose finds nothing.
5. Fix            Targeted code change (critical severity first)
6. Re-compare     Repeat 0–3
7. LLM review     Read ref+impl pairs for ALL positions (Phase E)
8. Gate           All axes PASS → DONE

Section-level comparison (precise — preferred for post-gen verification)

0. Structural    stray-absolute-check.sh + computed-diff.sh (CSS reset + section selectors)
1. Section compare  section-compare.sh <orig> <impl> <session> "$(pwd)/tmp/ref/<component>"
   → Per-section AE + severity (critical/major/minor) + structure diff
   ⚠️  The 4th argument (ref dir path) is MANDATORY — the Stop gate reads result.txt from that
       exact path. Omitting it writes result.txt to the wrong location and the gate never clears.
2. Transition compare  transition-compare.sh <orig> <impl> <session>
   → Per-element idle/hover style + timing diff
3. Diagnose     For FAIL sections: auto-diagnose.sh <session> <orig> <impl> <diff.png>
                → auto-finds mismatched elements within that section (zero vision tokens)
4. Fix          Targeted code change (critical severity first, then major, skip minor until Phase E)
5. Re-compare   Repeat 0–2
6. Gate         All sections PASS + all transitions PASS → DONE

Use section-level for ui-reverse-engineering Step 8b/8c. Use full-page for standalone /visual-debug invocations.

Escalation diagnostics (when the standard workflow misses the bug)

The standard workflow (AE + DSSIM + auto-diagnose.sh + computed-diff.sh) catches most mismatches. When AE keeps reporting failures but auto-diagnose returns clean — escalate to the tree-diff family. These walk every element on the page rather than a fixed selector list, so they catch what targeted diagnostics miss.

SymptomEscalate toWhy
AE fails repeatedly but auto-diagnose finds nothingtree-diff.shExhaustive computed-style diff — pairs every visible impl element with ref via elementFromPoint. Catches wrong fonts that render identically, same-box different-style overrides.
Element appears at wrong position but tree-diff says style matcheslayout-tree-diff.shGeometry diff via signature-based pairing — pairs by stable signature (text + tag + class hash + size class), reports top/left/w/h deltas regardless of where the element moved on screen.
Hover/transition feels off but transition-compare.sh reports PASShover-tree-diff.shPer-element CDP :hover capture for every hover-capable pair (not just the predefined set). Diffs idle→hover delta + timing.
Entrance/scroll animation runs but timing or curve is subtly differentkeyframes-diff.shDiffs @keyframes declarations directly. Catches missing rules, wrong steps, wrong easing baked into the keyframe definition rather than the animation shorthand.
bash "$SCRIPTS/tree-diff.sh"        <session> <orig> <impl>   # full-element style diff
bash "$SCRIPTS/layout-tree-diff.sh" <session> <orig> <impl>   # geometry deltas
bash "$SCRIPTS/hover-tree-diff.sh"  <session> <orig> <impl>   # hover style + timing
bash "$SCRIPTS/keyframes-diff.sh"   <session> <orig> <impl>   # @keyframes declarations

These are diagnostic, not gate-blocking. Use them when section-compare / transition-compare keep failing without a clear cause — they produce a markdown report (severity-sorted) that names the culprit elements and properties. Do not run all four by default — they are slower and more expensive than the standard workflow.

Three-axis verification (ALL required)

AxisToolCatchesBlind spot
PixelAEExact rendering diffLottie frame differences (false positive)
PerceptualDSSIMColor/tone mismatchMissing content on same-color bg
SemanticLLM (Phase E)Missing sections, wrong contentSlow, costs tokens

A position is PASS only when all three agree (or LLM explicitly approves a known difference).

Phase E: LLM Review (MANDATORY)

NOTE: Quick comparison (Phases A-D) uses zero vision tokens via AE/SSIM diff. Phase E (LLM verification) is mandatory for full verification workflow and DOES use vision tokens for the final review.

After AE + DSSIM, read every position's ref+impl pair. Judge PASS / PARTIAL / FAIL. Not optional — automated metrics can silently pass wrong results. ~44K tokens.

Always delegate Phase E to a subagent (Agent tool, subagent_type: "general-purpose"). The 44K vision tokens stay in the subagent context — only the verdict table (~500 tokens) returns. See comparison-fix.md Phase E section for the exact invocation.

Thresholds

MetricPassFail
AE per image≤ 500> 500
SSIM per frame≥ 0.995< 0.995
Computed style diff0 mismatches> 0

AE=500 allows anti-aliasing variance. Bump to 2000 for dynamic content.

Dynamic content (canvas/video) — EXCLUDE_DYNAMIC=1

RAF-driven canvases (Three.js shaders, particle fields) and <video> elements run on independent clocks in ref vs impl, so their per-frame pixel diff is unmatchable — they dominate AE without indicating a real defect.

section-compare.sh accepts an opt-in mask:

EXCLUDE_DYNAMIC=1 bash section-compare.sh <orig> <impl> <session> "$(pwd)/tmp/ref/<component>"

When set, the script injects visibility: hidden !important for the masked selectors into both ref and impl screenshots — identical hide rule on both sides, so layout is preserved while the noisy region drops out of AE.

VarDefaultEffect
EXCLUDE_DYNAMIC01 enables masking
DYNAMIC_SELECTORScanvas, videoOverride the default mask list
transition-spec.json entries with "dynamic": trueAuto-augment the mask list with each entry's target selector

Spec-driven (recommended): add "dynamic": true to every transition-spec.json entry whose visual is RAF-driven (auto-timer canvas, looping shader, <video> autoplay). Then EXCLUDE_DYNAMIC=1 masks them all without enumerating selectors at the call site.

Selector caveat: Selectors must not contain quote characters of either kind. " would close the injected JS string and ' would close the surrounding Python r-string. Use bare attribute matchers (e.g. [data-canvas=hero]) or class/id selectors (e.g. .canvas-hero, #hero-canvas). The script aborts if it sees " or '.

Full verification

  • verification.md — Phase A/B (capture) + D (pixel-perfect gate) + auxiliary checks
  • comparison-fix.md — Phase C (AE+DSSIM comparison, computed-style diagnosis, Phase E LLM review, Phase H self-healing loop)

Browser cleanup (MANDATORY)

Every skill run MUST end with browser cleanup — success, failure, or interruption.

# Always close your own session(s) by name
agent-browser --session <session-name> close
  • Close every --session <name> you opened during the comparison
  • Run cleanup before returning control to the user, even on error/early exit
  • Unclosed sessions spawn Chrome Helper processes (GPU + Renderer) that persist indefinitely
  • Never use close --all — other Claude sessions may have active browsers. Only close sessions you own.

Integration

SkillWhere
ui-reverse-engineering Step 8+9Full verification procedure
ui-reverse-engineering Step T4Phase D for transition resting states
ui-capture Phase 4APhase D before compare.html
Standalonebatch-scroll + batch-compare on any two URLs

What ships with it: 26 files

297.3 KB alongside SKILL.md, 21 of them executable

evals/

Gives 0 of the 12 instructions most debug triage skills give in ~6.7k tokens

Counted across 1,020 of the 1,639 authors here whose files we hold, read 2026-09-06

  • Find root cause before attempting any fixin 134 of 1020, across 118 files
  • Create a failing test case before implementing a fixin 109 of 1020, across 95 files
  • Read error messages and stack traces completelyin 102 of 1020, across 88 files
  • Reproduce the issue consistently before investigatingin 90 of 1020, across 77 files
  • Make the smallest possible change to test a hypothesisin 90 of 1020, across 76 files
  • Trace data flow backward to find the sourcein 84 of 1020, across 70 files
  • Form a single hypothesis before testingin 78 of 1020, across 64 files
  • Implement only one fix at a timein 76 of 1020, across 63 files
  • Question the architecture if three fixes failin 73 of 1020, across 59 files
  • Add diagnostic instrumentation at component boundariesin 68 of 1020, across 56 files
  • Compare broken code against working examplesin 68 of 1020, across 57 files
  • Write a regression test before applying the fixin 62 of 1020, across 55 files

Said here and by no other author read

  • Run structural checks before pixel comparison
  • Start at L1 and stop when a tier provides answers
  • Pipe large eval output to a file
  • Read summary files before drilling into detail files
  • Run browser cleanup for each session at end of run
  • Use subagent for Phase E to manage vision tokens

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.