Claude Code Plugins

Community-maintained marketplace

Feedback

|

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name code-smell-detector
description Identifies anti-patterns specific to amplihack philosophy. Use when reviewing code for quality issues or refactoring. Detects: over-abstraction, complex inheritance, large functions (>50 lines), tight coupling, missing __all__ exports. Provides specific fixes and explanations for each smell.

Code Smell Detector Skill

Purpose

This skill identifies anti-patterns that violate amplihack's development philosophy and provides constructive, specific fixes. It ensures code maintains ruthless simplicity, modular design, and zero-BS implementations.

When to Use This Skill

  • Code review: Identify violations before merging
  • Refactoring: Find opportunities to simplify and improve code quality
  • New module creation: Catch issues early in development
  • Philosophy compliance: Ensure code aligns with amplihack principles
  • Learning: Understand why patterns are problematic and how to fix them
  • Mentoring: Educate team members on philosophy-aligned code patterns

Core Philosophy Reference

Amplihack Development Philosophy focuses on:

  • Ruthless Simplicity: Every abstraction must justify its existence
  • Modular Design (Bricks & Studs): Self-contained modules with clear connection points
  • Zero-BS Implementation: No stubs, no placeholders, only working code
  • Single Responsibility: Each module/function has ONE clear job

Code Smells Detected

1. Over-Abstraction

What It Is: Unnecessary layers of abstraction, generic base classes, or interfaces that don't provide clear value.

Why It's Bad: Violates "ruthless simplicity" - adds complexity without proportional benefit. Makes code harder to understand and maintain.

Red Flags:

  • Abstract base classes with only one implementation
  • Generic helper classes that do very little
  • Deep inheritance hierarchies (3+ levels)
  • Interfaces for single implementations
  • Over-parameterized functions

Example - SMELL:

# BAD: Over-abstracted
class DataProcessor(ABC):
    @abstractmethod
    def process(self, data):
        pass

class SimpleDataProcessor(DataProcessor):
    def process(self, data):
        return data * 2

Example - FIXED:

# GOOD: Direct implementation
def process_data(data):
    """Process data by doubling it."""
    return data * 2

Detection Checklist:

  • Abstract classes with only 1-2 concrete implementations
  • Generic utility classes that don't encapsulate state
  • Type hierarchies deeper than 2 levels
  • Mixins solving single problems

Fix Strategy:

  1. Identify what the abstraction solves
  2. Check if you really need multiple implementations now
  3. Delete the abstraction - use direct implementation
  4. If multiple implementations needed later, refactor then
  5. Principle: Avoid future-proofing

2. Complex Inheritance

What It Is: Deep inheritance chains, multiple inheritance, or convoluted class hierarchies that obscure code flow.

Why It's Bad: Makes code hard to follow, creates tight coupling, violates simplicity principle. Who does what becomes unclear.

Red Flags:

  • 3+ levels of inheritance (GrandparentClass -> ParentClass -> ChildClass)
  • Multiple inheritance from non-interface classes
  • Inheritance used for code reuse instead of composition
  • Overriding multiple levels of methods
  • "Mixin" classes for cross-cutting concerns

Example - SMELL:

# BAD: Complex inheritance
class Entity:
    def save(self): pass
    def load(self): pass

class TimestampedEntity(Entity):
    def add_timestamp(self): pass

class AuditableEntity(TimestampedEntity):
    def audit_log(self): pass

class User(AuditableEntity):
    def authenticate(self): pass

Example - FIXED:

# GOOD: Composition over inheritance
class User:
    def __init__(self, storage, timestamp_service, audit_log):
        self.storage = storage
        self.timestamps = timestamp_service
        self.audit = audit_log

    def save(self):
        self.storage.save(self)
        self.timestamps.record()
        self.audit.log("saved user")

Detection Checklist:

  • Inheritance depth > 2 levels
  • Multiple inheritance from concrete classes
  • Methods overridden at multiple inheritance levels
  • Inheritance hierarchy with no code reuse

