Star 历史趋势
数据来源: GitHub API · 生成自 Stargazers.cn
README.md

slop-scan

CI status Latest release MIT License

Deterministic CLI for finding AI-associated slop patterns in JavaScript and TypeScript repositories.

Scan a repo, surface the hotspots, and compare codebases using normalized slop metrics.

Why use it

  • Find the hotspots fast — see which files and directories concentrate the most suspicious patterns
  • Understand why something was flagged — every finding includes a rule ID and evidence
  • Compare repos fairly — normalize by file count, logical KLOC, and function count
  • Benchmark heuristics over time — rerun the pinned benchmark set and watch movement

Good fit for

  • checking third-party repos that feel vibe-coded
  • comparing known AI-generated repos to mature OSS baselines
  • finding low-judgment boilerplate in your own codebase
  • iterating on deterministic slop heuristics

Why can you trust it?

Every rule is tested and benchmarked against popular, mature OSS repos pinned to exact commit SHAs from before AI coding was common. See Benchmarks.

Install

Install globally with npm:

npm install -g slop-scan

Install it in a project and run it with npm tools:

npm install --save-dev slop-scan npx slop-scan scan .

Quick start

Scan the current repo:

slop-scan scan .

Scan the current repo in lint mode:

slop-scan scan . --lint

Scan another repo and get JSON:

slop-scan scan /path/to/repo --json

Use it like a linter

Use --lint when you want human-readable findings in local runs, CI logs, or PR checks.

slop-scan scan . --lint

Example output:

medium Found 3 duplicated function signatures structure.duplicate-function-signatures at src/users/normalize.ts:1:1 at src/teams/normalize.ts:1:1 at src/accounts/normalize.ts:1:1

JSON output

Use --json when you want full-fidelity output for scripts, CI, or post-processing.

slop-scan scan . --json

Example CI check:

slop-scan scan . --json | jq -e '.summary.findingCount == 0'

The CLI currently exits non-zero for CLI/runtime errors, not for findings.

Delta comparisons

Use delta when you want a machine-readable comparison between two scans.

Compare two paths directly:

slop-scan delta ../main . slop-scan delta --base ../main --head . --json

Compare two saved reports:

slop-scan scan ../main --json > base.json slop-scan scan . --json > head.json slop-scan delta --base-report base.json --head-report head.json

Fail CI only when new or worse occurrence-level findings show up:

slop-scan delta --base ../main --fail-on added,worsened

delta --json emits a generic report format with:

  • base/head scan summaries
  • occurrence-level change classification (added, resolved, worsened, improved)
  • per-path score deltas
  • report metadata and config hashes so downstream tools can detect mismatched scan conditions
  • stable per-occurrence fingerprints for built-in rules, so grouped findings can match across rescans without relying on rendered message text

What it catches

Current default-pack checks focus on patterns that often show up in unreviewed generated code:

scan reports raw + normalized scores, hotspot tables, and grouped findings. Use --json when you want the full evidence payload.

Supported files

Current language support:

  • .ts
  • .tsx
  • .js
  • .jsx
  • .mjs
  • .cjs

Benchmarks

The repo ships with a pinned, recreatable benchmark set comparing known AI-generated repos against well-regarded OSS repos, with the mature-OSS cohort pinned to the latest default-branch commit on or before 2025-01-01.

Why before Jan 1, 2025? Because this cutoff aims to catch mature OSS before AI coding had materially changed mainstream repository shape and review norms.

Blended score = geometric mean of the six normalized-metric ratios versus the mature OSS cohort medians, then rescaled so the mature OSS cohort median is 1.00. Higher means a repo is consistently noisier across the benchmark dimensions.

Cohort medians

MetricAI medianMature OSS medianRatio
Blended score6.911.006.91x
Score / file1.070.128.82x
Score / KLOC10.901.487.38x
Score / function0.280.055.51x
Findings / file0.290.046.97x
Findings / KLOC3.040.565.39x
Findings / function0.080.023.51x

Rolling benchmark snapshot

Latest default-branch history, still normalized against the frozen pinned baseline. Ordered by latest pinned score.

