$npx -y skills add maddhruv/absolute --skill absolute-pruneDead code and dependency cleanup, repo-wide: unused deps, unreferenced exports, unreachable code, orphaned files — removed only with tool evidence, in reversible waves. Runs on green main. For diff-scoped cleanup use absolute-simplify. Triggers on "absolute prune", "remove dead c
| 1 | > Start your first response with the ✂️ emoji. |
| 2 | |
| 3 | ## Absolute Prune |
| 4 | |
| 5 | Cut dead growth from the repo: unused dependencies, unreferenced exports, unreachable code, |
| 6 | orphaned files. Evidence-based — every removal is backed by a tool that proves nothing |
| 7 | references it — applied in safe waves with tests green after each. |
| 8 | |
| 9 | Runs the shared engine in **`references/health-engine.md`** — read it for the |
| 10 | DETECT → SCAN → TRIAGE → FIX → VERIFY → REPORT loop and the safety contract. This file |
| 11 | covers only what's specific to pruning. |
| 12 | |
| 13 | --- |
| 14 | |
| 15 | ## When to use |
| 16 | |
| 17 | - "Remove dead code", "clean up unused deps", "what can we delete?". |
| 18 | - Bundle/install bloat from packages nothing imports anymore. |
| 19 | - Post-refactor orphans: files and exports left behind after a feature was rerouted. |
| 20 | |
| 21 | **`prune` vs `simplify`:** `simplify` polishes *your working git diff*. `prune` sweeps the |
| 22 | **whole committed repo** for things that are dead repo-wide. Use `simplify` mid-change; |
| 23 | `prune` as standing cleanup on green `main`. |
| 24 | |
| 25 | --- |
| 26 | |
| 27 | ## What it scans |
| 28 | |
| 29 | **Dead dependencies** — declared but never imported (and missing deps that are imported but |
| 30 | undeclared): |
| 31 | |
| 32 | | Ecosystem | Tool | |
| 33 | |---|---| |
| 34 | | JS/TS | `depcheck` or `knip` (knip also covers exports/files) | |
| 35 | | Python | `deptry` | |
| 36 | | Go | `go mod tidy` (diff), unused module detection | |
| 37 | |
| 38 | **Dead code** — unreferenced exports, unreachable branches, orphaned files: |
| 39 | |
| 40 | | Ecosystem | Tool | |
| 41 | |---|---| |
| 42 | | JS/TS | `knip` (exports/files), `ts-prune`, `eslint no-unused-vars` | |
| 43 | | Python | `vulture`, `ruff` unused rules | |
| 44 | | Go | `deadcode ./...`, `staticcheck` (U1000) | |
| 45 | |
| 46 | Prefer tools already in the project. Treat results as *candidates* — verify each isn't |
| 47 | reached via dynamic import, reflection, DI, public API, or a config string before removing. |
| 48 | |
| 49 | --- |
| 50 | |
| 51 | ## Risk ranking (TRIAGE) |
| 52 | |
| 53 | | Wave | Removal | Default | |
| 54 | |---|---|---| |
| 55 | | 1 | unused devDeps, unreferenced *local* exports/functions | fix now — lowest risk | |
| 56 | | 2 | unused runtime deps, orphaned internal files | fix this pass after confirming no dynamic ref | |
| 57 | | 3 | anything reachable via public API, plugin system, dynamic require, reflection, or config | **gated / usually defer** — high false-positive risk | |
| 58 | |
| 59 | Static tools miss dynamic references. Anything in wave 3, or anything a tool flags but you |
| 60 | can't *prove* is dead, gets confirmed with the user or deferred — never auto-removed. |
| 61 | |
| 62 | --- |
| 63 | |
| 64 | ## Fix & verify |
| 65 | |
| 66 | - Remove in small, reversible waves. One category per wave (e.g. "unused devDeps", then |
| 67 | "orphaned files"). |
| 68 | - After each wave: full test + build + typecheck. A green typecheck/build is the proof the |
| 69 | removed symbol truly had no references. If anything goes red, the symbol wasn't dead — |
| 70 | revert and reclassify. |
| 71 | - Removing a dep: drop it from the manifest, regenerate the lockfile, rebuild. |
| 72 | - Don't delete: generated files, vendored code, public-API surface, or anything load-bearing |
| 73 | for a config/plugin you can't trace. Report those as "suspected dead, needs human call". |
| 74 | Treat `preferences.health.protectedPaths` from config as never-delete globs — anything |
| 75 | matching is out of scope even if a tool flags it. |
| 76 | |
| 77 | --- |
| 78 | |
| 79 | ## Gotchas |
| 80 | |
| 81 | 1. **Trusting the tool blindly.** Dynamic imports, DI containers, reflection, and string-keyed |
| 82 | lookups defeat static analysis. Confirm before deleting. |
| 83 | 2. **Removing public API.** A library's unused-internally export may be its whole point. Check |
| 84 | the package entry points / `exports` map. |
| 85 | 3. **Deleting generated or vendored files.** They look orphaned but are rebuilt/checked-in on purpose. |
| 86 | 4. **Big-bang prune.** Deleting everything flagged in one commit makes regressions un-bisectable. |
| 87 | Wave it. |
| 88 | 5. **Scope creep into refactor.** `prune` removes dead things; it does not restructure live code. |
| 89 | Restructuring → `simplify` or `work`. |
| 90 | |
| 91 | --- |
| 92 | |
| 93 | ## Companion commands |
| 94 | |
| 95 | - **`/absolute simplify`** — for restructuring/clarity of *live* code in your diff. |
| 96 | - **`/absolute upgrade`** — pairs well: prune unused deps, then upgrade what remains. |
| 97 | - **`/absolute debt`** — pruning often clears a batch of lint/unused-var warnings too. |