@igorao79/slopanalyzer
v0.4.0
Published
Turn AI-generated 'slop' code into readable code: detect monoliths, dead code, leftovers, plan drift and over-engineering. Ships a zero-dependency CLI and a Claude Code skill/plugin.
Maintainers
Readme
slopanalyzer
Turn AI-generated slop into code a human can actually read.
LLMs — even the best ones — write structurally-correct but architecturally-careless code:
1000-line monolithic components, drift from the project plan (CLAUDE.md), dead/uncalled
code, leftover garbage (console.log, TODO stubs, commented-out blocks), and
over-engineered choices (Redux Toolkit in a tiny app where Zustand would do).
slopanalyzer is a hybrid:
- A fast, near-zero-dependency, language-agnostic CLI (one tiny dep:
ignore) that scans a project — monorepo-aware — and emits a structuredslop-report.jsonof facts. - A Claude Code skill (the brain) that reads those facts and the project plan, then reasons: it shows plan drift, confirms dead code before deletion, proposes lighter alternatives that don't break behavior, and — on your approval — refactors monoliths into clean, readable modules.
The CLI finds the cheap, deterministic stuff. The skill does the judgement that actually requires intelligence. (And the tool is deliberately kept lean — an anti-slop tool shouldn't be slop.)
Install
There are three ways to get it — pick what fits.
1. As a CLI (npm)
# one-off
npx @igorao79/slopanalyzer scan
# or install globally (the binary is named `slopanalyzer`)
npm i -g @igorao79/slopanalyzer
slopanalyzer scan2. As a Claude Code skill (recommended for the "smart" part)
npx @igorao79/slopanalyzer install-skill --global # into ~/.claude/skills
# or, per project:
npx @igorao79/slopanalyzer install-skill --project . # into ./.claude/skillsThen in Claude Code just say: "analyze this project for slop".
3. As a Claude Code plugin
/plugin marketplace add igorao79/slopanalyzer
/plugin install slopanalyzerPlugins are fetched from a git tag, so install picks up the latest released tag.
CLI usage
slopanalyzer scan [path] [options] Analyze a project, write slop-report.json
--json Print the raw JSON report to stdout
--out <file> Where to write the JSON (default: slop-report.json)
--no-out Don't write a file
--enhance Force-run dead-code tools (knip/vulture)
--no-enhance Skip dead-code tools (they auto-run when installed)
--config <file> Path to slop.config.json
slopanalyzer install-skill [--global | --project [dir]] [--force]
slopanalyzer report [file] Pretty-print an existing reportExample
slopanalyzer report
────────────────────────────────────────
Slop score: 100/100 ████████████████████████
Files: 2 (449 lines)
Plan file: CLAUDE.md
Monolithic files (>= threshold): 1
src/Dashboard.jsx (415 lines)
Oversized functions: 2
src/Dashboard.jsx:11 handleEverything() (244 lines)
Possibly over-engineered dependencies: 4
@reduxjs/toolkit → zustand or React context for small apps
moment → date-fns, dayjs, or the native Intl/Temporal API
...What it detects
| Category | How |
|----------|-----|
| Monolithic files & god-functions | line thresholds (configurable), plan-aware — see below |
| Fragmented backend tools | multiple loggers/validators/etc. that should be one; bypasses of the central tool (console.*, raw req.body) |
| Heavy / over-complex functions | cyclomatic-complexity proxy (the "calculator in 100 lines" smell), separate from length |
| Verbose / round-about code | reaching the long way when a simpler form exists, e.g. Model.sequelize.fn() → import { fn } from 'sequelize' (configurable patterns) |
| Long comments | walls-of-text comments flagged as a warning |
| Deep nesting | brace-depth heuristic |
| Duplicated blocks | normalized sliding-window hashing |
| Debug leftovers | console.log / print / fmt.Println / … |
| TODO/FIXME stubs | keyword scan |
| Commented-out code | code-shaped comment runs |
| Over-engineered deps | all manifests parsed (monorepo-aware) + heavy→light map |
| Plan drift | plan file located by CLI, compared by the skill |
| Dead/uncalled code | knip/vulture auto-run when installed (else the report suggests installing them) |
Every finding is tagged runtime / tooling / test, so console.log in a build
script or test doesn't inflate the score the way real runtime slop does. The walk honors
.gitignore (via the ignore library), so vendored/ignored directories stay out.
Large blocks aren't always slop. Monolith detection is plan-aware: when a plan
(CLAUDE.md/PLAN.md) is present, big/god-files are treated as possibly intentional and
the skill verifies them against the plan instead of demanding a split; with no plan, large
files are emphasized as readability risks. Centralization detection targets a common
backend smell — a logger here, another there, routes reading raw req.body — and surfaces
fragmented tools that should be unified into one (one logger, validate everywhere). Both
concern sets are configurable in slop.config.json.
The CLI is language-agnostic (JS/TS, Python, Go, Rust, Java, Ruby, PHP, C/C++, C#, and more). Whole-project semantic judgements (dead-code confirmation, plan drift, refactoring) are handled by the Claude Code skill.
Configuration
Drop a slop.config.json in your project root to tune thresholds:
{
"monolithFileLines": 400,
"oversizedFunctionLines": 60,
"maxNestingDepth": 5,
"duplicationMinLines": 6,
"heavyDeps": { "some-lib": "lighter alternative" }
}Programmatic API
import { scanProject, buildReport, loadConfig } from '@igorao79/slopanalyzer';
const config = loadConfig(process.cwd());
const scan = await scanProject(process.cwd(), config);
const report = buildReport(scan, { root: process.cwd() });Development
npm test # node:test suite
node bin/slopanalyzer.js scan tests/fixtures/sloppy-appLicense
MIT © igorao79
