Metadata-Version: 2.4
Name: fixmyslop
Version: 0.6.2
Summary: The slop linter for the AI-agent era: catch AI slop in UI and code in milliseconds, then let your agent fix it.
Author: FixMySlop Contributors
License: MIT
Project-URL: Homepage, https://github.com/MrSpideyNihal/FixMySlop
Project-URL: Repository, https://github.com/MrSpideyNihal/FixMySlop
Keywords: ai-slop,linter,code-review,claude-code,mcp,tailwind,accessibility,static-analysis,security,llm
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Quality Assurance
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: openai>=1.30.0
Requires-Dist: typer>=0.12.0
Requires-Dist: rich>=13.7.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: requests>=2.31.0
Provides-Extra: gui
Provides-Extra: analysis
Requires-Dist: ruff>=0.4.0; extra == "analysis"
Requires-Dist: bandit>=1.7.0; extra == "analysis"
Provides-Extra: dev
Requires-Dist: pytest>=8.0.0; extra == "dev"
Dynamic: license-file

# FixMySlop

[![PyPI](https://img.shields.io/pypi/v/fixmyslop)](https://pypi.org/project/fixmyslop/)
[![npm](https://img.shields.io/npm/v/fixmyslop)](https://www.npmjs.com/package/fixmyslop)
[![CI](https://github.com/MrSpideyNihal/FixMySlop/actions/workflows/python-package.yml/badge.svg)](https://github.com/MrSpideyNihal/FixMySlop/actions/workflows/python-package.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)

**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.

![fixmyslop scan output: 31 issues across UI slop, accessibility, code slop, security and dependencies, slop score 100, grade F](screenshots/cli.svg)

## 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

```bash
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](https://docs.astral.sh/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

```bash
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):

```bash
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

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="screenshots/app-overview-dark.png">
  <img alt="FixMySlop app overview: slop score 100, grade F, three fix steps, issues by category and the most affected files" src="screenshots/app-overview-light.png">
</picture>

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="screenshots/app-issues-dark.png">
  <img alt="FixMySlop issues view: findings grouped by file, with the explanation, highlighted code and the exact fix for the selected issue" src="screenshots/app-issues-light.png">
</picture>

## 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](https://en.wikipedia.org/wiki/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

```bash
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.json` with `check_slop`, `fix_safe`, `explain_rule`, `slop_guide` tools
- 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

```bash
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):

```json
{ "mcpServers": { "fixmyslop": { "command": "npx", "args": ["-y", "fixmyslop", "mcp"] } } }
```

### Hand off a fix

```bash
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

```bash
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

```yaml
# .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.2
        with: { fail-on: high, changed-only: true }
```

Findings show up as inline PR annotations (SARIF). Also on the [GitHub Marketplace](https://github.com/marketplace/actions/fixmyslop-ai-slop-linter). pre-commit:

```yaml
repos:
  - repo: https://github.com/MrSpideyNihal/FixMySlop
    rev: v0.6.2
    hooks: [{ id: fixmyslop }]
```

## Configure

`.fixmyslop.yml` (or `[tool.fixmyslop]` in pyproject.toml), created by `fixmyslop init`:

```yaml
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](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

```bash
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](SECURITY.md) for how FixMySlop handles your code (local, offline by default, secrets redacted)
and how to report a vulnerability, and [CHANGELOG.md](CHANGELOG.md) for what changed in each release.

## License

MIT
