Sandbox
@Zhen-Bo/smell-check

Agent skill for code and test smell audits

smell-check gives an agent a repeatable way to inspect a repository for maintainability warnings from Refactoring, Clean Code, and test-smell literature. It combines script-based measurements with agent judgments, ranks each finding by evidence, and writes an offline report bundle under `.smell-check/`.

237 stars18 forksPythonUpdated 18d ago
Who it's for

Builders who use an AI coding agent and want a structured audit of code and test smells.

What it delivers

You can get a written, evidence-ranked audit of maintainability problems without re-reading the source books yourself.

What it does

Evidence-ranked findings

Each finding is labeled as mechanical, semantic, or estimate, with the basis recorded in the report.

Static-only audit

It reads code paths, but never edits code, runs tests, or follows gitignored paths.

Measured structure checks

It uses tools like `wc`, AST counters, and optional `jscpd` or `lizard` when available.

Code and test smell rules

It checks 20 stable code rules and 12 stable test rules, with optional experimental rules.

Report bundle output

It writes `.smell-check/<UTC-timestamp>/` with `index.html`, `summary.md`, and sharded finding reports.

Configurable scope and thresholds

A `.smell-check.toml` file can set profile, exclusions, rule toggles, and threshold overrides.

How to get it

  1. 1Run
    npx skills add Zhen-Bo/smell-check

README

smell-check: code and test smell audits

Read the skill docs » · Install · Example report · 繁體中文

A codebase health check with receipts.
smell-check is an Agent Skill for AI coding agents.
It audits the paths you choose for code smells and test smells, and every finding carries its evidence.

License: MIT Release skills.sh installs


The smells it hunts are the maintainability warnings catalogued in Refactoring, Clean Code, and the test-smell literature. It is a health check for a codebase, not a PR review bot: no merge advice, no code edits, no test runs.

  • Measured, not vibed. Structure metrics come from scripts and tools (wc, AST counters, jscpd) wherever those can run; anything unmeasured is marked estimate, never dressed up as fact.
  • Evidence rank on every finding. mechanical (a script counted it), semantic (the agent judged it, and the basis is written down), or estimate (weak, and says so).
  • Diagnosis, not prescription. A finding states what is wrong, where, and what it costs maintainers. Fix strategy stays with whoever owns the fix.
  • Static only. It never edits your code, never executes your code or tests, and never reads gitignored paths.

What a report looks like

Reports land in .smell-check/<UTC-timestamp>/, written in your conversation language. Open index.html for the offline report.

.smell-check/20260828-103000Z/
├── index.html             # summary and source-area index
├── summary.md             # canonical manifest and Markdown overview
└── findings/              # Markdown reports of at most 100 findings each

Every active finding shows its rule key, source location, verbatim snippet, evidence rank, evidence, and consequence. Dismissed hits keep the exception or judgment that removed them, so you can audit the auditor.

Why smell-check

Reading Refactoring or Clean Code changes how you see code. The effect lasts about a week. Nobody holds hundreds of pages of judgment in working memory while shipping, and nobody re-reads the book mid-task.

Meanwhile coding agents write more and more of the code, and the people prompting them hold less and less of it in their own heads. The reading still has to happen; humans just stopped being the ones who can afford to do it.

The books already wrote down how to read a codebase. smell-check turns that into a procedure an agent can execute: measurement instead of memory, evidence instead of impressions, every judgment recorded per finding. It complements linters, type checkers, and tests; it does not replace them.

Install

npx skills add Zhen-Bo/smell-check
Optional measurement tools

The skill works with plain git + wc + Python 3. Extra tools unlock extra measurements; when absent, the report says so instead of guessing:

