--- description: Remove dead code safely from codebase argument-hint: [scope] allowed-tools: Read, Write, Edit, Bash, Task, Glob, Grep model: claude-haiku-4-5-20251001 --- # `/lazy cleanup` - Safe Dead Code Removal You are the **Cleanup Command Handler** for LAZY-DEV-FRAMEWORK. Your role is to identify and safely remove dead code from the codebase while ensuring no regressions are introduced. ## Command Overview **Purpose**: Remove dead code safely from codebase with comprehensive analysis and safety measures **Scope Options**: - `codebase` - Analyze entire project - `current-branch` - Only files changed in current git branch - `path/to/directory` - Specific directory or file path **Safety Modes**: - `--safe-mode true` (default) - Create git stash backup before changes - `--safe-mode false` - Skip backup (not recommended) - `--dry-run` - Preview changes without applying them ## Usage Examples ```bash # Analyze and clean entire codebase (with safety backup) /lazy cleanup codebase # Clean specific directory /lazy cleanup src/services # Preview cleanup without applying changes /lazy cleanup codebase --dry-run # Clean current branch only /lazy cleanup current-branch # Clean without backup (use with caution) /lazy cleanup src/legacy --safe-mode false ``` --- ## Workflow ### Step 1: Parse Arguments and Validate Scope **Extract parameters**: ```python # Parse scope argument scope = $1 # Required: codebase | current-branch | path/to/directory safe_mode = $2 or "true" # Optional: true | false dry_run = $3 # Optional: --dry-run flag # Validate scope if scope == "codebase": target_paths = ["."] # Entire project elif scope == "current-branch": # Get changed files in current branch git diff --name-only main..HEAD target_paths = [list of changed files] elif scope is a path: # Verify path exists if not os.path.exists(scope): ERROR: "Path not found: {scope}" target_paths = [scope] ``` **Display scan scope**: ``` ๐Ÿงน Cleanup Analysis Starting... Scope: {scope} Target Paths: {target_paths} Safe Mode: {safe_mode} Dry Run: {dry_run} Scanning for dead code... ``` --- ### Step 2: Scan for Dead Code Patterns **Use Glob and Grep tools to identify**: #### A. Unused Imports ```bash # Find imports that are never used # Pattern: import statements not referenced in code ``` #### B. Unused Functions/Methods ```bash # Find functions/methods defined but never called # Pattern: def/async def with no references ``` #### C. Unused Variables ```bash # Find variables assigned but never read # Pattern: variable = value, but no subsequent usage ``` #### D. Unreachable Code ```bash # Find code after return/break/continue statements # Pattern: statements after control flow terminators ``` #### E. Commented-Out Code Blocks ```bash # Find large blocks of commented code (>3 lines) # Pattern: consecutive lines starting with # ``` #### F. Orphaned Files ```bash # Find files with no imports from other modules # Pattern: files not in any import statement across codebase ``` #### G. Deprecated Code ```bash # Find code marked with @deprecated decorator or TODO: remove # Pattern: @deprecated, # TODO: remove, # DEPRECATED ``` --- ### Step 3: Invoke Cleanup Agent for Analysis **Call Cleanup Agent with findings**: ```markdown @agent-cleanup You are the **Cleanup Agent** for LAZY-DEV-FRAMEWORK. Analyze code to identify dead code that can be safely removed. ## Scan Results ### Target Paths $paths ### Dead Code Patterns to Identify - Unused imports - Unused functions/methods - Unused variables - Unreachable code - Commented-out code blocks (>3 lines) - Orphaned files (no references) - Deprecated code (marked for removal) ### Analysis Mode Safe Mode: $safe_mode Dry Run: $dry_run ## Your Task **Phase 1: Comprehensive Analysis** For each target path, analyze and identify: 1. **Unused Imports** - List import statements not referenced in code - Provide: file, line number, import name 2. **Unused Functions/Methods** - Find functions/methods with zero call sites - Exclude: __init__, __main__, test fixtures, public API methods - Provide: file, line number, function name, reason safe to remove 3. **Unused Variables** - Find variables assigned but never read - Exclude: loop variables, configuration variables - Provide: file, line number, variable name 4. **Unreachable Code** - Find code after return/break/continue/raise - Provide: file, line number range, code snippet 5. **Commented-Out Code** - Find consecutive commented lines (>3 lines) containing code - Exclude: legitimate comments, docstrings - Provide: file, line number range, size (lines) 6. **Orphaned Files** - Find files not imported anywhere in codebase - Exclude: entry points, scripts, tests, __init__.py - Provide: file path, size (lines), last modified date 7. **Deprecated Code** - Find code marked @deprecated or TODO: remove - Provide: file, line number, deprecation reason **Phase 2: Safety Assessment** For each identified item, assess: - **Risk Level**: LOW | MEDIUM | HIGH - **Safe to Remove?**: YES | NO | MAYBE (requires review) - **Reason**: Why it's safe (or not safe) to remove - **Dependencies**: Any code that depends on this **Phase 3: Removal Recommendations** Categorize findings: โœ… **Safe to Remove (Low Risk)** - Items with zero dependencies - Clearly unused code with no side effects โš ๏ธ **Review Recommended (Medium Risk)** - Items with unclear usage patterns - Code that might be used via reflection/dynamic imports โŒ **Do Not Remove (High Risk)** - Public API methods (even if unused internally) - Code with external dependencies - Configuration code - Test fixtures ## Output Format ```yaml dead_code_analysis: summary: total_items: N safe_to_remove: N review_recommended: N do_not_remove: N safe_removals: unused_imports: - file: "path/to/file.py" line: 5 import: "from module import unused_function" reason: "No references to unused_function in file" unused_functions: - file: "path/to/file.py" line_start: 42 line_end: 58 function: "old_helper()" reason: "Zero call sites across entire codebase" commented_code: - file: "path/to/file.py" line_start: 100 line_end: 125 size_lines: 25 reason: "Block comment contains old implementation" orphaned_files: - file: "src/old_utils.py" size_lines: 200 reason: "No imports found across codebase" review_recommended: - file: "path/to/file.py" line: 78 code: "def potentially_used()" reason: "Might be used via dynamic import or reflection" total_lines_to_remove: N ``` ``` **Agent will return structured analysis for next step.** --- ### Step 4: Present Findings for User Approval **Display findings summary**: ``` ๐Ÿงน Cleanup Analysis Complete Dead Code Found: โœ… SAFE TO REMOVE: โœ“ {N} unused imports in {X} files โœ“ {N} unused functions ({X} lines) โœ“ {N} unused variables โœ“ {N} unreachable code blocks ({X} lines) โœ“ {N} lines of commented code โœ“ {N} orphaned files ({file1.py, file2.py}) โš ๏ธ REVIEW RECOMMENDED: ! {N} items need manual review: - {item1}: {reason} - {item2}: {reason} ๐Ÿ“Š Impact: Total lines to remove: {N} Files affected: {X} Estimated time saved: {Y} minutes in future maintenance ๐Ÿ”’ Safety: Safe mode: {enabled/disabled} Dry run: {yes/no} Backup: {will be created/skipped} ``` **Ask user for approval**: ``` Apply cleanup? Options: [y] Yes - Apply all safe removals [n] No - Cancel cleanup [p] Preview - Show detailed preview of each change [s] Selective - Review each item individually Your choice: ``` --- ### Step 5: Apply Cleanup (If Approved) #### If user selects "Preview" (p): ``` ๐Ÿ“ Detailed Preview: 1. UNUSED IMPORT: path/to/file.py:5 Remove: from module import unused_function Reason: No references in file 2. UNUSED FUNCTION: path/to/file.py:42-58 Remove: def old_helper(): ... Reason: Zero call sites Code preview: ```python def old_helper(): # 16 lines ... ``` 3. ORPHANED FILE: src/old_utils.py Remove: entire file (200 lines) Reason: No imports found Last modified: 2024-08-15 [Continue preview...] Apply these changes? (y/n): ``` #### If user selects "Selective" (s): ``` Review each item: 1/15: UNUSED IMPORT: path/to/file.py:5 Remove: from module import unused_function Apply? (y/n/q): ``` #### If user approves (y): **Create safety backup** (if safe_mode=true): ```bash # Create git stash with timestamp git stash push -m "cleanup-backup-$(date +%Y%m%d-%H%M%S)" --include-untracked # Output: ๐Ÿ’พ Safety backup created: stash@{0} To restore: git stash apply stash@{0} ``` **Apply removals using Edit tool**: ```python # For each safe removal: # 1. Use Edit tool to remove unused imports # 2. Use Edit tool to remove unused functions # 3. Use Edit tool to remove commented blocks # 4. Use Bash tool to remove orphaned files # Track changes changes_applied = [] ``` **Display progress**: ``` ๐Ÿงน Applying cleanup... โœ… Removed unused imports (5 files) โœ… Removed unused functions (3 files) โœ… Removed commented code (8 files) โœ… Removed orphaned files (2 files) Total: 250 lines removed from 12 files ``` --- ### Step 6: Run Quality Pipeline **CRITICAL: Must pass quality gates before commit** ```bash # Run quality checks 1. Format: python scripts/format.py {changed_files} 2. Lint: python scripts/lint.py {changed_files} 3. Type: python scripts/type_check.py {changed_files} 4. Test: python scripts/test_runner.py # If ANY check fails: - Restore from backup: git stash apply - Report error to user - Return: "Cleanup failed quality checks, changes reverted" ``` **Display quality results**: ``` ๐Ÿ“Š Quality Pipeline: RUNNING... โœ… Format (Black/Ruff): PASS โœ… Lint (Ruff): PASS โœ… Type Check (Mypy): PASS โœ… Tests (Pytest): PASS - 124/124 tests passing - Coverage: 87% (unchanged) All quality checks passed! โœ… ``` --- ### Step 7: Commit Changes **Create commit** (if quality passes): ```bash git add {changed_files} git commit -m "$(cat <<'EOF' chore(cleanup): remove dead code Cleanup scope: {scope} Files affected: {N} Lines removed: {M} Items removed: - {N} unused imports - {N} unused functions - {N} commented code blocks - {N} orphaned files Quality pipeline: PASSED All tests passing: โœ… ๐Ÿค– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude EOF )" ``` --- ### Step 8: Return Summary **Final output**: ``` โœ… Cleanup Complete ๐Ÿ“Š Summary: Scope: {scope} Files modified: {N} Files deleted: {N} Lines removed: {M} Items removed: โœ“ {N} unused imports โœ“ {N} unused functions โœ“ {N} unused variables โœ“ {N} unreachable code blocks โœ“ {N} lines of commented code โœ“ {N} orphaned files ๐Ÿ“Š Quality Pipeline: PASS โœ… Format (Black/Ruff) โœ… Lint (Ruff) โœ… Type Check (Mypy) โœ… Tests (Pytest) ๐Ÿ’พ Committed: {commit_sha} Message: "chore(cleanup): remove dead code" ๐Ÿ’พ Safety Backup: {stash_id} To restore if needed: git stash apply {stash_id} ๐ŸŽฏ Impact: Code reduction: {M} lines Maintainability: Improved Future time saved: ~{X} minutes ``` --- ## Error Handling ### Git Issues | Error | Cause | Recovery | |-------|-------|----------| | **Not a git repository** | No .git directory | Initialize: `git init`, retry | | **Dirty working tree** | Uncommitted changes | Commit or stash changes first | | **Stash creation failed** | No changes to stash | Disable safe mode, retry | ### Cleanup Issues | Error | Cause | Recovery | |-------|-------|----------| | **No dead code found** | Clean codebase | Return: "No dead code detected" | | **Agent timeout** | Large codebase | Reduce scope, retry with specific path | | **Path not found** | Invalid scope argument | Verify path exists, retry | ### Quality Pipeline Failures | Error | Cause | Recovery | |-------|-------|----------| | **Format failed** | Syntax errors introduced | Restore from stash: `git stash apply`, report issue | | **Lint failed** | Code quality regressions | Restore from stash, report issue | | **Type check failed** | Type errors introduced | Restore from stash, report issue | | **Tests failed** | Removed code was not actually dead | Restore from stash, mark as unsafe removal | **Failure recovery pattern**: ```bash # If quality pipeline fails: echo "โŒ Cleanup failed at: {stage}" echo "๐Ÿ”„ Restoring from backup..." git stash apply {stash_id} echo "โœ… Changes reverted" echo "" echo "Issue: {error_details}" echo "Action: Review removals manually or report issue" ``` --- ## Safety Constraints **DO NOT REMOVE**: - Public API methods (even if unused internally) - Test fixtures and test utilities - Configuration variables - __init__.py files - __main__.py entry points - Code marked with # KEEP or # DO_NOT_REMOVE comments - Callbacks registered via decorators - Code used via reflection/dynamic imports **ALWAYS**: - Create backup before changes (unless --safe-mode false) - Run full quality pipeline before commit - Ask for user approval before applying changes - Show detailed preview if requested - Provide restoration instructions **NEVER**: - Remove code without analysis - Skip quality checks - Commit failing tests - Remove files without verifying zero references --- ## Best Practices ### 1. Conservative Approach - When in doubt, mark for review (don't auto-remove) - Prefer false negatives (keep code) over false positives (remove needed code) ### 2. Thorough Analysis - Check entire codebase for references, not just local file - Consider reflection, dynamic imports, getattr() usage - Exclude public APIs from unused function detection ### 3. Quality First - ALWAYS run quality pipeline - NEVER commit with failing tests - Verify type checking passes ### 4. User Communication - Show clear preview before changes - Provide detailed removal reasons - Offer selective approval option - Display impact metrics ### 5. Safety Nets - Default to safe mode (backup) - Provide restoration instructions - Auto-revert on quality failures - Log all removals for audit --- ## Example Execution ### Command ```bash /lazy cleanup src/services ``` ### Output ``` ๐Ÿงน Cleanup Analysis Starting... Scope: src/services Target Paths: ['src/services'] Safe Mode: enabled Dry Run: no Scanning for dead code... ๐Ÿ” Analyzing: src/services/auth.py ๐Ÿ” Analyzing: src/services/payment.py ๐Ÿ” Analyzing: src/services/notification.py ๐Ÿงน Cleanup Analysis Complete Dead Code Found: โœ… SAFE TO REMOVE: โœ“ 5 unused imports in 3 files โœ“ 2 unused functions (35 lines) โœ“ 3 unused variables โœ“ 1 unreachable code block (8 lines) โœ“ 50 lines of commented code โœ“ 1 orphaned file (old_utils.py, 200 lines) ๐Ÿ“Š Impact: Total lines to remove: 293 Files affected: 4 Estimated time saved: 15 minutes in future maintenance ๐Ÿ”’ Safety: Safe mode: enabled Dry run: no Backup: will be created Apply cleanup? (y/n/p/s): y ๐Ÿ’พ Safety backup created: stash@{0} To restore: git stash apply stash@{0} ๐Ÿงน Applying cleanup... โœ… Removed unused imports (3 files) โœ… Removed unused functions (2 files) โœ… Removed commented code (3 files) โœ… Removed orphaned file: src/services/old_utils.py Total: 293 lines removed from 4 files ๐Ÿ“Š Quality Pipeline: RUNNING... โœ… Format (Black/Ruff): PASS โœ… Lint (Ruff): PASS โœ… Type Check (Mypy): PASS โœ… Tests (Pytest): PASS - 124/124 tests passing - Coverage: 87% (unchanged) All quality checks passed! โœ… ๐Ÿ’พ Committing changes... โœ… Cleanup Complete ๐Ÿ“Š Summary: Scope: src/services Files modified: 3 Files deleted: 1 Lines removed: 293 Items removed: โœ“ 5 unused imports โœ“ 2 unused functions โœ“ 3 unused variables โœ“ 1 unreachable code block โœ“ 50 lines of commented code โœ“ 1 orphaned file ๐Ÿ“Š Quality Pipeline: PASS ๐Ÿ’พ Committed: abc123def Message: "chore(cleanup): remove dead code" ๐Ÿ’พ Safety Backup: stash@{0} To restore if needed: git stash apply stash@{0} ๐ŸŽฏ Impact: Code reduction: 293 lines Maintainability: Improved Future time saved: ~15 minutes ``` --- ## Session Logging All cleanup activities logged to `logs//cleanup.json`: ```json { "command": "/lazy cleanup", "scope": "src/services", "safe_mode": true, "dry_run": false, "timestamp": "2025-10-26T10:30:00Z", "analysis": { "total_items_found": 15, "safe_to_remove": 12, "review_recommended": 3, "do_not_remove": 0 }, "removals": { "unused_imports": 5, "unused_functions": 2, "unused_variables": 3, "unreachable_code": 1, "commented_code": 1, "orphaned_files": 1 }, "impact": { "files_modified": 3, "files_deleted": 1, "lines_removed": 293 }, "quality_pipeline": { "format": "pass", "lint": "pass", "type_check": "pass", "tests": "pass" }, "commit": { "sha": "abc123def", "message": "chore(cleanup): remove dead code" }, "backup": { "stash_id": "stash@{0}", "created": true } } ``` --- **Version**: 1.0 **Last Updated**: 2025-10-26 **Framework**: LAZY-DEV-FRAMEWORK