| name | code-smells |
| description | Detect, name, and remediate code smells using the classic taxonomy (Bloaters, Object-Orientation Abusers, Change Preventers, Dispensables, Couplers) when reviewing, refactoring, or authoring code. Use when the user asks to find code smells, review code for maintainability, identify long methods/large classes/duplicate code/feature envy, or wants refactoring guidance tied to a named smell. |
Code Smells
Purpose
Help spot, name, and treat code smells — surface indicators that usually correspond to deeper problems in a system. A smell is not a bug: the code works. It's a sign that the design will be costly to extend, understand, or change. Naming the smell precisely points to the right refactoring.
What is a code smell?
"Code smells are certain structures in the code that indicate violation of fundamental design principles and negatively impact design quality."
Smells don't crop up all at once — they accumulate over time as a program evolves, especially when nobody actively removes them. Treat them as heuristics that warrant a closer look, not automatic defects: context decides whether a given smell is worth fixing now.
When To Use
Use this skill when the user asks to:
- Find smells in a file, module, or PR ("what smells do you see here?", "review this for code smells").
- Refactor code and wants the change anchored to a named smell and its standard treatment.
- Author code and wants a pre-merge check against common smells.
- Diagnose why a change is painful (e.g., "every time I touch X I have to edit five files").
When to ease off
Smells are defaults, not laws. Apply a lighter bar when the user signals urgency or disposability: production hotfix, time-boxed spike, or generated/boilerplate code they won't own. A short method, a small switch on a stable discriminant, or a tiny data holder can be perfectly fine. Prefer clarity and safe change over checklist compliance; escalate a treatment only when duplication, churn, or comprehension cost justifies it.
The Five Categories
Each smell belongs to one family. Detail for every smell — signs & symptoms, reasons it occurs, treatment (refactorings), and payoff — lives in REFERENCE.md.
Bloaters
Code, methods, and classes that have grown to unmanageable proportions. They accumulate gradually.
Object-Orientation Abusers
Incomplete or incorrect application of object-oriented principles.
Change Preventers
A change in one place forces many changes elsewhere — development becomes slow and expensive.
Dispensables
Something pointless and unneeded whose removal makes code cleaner and easier to understand.
Couplers
Excessive coupling between classes, or what happens when coupling is replaced by excessive delegation.
Review Workflow
- Read from high level to detail (public API → implementation).
- Tag each issue with a smell name and its category from the index above.
- Assign severity:
blocker (correctness/safety risk), major (maintainability risk), minor (clarity), nit (style only). Most smells are major/minor, not blocker.
- Propose the standard treatment (the named refactoring), not vague advice.
- Cite the relevant
REFERENCE.md section anchor (e.g., REFERENCE.md#feature-envy).
Output Contract
Emit findings one line each where possible:
[severity] [smell] path:line — what's wrong → suggested refactoring (REFERENCE.md#anchor)
Optional summary at the end: counts by category and the top 3 recommended refactorings.
Quick Heuristics (highest leverage)
- A method longer than ~10 lines or that needs a comment to explain a block → suspect Long Method.
- A class with many fields/methods doing several jobs → Large Class / Divergent Change.
- The same group of fields/params appearing together repeatedly → Data Clumps / Long Parameter List.
- Primitives standing in for concepts (strings for currency, ints for state) → Primitive Obsession.
- A method more interested in another class's data than its own → Feature Envy.
a.getB().getC().getD() → Message Chains.
- One change forces edits in many classes → Shotgun Surgery; one class changed for many reasons → Divergent Change.
- Adding a subclass forces a parallel subclass elsewhere → Parallel Inheritance Hierarchies.
switch/if chains on a type code that recur → Switch Statements.
Anti-Patterns to Flag Aggressively
- Duplicated business rules across files (Duplicate Code).
- Commented-out code and dead branches (Dead Code).
- Comments that excuse bad names instead of fixing them (Comments).
- Subclasses that throw/no-op inherited methods they don't want (Refused Bequest).
- Classes built for imagined future needs that never arrived (Speculative Generality).
- Fields only populated in certain circumstances (Temporary Field).