From b621914b3a748f42ddb6ae82c385e26174c982be Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sun, 28 Jun 2026 12:24:49 -0400 Subject: feat(refactor): add simplification scan mode I added a simplification mode for behavior-preserving clarity and size reduction: over-defensive guards, needless indirection, convoluted logic, redundant state, and legibility rewrites. It runs in the default full scan and on its own. For the lenses dead-code and duplication already own (identical-twin branches, plain deletion, repeated literals) it cross-references those modes instead of specifying detection twice. It's distinct from /simplify, which works the current diff. This sweeps existing code. --- .claude/commands/refactor.md | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/.claude/commands/refactor.md b/.claude/commands/refactor.md index 08cbdab..97ce366 100644 --- a/.claude/commands/refactor.md +++ b/.claude/commands/refactor.md @@ -1,5 +1,5 @@ --- -description: Scan code for refactoring opportunities or perform a targeted refactor. Six modes — `full` (default; complexity + duplication + dead-code scans), `quick` (high-severity findings only), `complexity` (length / nesting / cyclomatic / parameter count / boolean ops with severity bands and techniques like guard clauses, extract method/predicate, parameter object, decompose conditional), `duplication` (clones / logic / constants / patterns / error-handling with extract-function / parameterize / template-method strategies), `dead-code` (imports / exports / branches / feature flags / deps with high/medium/low confidence labels), `rename old new` (codebase-wide symbol rename with reference search, preview gate, atomic commit, post-apply verification). Findings render as `[SEVERITY] Category — File / Metric / Issue / Suggestion` blocks plus a summary table and quick-wins. Structure-only — no feature work mixed in, no auto-apply without confirmation, characterization tests first when coverage is missing, small focused commits. Use for cleanup or wide renames. Do NOT use for behavior changes (`fix:` or `feat:`, not refactor), green-field design (use `/arch-design`), or single-symbol single-file renames (just edit). Companion to `/add-tests` for the characterization-test prereq. +description: Scan code for refactoring opportunities or perform a targeted refactor. Seven modes — `full` (default; complexity + duplication + dead-code + simplification scans), `quick` (high-severity findings only), `complexity` (length / nesting / cyclomatic / parameter count / boolean ops with severity bands and techniques like guard clauses, extract method/predicate, parameter object, decompose conditional), `duplication` (clones / logic / constants / patterns / error-handling with extract-function / parameterize / template-method strategies), `dead-code` (imports / exports / branches / feature flags / deps with high/medium/low confidence labels), `simplification` (over-defensive guards / needless indirection / convoluted logic / redundant state / legibility rewrites — behavior-preserving clarity and size reduction, distinct from the metric-driven complexity scan), `rename old new` (codebase-wide symbol rename with reference search, preview gate, atomic commit, post-apply verification). Findings render as `[SEVERITY] Category — File / Metric / Issue / Suggestion` blocks plus a summary table and quick-wins. Structure-only — no feature work mixed in, no auto-apply without confirmation, characterization tests first when coverage is missing, small focused commits. Use for cleanup or wide renames. Do NOT use for behavior changes (`fix:` or `feat:`, not refactor), green-field design (use `/arch-design`), or single-symbol single-file renames (just edit). Companion to `/add-tests` for the characterization-test prereq. argument-hint: "[scope: full|quick|complexity|duplication|dead-code|rename old new]" --- @@ -9,11 +9,12 @@ Parse `$ARGUMENTS` to determine the operation: | Argument | Description | |----------|-------------| -| `full` (default) | Run all scans: complexity + duplication + dead code | +| `full` (default) | Run all scans: complexity + duplication + dead code + simplification | | `quick` | High-severity issues only (critical/high across all scans) | | `complexity` | Analyze code complexity: nesting, length, parameters, boolean expressions | | `duplication` | Detect duplicated logic, clone blocks, repeated patterns | | `dead-code` | Find unused imports, exports, unreachable code, dead feature flags | +| `simplification` | Find over-complicated code: redundant guards, needless indirection, convoluted logic, redundant state, legibility rewrites | | `rename old new` | Codebase-wide symbol rename with verification | If a file or directory path is included in the arguments, scope the scan to that path. Otherwise scan the project source directories (exclude vendored code, node_modules, build output, test fixtures). @@ -182,6 +183,40 @@ Group findings by category with confidence levels: --- +## Mode: Simplification + +Scan for code that's more complicated than it needs to be — a plainer, smaller, more direct expression of the same behavior. Behavior-preserving like every other mode; this targets clarity and size, not metrics (complexity mode) or repetition (duplication mode). + +### What to Check + +- **Over-defensive / redundant guards** — existence checks and fallbacks for conditions that can't occur given the actual call sites. +- **Needless indirection / unearned abstraction** — single-use closures, helpers, or wrappers; a single-use local that could inline (or a repeated expression that should be a local); a parameter always passed the same value; an option or branch never exercised. +- **Convoluted logic expressible more directly** — a manual loop that's a map/filter/comprehension; a verbose if-chain that's a lookup table; an if/else assigning a value that's a ternary; boolean expressions that simplify; redundant intermediate computations. +- **Redundant state** — a cache rebuilt every call anyway; two variables tracking the same thing; write-only "dead storage" (assigned, never read); dead flags. +- **Legibility rewrites** — named locals to expose a decision matrix obscured by indexing or chaining. No structural change, large readability win. + +For identical-twin branches and plain deletion of unreachable code, see Mode: Dead Code; for repeated literals → named constant, see Mode: Duplication. Those modes already own that detection. + +### Detection Heuristics + +- Search for guard clauses and fallbacks (null checks, default branches), then check every call site to see whether the guarded condition can actually occur +- Search for helpers, closures, and locals referenced exactly once +- Search for manual index/accumulator loops that build or filter a collection +- Search for variables assigned but never read, and for values recomputed on every call that never change + +### Rules + +- Behavior-preserving only. +- Verify against **all** call sites before deleting a guard, dropping an option, or removing "never read" state — "can't occur" and "never read" are only true relative to every caller. Never remove a guard or fallback that's genuinely reachable. +- Run the test suite after each change. +- Present findings before applying. + +### Boundary with /simplify + +`/refactor simplification` sweeps the whole tree (or a scoped path), presents findings, and applies on confirmation. The built-in `/simplify` works on the current diff and applies its lenses directly. Reach for `/simplify` on a change in flight; reach for `/refactor simplification` to sweep existing code. + +--- + ## Mode: Rename Perform a codebase-wide symbol rename. -- cgit v1.2.3