Fix Strategy:

  1. Use composition instead of inheritance
  2. Pass services as constructor arguments
  3. Each class handles its own responsibility
  4. Easier to test, understand, and modify

3. Large Functions (>50 Lines)

What It Is: Functions that do too many things and are difficult to understand, test, and modify.

Why It's Bad: Violates single responsibility, makes testing harder, increases bug surface area, reduces code reusability.

Red Flags:

  • Functions with >50 lines of code
  • Multiple indentation levels (3+ nested if/for)
  • Functions with 5+ parameters
  • Functions that need scrolling to see all of them
  • Complex logic that's hard to name

Example - SMELL:

# BAD: Large function doing multiple things
def process_user_data(user_dict, validate=True, save=True, notify=True, log=True):
    if validate:
        if not user_dict.get('email'):
            raise ValueError("Email required")
        if not '@' in user_dict['email']:
            raise ValueError("Invalid email")

    user = User(
        name=user_dict['name'],
        email=user_dict['email'],
        phone=user_dict['phone']
    )

    if save:
        db.save(user)

    if notify:
        email_service.send(user.email, "Welcome!")

    if log:
        logger.info(f"User {user.name} created")

    # ... 30+ more lines of mixed concerns
    return user

Example - FIXED:

# GOOD: Separated concerns
def validate_user_data(user_dict):
    """Validate user data structure."""
    if not user_dict.get('email'):
        raise ValueError("Email required")
    if '@' not in user_dict['email']:
        raise ValueError("Invalid email")

def create_user(user_dict):
    """Create user object from data."""
    return User(
        name=user_dict['name'],
        email=user_dict['email'],
        phone=user_dict['phone']
    )

def process_user_data(user_dict):
    """Orchestrate user creation workflow."""
    validate_user_data(user_dict)
    user = create_user(user_dict)
    db.save(user)
    email_service.send(user.email, "Welcome!")
    logger.info(f"User {user.name} created")
    return user

Detection Checklist:

  • Function body >50 lines
  • 3+ levels of nesting
  • Multiple unrelated operations
  • Hard to name succinctly
  • 5+ parameters

Fix Strategy:

  1. Extract helper functions for each concern
  2. Give each function a clear, single purpose
  3. Compose small functions into larger workflows
  4. Each function should fit on one screen
  5. Easy to name = usually doing one thing

4. Tight Coupling

What It Is: Modules/classes directly depend on concrete implementations instead of abstractions, making them hard to test and modify.

Why It's Bad: Changes in one module break others. Hard to test in isolation. Violates modularity principle.

Red Flags:

  • Direct instantiation of classes inside functions (db = Database())
  • Deep attribute access (obj.service.repository.data)
  • Hardcoded class names in conditionals
  • Module imports everything from another module
  • Circular dependencies between modules

Example - SMELL:

# BAD: Tight coupling
class UserService:
    def create_user(self, name, email):
        db = Database()  # Hardcoded dependency
        user = db.save_user(name, email)

        email_service = EmailService()  # Hardcoded dependency
        email_service.send(email, "Welcome!")

        return user

    def get_user(self, user_id):
        db = Database()
        return db.find_user(user_id)

Example - FIXED:

# GOOD: Loose coupling via dependency injection
class UserService:
    def __init__(self, db, email_service):
        self.db = db
        self.email = email_service

    def create_user(self, name, email):
        user = self.db.save_user(name, email)
        self.email.send(email, "Welcome!")
        return user

    def get_user(self, user_id):
        return self.db.find_user(user_id)

# Usage:
user_service = UserService(db=PostgresDB(), email_service=SMTPService())

Detection Checklist:

  • Class instantiation inside methods (Service())
  • Deep attribute chaining (3+ dots)
  • Hardcoded class references
  • Circular imports or dependencies
  • Module can't be tested without other modules

Fix Strategy:

  1. Accept dependencies as constructor parameters
  2. Use dependency injection
  3. Create test doubles (mocks) easily
  4. Swap implementations without changing code
  5. Each module is independently testable

5. Missing __all__ Exports (Python)