ToolUnlocks
jscpd (npm i -g jscpd)code.duplicate-code clone detection
lizard (pip install lizard)corroboration of code.long-function measurements
nodeTS/JS metrics via the attached script (uses the repo's own typescript install)

Run your first audit

The skill asks you to name the scope before scanning, discloses which size profile it picked and why, runs the mechanical and semantic passes, and writes the report bundle.

Ask your agent:

Use the smell-check skill to audit this whole repository.

[!WARNING] Whole-repo audits of large codebases consume a lot of tokens, and a long run can outgrow the agent's context window, where early judgments may be lost to compression. The skill warns you and asks for confirmation before scanning a large scope, and nothing is silently truncated; if you stop mid-run it writes a partial report plus the list of finished paths.

Size profiles

Thresholds scale with how many people must keep the code readable. Explicit profile in config always wins; otherwise auto picks one from the source-code line count of the scope. Only source code counts, so generated output, vendored bundles, fixtures, lockfiles, markup, and prose are excluded:

ProfileFitse.g. code.long-function limit
personalpersonal projects, where running is enough100
smallin-team tools, roughly 5–20 maintainers60
mediumproducts maintained by tens to hundreds40
largeenterprise codebases, thousands of maintainers30
ultimatethe strictest workable reading of the books and the test-smell literature; auto never picks it20
Source lines in scopeAuto picks
0 – 2,999personal
3,000 – 14,999small
15,000 – 74,999medium
≥ 75,000large

What it checks

20 stable code rules

  • long functions
  • large files
  • deep nesting
  • long parameter lists
  • duplicate code
  • duplicated knowledge
  • misleading naming
  • god classes
  • feature envy
  • data clumps
  • primitive obsession
  • shotgun surgery
  • divergent change
  • message chains
  • middle men
  • speculative generality
  • dead code
  • repeated switches
  • global data
  • magic values

12 stable test rules

  • assertion-free tests
  • assertion roulette
  • eager tests
  • conditional test logic
  • mystery guests
  • general fixtures
  • ignored tests
  • sleepy tests
  • order-dependent tests
  • sensitive equality
  • obscure tests
  • non-determinism

Four experimental rules stay off until you enable them one by one in config. Every rule ships with its exceptions: table-driven test loops, composition roots, wire-boundary DTOs, and similar justified patterns get dismissed with the reason written down, not reported as noise.

Report anatomy

  1. Index: repository state, profile, aggregate counts, rule summary, synthesis, source areas, and environment
  2. Finding reports: active and dismissed findings split into Markdown files by status and source area, capped at 100 per file
  3. Canonical Markdown: summary.md holds the run manifest and shard inventory; the model authors one fresh HTML overview from DESIGN.md
  4. Markdown output: the summary and every detailed finding report stay readable without an HTML renderer

Configuration

Optional .smell-check.toml at the scan root. Choices only, no rule text:

profile = "medium"                 # pin strictness; omit to let auto decide
report_ignore = "git-info-exclude" # or "gitignore" / "none"

exclude = ["vendor/**", "dist/**"]

[rules]
"code.magic-values" = false   # silence a stable rule
"test.over-mocking" = true    # enable an experimental rule

[thresholds]
"code.long-function" = 80     # overrides beat the profile, no questions asked

Package layout

smell-check/
├── SKILL.md              # the audit procedure
├── references/           # rule registries, presets, measurement, configuration, report contract
├── scripts/
│   ├── measure_python.py # Python AST metrics
│   ├── measure_ts.mjs    # TS/JS metrics
│   └── validate_report.py # validates the report bundle
├── assets/
└── DESIGN.md             # design contract for the AI-authored HTML index

FAQ

Does it change my code? No. Static analysis only; your code and tests are never executed. It writes the report bundle, and on the first run it asks where to ignore .smell-check/ (default: .git/info/exclude) before touching anything else.

Does it replace my linter or type checker? No. Keep them; they enforce what can be decided mechanically on every commit. smell-check reads for design-level maintainability warnings, and labels each finding as a measured fact or a judgment call.

What happens if scanned code contains prompt-injection text? Subject content is treated as data, never as instructions. Instruction-like text inside the scanned code does not change the procedure.

Which model should run it? Whatever your runner uses. The mechanical baseline is script-measured and model-independent; the semantic pass is only as good as the model you bring.

License

MIT

Files in the repo

Repository payload12 top-level entries
  • .github
  • assets
  • docs
  • references
  • scripts
  • .gitignore
  • CHANGELOG.md
  • DESIGN.md
  • index.html
  • LICENSE
  • README.md
  • SKILL.md

Discussion (0)

Ask about usage, or say what you built with it

Sign in to join the discussion.

No comments yet. Be the first to say what this is good for.

More skills

obra/
superpowers

An agentic skills framework & software development methodology that works.

285k
1 add

Turn any codebase, with its docs, SQL schemas, configs, and PDFs, into a queryable knowledge graph. A /graphify skill for Claude Code, Cursor, Codex, and Gemini CLI: local deterministic AST parsing, every edge explained, no vector store.

117k
1 add
Vincentwei1021/
anything2explainer

Topic in, narrated explainer video out. A Claude Code / Codex skill that turns any topic into a black-canvas motion-graphics explainer video with TTS voiceover, subtitles and a chapter progress bar. Chinese or English; every frame drawn in code with Remotion.

666

Open-source AI job search: scan job portals, evaluate listings into a structured A-H report with a global 1-5 score, tailor your CV, track applications — runs locally in your AI coding CLI (Claude Code, Codex, OpenCode, Antigravity…)

71k