prunify 0.1.5 β†’ 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -28,7 +28,7 @@
28
28
 
29
29
  | Module | What it finds |
30
30
  |--------|---------------|
31
- | πŸ—‘οΈ **Dead code** | Files and named exports that are never imported anywhere in the codebase |
31
+ | πŸ—‘οΈ **Dead code** | **Safe to delete** (nothing imports them), **transitively dead** (only dead files import them), and **dead exports** (live files with unused named exports) |
32
32
  | πŸ” **Duplicate code** | Functions with identical bodies, suspiciously similar names, and duplicate constants |
33
33
  | ♻️ **Circular imports** | Dependency cycles that can cause runtime bugs and bundler issues |
34
34
  | πŸ“¦ **Unused dependencies** | Packages declared in `package.json` that are never actually imported |
@@ -81,7 +81,7 @@ npx prunify --ci
81
81
  βœ” Parsed codebase β€” 142 file(s) found
82
82
  βœ” Import graph built β€” 389 edge(s)
83
83
 
84
- βœ” Dead code analysis complete β€” 7 item(s) found
84
+ βœ” Dead code analysis complete β€” 3 safe to delete, 1 transitively dead, 3 dead export(s)
85
85
  βœ” Duplicate scan complete β€” 3 duplicate block(s) found
86
86
  βœ” Circular import analysis complete β€” 2 cycle(s) found
87
87
  βœ” Dependency audit complete β€” 4 issue(s) found
@@ -89,15 +89,22 @@ npx prunify --ci
89
89
 
90
90
  Summary
91
91
 
92
- β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
93
- β”‚ Check β”‚ Found β”‚ Output File β”‚
94
- β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
95
- β”‚ Dead Files / Exports β”‚ 7 β”‚ dead-code.txt β”‚
96
- β”‚ Duplicate Clusters β”‚ 3 β”‚ dupes.md β”‚
97
- β”‚ Unused Packages β”‚ 4 β”‚ deps.md β”‚
98
- β”‚ Circular Deps β”‚ 2 β”‚ circular.txt β”‚
99
- β”‚ Unused Assets β”‚ 5 β”‚ assets.md β”‚
100
- β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
92
+ ========================================
93
+ DEAD CODE REPORT
94
+ Safe to delete : 3
95
+ Transitively dead : 1
96
+ Dead exports : 3
97
+ Recoverable : ~12.4 KB
98
+ ========================================
99
+
100
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
101
+ β”‚ Check β”‚ Found β”‚ Output File β”‚
102
+ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
103
+ β”‚ Circular Dependencies β”‚ 2 β”‚ circular.txt β”‚
104
+ β”‚ Duplicate Clusters β”‚ 3 β”‚ dupes.md β”‚
105
+ β”‚ Unused Packages β”‚ 4 β”‚ deps.md β”‚
106
+ β”‚ Unused Assets β”‚ 5 β”‚ assets.md β”‚
107
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
101
108
  ```
102
109
 
103
110
  ---
@@ -112,10 +119,23 @@ Summary
112
119
  | `--ignore <pattern>` | β€” | Glob pattern to exclude from analysis. Repeatable. |
113
120
  | `--out <path>` | `<dir>/prunify-reports/` | Directory to write report files to. |
114
121
  | `--html` | `false` | Generate `code_health.html` β€” a self-contained page with an SVG score gauge. |
115
- | `--delete` | `false` | After analysis, prompt to permanently delete dead files. |
116
- | `--ci` | `false` | Non-interactive mode. Exits `1` if any issues are found. |
122
+ | `--delete` | `false` | Prompt to permanently delete dead **code files** (safe to delete + transitively dead β€” not dead exports). See **Delete commands & cached reports** below. |
123
+ | `--delete-assets` | `false` | Prompt to delete unused files under `public/` from the asset report. Only paths inside `public/` are removed. See **Delete commands & cached reports** below. |
124
+ | `--ci` | `false` | Non-interactive mode. Exits `1` if any issues are found. With `--delete` / `--delete-assets`, does not prompt and does **not** delete files. |
117
125
  | `-v, --version` | β€” | Print the installed version. |
118
126
 
127
+ ### Delete commands & cached reports
128
+
129
+ When you use **`--delete`** or **`--delete-assets`**, prunify prefers your last report so you do not have to re-scan the whole repo every time:
130
+
131
+ | Flag | If the report already exists | If the report is missing |
132
+ |------|------------------------------|---------------------------|
133
+ | **`--delete`** | Reads file paths from `prunify-reports/dead-code.txt` (skips dead-code analysis and may skip building the import graph when no other module needs it). | Runs dead-code analysis, writes `dead-code.txt`, then prompts to delete. |
134
+ | **`--delete-assets`** | Reads paths from `prunify-reports/assets.md` (skips the asset scan). | Runs the asset scan, writes `assets.md`, then prompts to delete. |
135
+
136
+ - **`dead-code.txt`** starts with a line like `prunify <version> β€” <ISO timestamp>` so you know which run produced it.
137
+ - Keep your dependency on prunify up to date (e.g. `"prunify": "^0.1.5"` in `devDependencies`) so you get the latest detection logic; pinning an old exact version will not pick up fixes from npm.
138
+
119
139
  ### More examples
120
140
 
121
141
  ```bash
