| name | code-purge |
| description | Deep code analysis and automated cleanup skill. Removes dead code, unused imports, unreferenced files, and duplicated logic from any codebase. Simplifies overly complex or hard-to-maintain code. Always backs up before changes and validates with tests after.
Use when the user asks to: - "clean up", "remove dead code", "purge unused code" - "find and delete unused files/folders" - "remove duplicate code" or "refactor duplicated logic" - "simplify this codebase" or "the code is too complex" - "do a cleanup pass" or "code hygiene" - "remove everything that's not used"
|
Code Purge
A five-phase workflow for safe, thorough removal of waste from any codebase.
Workflow
Phase 1 → Analyze deep scan: detect languages, map dead code, duplicates, unused files
Phase 2 → Report present findings to user, confirm scope before touching anything
Phase 3 → Backup snapshot the codebase (git stash + tar)
Phase 4 → Clean execute removals in order: imports → dead code → files → refactors
Phase 5 → Verify run test suite; report pass/fail; rollback guide if needed
Phase 1 — Analyze
Run the bundled analyzer first. Never skip this step.
python3 scripts/analyze.py <project_root> --summary
python3 scripts/analyze.py <project_root> --json
The script auto-detects languages and dispatches to:
- Python:
vulture (dead code) + pyflakes (unused imports)
- JS/TS:
knip (dead exports, unused deps, unused files)
- All languages:
jscpd (duplicate blocks) + heuristic file reference scan
Read references/tools.md for the full tool inventory and manual commands per language.
Also perform manual analysis:
- Scan
package.json / pyproject.toml / Cargo.toml for unused dependencies
- Check for
TODO, FIXME, HACK comments that indicate dead branches
- Check git blame for files/functions untouched for >12 months with no external callers
- Review complexity: run
radon cc . -nb (Python) or lizard . --CCN 10 (multi-lang)
Read references/patterns.md for the complete list of dead code, duplicate, and complexity patterns.
Phase 2 — Report & Confirm
Present a structured report before touching any file:
DEAD CODE 23 findings (8 high, 11 medium, 4 low)
DUPLICATES 7 blocks (2 high, 4 medium, 1 low)
UNUSED FILES 5 files (all medium confidence)
UNUSED IMPORTS 41 imports (all low severity)
COMPLEXITY 3 functions (CC > 10, flagged for refactor)
For each category, list the top findings with file:line.
Ask the user: "Which categories should I clean? Any items to skip?"
Do NOT proceed to Phase 3 without explicit user confirmation of scope.
Phase 3 — Backup
Always create a backup before any removal. No exceptions.
bash scripts/backup.sh <project_root>
The script creates:
- A
git stash with a timestamped message (if inside a git repo)
- A
.tar.gz archive in <project_root>/.code-purge-backups/
Note the stash ref and archive path — include them in the final summary so the user knows how to rollback.
Rollback commands to provide to user:
git stash pop <stash-ref>
tar -xzf .code-purge-backups/backup_TIMESTAMP.tar.gz -C ..
Phase 4 — Clean
Execute removals in this order to minimize cascading errors:
4a. Unused imports (lowest risk)
autoflake -r --in-place --remove-unused-variables --remove-all-unused-imports <root>
eslint --fix --rule 'no-unused-vars: ["error", {"vars": "all"}]' <root>
4b. Dead code — functions, classes, variables
- Remove high-confidence findings first (vulture ≥90%, knip unused exports)
- For each removal: delete the definition, then grep for any remaining references
- Verify the project still compiles/imports after each batch of 5–10 removals
4c. Unused files
- Delete files only after confirming no string-based references exist:
grep -r "filename_stem" <root> --include="*.{py,js,ts,yaml,json,toml,cfg}"
- Delete empty directories after removing their files
- Never delete:
__init__.py that may affect package structure, config files loaded by name
4d. Duplicate consolidation
- Extract the shared logic into a well-named shared module/function
- Update all call sites to use the shared version
- Delete the duplicate copies
- Do one duplicate group per commit — do not mix multiple consolidations
4e. Complexity refactors
Follow the heuristics in references/patterns.md#refactoring-heuristics.
Key rules:
- Apply "guard clause" / early-return to reduce nesting depth
- Extract sub-functions when cyclomatic complexity > 10
- Replace long if/elif chains with dict dispatch or polymorphism
- Add a docstring only if the "why" is non-obvious (not the "what")
Phase 5 — Verify
bash scripts/run_tests.sh <project_root>
The script auto-detects pytest, jest/vitest/mocha, go test, cargo test, rspec, and maven.
If tests pass: commit the cleanup with a message like:
chore: remove dead code, unused imports, and 5 unreferenced files
- vulture: removed 8 dead functions in auth/, utils/
- knip: removed 3 unused exports, 2 unused npm deps
- jscpd: consolidated 2 duplicate validation blocks into shared/validators
- autoflake: removed 41 unused imports
If tests fail:
- Identify which removal caused the failure (bisect with
git diff --stat)
- Restore that specific file:
git checkout HEAD~1 -- path/to/file
- Re-run tests to confirm restoration
- Investigate: was the "dead" code actually called dynamically (reflection, config)?
- Add to a "skip list" for this project and continue with the rest
Tool Installation (quick reference)
pip install vulture pyflakes autoflake radon lizard
npm i -g knip jscpd
npx knip
npx jscpd .
Read references/tools.md for per-language tool details, Go/Rust/Ruby specifics, and SonarQube setup.
Key Safety Rules
- Never skip backup — even for "quick" cleanups
- Never mix dead-code removal with feature changes in the same commit
- Always grep for string references before deleting a file or function
- Framework magic is invisible to static analysis — decorators, signals, dynamic dispatch need manual verification
- Public API surfaces (published packages, shared libraries) require extra caution — check external consumers
- Read
references/patterns.md#safe-removal-checklist before each removal batch