What It Is: Python modules that don't explicitly define their public interface via __all__.

Why It's Bad: Unclear what's public vs internal. Users import private implementation details. Violates the "stud" concept - unclear connection points.

Red Flags:

  • No __all__ in __init__.py
  • Modules expose internal functions/classes
  • Users uncertain what to import
  • Private names (_function) still accessible
  • Documentation doesn't match exports

Example - SMELL:

# BAD: No __all__ - unclear public interface
# module/__init__.py
from .core import process_data, _internal_helper
from .utils import validate_input, LOG_LEVEL

# What should users import? All of it? Only some?

Example - FIXED:

# GOOD: Clear public interface via __all__
# module/__init__.py
from .core import process_data
from .utils import validate_input

__all__ = ['process_data', 'validate_input']

# Users know exactly what's public and what to use

Detection Checklist:

  • Missing __all__ in __init__.py
  • Internal functions (prefixed with _) exposed
  • Unclear what's "public API"
  • All imports at module level

Fix Strategy:

  1. Add __all__ to every __init__.py
  2. List ONLY the public functions/classes
  3. Prefix internal implementation with _
  4. Update documentation to match __all__
  5. Clear = users know exactly what to use

Analysis Process

Step 1: Scan Code Structure

  1. Review file organization and module boundaries
  2. Identify inheritance hierarchies
  3. Scan for large functions (count lines)
  4. Note __all__ presence/absence
  5. Check for tight coupling patterns

Step 2: Analyze Each Smell

For each potential issue:

  1. Confirm it violates philosophy
  2. Measure severity (critical/major/minor)
  3. Find specific line numbers
  4. Note impact on system

Step 3: Generate Fixes

For each smell found:

  1. Provide clear explanation of WHY it's bad
  2. Show BEFORE code
  3. Show AFTER code with detailed comments
  4. Explain philosophy principle violated
  5. Give concrete refactoring steps

Step 4: Create Report

  1. List all smells found
  2. Prioritize by severity/impact
  3. Include specific examples
  4. Provide actionable fixes
  5. Reference philosophy docs

Detection Rules

Rule 1: Abstract Base Classes

Check: class X(ABC) with exactly 1 concrete implementation

# BAD pattern detection
- Count implementations of abstract class
- If count <= 2 and not used as interface: FLAG

Fix: Remove abstraction, use direct implementation

Rule 2: Inheritance Depth

Check: Class hierarchy depth

# BAD pattern detection
- Follow inheritance chain: class -> parent -> grandparent...
- If depth > 2: FLAG

Fix: Use composition instead

Rule 3: Function Line Count

Check: All function bodies

# BAD pattern detection
- Count lines in function (excluding docstring)
- If > 50 lines: FLAG
- If > 3 nesting levels: FLAG

Fix: Extract helper functions

Rule 4: Dependency Instantiation

Check: Class instantiation inside methods/functions

# BAD pattern detection
- Search for "= ServiceName()" inside methods
- If found: FLAG

Fix: Pass as constructor argument

Rule 5: Missing all

Check: Python modules

# BAD pattern detection
- Look for __all__ definition
- If missing: FLAG
- If __all__ incomplete: FLAG

Fix: Define explicit __all__


Common Code Smells & Quick Fixes

Smell: "Utility Class" Holder

# BAD
class StringUtils:
    @staticmethod
    def clean(s):
        return s.strip().lower()

Fix: Use direct function

# GOOD
def clean_string(s):
    return s.strip().lower()

Smell: "Manager" Class

# BAD
class UserManager:
    def create(self): pass
    def update(self): pass
    def delete(self): pass
    def validate(self): pass
    def email(self): pass

Fix: Split into focused services

# GOOD
class UserService:
    def __init__(self, db, email):
        self.db = db
        self.email = email

    def create(self): pass
    def update(self): pass
    def delete(self): pass

def validate_user(user): pass

Smell: God Function

# BAD - 200 line function doing everything
def process_order(order_data, validate, save, notify, etc...):
    # 200 lines mixing validation, transformation, DB, email, logging