@@ -131,9 +151,18 @@ npx prunify --only health --html
131
151
  # Only check unused public assets
132
152
  npx prunify --only assets
133
153
 
134
- # Delete dead files after reviewing
154
+ # First run: analyse + write reports, then prompt to delete dead code files
135
155
  npx prunify --delete
136
156
 
157
+ # Later: delete from existing dead-code.txt only (no graph build if e.g. --only deps)
158
+ npx prunify --only deps --delete
159
+
160
+ # Unused public assets: scan + prompt to delete
161
+ npx prunify --only assets --delete-assets
162
+
163
+ # Reuse assets.md only (no asset scan)
164
+ npx prunify --delete-assets
165
+
137
166
  # Strict CI gate β€” fails the build if any issues exist
138
167
  npx prunify --ci
139
168
  ```
@@ -146,11 +175,11 @@ All reports are written to `prunify-reports/` (auto-added to `.gitignore`).
146
175
 
147
176
  | File | Contents |
148
177
  |------|----------|
149
- | `dead-code.txt` | Dead files and exports with chain analysis and recoverable byte count |
178
+ | `dead-code.txt` | Header with tool version + time, then **Safe to delete**, **Transitively dead**, and **Dead exports** sections (sizes and optional chains). Used by `--delete` when re-running deletes. |
150
179
  | `dupes.md` | Duplicate function clusters with AI-ready refactor prompts |
151
- | `circular.txt` | Circular dependency chains |
180
+ | `circular.txt` | Circular dependency chains (relative paths; header with tool version + time) |
152
181
  | `deps.md` | Unused packages |
153
- | `assets.md` | Unused files found in `public/` with sizes |
182
+ | `assets.md` | Unused files found in `public/` with sizes (Markdown table). Used by `--delete-assets` when re-running deletes. |
154
183
  | `health-report.md` | Combined report with health score (with `--only health`) |
155
184
  | `code_health.html` | Self-contained HTML page with SVG score gauge (with `--html`) |
156
185
 
@@ -158,16 +187,15 @@ All reports are written to `prunify-reports/` (auto-added to `.gitignore`).
158
187
 
159
188
  ## How Dead Code Detection Works
160
189
 
161
- prunify builds a directed import graph of your entire codebase, then runs a depth-first traversal starting from your entry points.
190
+ prunify builds a directed import graph (with `tsconfig.json` path aliases) and a **reverse** map of β€œwho imports this file”.
162
191
 
163
- **Entry point auto-detection order:**
192
+ 1. **Safe to delete** β€” No other project file imports this file, and it is not treated as an app entry (e.g. Next.js `pages/` / `app/` routes) or a known framework/config file (`next.config.*`, `middleware.*`, `tailwind.config.*`, etc.).
193
+ 2. **Transitively dead** β€” The file is only imported by files that are already dead; removing the safe-to-delete roots would leave it orphaned.
194
+ 3. **Dead exports** β€” The file is still used, but specific named exports are never imported by name elsewhere (namespace imports count as β€œall exports used”). Files under **`pages/`** / **`src/pages/`**, route trees like **`src/routes/`**, **`src/views/`**, **`src/screens/`**, and Next.js App Router entry files (**`page.tsx`**, **`layout.tsx`**, **`route.ts`**, etc. under **`app/`** / **`src/app/`**) are **excluded** β€” the framework consumes those exports without normal `import` edges.
164
195
 
165
- 1. Next.js β€” all files inside `pages/` and `app/` directories
166
- 2. `package.json` `"main"` and `"module"` fields
167
- 3. Common fallbacks β€” `src/main`, `src/index`, `src/App`, `index` (all TS/JS extensions)
168
- 4. If none found β€” files with no importers are used as roots (safest heuristic)
196
+ **Why not β€œreachable from entry” only?** A pure reachability scan from entry points can mark heavily shared modules as dead if any link in the chain fails to resolve. The importer-based model matches the usual meaning of β€œnothing uses this file.”
169
197
 
170
- Any file not reachable from an entry point is flagged as dead. Circular dependencies are handled correctly β€” files in a cycle that are reachable from an entry point are always marked live.
198
+ **Circular imports** are reported separately in `circular.txt`; they are not lumped into β€œsafe to delete.”
171
199
 
172
200
  ---
173
201
 
@@ -218,7 +246,8 @@ src/
218
246
  β”œβ”€β”€ cli.ts # Entry point & CLI flag handling
219
247
  β”œβ”€β”€ core/
220
248
  β”‚ β”œβ”€β”€ parser.ts # File discovery + ts-morph AST parsing
221
- β”‚ β”œβ”€β”€ graph.ts # Import graph builder, DFS traversal, cycle detection
249
+ β”‚ β”œβ”€β”€ graph.ts # Import graph builder, cycle detection, reverse graph
250
+ β”‚ β”œβ”€β”€ report-parser.ts # Parse dead-code.txt / assets.md for --delete / --delete-assets
222
251
  β”‚ └── reporter.ts # Markdown / JSON / HTML output writer
223
252
  β”œβ”€β”€ modules/
224
253
  β”‚ β”œβ”€β”€ dead-code.ts # Dead file + dead export detection