with one click
visual-lint
Screenshot UI defect lint
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Screenshot UI defect lint
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Create a GitHub PR for completed work, then run coderabbit-resolver through review, CI, merge, and cleanup. Use when: the user asks for PR creation followed by CodeRabbit resolution. Keywords: create PR, CodeRabbit, merge.
Secure pnpm GitHub Actions CI
Live onboarding tour of newly implemented code. Combines /deep-trace, the vscode-debug-mcp bridge, and playwright-cli to run the target app in a debug session, drive the UI, pause at curated breakpoints inside the new code, and narrate "this modal is the newly created one" โ mapping every UI moment to the exact file:line. Use when the user wants to understand where and how AI-written feature code executes in the running application ("ใฉใฎ UI / ใฉใฎใญใธใใฏใงๅใใฎใๅใใใชใ", "ใชใณใใผใใฃใณใฐใใฆ", "/feature-tour").
Debug Claude Code plugins
Record a web or Electron-renderer flow as an annotated video with playwright-cli, then extract frames to confirm how it actually looks. Use when the user points at a flow to capture โ "record that part", "ใใใใฎ้จๅ", "ใใฎไธ้ฃใฎๅไฝ", "ๅไฝ็ขบ่ชใใฆ้ฒ็ปใใฆ", QA-ing a screen's motion/behavior, or proving a web / Electron-renderer interaction works on video. For analyzing a clip you were handed or generic cross-surface motion verification, use the `video` skill; for native macOS chrome (menu / tray / dock / traffic-lights) use computer-use โ playwright cannot see those.
Refresh Chromium-based browsers by backing up profile/cache data, guiding a clean reinstall, and restoring bookmarks only. Use when Chrome, Chrome Canary, Edge, Brave, Arc, Dia, or another Chromium browser has browser-specific corruption, black screens, Meet/video issues, bad flags, GPU/WebGL cache problems, or profile-state bugs.
| name | visual-lint |
| version | 0.1.1 |
| description | Screenshot UI defect lint |
| allowed-tools | ["Bash","Read","Write","Glob","Grep","AskUserQuestion","Agent"] |
When running this skill in Codex, translate Claude Code-only primitives before acting: AskUserQuestion -> chat/request_user_input, TodoWrite -> update_plan, Task/TaskCreate/TeamCreate/SendMessage -> spawn_agent/send_input/wait_agent when available and allowed, and EnterPlanMode/ExitPlanMode -> a concise chat plan plus explicit approval.
Resolve Read/Write/Bash/WebSearch/WebFetch to Codex file/shell/web tools, and map ~/.claude/... paths to ~/.agents/... or ~/.codex/... unless the task explicitly targets Claude Code. The Agent-launched web-designer adjudicator maps to a Codex sub-agent spawn; if unavailable, run the rubric inline (lightweight mode).
When running this skill in Cursor Agent, translate Claude Code-only primitives before acting: AskUserQuestion -> AskQuestion; TodoWrite -> Cursor TodoWrite or an equivalent checklist; Task/Agent sub-agent flows -> Cursor Task (subagents), parallel Tasks, or run_in_background when allowed; EnterPlanMode/ExitPlanMode -> Plan mode (SwitchMode / CreatePlan) plus explicit user approval.
Resolve Read/Write/Bash/web/search/MCP via Cursor Composer or Agent equivalents. MCP names written as mcp__server__tool typically map to call_mcp_tool. Map ~/.claude/... to ~/.cursor/skills/ unless the task explicitly targets Claude Code.
Screenshot a running app, run a structured defect rubric over the rendered pixels, and produce a findings report with cited evidence. Fixing is out of scope โ this skill reports. Hand the report to a session that owns the source if the user wants the issues fixed.
lint and typecheck catch code-level problems the instant you save. But a whole
class of bugs lives only in rendered pixels and is invisible to every static
tool:
83% / 15px wraps onto two lines because a fixed-width span
(w-14=56px) is narrower than its ~75px content. The code is type-correct and
lint-clean โ the breakage exists only on screen. (This skill's calibration fixture:
references/fixtures/opacity-blur-wrap.png.)Today these get fixed only when a human notices and points them out. This skill codifies that human "that looks broken" judgment into a repeatable rubric so a model can catch it the way ESLint catches an unused variable.
Why VLM judgment, not a visual-regression tool: every mainstream visual-testing
tool (Applitools, Percy, Chromatic, Playwright toHaveScreenshot) is a
baseline-required regression detector โ it diffs against a saved golden image and
therefore cannot flag a first-occurrence bug. The goal here is to catch new
breakage with no baseline, which only spec-driven geometry or vision-language-model
judgment can do. v1 uses VLM judgment.
Where it sits among sibling skills:
| Skill | Question it answers |
|---|---|
| Functional QA | Does it function? (clicks work, IPC fires, state persists) |
/design-review | Is it aesthetically good? (hierarchy, polish, AI-slop) โ and it fixes |
/visual-lint | Is the render broken? (wrap, overflow, overlap, misalign) โ read-only |
In scope (v1, pure-VLM): detecting display defects in the rendered pixels of a running app โ unintended wrapping, truncation/clipping, element overlap, containment overflow, gross misalignment, off-grid spacing, broken/missing assets, contrast and target-size problems, theme/mode bleed, and state-dependent breakage (modal, hover, context menu, drag, scroll).
Out of scope:
/design-review.getComputedStyle/getBoundingClientRect + axe-core + token-diff pre-pass that
feeds the VLM bounded confirm/reject questions). v1 does not build that layer;
for measurable claims the rubric reports "borderline โ needs measurement", never a
fabricated number.This skill MUST NOT:
git commit, git add, or any state-changing VCS command,It MAY only: read source, drive the running app via playwright-cli, capture
screenshots, and write a single report file under ./visual-lint-reports/.
allowed-tools deliberately omits Edit to enforce this at the tool layer. If a user
wants fixes, this skill's output is the input to a separate fixing session.
Gather these; if any is missing and not inferable, ask once via AskUserQuestion:
playwright-cli. Default assumption:
an Electron app exposing CDP on http://localhost:9222 (the skills-desktop
convention: pnpm dev exposes it). For a web app, a URL + a browser context../DESIGN.md in the target project. If present,
project-aware mode activates (see references/design-system-criteria.md); if
absent, fall back to the generic rubric. Do not ask โ detect.Adjudication needs a vision-capable agent that reads the screenshots and applies the rubric. Two modes:
web-designer subagent. Launch via the Agent tool
(subagent_type: web-designer). It owns capture + judgment end-to-end, reading this
skill's references/. Use it for a full pass: a professional design eye applies the
DESIGN.md criteria most faithfully. This is the user's stated default.--lightweight โ inline. The main Claude agent runs the same rubric itself
(Claude is vision-capable; this was proven to catch the calibration fixture cleanly).
No subagent spawn โ faster and cheaper. Use for a quick single-screen check, when
iterating, or when subagent overhead isn't worth it.Same rubric, same report either way. If the user passes --lightweight, run inline;
otherwise default to web-designer. (If the per-run subagent cost proves not worth it
in practice, flipping the default to inline needs no code change.)
playwright-cli list; detach/kill-all if wedged.kill-port 9222 if a prior pnpm dev died unclean, then pnpm dev.playwright-cli attach --cdp=http://localhost:9222. All later commands use
--s=default../DESIGN.md; note project-aware vs generic mode in the report header.Derive the list of UI states to capture per references/ui-state-coverage.md:
the always-on default-state full-window pass plus the five operation-path states
(modal / context-menu / drag / scroll / hover) where reachable. Output a short
per-screen state plan table before capturing so the run is auditable.
For each planned state, capture a full-window screenshot via playwright-cli. Capture
resolution caveat: playwright-cli hardcodes scale: 'css', so the PNG is 1ร CSS
resolution (~1400ร941 on this app), not the 2ร device pixels of a DPR-2 render โ
window.devicePixelRatio reports 2 but that does not change the captured file. For
dense or borderline regions, take an element-scoped or CSS-zoom crop (see Capture
recipes below) and re-judge from that. Re-snapshot after any DOM-mutating action โ
eN refs are valid only for the latest snapshot. Save shots under the report's
screenshots/ dir.
Apply, in this order, against every screenshot:
references/anti-false-positive.md โ the process rules that bound the judgment
(describe-before-judge, cite-or-drop, enumeration-not-quota, low-confidence โ
question, adversarial self-check). Read this first; it governs everything.references/defect-rubric.md โ categories AโF. Each item is a direct verification
prompt. Every finding uses the 4+1 scaffold: element ยท defect ยท expected_vs_actual ยท severity ยท confidence.references/design-system-criteria.md โ in project-aware mode, fold the DESIGN.md
tokens in as perceptual checks (e.g. status-green must survive the neutral theme;
no shadow on resting cards). In generic mode, skip the project-specific rows.Emit templates/visual-lint-report.md to
./visual-lint-reports/{YYYYMMDD}-{scope}.md (screenshots in a sibling
screenshots/ dir). Group findings by severity. End with the read-only footer.
Then detach: playwright-cli --s=default detach (does not close the app).
Electron (primary โ skills-desktop CDP :9222):
playwright-cli list # check for stale sessions
playwright-cli attach --cdp=http://localhost:9222 # attach once per run
playwright-cli --s=default snapshot # a11y tree with eN refs
playwright-cli --s=default screenshot --filename=./visual-lint-reports/<run>/screenshots/<state>.png
playwright-cli --s=default click e5 # interact by ref from latest snapshot
playwright-cli --s=default fill e3 "text"
playwright-cli --s=default press Escape
playwright-cli --s=default eval 'window.devicePixelRatio' # reports 2, but PNG stays 1ร CSS (scale:css hardcoded) โ NOT a resolution check
playwright-cli --s=default detach # leaves the app running
Web app (documented alternate): open a browser context to the URL instead of CDP attach; the screenshot/snapshot/interact verbs are otherwise identical. The rubric and report are capture-method-agnostic.
Two worked-example bugs anchor the rubric, each paired with an .expected.md target:
references/fixtures/opacity-blur-wrap.png โ the wrapping anchor: the
83% / 15px readout wraps onto two lines (severity 2, high confidence, citing both
lines; rubric A1/A7, home B).references/fixtures/symlink-health-clip.png โ the clipping anchor: the large
100% value in the "Symlink Health" card is sliced at the card's top content edge
(severity 2โ3, high confidence, citing the 100% value; rubric A3, home B1/B3).When you change this skill's rubric, run it once against both PNGs and confirm
each still emits its expected finding. A rubric edit that stops catching either fixture
is a regression โ fix it before shipping. This is a construction-time anchor; normal
/visual-lint runs do not re-run it.
./DESIGN.md detection resolved (project-aware vs generic noted in report)../visual-lint-reports/; no source edits, no commits.references/defect-rubric.md โ what to look for (categories AโF + finding scaffold).references/anti-false-positive.md โ how to judge without hallucinating (read first).references/ui-state-coverage.md โ which states to capture (default + 5 op paths).references/design-system-criteria.md โ DESIGN.md tokens as perceptual checks.references/fixtures/opacity-blur-wrap.{png,expected.md} โ wrapping calibration anchor.references/fixtures/symlink-health-clip.{png,expected.md} โ clipping calibration anchor.templates/visual-lint-report.md โ the read-only report skeleton.