RepositoryCohortLatest refCurrent blendedLatest pinnedHighest pinnedΔ prevΔ peak
garrytan/gstackaimain@ed1e4be9.1511.1411.14+6.370.00
FullAgent/fullingaimain@d95060f8.4210.2410.24+8.080.00
redwoodjs/agent-ciaimain@76b46f97.839.539.53+5.610.00
jiayun/DevWorkbenchaimain@ea508627.398.998.99+5.600.00
robinebers/openusageaimain@584d44d5.276.416.41+3.390.00
openclaw/openclawaimain@6b6dcaf5.266.406.40+3.480.00
emdash-cms/emdashaimain@3dd1a1f4.155.065.06+3.040.00
cloudflare/vinextaimain@67a929b3.063.733.73+1.800.00
modem-dev/hunkaimain@a6aa1cb2.953.593.59+2.080.00
vitejs/vitemature-ossmain@640202a1.712.082.08+0.560.00
withastro/astromature-ossmain@10584281.692.052.05+0.590.00
egoist/tsupmature-ossmain@b906f861.251.521.52+0.600.00
pmndrs/zustandmature-ossmain@95d3f331.121.361.38-0.02-0.02
payloadcms/payloadmature-ossmain@0ceba021.001.221.34-0.13-0.13
sindresorhus/execamature-ossmain@f3a2e840.820.990.99+0.110.00
mikaelbr/node-notifiermature-ossmaster@b36c2370.780.950.95+0.530.00
vercel/hypermature-osscanary@2a7bb180.740.900.90+0.490.00
umami-software/umamimature-ossmaster@c78ff360.700.851.04-0.19-0.19

Legend:

  • Current blended = latest repo score vs the current mature-OSS medians from the same rolling run
  • Latest pinned = latest repo score vs the frozen pinned mature-OSS baseline snapshot
  • Highest pinned = highest stored repo score on that same pinned baseline
  • Δ prev = latest pinned - previous week's pinned score
  • Δ peak = latest pinned - highest pinned score, so more negative means the repo is below its own historical high

For exact pinned SHAs, the current default-pack medians, and the full per-metric breakdowns, see the saved snapshot and pinned benchmark report.

Full benchmark assets:

Configuration

The analyzer reads slop-scan.config.ts, slop-scan.config.js, slop-scan.config.mjs, slop-scan.config.cjs, or slop-scan.config.json from the scan root. Root .gitignore entries are also respected.

{ "ignores": ["dist/**", "coverage/**", "**/*.generated.ts"], "plugins": { "acme": "slop-scan-plugin-acme" }, "extends": ["plugin:acme/recommended"], "rules": { "structure.over-fragmentation": { "enabled": true, "weight": 1.2 }, "comments.placeholder-comments": { "enabled": false }, "acme/no-generated-wrapper": { "enabled": true, "options": { "threshold": 3 } } }, "overrides": [ { "files": ["src/rules/**"], "rules": { "structure.over-fragmentation": { "enabled": false } } } ] }

Supported today:

  • ignores
  • plugins.<namespace> as either a package/path string or a plugin object in module configs
  • extends: ["plugin:<namespace>/<config>"]
  • rules.<id>.enabled
  • rules.<id>.weight
  • rules.<id>.options
  • overrides[].files
  • overrides[].rules.<id>.enabled
  • overrides[].rules.<id>.weight
  • overrides[].rules.<id>.options

Plugins

slop-scan can load third-party rule plugins and plugin preset configs from JSON or module configs.

For plugin setup, naming rules, and authoring examples, see docs/plugins.md. Simple plugin rules can now declare stable delta behavior with helpers like delta.byPath() / delta.byLocations(), and clustered rules can attach lightweight deltaKeys instead of building fingerprints manually.

See also:

This repo also commits a root slop-scan.config.json for self-scans and local development. It keeps the scan focused on the tool itself by excluding heavyweight benchmark checkouts and intentionally disables directory-structure rules under src/rules/**.

Docs

Contributing

Issues and pull requests are welcome.

For local development, validation, and benchmark reproduction, see CONTRIBUTING.md.

Sponsor

Sponsored by Modem.

Modem

License

MIT

关于 About

Detect AI code slop patterns in your repo

语言 Languages

TypeScript100.0%
JavaScript0.0%
Shell0.0%

提交活跃度 Commit Activity

代码提交热力图
过去 52 周的开发活跃度
73
Total Commits
峰值: 55次/周
Less
More

核心贡献者 Contributors