Your codebase is accumulating AI slop. Now you can measure it.

A free, local-first CLI that scores any repo 0–100 for the mess AI coding tools leave behind — then hands your coding agent a plan to remove it.

$ npx ai-slop-remover scan .
No LLM — deterministic & instant 100% local, zero telemetry 9 languages MIT
ai-slop-remover — real output, scanning browser-use
$ npx ai-slop-remover scan ./browser-use ai-slop-remover · scanned browser-use (362 files, 106.0k lines) in 2.7s Slop Score  74 / 100  (C) Comment Slop         ██████░░░░  681 finding(s)  −15.2 ptsSwallowed Errors     ██░░░░░░░░   54 finding(s)  −4.1 ptsUtility Duplication  ░░░░░░░░░   34 finding(s)  −3.7 ptsCommented Out Code   ░░░░░░░░░   43 finding(s)  −3.0 pts ▲ med  browser_use/actor/element.py:117  Error swallowed silently  Every exception is silently discarded; failures in this block are invisible.  fix: Handle the error: rethrow it, return an error result, or justify ignoring it. 819 finding(s) · Hand them to your coding agent: ai-slop-remover fix
What you get

One command. Everything you need to see the rot.

A Slop Score you can defend

0–100, severity- and confidence-weighted, normalized per 1k lines. Deterministic: same code, same score. The formula is public.

Findings with receipts

Every finding has a location, the evidence line, a plain-English why, and a concrete fix instruction. No vibes, no black box.

An agent-ready fix plan

ai-slop-remover fix emits a prioritized per-file plan with guardrails — paste it into Claude Code, Cursor, or Codex and let it clean up after itself.

A CI gate that holds the line

--check --min-score 85 fails the build when slop creeps in. Baseline existing findings so brownfield repos only answer for new slop.

Detectors

Rules catch bad code. Drift catches incoherent code.

Linters check universal rules. The slop that survives review is different: code that's fine in isolation but doesn't match how your repo does things. We detect both.

Universal slop

The greatest hits of agent output

  • Comment slop — comments that restate the code, banner art, “Step 1 / Step 2” narration, emoji in logs
  • Fake-done code — “in a real implementation…”, todo!(), empty bodies with confident names
  • Swallowed errors — empty catch, log-and-continue, except: pass, ignored err
  • Phantom imports — dependencies that exist only in the model's imagination (slopsquatting risk)
  • Commented-out code — dead implementations left behind as comments
Convention drift — our specialty

Statistically inferred from your own code

  • Error-handling drift — the one throw where 86% of neighboring code returns Result
  • Data-access drift — raw DB calls bypassing the repository layer everyone else uses
  • Naming driftfetchUser in a directory of getX
  • Utility duplication — the same helper reimplemented for the third time, even with renamed variables
No other slop scanner does repo-relative analysis. A drift finding means “this differs from how your codebase does it” — the thing reviewers feel but can't point to.
Case study · scanned 2026-07-05, commit 18484f2

We scanned browser-use — 60k+ stars, the hottest AI-agent repo of the year.

74 / 100
GRADE C
819
findings
681
narrative comments
54
swallowed errors
2.7s
scan time, 106k lines

Slop Score — browser-use vs. mature codebases

Same scanner, same day, default settings. Higher is cleaner.
express · JS
97 · A
openai/codex · Rust
96 · A
gson · Java
95 · A
ollama · Go
92 · A
browser-use · Py
74 · C
Calibration matters: well-maintained repos score A. The scanner isn't cynical — it's specific. (openai/codex: 1.14M lines scanned in 23s.)
low · ×681browser_use/actor/element.py:403
Comments that narrate the code they sit on — prompt-transcript style, the #1 agent tell.
# Step 1: Focus the element
focused = await self._focus_element(...)
fix: Delete it; the code already says this.
med · ×54browser_use/actor/element.py:117
Cascading fallback chains where every failure is silently discarded — the demo works, production lies.
except Exception:
    pass
fix: Handle it, return an error result, or justify why ignoring is safe.
med · ×34browser_use/llm/aws/chat_anthropic.py:162
ainvoke reimplemented near-identically across provider files — agents don't refactor, they re-generate.
async def ainvoke(self, messages, ...)
# same shape in chat_bedrock.py:148
fix: Extract one shared implementation and import it.

To be fair to browser-use: it's an excellent, fast-moving project — that's why we picked it. This is a point-in-time snapshot of one commit, findings are heuristics (not bugs), and a C score measures style debt from velocity, not product quality. Run the scanner on the latest commit and you may get different numbers. That's the point: now you can.

Coverage

Nine languages. Idiom-aware by design.

Java constructor guards, @Override delegation, Rust lock().unwrap(), TYPE_CHECKING imports — established idioms are recognized as intentional, not flagged. That's why mature repos score A.

JavaScript TypeScript Python Go Java C# Rust PHP Ruby
The remover part

The scanner finds it. Your agent fixes it. The rescan proves it.

Scan

Zero config. Point it at any repo and get the score, the categories, and every finding with evidence.

$ npx ai-slop-remover scan .

Hand off the fix plan

A prioritized, per-file plan with guardrails: don't change behavior, run tests after each file, skip anything that looks wrong.

$ npx ai-slop-remover fix -o SLOP-FIXES.md
$ claude "Apply the plan in SLOP-FIXES.md"

Hold the line in CI

Gate merges on the score. Baseline old findings so only new slop fails the build.

$ npx ai-slop-remover baseline
$ npx ai-slop-remover scan . --baseline \
    --check --min-score 85  # exit 1 on fail

We eat our own dog food: the scanner flagged duplicated helpers in its own source, its fix plan removed them, and the repo now scans 100/100.

Thirty seconds from now, you'll know your score.

$ npx ai-slop-remover scan .
Star it on GitHub ↗