mcpField
C
clean-code

clean-code

github.com/bseneDevelopment7120 installsUpdated 1w ago
Repository

About clean-code

clean-code is a skill for coding agents that evaluates code through design, naming, complexity, and comments, using concrete criteria rather than intuition. It also routes behavior-preserving refactors to a related skill and defines when to use a CUPID review.

Key features

  1. 01Checks design, naming, complexity, and comments
  2. 02Sets per-function complexity budgets
  3. 03Routes work to related skills
  4. 04Supports CUPID design reviews
  5. 05Emphasizes root-cause fixes and clear boundaries

Use cases

  1. 01Assess whether code is readable and maintainable
  2. 02Evaluate design and complexity before refactoring
  3. 03Run a CUPID quality review when requested

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/bsene/skills --skill clean-code

After installing, type/clean-codein Claude Code to confirm it loaded.

Bundled files

References and scripts installed along with SKILL.md.

refactoring/references/
decision-guide.md
language-idioms.md
legacy-first-aid.md
smells.md
techniques.md
references/
cupid-properties.md
hacker-manifesto.md
simplicity-principles.md
xp-practices.md

Details

From the project README

Clean Code

Code is for people to read, modify, and delete. Run four checks: design, naming, complexity, comments. Each has a concrete bar, not a vibe.

Route to sub-skill

For a behavior-preserving refactor within a function, class, or file, read refactoring/SKILL.md. It supplies the smell catalog, technique selector, and guardrails. Do not use it for behavior changes (testing (TCRDD reference)) or cross-file dependency untangling (mikado-method).

1. Design for a human-sized mental model

Prefer the concrete solution until the same need has appeared independently at least three times. An abstraction is cheap to write and expensive for every later reader to learn and trace. A hypothetical future need is not a reason to add one.

Fix defects at their cause, not with another special-case branch around the symptom. A good fix should reduce paths through the code or repair the shared rule that created the problem.

Chunks are containment boundaries — repository → service → module → function — that let a reader ignore what is outside the task. Keep each chunk coherent enough to understand locally. Slices cross those boundaries: observability, recoverability, accessibility, security, and similar concerns. Make their path through the affected chunks easy to find and follow; do not hide a cross-cutting concern just to make one chunk look tidy.

Some complexity belongs to the domain. Do not flatten tax, compliance, or other real rules into a simple-looking but incorrect model. Prefer the design a new reader can understand correctly without extra context, not merely the shortest expression.

2. Naming

Every module, file, function, class, and variable name must reveal intention on its own — no need to read the body to know what it does.

Operational checks, in order:

  1. Intention-revealing: name says what it does/holds, not how (elapsedTimeInDays, not d). If you need a comment to explain a name, the name failed.
  2. No confusion: don't use names that differ in ways that are hard to spot (userList vs usersList), and don't call something a list unless it's actually a List type. Don't use two names for the same concept, or one name for two concepts.
  3. Reduce noise: strip noise words that add no meaning — data, info, manager, object, Impl. ProductInfo vs Product — if both exist, the names are indistinguishable in practice. Prefer the shorter one and let context (folder, type) carry the rest.
  4. Avoid acronyms/abbreviations: calculateInvoiceTotal, not calcInvTot. Exception: acronyms that are more standard than the spelled-out form in the domain (id, url, html) — but pick one casing convention and stay consistent.
  5. Searchable: no magic numbers/single-letter names for anything beyond a tight loop index. MAX_RETRY_COUNT, not 5 or n. A name you can grep for beats one you can't.
  6. Part of speech: classes/types get noun phrases (Invoice, PaymentProcessor); functions/methods get verb phrases (calculateTotal, isValid, hasExpired). A function named like a noun is a smell — it's probably returning something it should be named after, or doing too much.
  7. One word per concept: pick one verb for one action across the whole codebase — don't mix fetch/retrieve/get for the same kind of operation, or add/insert/append for the same kind of mutation. Check for existing convention in the codebase before introducing a new synonym.

3. Cyclomatic complexity

Budget, per function:

  • Human-authored code: ≤ 4
  • Agent-authored code (Claude/AI-generated): ≤ 6

