--- description: Scan code for refactoring opportunities or perform targeted refactoring operations argument-hint: "[scope: full|quick|complexity|duplication|dead-code|rename old new]" --- # /refactor — Code Refactoring Skill Parse `$ARGUMENTS` to determine the operation: | Argument | Description | |----------|-------------| | `full` (default) | Run all scans: complexity + duplication + dead code | | `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 | | `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). --- ## General Rules (All Modes) - Refactoring changes structure, not behavior. If behavior changes, that is a fix, not a refactoring. - Never refactor and add features in the same step. - Run tests after each change to confirm behavior preservation. - If tests are missing for the code being refactored, write characterization tests first. - Commit each refactoring step individually with a message naming the specific transformation. - Present findings to the user before making changes. Do not auto-apply without confirmation. --- ## Mode: Complexity Scan for code that is too complex to maintain, test, or understand. ### What to Check **Function length:** | Lines | Severity | Action | |-------|----------|--------| | 1-30 | OK | — | | 31-50 | Medium | Consider splitting | | 51-100 | High | Split recommended | | 101+ | Critical | Split required | **Nesting depth:** | Levels | Severity | Action | |--------|----------|--------| | 1-2 | OK | — | | 3 | Medium | Consider flattening | | 4+ | High | Refactor: guard clauses, extract method | **Cyclomatic complexity** (count decision points: if, else if, else, case, for, while, catch, &&, ||): | Score | Severity | Action | |-------|----------|--------| | 1-5 | OK | — | | 6-10 | Medium | Consider simplifying | | 11-15 | High | Refactor recommended | | 16+ | Critical | Refactor required | **Parameter count:** | Params | Severity | Action | |--------|----------|--------| | 0-3 | OK | — | | 4-5 | Medium | Consider parameter object | | 6+ | High | Use parameter object or split function | **Complex boolean expressions** (count operators in a single condition): | Operators | Severity | Action | |-----------|----------|--------| | 1-2 | OK | — | | 3-4 | Medium | Extract to named predicate | | 5+ | High | Extract required | ### Detection Heuristics Use Grep to find candidates: - Long functions: Search for function/method definitions, then count lines to closing brace/end - Deep nesting: Search for lines with 4+ levels of indentation inside control structures - Complex conditions: Search for lines with 3+ `&&` or `||` operators - Long parameter lists: Search for function signatures spanning 60+ characters in the parameter area ### Refactoring Strategies Apply the simplest effective technique: 1. **Guard clauses** — Flatten nested if/else by returning early 2. **Extract method** — Pull a named function from a block that has a comment explaining it or that does a distinct sub-task 3. **Extract predicate** — Replace complex boolean expression with a named function returning bool 4. **Parameter object** — Group related parameters into a struct/type/alist 5. **Decompose conditional** — Replace if/else branches with named functions for each branch --- ## Mode: Duplication Scan for duplicated code that violates DRY. ### What to Check **Clone blocks** (nearly identical code in multiple places): | Lines | Severity | Action | |-------|----------|--------| | 5-10 | Low | Consider extraction | | 11-25 | Medium | Should extract | | 26-50 | High | Must extract | | 51+ | Critical | Extract immediately | **Logic duplication** — Same algorithm with minor variations (different variable names, different field access, different types). **Constant duplication** — Same magic number or string literal in 3+ places. **Pattern repetition** — Same structural pattern (setup-execute-teardown, validate-process-respond) repeated across files. **Error handling duplication** — Same try/catch or condition-case pattern repeated in many functions. ### Detection Heuristics - Search for identical or near-identical multi-line blocks across files - Search for the same string literal appearing in 3+ locations - Search for functions with very similar names that suggest copy-paste origin - Search for the same error message string in multiple places ### Refactoring Strategies 1. **Extract function** — Pull the duplicated block into a shared function with parameters for the varying parts 2. **Extract constant** — Replace magic numbers/strings with named constants 3. **Parameterize** — If two functions differ only in one value, merge into one function with a parameter 4. **Template method / higher-order function** — If the structure is the same but the operations differ, extract the structure and accept operations as arguments --- ## Mode: Dead Code Find code that is never executed or referenced. ### Step-by-step 1. **Unused imports** — Use available tooling or grep for imports, then search for usage of each imported symbol. Language hints: - TypeScript/JS: `tsc --noUnusedLocals --noEmit`, or ESLint `no-unused-vars` - Python: `ruff check --select F401` or `pyflakes` - Go: compiler catches these automatically - Emacs Lisp: search for `(require 'X)` then grep for symbols from X - Rust: compiler warns on dead code 2. **Unused exports / public functions** — For each exported or public symbol, search the codebase for references. If zero references and not a public API entry point, flag it. 3. **Unreachable code** — Look for: - Code after unconditional return/throw/break/signal - Branches with conditions that are always true or always false - Functions defined but never called - Commented-out code blocks (these should be deleted; version control has the history) 4. **Dead feature flags** — Search for feature flag checks or environment variable guards. If the flag is always true/false in all environments, remove the dead branch. 5. **Unused dependencies** — Compare declared dependencies against actual imports. Flag packages with zero import references. ### Presentation Group findings by category with confidence levels: - **High confidence** — Definitely unused, safe to remove - **Medium confidence** — Likely unused, needs manual review - **Low confidence** — Possibly unused, dynamic references may exist ### Rules - Never remove code used via dynamic imports, reflection, metaprogramming, or string-based references - Preserve public API exports in libraries - Skip test utilities, fixtures, and dev-only code unless explicitly asked - Remove code in small, focused commits — one category per commit - Never remove error handling or fallback code just because it hasn't triggered yet - Run the full test suite after each removal batch --- ## Mode: Rename Perform a codebase-wide symbol rename. Parse `$ARGUMENTS` for: `rename ` ### Step-by-step 1. **Determine symbol type** — Variable, function, class, type, file, directory, CSS class, config key. 2. **Find all references:** - Source code: imports, exports, usages, type references - Tests: descriptions, assertions, mocks, fixtures - Configuration: env vars, config files, build scripts - Documentation: comments, README, API docs, org files 3. **If renaming a file:** - Update all import/require paths referencing the old filename - Update dynamic imports or autoloads - Update config references (tsconfig paths, Makefile targets, load-path entries) 4. **Preview changes** — Show every file that will be modified with the specific line changes. Highlight ambiguous matches that might be false positives. 5. **Get confirmation** — Do not apply until the user approves. 6. **Apply changes** across all files in a single atomic commit. 7. **Verify** — Run tests and type checker / byte-compiler to confirm nothing broke. ### Rules - Always preview before applying - Handle case sensitivity: distinguish `myFunc`, `MyFunc`, `MY_FUNC`, `my-func` - Do not rename inside vendored/dependency directories - Preserve casing conventions (camelCase, PascalCase, snake_case, kebab-case) - Check string literals that may reference the symbol (routes, error messages, logging) - Update related names when appropriate (renaming `User` should prompt about `UserProps`, `UserSchema`, etc.) --- ## Output Format For every finding in any scan mode, use this format: ``` [SEVERITY] Category — Title File: path/to/file:line Metric: specific measurement (e.g., "cyclomatic complexity: 18", "47 duplicated lines") Issue: what the problem is (1-2 sentences) Suggestion: recommended refactoring technique ``` Severity levels: `CRITICAL`, `HIGH`, `MEDIUM`, `LOW` ### After All Findings Present a summary: ``` Refactoring Scan Summary ======================== Critical: N High: N Medium: N Low: N Quick wins (low effort, high impact): 1. ... 2. ... 3. ... Shall I apply any of these? (specify by number, or "all quick wins") ``` Do not generate a separate report file unless the user asks for one. Present findings inline in the conversation.