Fix: Compose small functions

# GOOD
def process_order(order_data):
    validate_order(order_data)
    order = create_order(order_data)
    save_order(order)
    notify_customer(order)
    log_creation(order)

Smell: Brittle Inheritance

# BAD
class Base:
    def work(self): pass
class Middle(Base):
    def work(self):
        return super().work()
class Derived(Middle):
    def work(self):
        return super().work()  # Which work()?

Fix: Use clear, testable composition

# GOOD
class Worker:
    def __init__(self, validator, transformer):
        self.validator = validator
        self.transformer = transformer

    def work(self, data):
        self.validator.check(data)
        return self.transformer.apply(data)

Smell: Hidden Dependencies

# BAD
def fetch_data(user_id):
    db = Database()  # Where's this coming from?
    return db.query(f"SELECT * FROM users WHERE id={user_id}")

Fix: Inject dependencies explicitly

# GOOD
def fetch_data(user_id, db):
    return db.query(f"SELECT * FROM users WHERE id={user_id}")

# Or in a class:
class UserRepository:
    def __init__(self, db):
        self.db = db

    def fetch(self, user_id):
        return self.db.query(f"SELECT * FROM users WHERE id={user_id}")

Usage Examples

Example 1: Review New Module

User: Review this new authentication module for code smells.

Claude:
1. Scans all Python files in module
2. Checks for each smell type
3. Finds:
   - Abstract base class with 1 implementation
   - Large 120-line authenticate() function
   - Missing __all__ in __init__.py
4. Provides specific fixes with before/after code
5. Explains philosophy violations

Example 2: Identify Tight Coupling

User: Find tight coupling in this user service.

Claude:
1. Traces all dependencies
2. Finds hardcoded Database() instantiation
3. Finds direct EmailService() creation
4. Shows dependency injection fix
5. Includes test example showing why it matters

Example 3: Simplify Inheritance

User: This class hierarchy is too complex.

Claude:
1. Maps inheritance tree (finds 4 levels)
2. Shows each level doing what
3. Suggests composition approach
4. Provides before/after refactoring
5. Explains how it aligns with brick philosophy

Analysis Checklist

Philosophy Compliance

  • No unnecessary abstractions
  • Single responsibility per class/function
  • Clear public interface (__all__)
  • Dependencies injected, not hidden
  • Inheritance depth <= 2 levels
  • Functions < 50 lines
  • No dead code or stubs

Code Quality

  • Each function has one clear job
  • Easy to understand at a glance
  • Easy to test in isolation
  • Easy to modify without breaking others
  • Clear naming reflects responsibility

Modularity

  • Modules are independently testable
  • Clear connection points ("studs")
  • Loose coupling between modules
  • Explicit dependencies

Success Criteria for Review

A code review using this skill should:

  • Identify all violations of philosophy
  • Provide specific line numbers
  • Show before/after examples
  • Explain WHY each is a problem
  • Suggest concrete fixes
  • Include test strategies
  • Reference philosophy docs
  • Prioritize by severity
  • Be constructive and educational
  • Help writer improve future code

Integration with Code Quality Tools

When to Use This Skill:

  • During code review (before merge)
  • In pull request comments
  • Before creating new modules
  • When refactoring legacy code
  • To educate team members
  • In design review meetings

Works Well With:

  • Code review process
  • Module spec generation
  • Refactoring workflows
  • Architecture discussions
  • Mentoring and learning

Resources

  • Philosophy: .claude/context/PHILOSOPHY.md
  • Patterns: .claude/context/PATTERNS.md
  • Brick Philosophy: See "Modular Architecture for AI" in PHILOSOPHY.md
  • Zero-BS: See "Zero-BS Implementations" in PHILOSOPHY.md

Remember

This skill helps maintain code quality by:

  1. Catching issues before they become technical debt
  2. Educating developers on philosophy
  3. Keeping code simple and maintainable
  4. Preventing tightly-coupled systems
  5. Making code easier to understand and modify

Use it constructively - the goal is learning and improvement, not criticism.