FixMySlop
The slop linter for the AI-agent era. FixMySlop catches the things AI coding agents get wrong — the
purple-gradient landing page, the // ... existing code ... that silently deleted half a file, the npm
package that doesn't exist, the OpenAI key in NEXT_PUBLIC_ — in milliseconds, without an LLM. Then it
hands a precise fix list to the agent you already use (Claude Code, Codex, Cursor, Gemini) and re-scans to
prove it's fixed.
Why this exists when you already have a frontier model
Frontier models are great at fixing slop and bad at noticing their own. They write the purple gradient because it's the statistical default; they elide code when an edit gets long; they import packages that sound right. FixMySlop is the other half of the loop:
| Your agent | FixMySlop | |
|---|---|---|
| Speed | seconds–minutes per review | ~0.5s for a 10k-line repo |
| Determinism | different answer each run | same input → same findings, stable rule IDs |
| Cost | tokens on every review | free, offline, no API key |
| Good at | fixing code | finding the tells, every time, in CI |
So: FixMySlop finds, your agent fixes, FixMySlop verifies. The old "local LLM reviews your code"
mode still exists (--llm), but it's optional — the rules engine is the product.
Install
pipx install fixmyslop # or: pip install fixmyslop
npx fixmyslop scan # JavaScript projects: no install step (runs via uvx/pipx)
npx needs Python 3.10+ plus uv or pipx on the machine; it always runs the
FixMySlop version that matches the npm package.
Optional: pip install "fixmyslop[analysis]" adds Ruff + Bandit findings for Python.
30 seconds
fixmyslop scan # whole repo
fixmyslop scan --changed # only what changed vs main (+ uncommitted)
fixmyslop baseline # existing codebase: accept today's issues, report only new ones
fixmyslop ui # the app: browse issues, apply fixes, copy prompts for your agent
fixmyslop scan --open # one-off interactive HTML report
fixmyslop fix --safe-only # behavior-preserving auto-fixes
fixmyslop fix # safe fixes → hand the rest to your agent → re-scan
fixmyslop init --claude # make Claude Code check its own work, live
Try it on the bundled demos: fixmyslop ui examples/slop-app (classic purple-gradient slop) and
fixmyslop scan examples/slop-2026 (the newer dark, glowing, aphorism-heavy look).
For AI agents
If a user asks you to set up or run FixMySlop, these are the exact commands (all exist in the CLI; fixmyslop <command> --help shows every option):
pip install fixmyslop # needs internet access to PyPI (sandboxes without network can't install it)
fixmyslop init --all # config + agent rules + skill + MCP + Claude hook + CI + pre-commit
fixmyslop scan . -f compact # one line per issue, token-efficient
fixmyslop scan . -f prompt # full fix brief: issues, exact fixes, the project's design tokens
fixmyslop fix . --safe-only # behavior-preserving auto-fixes only
fixmyslop scan . --fail-on medium # exit 1 while CRITICAL/HIGH/MEDIUM issues remain
fixmyslop rules <rule-id> # why a rule exists and how to fix it
Loop: scan → fix what the brief says → re-scan until clean. Report the before/after slop score to the user. Supported files: Python, JS/TS, JSX/TSX, Vue, Svelte, Astro, HTML, CSS/SCSS (plus generic checks for Go, Rust, Java, C/C++, C#, Ruby, PHP, Swift, Kotlin).
The app
fixmyslop ui opens FixMySlop in your browser. It runs only on your machine (127.0.0.1, per-session token,
no external requests) and uses the same engine as the CLI:
- Overview: slop score with the change since your last scan, what to fix first, and three steps to fix it
- Issues: filter and search every finding, see the exact code, and copy a fix prompt for your agent
- Rules: turn rules on or off for the project (saved to
.fixmyslop.yml) - Setup: one-click install for Claude Code, Cursor, AGENTS.md, GitHub Actions and pre-commit
What it catches
UI slop — the visual and copy tells of generated frontends (React, Vue, Svelte, Astro, HTML, CSS, Tailwind)
| Rule | Catches |
|---|---|
ui/ai-gradient |
from-purple-600 to-pink-500, #667eea → #764ba2 |
ui/gradient-text |
bg-clip-text text-transparent headlines |
ui/emoji-icons |
🚀 ⚡ ✨ used as feature icons |
ui/marketing-slop |
"Revolutionize", "Unlock the power of", "seamless", "next-gen" |
ui/fake-social-proof |
"10,000+ happy users", "99.9% uptime", testimonials from "Sarah Johnson" |
ui/placeholder-copy |
Lorem ipsum, "Your Company Name" |
ui/glassmorphism, ui/blur-blobs, ui/hover-scale, ui/heavy-shadows, ui/gimmick-animation |
the template aesthetic |
ui/rainbow-palette, ui/palette-sprawl, ui/arbitrary-color, ui/arbitrary-values |
no design system: 9 accent hues, 40 hex codes, w-[347px] |
ui/default-font, ui/z-index-war, ui/important-abuse |
Inter-everywhere, z-index: 9999, !important piles |
ui/aphorism-copy |
the newer AI voice: "Make space for what matters", "Intentional by design", "Less X. More Y." |
ui/neon-glow, ui/two-tone-headline, ui/eyebrow-labels |
glowing orbs in any hue, accent-colored second line, uppercase micro-labels on every section |
ui/fake-chart |
sparklines drawn from hard-coded heights, often right next to a "0" |
Accessibility — a11y/img-alt, a11y/clickable-div, a11y/icon-button, a11y/focus-removed, a11y/dead-link
Code slop — slop/elided-code (// ... existing code ...), slop/placeholder-impl ("in a real app you would…"),
slop/stub-function, slop/swallowed-exception, slop/empty-catch, slop/bare-except, slop/narrating-comment,
slop/step-comments, slop/debugger, slop/console-log, slop/emoji-log, slop/ts-any, slop/ts-ignore,
slop/blanket-suppression, slop/placeholder-credential, slop/ai-voice
Backend — slop/empty-test (tests that assert nothing — pytest, Jest, Vitest, Mocha), slop/duplicate-function
(the same body copy-pasted across files, names ignored), slop/pointless-wrapper, slop/catch-rethrow,
Go slop/ignored-error (if err != nil { return nil }), Java/Kotlin slop/print-stacktrace, and empty catch {}
in JS/TS, Java, C#, Kotlin, Swift, PHP and Dart
Dependencies — deps/phantom-import: imports that aren't stdlib, local, declared, or installed (hallucinated
packages are what slopsquatting attacks register).
--online confirms against PyPI / npm. deps/undeclared-import: works on your machine, breaks in CI.
Security — sec/leaked-key (OpenAI/Anthropic/AWS/GitHub/Stripe/Google key formats, private keys — always
redacted in output), sec/public-env-secret (NEXT_PUBLIC_*SECRET*, VITE_*OPENAI*), sec/hardcoded-credential,
sec/sql-injection, sec/cors-wildcard, sec/tls-disabled, sec/raw-html, sec/eval
Plus Ruff, Bandit and Semgrep findings when installed. fixmyslop rules lists everything;
fixmyslop rules ui/ai-gradient explains one.
Use it with your agent
Claude Code
fixmyslop init --claude
This installs four things, all idempotent:
- a skill (
.claude/skills/fixmyslop/SKILL.md) so Claude reaches for FixMySlop on its own when it builds UI or finishes a task - an MCP server in
.mcp.jsonwithcheck_slop,fix_safe,explain_rule,slop_guidetools - a PostToolUse hook — every file Claude writes is checked instantly; only the lines it just wrote are reported, and Claude is told to fix them before moving on
- anti-slop rules in CLAUDE.md
fixmyslop init --user installs the skill for every project on your machine.
Cursor, Codex, Gemini, Windsurf, anything with MCP
fixmyslop init --cursor # .cursor/rules + .cursor/mcp.json
fixmyslop init --agents # AGENTS.md (Codex, Gemini, Jules, Copilot agents)
claude mcp add fixmyslop -- fixmyslop mcp # or register the MCP server anywhere
MCP config for JSON-configured clients (Cursor, Windsurf, Claude Desktop):
{ "mcpServers": { "fixmyslop": { "command": "npx", "args": ["-y", "fixmyslop", "mcp"] } } }
Hand off a fix
fixmyslop fix # auto-detects claude / codex / gemini on PATH
fixmyslop fix --agent claude --yes
fixmyslop fix --agent-cmd "aider --message-file {brief} --yes"
fixmyslop fix --agent llm -b https://openrouter.ai/api/v1 -m <model> # any OpenAI-compatible API, incl. Ollama
fixmyslop scan -f prompt > brief.md # or paste the brief yourself
fix applies safe deterministic fixes first, writes a brief to .fixmyslop/brief.md (file-by-file checklist with
a concrete fix for every rule plus UI design direction), runs the agent, re-scans, and repeats for up to --rounds.
It ends with the before/after score.
Existing codebase? Baseline it
fixmyslop baseline # accept today's issues (writes .fixmyslop-baseline.json — commit it)
fixmyslop scan --fail-on high # from now on only NEW slop is reported and fails CI
fixmyslop scan --no-baseline # see everything again
Fingerprints ignore line numbers, so editing code above an old issue doesn't bring it back. Also available in the app under Setup.
CI
# .github/workflows/fixmyslop.yml (or: fixmyslop init --github)
on: [pull_request]
permissions: { contents: read, security-events: write }
jobs:
slop:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: MrSpideyNihal/FixMySlop@v0.6.1
with: { fail-on: high, changed-only: true }
Findings show up as inline PR annotations (SARIF). Also on the GitHub Marketplace. pre-commit:
repos:
- repo: https://github.com/MrSpideyNihal/FixMySlop
rev: v0.6.1
hooks: [{ id: fixmyslop }]
Configure
.fixmyslop.yml (or [tool.fixmyslop] in pyproject.toml), created by fixmyslop init:
exclude: ["legacy/**", "**/*.generated.ts"]
disable: ["ui/default-font"] # ids or groups: ui, a11y, slop, sec, deps
severity: {"slop/console-log": "INFO"}
fail_on: high
hook: { min_severity: MEDIUM }
Silence one finding with a reason: // fixmyslop-ignore[ui/gradient-text] brand guideline.
Skip a file: fixmyslop-ignore-file in its first lines. Paths passed explicitly are always scanned.
Output formats
-f text (default) · compact (one line per issue, for agents) · prompt (fix brief) · sarif · json ·
markdown · html (a shareable single file with filters, search and "copy fix prompt" per file) · csv · pdf. Save with -s report.html (format inferred from the extension).
Exit codes: 0 clean, 1 issues at/above --fail-on, 2 usage error.
How accurate is it?
On a pinned corpus of 9 AI-built apps and 4 hand-built repos, 95% of findings were correct in a random,
hand-reviewed sample of 80, and AI-built apps averaged about 2× more findings per 1,000 lines. Method, raw labels,
per-repo grades and limitations: benchmarks/BENCHMARK.md. Reproduce with
python benchmarks/run.py.
Slop score
0 (clean) to 100, from severity-weighted findings per 1,000 lines, so a 500-line app and a 500k-line monorepo are comparable. Grades: A < 10 ≤ B < 25 ≤ C < 45 ≤ D < 65 ≤ F. FixMySlop's own repo is scanned in CI and holds an A.
Optional: LLM review
fixmyslop scan --llm adds a model review pass over each file (Ollama, llama.cpp, vLLM, LM Studio, or any
OpenAI-compatible endpoint via --base-url/--api-key/--model, or FIXMYSLOP_* env vars). It's slow and
non-deterministic, so it's off by default — every check above works without it.
Development
pip install -e ".[analysis,dev]"
pytest -q
fixmyslop scan . --fail-on medium # the repo must stay clean
python screenshots/make_screenshots.py # regenerate README screenshots
Adding a rule: write a check in fixmyslop/core/slop/rules_*.py with the @rule decorator (or line_rule for a regex),
then add a sloppy + clean pair to tests/test_slop_rules.py. Every rule needs a why and an actionable fix —
the fix text is what agents follow.
Security and changes
See SECURITY.md for how FixMySlop handles your code (local, offline by default, secrets redacted) and how to report a vulnerability, and CHANGELOG.md for what changed in each release.
License
MIT
Metadata
Release files for fixmyslop 0.6.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fixmyslop-0.6.1.tar.gz | 153.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fixmyslop-0.6.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 302.0 kB
Release files / fixmyslop-0.6.1.tar.gz
| Download URL | fixmyslop-0.6.1.tar.gz |
|---|---|
| Size | 153.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c65925eb8af36c91eeb33e8979f5ccb10a1b8c7a84a695481c398c5c6f5c0505
|
|
BLAKE2b-256 checksum How to use checksums |
99bbaddedb610569de32ae9b47f3435d2bc5c424106d0ba0e99f2289becb9021
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency logRelease files / fixmyslop-0.6.1-py3-none-any.whl
| Download URL | fixmyslop-0.6.1-py3-none-any.whl |
|---|---|
| Size | 148.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
499ff8481294fa3f88df05e0e9dc470b499fcae22051b10623e1795301928702
|
|
BLAKE2b-256 checksum How to use checksums |
14a05b9ed5d943eba4889592b2cf114f24ea522712be3f8975917035f47bfd1e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 16, 2026.
Transparency log