@intentsolutionsio/code-cleanup 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,183 @@
1
+ ---
2
+ name: cleanup-code
3
+ description: |
4
+ Comprehensive codebase cleanup across 11 quality dimensions: dead code, duplication,
5
+ weak types, circular deps, defensive cruft, legacy code, AI slop, type consolidation,
6
+ security, performance, and async patterns. Analyzes code with confidence scoring and
7
+ verifies changes with build/test gates. Use when codebase has accumulated tech debt,
8
+ after major feature work, before releases, or when code quality metrics are declining.
9
+ Trigger with "/cleanup-code-code", "clean up the codebase", "remove dead code", "fix code quality".
10
+ allowed-tools: Read, Write, Edit, Glob, Grep, Bash(git:*), Bash(npm:*), Bash(npx:*), Bash(pnpm:*), Bash(python3:*), Bash(tsc:*), Bash(wc:*), Bash(ls:*), AskUserQuestion
11
+ version: 1.0.0
12
+ author: Jeremy Longshore <jeremy@intentsolutions.io>
13
+ license: MIT
14
+ compatible-with: claude-code, codex, openclaw
15
+ tags: [code-quality, cleanup, refactoring, dead-code, deduplication, type-safety, security]
16
+ argument-hint: "[scope] [--dimensions d1,d2,...] [--changed]"
17
+ ---
18
+
19
+ # Codebase Cleanup
20
+
21
+ Systematic code cleanup across 11 quality dimensions, ordered by risk. Each finding includes
22
+ confidence scoring (HIGH/MEDIUM/LOW) and all changes are verified through build/test gates.
23
+
24
+ ## Environment Detection
25
+
26
+ !`git rev-parse --show-toplevel 2>/dev/null && echo "---" && git diff --stat HEAD~5 2>/dev/null | tail -5`
27
+ !`ls package.json pyproject.toml Cargo.toml go.mod Makefile 2>/dev/null | head -5`
28
+ !`cat package.json 2>/dev/null | head -3; echo "---"; ls tsconfig.json .eslintrc* 2>/dev/null`
29
+
30
+ ## Prerequisites
31
+
32
+ - Git repository with clean working tree (no uncommitted changes)
33
+ - Language toolchain installed (Node.js/Python/Go/Rust as applicable)
34
+ - Optional: `knip`, `madge`, `jscpd`, `ruff`, `bandit` for tool-verified scanning
35
+
36
+ ## Overview
37
+
38
+ This skill orchestrates cleanup across **11 dimensions**, each with a dedicated agent.
39
+ Dimensions are ordered LOW → HIGH risk. See [dimensions reference](references/dimensions.md)
40
+ for full detection criteria, verification steps, and risk profiles.
41
+
42
+ **The 11 Dimensions** (by risk level):
43
+
44
+ | # | Dimension | Key | Risk | Auto-apply? |
45
+ |---|-----------|-----|------|-------------|
46
+ | 1 | Dead code removal | `dead` | LOW | Yes (after build) |
47
+ | 2 | AI slop removal | `slop` | LOW | Comments only |
48
+ | 3 | Weak type elimination | `types` | MED | Yes (after typecheck) |
49
+ | 4 | Security cleanup | `security` | MED | Flag only |
50
+ | 5 | Legacy code removal | `legacy` | MED | With confirmation |
51
+ | 6 | Type consolidation | `typecons` | MED | Yes (after typecheck) |
52
+ | 7 | Defensive code cleanup | `defensive` | MED | Flag only |
53
+ | 8 | Performance optimization | `perf` | MED | Flag only |
54
+ | 9 | DRY deduplication | `dry` | HIGH | Flag only (>=10 lines) |
55
+ | 10 | Async pattern fixes | `async` | HIGH | Flag only |
56
+ | 11 | Circular dep untangling | `circular` | HIGH | Flag only |
57
+
58
+ ## Instructions
59
+
60
+ ### Step 1: Safety Checkpoint
61
+
62
+ Before any changes:
63
+
64
+ 1. Verify clean git state: `git status --porcelain` must be empty (or stash changes)
65
+ 2. Record baseline: `git rev-parse HEAD` as rollback point
66
+ 3. Run existing tests to confirm green baseline
67
+ 4. See [safety protocol](references/safety.md) for revert procedures
68
+
69
+ ### Step 2: Determine Scope
70
+
71
+ Parse user arguments to set scope:
72
+
73
+ - **Full codebase** (default): scan all source files
74
+ - **Specific path**: `cleanup src/api/` — limit to directory
75
+ - **Changed files only**: `--changed` flag — `git diff --name-only HEAD~10`
76
+ - **Specific dimensions**: `--dimensions dead,types,security`
77
+ - **Single dimension**: `cleanup --dimensions dry`
78
+
79
+ Exclude from all scans: `node_modules/`, `dist/`, `build/`, `.git/`, vendor dirs, generated files.
80
+
81
+ ### Step 3: Execute Dimensions
82
+
83
+ For each selected dimension (in risk order):
84
+
85
+ 1. **Scan** using patterns from [patterns reference](references/patterns.md)
86
+ 2. **Score confidence** — HIGH (certain, safe to fix), MEDIUM (likely, needs review), LOW (possible, flag only)
87
+ 3. **Apply or flag** based on the dimension's auto-apply policy (see table above)
88
+ 4. **Verify** — run build/typecheck/tests after each dimension with auto-apply
89
+
90
+ Use [tools reference](references/tools.md) for language-specific tool commands (knip, madge, ruff, jscpd, etc.).
91
+
92
+ ### Step 4: Build Verification Gate
93
+
94
+ After each auto-applied dimension:
95
+
96
+ ```bash
97
+ # TypeScript/JavaScript
98
+ npx tsc --noEmit 2>&1 | tail -20
99
+ npm test 2>&1 | tail -30
100
+
101
+ # Python
102
+ python3 -m py_compile <changed_files>
103
+ python3 -m pytest --tb=short 2>&1 | tail -30
104
+
105
+ # General
106
+ git diff --stat # Show what changed
107
+ ```
108
+
109
+ If verification fails, revert that dimension: `git checkout -- .`
110
+
111
+ ### Step 5: Generate Report
112
+
113
+ Produce a cleanup report in this format:
114
+
115
+ ```
116
+ ## Cleanup Report
117
+
118
+ **Scope:** [path or "full codebase"]
119
+ **Baseline:** [commit hash]
120
+ **Dimensions:** [list of dimensions run]
121
+
122
+ ### Summary
123
+ | Dimension | Findings | Applied | Flagged | Confidence |
124
+ |-----------|----------|---------|---------|------------|
125
+ | dead | 12 | 10 | 2 | HIGH |
126
+ | types | 8 | 8 | 0 | HIGH |
127
+ | security | 3 | 0 | 3 | MEDIUM |
128
+
129
+ ### Changes Applied
130
+ - [file:line] description of change
131
+
132
+ ### Flagged for Review
133
+ - [file:line] description + reasoning + suggested fix
134
+
135
+ ### Lines Removed: N | Lines Modified: N | Files Touched: N
136
+ ```
137
+
138
+ ## Output
139
+
140
+ A structured cleanup report containing:
141
+ - Summary table with findings per dimension (count, applied, flagged, confidence)
142
+ - List of changes applied with file:line references
143
+ - List of flagged items with reasoning and suggested fixes
144
+ - Stats: lines removed, lines modified, files touched
145
+
146
+ ## Error Handling
147
+
148
+ | Error | Recovery |
149
+ |-------|----------|
150
+ | Dirty git state | Ask user to commit or stash first |
151
+ | Build fails after cleanup | `git checkout -- .` to revert dimension |
152
+ | No test command found | Skip verification, flag all as "unverified" |
153
+ | Tool not installed | Fall back to grep patterns (see references/patterns.md) |
154
+ | Confidence unclear | Default to flag-only, never auto-apply |
155
+
156
+ ## Examples
157
+
158
+ **Full cleanup:**
159
+ ```
160
+ /cleanup-code
161
+ ```
162
+
163
+ **Security-focused:**
164
+ ```
165
+ /cleanup-code --dimensions security,async
166
+ ```
167
+
168
+ **Changed files only:**
169
+ ```
170
+ /cleanup-code src/api/ --changed
171
+ ```
172
+
173
+ **Single dimension deep-dive:**
174
+ ```
175
+ /cleanup-code --dimensions dead
176
+ ```
177
+
178
+ ## Resources
179
+
180
+ - [All 11 Dimensions](references/dimensions.md) — detection criteria, verification, risk profiles
181
+ - [Tool Reference](references/tools.md) — language-specific cleanup tools
182
+ - [Grep Patterns](references/patterns.md) — detection patterns by dimension
183
+ - [Safety Protocol](references/safety.md) — revert procedures, confidence scoring
@@ -0,0 +1,241 @@
1
+ # Cleanup Dimensions Reference
2
+
3
+ Complete reference for all 11 cleanup dimensions, ordered by risk level.
4
+
5
+ ---
6
+
7
+ ## 1. Dead Code (Key: `dead` | Risk: LOW)
8
+
9
+ **What:** Unreachable code, unused exports, unused variables, unused imports, unused functions, dead branches.
10
+
11
+ **Detection:**
12
+ - Unused exports: `knip` (JS/TS), `vulture` (Python), `deadcode` (Go)
13
+ - Unused variables: compiler warnings, linter output
14
+ - Unreachable code: code after `return`/`throw`/`break`/`continue`
15
+ - Dead feature flags: flags that are always true/false
16
+
17
+ **Verification:**
18
+ 1. Remove candidate
19
+ 2. Run `tsc --noEmit` (TS) or equivalent type check
20
+ 3. Run test suite
21
+ 4. If both pass → confirmed dead code
22
+
23
+ **Auto-apply:** Yes, after build verification passes.
24
+
25
+ **False positive signals:** Dynamic imports, reflection, test fixtures, plugin entry points, CLI entry points.
26
+
27
+ ---
28
+
29
+ ## 2. AI Slop (Key: `slop` | Risk: LOW)
30
+
31
+ **What:** Low-value comments generated by AI assistants — restating obvious code, adding filler.
32
+
33
+ **Detection patterns:**
34
+ - Comments that restate the next line: `// Set the name` above `name = value`
35
+ - Obvious JSDoc: `@param name - The name` or `@returns The result`
36
+ - Section markers with no value: `// --- Helper Functions ---`
37
+ - Filler phrases: "This function", "This method", "This class", "As mentioned above"
38
+ - Over-documentation of trivial code
39
+
40
+ **Verification:** Read the comment and the code it describes. If removing the comment loses zero information, it's slop.
41
+
42
+ **Auto-apply:** Comments only — remove slop comments. Never modify actual code in this dimension.
43
+
44
+ **False positive signals:** Comments explaining *why* (business logic, workarounds, TODOs with context), JSDoc on public APIs.
45
+
46
+ ---
47
+
48
+ ## 3. Weak Types (Key: `types` | Risk: MEDIUM)
49
+
50
+ **What:** `any`, `unknown` used unnecessarily, missing return types, implicit any, overly broad generics.
51
+
52
+ **Detection:**
53
+ - TypeScript: `any` type annotations, missing return types on exported functions
54
+ - Python: missing type hints on public functions, `Any` imports from typing
55
+ - Untyped function parameters in public APIs
56
+
57
+ **Verification:**
58
+ 1. Replace `any` with specific type
59
+ 2. Run `tsc --noEmit` — must compile without new errors
60
+ 3. Run tests
61
+
62
+ **Auto-apply:** Yes, when the correct type is unambiguous (inferred from usage). Flag when ambiguous.
63
+
64
+ **False positive signals:** Intentional `any` for serialization boundaries, third-party type gaps, `unknown` in catch blocks (correct usage).
65
+
66
+ ---
67
+
68
+ ## 4. Security (Key: `security` | Risk: MEDIUM)
69
+
70
+ **What:** Hardcoded secrets, weak crypto, SQL injection vectors, command injection, path traversal, insecure defaults.
71
+
72
+ **Detection categories:**
73
+
74
+ | Category | Patterns |
75
+ |----------|----------|
76
+ | Hardcoded secrets | API keys, tokens, passwords in source code |
77
+ | Weak crypto | MD5, SHA1 for security purposes, `Math.random()` for tokens |
78
+ | SQL injection | String concatenation in SQL queries |
79
+ | Command injection | Unsanitized input in `exec()`, `spawn()`, shell commands |
80
+ | Path traversal | Unsanitized `../` in file paths |
81
+ | Insecure defaults | HTTP instead of HTTPS, disabled TLS verification |
82
+
83
+ **Verification:** Manual review required — security findings are NEVER auto-applied.
84
+
85
+ **Auto-apply:** NEVER. Flag all findings with severity (CRITICAL/HIGH/MEDIUM/LOW) and suggested fix.
86
+
87
+ **False positive signals:** Test fixtures, example code in docs, intentionally disabled security in dev mode.
88
+
89
+ ---
90
+
91
+ ## 5. Legacy Code (Key: `legacy` | Risk: MEDIUM)
92
+
93
+ **What:** Deprecated API usage, old syntax patterns, compatibility shims for dropped platforms, polyfills for supported targets.
94
+
95
+ **Detection:**
96
+ - Deprecated Node.js APIs (`fs.exists`, `url.parse`, `new Buffer()`)
97
+ - Old JS patterns (`var`, `arguments` object, `prototype` instead of class)
98
+ - Unnecessary polyfills based on browserslist/engines config
99
+ - Compatibility code for unsupported environments
100
+
101
+ **Verification:**
102
+ 1. Replace with modern equivalent
103
+ 2. Check minimum platform target (engines, browserslist)
104
+ 3. Run tests
105
+
106
+ **Auto-apply:** Yes, with confirmation prompt for each batch.
107
+
108
+ **False positive signals:** Intentional backward compatibility, library code that must support older runtimes.
109
+
110
+ ---
111
+
112
+ ## 6. Type Consolidation (Key: `typecons` | Risk: MEDIUM)
113
+
114
+ **What:** Duplicate type definitions, inconsistent interfaces, types that should be derived/shared.
115
+
116
+ **Detection:**
117
+ - Multiple interfaces with >80% field overlap
118
+ - Same type defined in multiple files
119
+ - Types that could use `Pick<>`, `Omit<>`, `Partial<>` instead of duplication
120
+ - Enum values duplicated as string literals elsewhere
121
+
122
+ **Verification:**
123
+ 1. Consolidate to single source
124
+ 2. Update all imports
125
+ 3. Run `tsc --noEmit` + tests
126
+
127
+ **Auto-apply:** Yes, after typecheck passes.
128
+
129
+ **False positive signals:** Types that are intentionally separate (different domains), API boundary types that mirror but shouldn't depend on internal types.
130
+
131
+ ---
132
+
133
+ ## 7. Defensive Code (Key: `defensive` | Risk: MEDIUM)
134
+
135
+ **What:** Unnecessary null checks, impossible error handling, redundant validation, dead catch blocks.
136
+
137
+ **Detection:**
138
+ - Null checks on values that are never null (check upstream guarantees)
139
+ - Try/catch around code that cannot throw
140
+ - Validation of internal function parameters (not at system boundary)
141
+ - Default values for required parameters
142
+ - `typeof x !== 'undefined'` checks in module scope
143
+
144
+ **Verification:** Trace data flow to confirm the defensive check is unnecessary. Read callers and type definitions.
145
+
146
+ **Auto-apply:** Flag only. Show reasoning for why the check is unnecessary.
147
+
148
+ **False positive signals:** Legitimate boundary validation, checks that guard against runtime data (API responses, user input), platform-specific guards.
149
+
150
+ ---
151
+
152
+ ## 8. Performance (Key: `perf` | Risk: MEDIUM)
153
+
154
+ **What:** N+1 queries, blocking I/O in async contexts, bundle bloat, unnecessary re-renders, inefficient algorithms.
155
+
156
+ **Detection categories:**
157
+
158
+ | Category | Patterns |
159
+ |----------|----------|
160
+ | N+1 queries | Loop containing DB/API call |
161
+ | Blocking I/O | `fs.readFileSync` in request handlers, synchronous HTTP |
162
+ | Bundle bloat | Full library import when tree-shakeable (`import lodash` vs `import map from 'lodash/map'`) |
163
+ | Re-renders | Missing `useMemo`/`useCallback` on expensive ops, object literals in JSX props |
164
+ | Inefficient algorithms | Nested loops on large datasets, repeated array scans |
165
+
166
+ **Verification:** Performance changes require benchmarking or profile evidence.
167
+
168
+ **Auto-apply:** Flag only. Provide suggested fix and estimated impact.
169
+
170
+ **False positive signals:** One-time startup code, build scripts, code paths that handle small datasets, intentional eager loading.
171
+
172
+ ---
173
+
174
+ ## 9. DRY Deduplication (Key: `dry` | Risk: HIGH)
175
+
176
+ **What:** Copy-pasted code blocks, duplicated logic across files, repeated patterns that should be abstracted.
177
+
178
+ **Detection:**
179
+ - `jscpd` tool for exact/near-duplicate detection
180
+ - Manual scan for functions with identical structure but different names
181
+ - Threshold: **>=10 identical lines** before flagging
182
+
183
+ **Verification:** Ensure the duplicated code truly serves the same purpose. Sometimes identical code has different *reasons* to change.
184
+
185
+ **Auto-apply:** NEVER for code. Flag only, with suggested extraction.
186
+
187
+ **Important:** Three similar lines is NOT duplication. Only flag when extraction genuinely reduces maintenance burden. Premature abstraction is worse than duplication.
188
+
189
+ **False positive signals:** Test setup code (intentionally duplicated for isolation), similar but semantically different operations, code that will diverge.
190
+
191
+ ---
192
+
193
+ ## 10. Async Patterns (Key: `async` | Risk: HIGH)
194
+
195
+ **What:** Floating promises, `async` in `forEach`, missing `await`, unhandled rejections, race conditions.
196
+
197
+ **Detection:**
198
+
199
+ | Pattern | Problem |
200
+ |---------|---------|
201
+ | `array.forEach(async ...)` | Promises float, no error handling |
202
+ | Missing `await` | Promise returned but not awaited |
203
+ | `async` function with no `await` | Unnecessary async wrapper |
204
+ | `.then()` mixed with `await` | Inconsistent patterns, harder to debug |
205
+ | Missing `.catch()` on fire-and-forget | Unhandled rejection |
206
+ | `Promise.all` without error strategy | One failure kills all |
207
+
208
+ **Verification:**
209
+ 1. Confirm the async pattern is actually incorrect (not intentional fire-and-forget)
210
+ 2. Apply fix
211
+ 3. Run tests — async bugs often only surface under load
212
+
213
+ **Auto-apply:** NEVER. Flag with explanation of the specific risk.
214
+
215
+ **False positive signals:** Intentional fire-and-forget with error logging, event emitters, streaming patterns where floating is expected.
216
+
217
+ ---
218
+
219
+ ## 11. Circular Dependencies (Key: `circular` | Risk: HIGH)
220
+
221
+ **What:** Module A imports B which imports A, creating initialization order issues, bundle bloat, and test difficulty.
222
+
223
+ **Detection:**
224
+ - `madge --circular` (JS/TS)
225
+ - `dependency-cruiser` (JS/TS, configurable)
226
+ - Import graph analysis
227
+
228
+ **Resolution strategies:**
229
+ 1. **Extract shared types** to a separate module
230
+ 2. **Dependency inversion** — depend on interfaces, not implementations
231
+ 3. **Lazy imports** — dynamic `import()` to break cycles
232
+ 4. **Barrel file restructuring** — split index.ts re-exports
233
+
234
+ **Verification:**
235
+ 1. Run `madge --circular` — should show fewer cycles
236
+ 2. Run full test suite
237
+ 3. Check bundle size hasn't increased
238
+
239
+ **Auto-apply:** NEVER. Flag with dependency graph and suggested resolution strategy.
240
+
241
+ **False positive signals:** Circular type-only imports (no runtime impact in TS), monorepo cross-references that are resolved by bundler.
@@ -0,0 +1,195 @@
1
+ # Grep Patterns by Dimension
2
+
3
+ Fallback detection patterns when dedicated tools aren't installed. Use with `Grep` tool or `rg`.
4
+
5
+ ---
6
+
7
+ ## Dead Code
8
+
9
+ ```bash
10
+ # Unused imports (JS/TS) — imported but never referenced
11
+ rg "^import .+ from " --type ts -l # Get all files with imports, then cross-reference
12
+
13
+ # Unreachable code after return/throw
14
+ rg "^\s*(return|throw)\b" -A 2 --type ts # Look for code after return/throw
15
+
16
+ # Commented-out code blocks (>3 lines)
17
+ rg "^\s*//" --type ts -c | sort -t: -k2 -rn | head -20 # Files with most comments
18
+
19
+ # TODO/FIXME/HACK markers (potential dead code indicators)
20
+ rg "(TODO|FIXME|HACK|XXX|DEPRECATED)" --type-add 'src:*.{ts,js,py,go,rs}' --type src
21
+
22
+ # Empty catch blocks
23
+ rg "catch\s*\([^)]*\)\s*\{\s*\}" --type ts
24
+
25
+ # Unused function parameters (starts with _)
26
+ rg "function\s+\w+\([^)]*_\w+" --type ts
27
+ ```
28
+
29
+ ## AI Slop
30
+
31
+ ```bash
32
+ # Restating comments: "// Set X" or "// Get X" or "// Return X"
33
+ rg "//\s*(Set|Get|Return|Create|Initialize|Define|Check|Update|Delete|Remove)\s+(the\s+)?\w+" --type ts
34
+
35
+ # Obvious JSDoc
36
+ rg "@param\s+\w+\s*-?\s*(The|A|An)\s+\w+$" --type ts
37
+ rg "@returns?\s*(The|A|An)\s+\w+$" --type ts
38
+
39
+ # Filler section markers
40
+ rg "//\s*-{3,}.*-{3,}" --type ts
41
+ rg "//\s*(Helper|Utility|Private|Public)\s+(Functions|Methods|Variables)" --type ts
42
+
43
+ # "This function/method/class" comments
44
+ rg "//.*\b(This (function|method|class|variable|constant|module))" --type ts
45
+ ```
46
+
47
+ ## Weak Types
48
+
49
+ ```bash
50
+ # Explicit any (TypeScript)
51
+ rg ": any\b" --type ts
52
+ rg "as any\b" --type ts
53
+ rg "<any>" --type ts
54
+
55
+ # Implicit any — missing return types on exported functions
56
+ rg "export (async )?function \w+\([^)]*\)\s*\{" --type ts # No return type annotation
57
+
58
+ # Python Any import
59
+ rg "from typing import.*\bAny\b" --type py
60
+ rg ":\s*Any\b" --type py
61
+
62
+ # Object type (too broad)
63
+ rg ": object\b" --type ts
64
+ rg ": Object\b" --type ts
65
+ rg ": \{\}" --type ts # Empty object type
66
+ ```
67
+
68
+ ## Security
69
+
70
+ ```bash
71
+ # Hardcoded secrets
72
+ rg "(api[_-]?key|secret|password|token|auth)\s*[:=]\s*['\"][^'\"]{8,}" -i
73
+ rg "(AKIA[A-Z0-9]{16})" # AWS access keys
74
+ rg "-----BEGIN (RSA |EC |DSA )?PRIVATE.KEY-----"
75
+ rg "(ghp_|gho_|ghu_|ghs_|ghr_)[A-Za-z0-9_]{36,}" # GitHub tokens
76
+
77
+ # Weak crypto
78
+ rg "(md5|sha1)\s*\(" -i --type-add 'src:*.{ts,js,py,go,rs}' --type src
79
+ rg "Math\.random\(\)" --type ts # Insecure random for tokens
80
+ rg "crypto\.createHash\(['\"]md5" --type ts
81
+
82
+ # SQL injection vectors
83
+ rg "(query|exec|execute)\s*\(\s*[`'\"].*\$\{" --type ts # Template literal in SQL
84
+ rg "f['\"].*SELECT.*\{" --type py # Python f-string SQL
85
+
86
+ # Command injection
87
+ rg "(exec|execSync|spawn|spawnSync)\s*\(" --type ts
88
+ rg "(subprocess\.call|os\.system|os\.popen)\s*\(" --type py
89
+
90
+ # eval usage
91
+ rg "\beval\s*\(" --type-add 'src:*.{ts,js,py}' --type src
92
+
93
+ # Insecure defaults
94
+ rg "rejectUnauthorized:\s*false" --type ts
95
+ rg "verify\s*=\s*False" --type py # Disabled SSL verify
96
+ rg "http://" --type-add 'src:*.{ts,js,py,go}' --type src # Plain HTTP
97
+ ```
98
+
99
+ ## Legacy Code
100
+
101
+ ```bash
102
+ # Old Node.js APIs
103
+ rg "\bnew Buffer\b" --type ts
104
+ rg "\bfs\.exists\b" --type ts # Use fs.access instead
105
+ rg "\burl\.parse\b" --type ts # Use new URL() instead
106
+ rg "\bpath\.resolve\(__dirname" --type ts # Use import.meta in ESM
107
+
108
+ # Old JS patterns
109
+ rg "\bvar\s+" --type ts # Use let/const
110
+ rg "\.prototype\." --type ts # Use class syntax
111
+ rg "\barguments\b" --type ts # Use rest params
112
+ rg "require\(" --type ts # CJS in TS files
113
+
114
+ # Unnecessary polyfills
115
+ rg "core-js|regenerator-runtime|@babel/polyfill" --type json
116
+ rg "Object\.assign" --type ts # Spread is available everywhere now
117
+ ```
118
+
119
+ ## Type Consolidation
120
+
121
+ ```bash
122
+ # Duplicate interface names across files
123
+ rg "^(export )?(interface|type) (\w+)" --type ts -o | sort | uniq -d
124
+
125
+ # Pick/Omit opportunities — interfaces with many shared fields
126
+ rg "^\s+(id|name|email|createdAt|updatedAt|status):" --type ts -c | sort -t: -k2 -rn
127
+ ```
128
+
129
+ ## Defensive Code
130
+
131
+ ```bash
132
+ # Unnecessary null checks (look for patterns after non-null assertions)
133
+ rg "\?\.\w+\?\." --type ts # Excessive optional chaining
134
+ rg "!= null|!== null|!= undefined|!== undefined" --type ts
135
+ rg "typeof \w+ !== ['\"]undefined['\"]" --type ts
136
+
137
+ # Empty catch blocks (swallowed errors)
138
+ rg "catch\s*\(\w*\)\s*\{\s*\}" --type ts
139
+
140
+ # Redundant boolean comparisons
141
+ rg "=== true|=== false|!== true|!== false" --type ts
142
+ ```
143
+
144
+ ## Performance
145
+
146
+ ```bash
147
+ # N+1 query indicators (loop + await)
148
+ rg "for.*\{" -A 5 --type ts | rg "await.*(find|query|fetch|get)"
149
+
150
+ # Sync I/O in potentially async contexts
151
+ rg "readFileSync|writeFileSync|execSync" --type ts
152
+ rg "JSON\.parse\(fs\.readFileSync" --type ts
153
+
154
+ # Bundle bloat — full library imports
155
+ rg "import \w+ from ['\"]lodash['\"]" --type ts # Should use lodash/map
156
+ rg "import \* as" --type ts # Namespace imports prevent tree shaking
157
+ rg "require\(['\"]moment['\"]" --type ts # moment.js is heavy, use date-fns/dayjs
158
+
159
+ # React re-render triggers
160
+ rg "\{\{" --type tsx # Inline objects in JSX (new ref every render)
161
+ rg "useEffect\(\s*\(\)\s*=>" -A 3 --type tsx # Missing deps array
162
+ ```
163
+
164
+ ## Async Patterns
165
+
166
+ ```bash
167
+ # forEach with async (floating promises)
168
+ rg "\.forEach\(async" --type ts
169
+
170
+ # Missing await
171
+ rg "async.*=>" -A 3 --type ts | rg "return [^a]" # Async arrow without await
172
+
173
+ # Async function with no await
174
+ rg "async function" --type ts # Then check function body for await
175
+
176
+ # Mixed .then() and await
177
+ rg "await.*\.then\(" --type ts
178
+ rg "\.then\(" --type ts -c | sort -t: -k2 -rn # Files with most .then()
179
+
180
+ # Unhandled promise rejection
181
+ rg "\.catch\(\s*\)" --type ts # Empty catch on promise
182
+ rg "Promise\.(all|race|allSettled)\(" --type ts # Check for error handling
183
+ ```
184
+
185
+ ## Circular Dependencies
186
+
187
+ ```bash
188
+ # Barrel file re-exports (common source of circles)
189
+ rg "export \* from" --type ts
190
+ rg "export \{.*\} from ['\"]\.\./" --type ts # Re-exporting from parent
191
+
192
+ # Mutual imports — quick heuristic
193
+ # Find files that import each other (requires cross-referencing)
194
+ rg "from ['\"]\.\.?/" --type ts -l # Files with relative imports
195
+ ```