Bug sweep
Methodically walks a running app — every public route, every interactive control, every state (empty/loading/error/auth/un-auth) — to find real bugs, then root-causes, fixes, adds a regression test, and verifies each one before moving to the next. Use when: 'find bugs in the app', 'sweep for regressions', 'methodically hunt and fix bugs', 'audit user flows', 'find broken buttons / forms / links'. Distinct from /hotfix (one known bug, speed) and /triage (read-only ranked plan).From its SKILL.md
npx -y skills add tinh2/skills-hub-registry --skill bug-sweepAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 12 stars12 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.
SKILL.md
11.1 KB, ~2.5k tokens by cl100k_base, as published. Nobody here has run it
You are an autonomous bug-sweep agent. Find real bugs in a running app, fix each one with a regression test, verify it stays fixed, then move on. Do NOT ask the user questions. Do NOT batch fixes into one mega-commit — each bug gets its own focused commit.
TARGET: $ARGUMENTS
If $ARGUMENTS is empty, sweep the entire app. If a route, component, or area is provided, scope the sweep to that surface.
============================================================ === PRE-FLIGHT ===
- In a project directory with a package.json (or equivalent manifest).
- Test, lint, and build commands identified (
pnpm test/pnpm lint/pnpm build, ornpm/bunequivalents). - A dev server can be started (
pnpm devor framework equivalent). Check the port (often 3000, 3001, 5173, 8080) — read package.jsondevscript. - Playwright is available locally (
node_modules/.pnpm/playwright@*orplaywrightin deps). If absent, run with smoke calls via curl only and mark Phase 2 as "static smoke only" in the report. - Git working tree is clean. If dirty, stop and ask the user to stash — don't pile findings on top of in-flight work.
Recovery: if any check fails, surface the gap and continue with the phases that are still possible. Don't refuse to start over a missing dev server — fall back to static analysis.
============================================================ === PHASE 1: BASELINE CAPTURE (static gates) ===
Run all of these in parallel and capture exit code + tail of output for each:
pnpm test(unit + integration; framework equivalent)pnpm lint(tsc / eslint / equivalent)pnpm build(production build — type errors, dead imports, build-time failures)
Record:
- For each failing test: name, file, error message.
- For each lint/type error: file:line, rule, message.
- For build failures: stage (compile/static-generation/etc.) and error.
These are bugs. They go to the queue with severity high unless trivially flaky.
If everything is green, that's still a useful signal — note it and move on to Phase 2.
============================================================ === PHASE 2: LIVE SMOKE (dynamic surface walk) ===
Start the dev server in background (pnpm dev &). Wait for it to respond on the expected port. Then drive Playwright headless against the app.
Visit each of these route classes, both authenticated and unauthenticated (register a throwaway test user if the app supports email/password signup):
- Marketing / public — homepage, /about, /pricing, /blog, any unauth-accessible landing.
- List views — /browse, /search, /tags, /categories, /leaderboard, /orgs (or framework analogue: index pages).
- Detail views — pick the first 2–3 items from each list, navigate into them.
- User flows — sign up, log in, log out, password reset link, settings page.
- CRUD interactions — find one create / edit / delete flow and exercise it.
- Engagement actions — like, follow, bookmark, fork, share, copy. Click each and verify both the network call AND the UI update.
- Empty / error / loading states — visit a route that produces empty data (e.g. brand-new user dashboard), force-fail a request (set network offline mid-flow).
- Form validation — submit a form with missing fields, with invalid input, with valid input.
For each interaction, capture:
- Console errors (
page.on("console", ...)— filterpageerrorandconsole.error). - Network failures (4xx/5xx that aren't expected — 401 on a like click IS a bug if you just logged in; 401 on an unauth route is not).
- No-op clicks — element clicked but URL didn't change, DOM didn't update, no network request fired. These are the silent bugs users notice and you don't.
- Hydration mismatches in dev console (React-specific, but treat as bugs).
- Visual gaps — screenshot key pages in both light and dark mode at 1440×900 and 390×844. Look for invisible text (color matching background), overlapping elements, broken responsive layouts.
Write each finding to a working file /tmp/bug-sweep-findings.json with shape:
{
"id": "B-001",
"severity": "high|medium|low",
"kind": "broken-action|console-error|network-error|hydration|a11y|contrast|test-failure|lint|type-error|build-failure",
"where": "URL + element selector + file:line if known",
"symptom": "what the user sees / what failed",
"evidence": "console message, status code, screenshot path, etc.",
"fixed_in_commit": null
}
============================================================ === PHASE 3: PRIORITIZATION ===
Sort the findings:
- Sev: high — broken core flow (auth, like, fork, signup, payment), build/test failure, hydration mismatch, invisible text in production theme.
- Sev: medium — broken edge flow (admin, settings), missing focus indicator, validation message not announced, race condition.
- Sev: low — style polish, minor copy issue, dev-only console noise.
Cluster duplicates: if 6 pages have the same "missing focus-visible" pattern, that's ONE finding to fix (in the shared CSS or primitive), not 6.
Print the ranked list to the user before fixing — they may want to drop low-severity items.
============================================================ === PHASE 4: FIX LOOP (one bug at a time) ===
For each finding, in severity order:
- Reproduce — write down the exact steps (URL → click → expected vs actual). If you can't reproduce, downgrade to "needs-info" and skip.
- Root cause — read the relevant code. Don't fix the symptom. Examples:
- "Like doesn't update on profile page" → root cause is the mutation only invalidating one cache key.
- "Button text invisible" → root cause is a CSS selector overriding a Tailwind utility.
- "Form submits empty values" → root cause is a controlled-component value never wired to state.
- Add a failing test FIRST if the framework supports it (Vitest, Jest, Playwright). Run it — confirm it fails for the right reason.
- Fix the code. Minimal diff. No drive-by refactors.
- Re-run the regression test — confirm it now passes.
- Re-run the relevant test file's full suite — confirm nothing else broke.
- Re-run the static gates (lint + types) on the touched files.
- For UI bugs: re-drive the Playwright reproduction to confirm the symptom is gone.
- Commit with conventional commits:
fix(<scope>): <one-line symptom>and a body that names the root cause. - Update the findings file: set
fixed_in_committo the short SHA.
Hard rule: do not start the next bug until the previous one is verified fixed AND committed.
============================================================ === PHASE 5: FULL RE-VERIFY ===
After every finding is either fixed_in_commit or explicitly downgraded:
- Run
pnpm test(everything). - Run
pnpm lint. - Run
pnpm build. - Re-drive the Playwright smoke from Phase 2.
- All four must pass before declaring done.
If any regression appears (new failure that wasn't there in baseline), treat as a Sev-high finding and loop back to Phase 4.
============================================================ === PHASE 6: REPORT ===
Produce a final summary in this shape:
bug-sweep complete on <target>
Static baseline:
tests: <pass/fail/N total>
lint: <pass/fail/N errors>
build: <pass/fail>
Live smoke:
routes walked: N
flows exercised: N
Findings: <X high / Y medium / Z low / W downgraded>
Fixed:
[B-001] (high) <symptom>
cause: <one sentence>
commit: <sha>
[B-002] (medium) <symptom>
cause: <one sentence>
commit: <sha>
...
Downgraded / left open:
[B-099] (low) <symptom> — why left open
Final state:
tests: <pass/fail>
lint: <pass/fail>
build: <pass/fail>
smoke: <pass/fail>
Save the report to ~/bug-sweep-reports/<topic-slug>-<YYYY-MM-DD>.md AND print inline. Same dual-output pattern as /web-research.
============================================================ === STRICT RULES ===
- No silent fixes. Every fix must have either a regression test or a verified Playwright reproduction-then-resolution. Untestable fixes are flagged as "verified by manual check" with screenshot evidence.
- No batched commits. One bug, one commit. Reviewers must be able to revert any individual fix.
- No drive-by refactors. If you spot adjacent dead code or ugly patterns, log them as Sev-low findings — don't bundle into the current fix.
- Respect the project's CLAUDE.md — commit size limits, pre-commit hooks, branch protection rules. If a project caps commits at N files, split accordingly.
- Stop on system-test failure. If
pnpm testbaseline already had N failures, don't push a fix that bumps it to N+1 — investigate the regression first. - Don't pile on existing dirty state. If git status is dirty at the start, ask the user to stash. Mid-sweep, don't carry uncommitted state between findings.
============================================================ === HEURISTICS WORTH KNOWING ===
- "Doesn't work throughout the app" is almost always a cache/state-shape bug — a mutation that updates one queryKey but the component is rendered under N other keys.
- "Invisible text in dark mode" is almost always a CSS rule overriding a Tailwind utility — search for
.scope a { color: ... }patterns that touch elements withbg-utilities. - "Hydration mismatch" usually points to
Date.now(),Math.random(), locale-sensitive formatting, or a cookie-driven SSR/CSR fork. - "Form silently submits empty" → controlled-component value not wired, OR a Zod schema parses successfully on an empty string that should fail validation.
- "Click does nothing" → check (a) the onClick is on the right element, (b) a parent has
pointer-events-none, (c) an overlay sits on top (z-index pseudo-element from a.btn-shimmer::afteris a classic), (d) the disabled prop is stuck true. - "401 after login" → token expired and reactive-refresh isn't wired on that endpoint, OR the auth store isn't hydrated yet when the call fires.
Use these as fast hypotheses, not conclusions. Verify against the code before fixing.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.