$npx -y skills add softspark/ai-toolkit --skill clean-codeCode quality: meaningful names, SRP, DRY, small functions, guard clauses, refactoring. Triggers: clean code, naming, code smell, SRP, DRY, long function, god class, dead code.
| 1 | # Clean Code Skill |
| 2 | |
| 3 | ## Core Principles |
| 4 | |
| 5 | ### 1. Meaningful Names |
| 6 | |
| 7 | ```python |
| 8 | # Bad |
| 9 | def calc(a, b): |
| 10 | return a * b |
| 11 | |
| 12 | # Good |
| 13 | def calculate_total_price(unit_price: float, quantity: int) -> float: |
| 14 | return unit_price * quantity |
| 15 | ``` |
| 16 | |
| 17 | ### 2. Single Responsibility |
| 18 | |
| 19 | ```python |
| 20 | # Bad - does too much |
| 21 | def process_user(user_data): |
| 22 | validate(user_data) |
| 23 | user = create_user(user_data) |
| 24 | send_welcome_email(user) |
| 25 | log_creation(user) |
| 26 | return user |
| 27 | |
| 28 | # Good - each function does one thing |
| 29 | def create_user(user_data: UserData) -> User: |
| 30 | return User(**user_data) |
| 31 | |
| 32 | def onboard_user(user_data: UserData) -> User: |
| 33 | user = create_user(user_data) |
| 34 | send_welcome_email(user) |
| 35 | log_user_creation(user) |
| 36 | return user |
| 37 | ``` |
| 38 | |
| 39 | ### 3. DRY (Don't Repeat Yourself) |
| 40 | |
| 41 | ```python |
| 42 | # Bad |
| 43 | def get_active_users(): |
| 44 | return [u for u in users if u.status == "active"] |
| 45 | |
| 46 | def get_active_admins(): |
| 47 | return [u for u in users if u.status == "active" and u.role == "admin"] |
| 48 | |
| 49 | # Good |
| 50 | def filter_users(status: str | None = None, role: str | None = None) -> list[User]: |
| 51 | result = users |
| 52 | if status: |
| 53 | result = [u for u in result if u.status == status] |
| 54 | if role: |
| 55 | result = [u for u in result if u.role == role] |
| 56 | return result |
| 57 | ``` |
| 58 | |
| 59 | --- |
| 60 | |
| 61 | ## Code Organization |
| 62 | |
| 63 | Keep modules focused. Order contents consistently: imports (stdlib, third-party, local), constants, public API, private helpers. Use clear visibility markers (underscore prefix in Python, access modifiers in other languages). Group related functionality into cohesive modules rather than dumping everything into a single file. |
| 64 | |
| 65 | --- |
| 66 | |
| 67 | ## Anti-Patterns to Avoid |
| 68 | |
| 69 | | Anti-Pattern | Problem | Solution | |
| 70 | |--------------|---------|----------| |
| 71 | | God class | Too many responsibilities | Split into smaller classes | |
| 72 | | Long methods | Hard to understand | Extract methods | |
| 73 | | Deep nesting | Complex control flow | Early returns, extract methods | |
| 74 | | Magic numbers | Unclear meaning | Use named constants | |
| 75 | | Bare except | Hides bugs | Catch specific exceptions | |
| 76 | | Mutable defaults | Shared state bugs | Use `None` and create inside | |
| 77 | |
| 78 | --- |
| 79 | |
| 80 | ## Quality Checklist |
| 81 | |
| 82 | - [ ] Functions are small (<20 lines ideal) |
| 83 | - [ ] Names are descriptive and consistent |
| 84 | - [ ] Type hints on all public APIs |
| 85 | - [ ] Docstrings on all public functions/classes |
| 86 | - [ ] No magic numbers (use constants) |
| 87 | - [ ] No hardcoded strings (use enums/constants) |
| 88 | - [ ] Error handling is specific |
| 89 | - [ ] Resources are properly cleaned up |
| 90 | - [ ] No code duplication |
| 91 | - [ ] Tests cover critical paths |
| 92 | - [ ] **No dead code** — grep-verified zero references for every removed/renamed symbol; pre-existing dead code touched by this change is deleted too (Constitution Art. VI.1) |
| 93 | - [ ] **Every found bug fixed** — bugs, missing tests for changed behavior, and stale docs discovered during the task are fixed in the same change, not deferred (Constitution Art. VI.2) |
| 94 | |
| 95 | --- |
| 96 | |
| 97 | ## Common Rationalizations |
| 98 | |
| 99 | | Excuse | Why It's Wrong | |
| 100 | |--------|----------------| |
| 101 | | "It's readable enough" | "Enough" means someone will misread it eventually — clarity prevents incidents | |
| 102 | | "Refactoring for readability is gold-plating" | Readability is maintainability — future you will thank present you | |
| 103 | | "Short variable names are faster to type" | You type it once, readers parse it hundreds of times — optimize for reading | |
| 104 | | "DRY means never repeat anything" | Wrong DRY creates coupling — duplicate until you see the real abstraction | |
| 105 | | "More abstractions = cleaner code" | Premature abstraction is worse than duplication — wait for the third use | |
| 106 | | "That dead file is pre-existing, not my problem" | If your change makes it verifiably unused, deleting it IS your problem (Constitution Art. VI.1) | |
| 107 | | "I'll fix the missing test in a separate PR" | Forbidden when the test covers behavior you just changed — add it now (Constitution Art. VI.2) | |
| 108 | | "Świadome pominięcie" / "out of scope" | Deferral of directly-adjacent fixes is forbidden; if a user decision is needed, ASK, don't bury it | |
| 109 | |
| 110 | ## Language-Specific References |
| 111 | |
| 112 | For detailed patterns, type hints, linting configuration, and idiomatic code per language: |
| 113 | |
| 114 | - **Python:** type hints, docstrings, error handling, context managers, module/class structure, ruff/mypy config -- see [reference/python.md](reference/python.md) |
| 115 | - **TypeScript:** strict tsconfig, ESLint setup, discriminated unions, type safety -- see [reference/typescript.md](reference/typescript.md) |
| 116 | - **PHP:** PHPStan config, PSR-12, enums, constructor promotion -- see [reference/php.md](reference/php.md) |
| 117 | - **Go:** gofmt, error handling, receiver naming, early returns -- see [reference/go.md](reference/go.md) |
| 118 | - **Dart/Flutter:** null safety, named parameters, const constructors, dart analyze -- see [reference/dart.md](r |