Count: start at 1, +1 per if, else if, case, for, while, catch, &&/|| in a condition, ternary. If a function crosses the budget, refactor before considering it done — don't leave it and move on.

For a behavior-preserving change, use the refactoring sub-skill to select a technique rather than extracting merely to hit the budget.

Don't refactor purely to hit the number — a clean 5 beats a contorted 4. The budget is a trigger to look closer, not a hard gate to game.

4. Comments

No big deal. Don't treat comments as sacred or as a metric to hit — code that needs a comment to be understood should usually be rewritten first (better name, extracted function), but if a comment is the clearest way to convey something, just write it.

  • Prefer self-documenting code over comments explaining what code does.
  • Comments earn their place explaining why — a non-obvious tradeoff, a workaround for an external constraint, a deliberate deviation from the "obvious" approach.
  • Delete comments that just restate the code (// increment i above i++).
  • Stale comments (describing behavior the code no longer has) are worse than no comment — flag them for removal on sight.
  • TODOs are fine when they carry real information (why deferred, ideally by whom/when); a bare // TODO isn't worth keeping.

5. CUPID review

Use CUPID when the user asks for that framework or a broad design-quality review. First establish the language, purpose, local conventions, and scope. For each property, cite concrete code and use this shape:

### C — Composable
**Rating:** 🟢 Strong / 🟡 Moderate / 🔴 Weak
**Observations:** specific code evidence
**Suggestions:** a direction-of-travel improvement
PropertyLook for
ComposableNarrow, intention-revealing API; minimal dependencies
Unix philosophyOne externally coherent purpose; unsurprising side effects
PredictableVisible behavior, bounded failures, deterministic state
IdiomaticLanguage and local conventions; no reinvention
Domain-basedDomain vocabulary and boundaries rather than framework structure

Simplicity rules (OAOO, rule of three, YAGNI, simplest thing): simplicity principles. XP practices (collective ownership, pairing, CI, refactor mercilessly): XP practices. End with what is already working and the one to three highest-leverage improvements. CUPID is a direction, not compliance: acknowledge trade-offs and avoid “violates” or “must.” Read the full CUPID reference when a property needs deeper analysis.

Hacker ethos (curiosity- and craftsmanship-led engineering, open-source contribution approach; refuse unauthorized access): hacker manifesto.

Gotchas

  • Don't apply the agent complexity budget (6) to code a human will primarily maintain by hand — check who owns the file going forward, not who wrote the current diff.
  • Naming and complexity interact: half of what looks like "high complexity" is actually "badly named branches hiding what the function does" — try renaming before reaching for extraction.
  • Don't chase noise-word removal into ambiguity — Product vs ProductInfo is a good trim; Product vs ProductOwner is not, they're different concepts.
  • One-word-per-concept is a codebase-wide check, not a per-file one — grep for the existing verb before introducing a synonym.
  • Don't force away complexity that comes from the domain; make it explicit and verifiable instead.
  • A CUPID score is a review lens, not a reason to extract or split code without a concrete design benefit.

Benchmark

Scenario: .benchmarks/scenarios/clean-code-001-agent-code-review.md · Run: 2026-08-31 · Log: .benchmarks/runs/2026-08-31/clean-code-001-agent-code-review.json

ModelWithoutWithDelta
claude-opus-4-867%100%+33%
claude-sonnet-4-683%100%+17%
claude-haiku-4-567%67%+0%

PASS (run 2026-08-31). Opus +33 (67→100); sonnet +17 (83→100); haiku at ceiling. No regressions. Gate per .agents/skills/skill-optimizer/rules/release-gates.md.

Scenario: .benchmarks/scenarios/simple-001-root-cause-fix.md · Run: 2026-08-31 · Log: .benchmarks/runs/2026-08-31/simple-001-root-cause-fix.json

ModelWithoutWithDelta
claude-opus-4-883%100%+17%
claude-sonnet-4-683%100%+17%
claude-haiku-4-583%100%+17%

SOFT PASS (run 2026-08-31). Small uniform gains; no regressions. Gate per .agents/skills/skill-optimizer/rules/release-gates.md.

Scenario: .benchmarks/scenarios/clean-code-002-cupid-review.md — pending a baseline/skill-on rerun after this merge.

Comments

Markdown supported