pruneguard 0.1.0 → 0.2.0
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 +276 -3
- package/dist/bin.mjs +0 -0
- package/package.json +12 -12
package/README.md
CHANGED
|
@@ -1,6 +1,279 @@
|
|
|
1
1
|
# pruneguard
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**One graph. Every answer.** Find unused exports, dead files, phantom dependencies, import cycles, and boundary violations across your entire JS/TS monorepo — in a single, fast Rust-powered pass.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/pruneguard)
|
|
6
|
+
[](https://github.com/ferc/pruneguard/blob/main/LICENSE)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Why pruneguard?
|
|
11
|
+
|
|
12
|
+
Large JS/TS monorepos accumulate dead code, orphan files, and undeclared cross-package imports faster than any team can manually track. Existing tools either focus on a single concern, struggle with monorepo workspaces, or sacrifice accuracy for speed.
|
|
13
|
+
|
|
14
|
+
Pruneguard builds one complete module graph — resolving TypeScript paths, package.json `exports`, workspace links, and framework conventions — then runs every analyzer over it in a single pass. The result: fast, accurate, actionable findings with proof chains you can verify before deleting a single line.
|
|
15
|
+
|
|
16
|
+
### Key strengths
|
|
17
|
+
|
|
18
|
+
- **Rust-native speed** — parses and resolves thousands of files in seconds, powered by [oxc](https://oxc.rs)
|
|
19
|
+
- **Monorepo-first** — understands pnpm/npm/yarn/bun workspaces, cross-package imports, and `exports` maps out of the box
|
|
20
|
+
- **8 built-in analyzers** — unused exports, unused files, unused packages, unused dependencies, cycles, boundary violations, ownership, and impact analysis
|
|
21
|
+
- **Framework-aware** — auto-detects Next.js, Vite, Vitest, Jest, and Storybook entrypoints so you don't over-report
|
|
22
|
+
- **Trust model** — every finding carries a confidence level; partial-scope scans are clearly marked as advisory
|
|
23
|
+
- **Explainability** — `impact` and `explain` commands let you trace proof chains before acting
|
|
24
|
+
- **CI-ready** — SARIF output, deterministic mode, `--changed-since` for incremental PR checks, exit codes for gating
|
|
25
|
+
- **Migrate easily** — built-in config converters for knip and dependency-cruiser
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Quick start
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
# Install
|
|
33
|
+
npm install -D pruneguard # or: npx pruneguard scan
|
|
34
|
+
|
|
35
|
+
# Scan your repo
|
|
36
|
+
pruneguard scan
|
|
37
|
+
|
|
38
|
+
# See what breaks if you touch a file
|
|
39
|
+
pruneguard impact src/utils/helpers.ts
|
|
40
|
+
|
|
41
|
+
# Understand why something is flagged
|
|
42
|
+
pruneguard explain unused-export:packages/core:src/old.ts#deprecatedFn
|
|
43
|
+
|
|
44
|
+
# Generate a config file
|
|
45
|
+
pruneguard init
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## CLI reference
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
pruneguard [OPTIONS] <COMMAND>
|
|
54
|
+
|
|
55
|
+
Commands:
|
|
56
|
+
scan [PATHS...] Analyze the repo (default command)
|
|
57
|
+
impact <TARGET> Compute blast radius for a file or export
|
|
58
|
+
explain <QUERY> Show proof chain for a finding, file, or export
|
|
59
|
+
init Generate a default pruneguard.json
|
|
60
|
+
print-config Display the resolved configuration
|
|
61
|
+
debug resolve Debug module resolution
|
|
62
|
+
debug entrypoints List detected entrypoints
|
|
63
|
+
debug runtime Print runtime diagnostics
|
|
64
|
+
migrate knip Convert knip config to pruneguard
|
|
65
|
+
migrate depcruise Convert dependency-cruiser config to pruneguard
|
|
66
|
+
|
|
67
|
+
Options:
|
|
68
|
+
-c, --config <FILE> Config file path [default: pruneguard.json]
|
|
69
|
+
--format <FORMAT> Output format: text, json, sarif, dot
|
|
70
|
+
--profile <PROFILE> Analysis profile: production, development, all
|
|
71
|
+
--changed-since <REF> Only analyze files changed since a git ref
|
|
72
|
+
--focus <GLOB> Filter findings to matching files
|
|
73
|
+
--severity <SEVERITY> Minimum severity: error, warn, info
|
|
74
|
+
--no-cache Disable incremental cache
|
|
75
|
+
--no-baseline Disable baseline suppression
|
|
76
|
+
--require-full-scope Fail if scan is partial-scope
|
|
77
|
+
--max-findings <N> Cap the number of reported findings
|
|
78
|
+
-V, --version Print version
|
|
79
|
+
-h, --help Print help
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Common workflows
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
# Full scan with JSON output for CI
|
|
86
|
+
pruneguard scan --format json
|
|
87
|
+
|
|
88
|
+
# PR check — only findings from changed files
|
|
89
|
+
pruneguard --changed-since origin/main scan
|
|
90
|
+
|
|
91
|
+
# Deterministic CI (no cache, no baseline)
|
|
92
|
+
pruneguard --no-baseline --no-cache scan
|
|
93
|
+
|
|
94
|
+
# Focus on a specific area without narrowing analysis scope
|
|
95
|
+
pruneguard --focus "packages/core/**" scan
|
|
96
|
+
|
|
97
|
+
# SARIF for GitHub Code Scanning
|
|
98
|
+
pruneguard scan --format sarif > results.sarif
|
|
99
|
+
|
|
100
|
+
# Visualize the module graph
|
|
101
|
+
pruneguard scan --format dot | dot -Tsvg -o graph.svg
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## Configuration
|
|
107
|
+
|
|
108
|
+
Create `pruneguard.json` (or `.pruneguardrc.json`) in your project root. Run `pruneguard init` to generate one.
|
|
109
|
+
|
|
110
|
+
```jsonc
|
|
111
|
+
{
|
|
112
|
+
"$schema": "./node_modules/pruneguard/configuration_schema.json",
|
|
113
|
+
|
|
114
|
+
"workspaces": {
|
|
115
|
+
"roots": ["apps/*", "packages/*"],
|
|
116
|
+
"packageManager": "pnpm"
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
"entrypoints": {
|
|
120
|
+
"auto": true,
|
|
121
|
+
"include": ["src/index.ts"],
|
|
122
|
+
"exclude": ["**/*.test.ts"]
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
"analysis": {
|
|
126
|
+
"unusedExports": "error",
|
|
127
|
+
"unusedFiles": "warn",
|
|
128
|
+
"unusedDependencies": "error",
|
|
129
|
+
"unusedPackages": "warn",
|
|
130
|
+
"cycles": "warn",
|
|
131
|
+
"boundaries": "error"
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
"frameworks": {
|
|
135
|
+
"next": "auto",
|
|
136
|
+
"vitest": "auto",
|
|
137
|
+
"storybook": "auto"
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
"rules": {
|
|
141
|
+
"forbidden": [
|
|
142
|
+
{
|
|
143
|
+
"name": "no-cross-app-imports",
|
|
144
|
+
"severity": "error",
|
|
145
|
+
"comment": "Apps must not import from other apps",
|
|
146
|
+
"from": { "workspace": ["apps/*"] },
|
|
147
|
+
"to": { "workspace": ["apps/*"] }
|
|
148
|
+
}
|
|
149
|
+
]
|
|
150
|
+
},
|
|
151
|
+
|
|
152
|
+
"ownership": {
|
|
153
|
+
"importCodeowners": true,
|
|
154
|
+
"unownedSeverity": "warn"
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Full schema reference is bundled at `node_modules/pruneguard/configuration_schema.json` — editors with JSON Schema support will provide autocomplete and validation automatically.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Analyzers
|
|
164
|
+
|
|
165
|
+
| Analyzer | Config key | What it finds |
|
|
166
|
+
|---|---|---|
|
|
167
|
+
| **Unused exports** | `unusedExports` | Named/default exports never imported by reachable code |
|
|
168
|
+
| **Unused files** | `unusedFiles` | Source files unreachable from any entrypoint |
|
|
169
|
+
| **Unused packages** | `unusedPackages` | Workspace packages with zero reachable files |
|
|
170
|
+
| **Unused dependencies** | `unusedDependencies` | Declared `dependencies` never referenced by reachable code |
|
|
171
|
+
| **Cycles** | `cycles` | Circular dependency chains (strongly connected components) |
|
|
172
|
+
| **Boundary violations** | `boundaries` | Custom forbidden/required import rules |
|
|
173
|
+
| **Ownership** | `ownership` | Files without a matching team in CODEOWNERS or config |
|
|
174
|
+
| **Impact** | — | Reverse-reachability blast radius (via `pruneguard impact`) |
|
|
175
|
+
|
|
176
|
+
Each finding includes a **confidence level** (high / medium / low) based on analysis scope and unresolved-specifier pressure, so you always know how much to trust a result.
|
|
177
|
+
|
|
178
|
+
---
|
|
179
|
+
|
|
180
|
+
## Trust model
|
|
181
|
+
|
|
182
|
+
Pruneguard is designed for safe, incremental adoption — not surprise bulk deletions.
|
|
183
|
+
|
|
184
|
+
| Mode | Behavior | Use case |
|
|
185
|
+
|---|---|---|
|
|
186
|
+
| `pruneguard scan` | Full-repo analysis, high-confidence findings | Deletion decisions, CI gating |
|
|
187
|
+
| `--focus "glob"` | Full analysis, findings filtered to matching files | Scoping reports to a team or area |
|
|
188
|
+
| `scan <paths...>` | Partial-scope, findings marked advisory | Quick local checks |
|
|
189
|
+
| `--changed-since ref` | Incremental, only changed files analyzed | PR review, fast CI |
|
|
190
|
+
| `--require-full-scope` | Fails if scan would be partial-scope | Strict CI enforcement |
|
|
191
|
+
| `--no-baseline` | No baseline suppression | Deterministic CI, benchmarks |
|
|
192
|
+
|
|
193
|
+
**Recommended deletion flow:**
|
|
194
|
+
|
|
195
|
+
1. `pruneguard scan --format json` — identify candidates
|
|
196
|
+
2. `pruneguard impact <target>` — check blast radius
|
|
197
|
+
3. `pruneguard explain <finding>` — review proof chain
|
|
198
|
+
4. Delete with confidence
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## Programmatic API
|
|
203
|
+
|
|
204
|
+
```ts
|
|
205
|
+
import { scan, impact, explain, loadConfig } from "pruneguard";
|
|
206
|
+
|
|
207
|
+
// Scan and get structured results
|
|
208
|
+
const report = await scan({
|
|
209
|
+
profile: "production",
|
|
210
|
+
changedSince: "origin/main",
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
console.log(`${report.summary.totalFindings} findings`);
|
|
214
|
+
|
|
215
|
+
// Blast radius analysis
|
|
216
|
+
const blast = await impact({ target: "src/utils/helpers.ts" });
|
|
217
|
+
console.log(`Affects ${blast.affectedEntrypoints.length} entrypoints`);
|
|
218
|
+
|
|
219
|
+
// Explain a finding
|
|
220
|
+
const proof = await explain({
|
|
221
|
+
query: "unused-export:packages/core:src/old.ts#deprecatedFn",
|
|
222
|
+
});
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Full TypeScript types are included via `dist/index.d.mts`.
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Framework detection
|
|
230
|
+
|
|
231
|
+
Pruneguard auto-detects popular frameworks and registers their entrypoints and file conventions, so test files, stories, and framework config files aren't flagged as unused.
|
|
232
|
+
|
|
233
|
+
| Framework | Auto-detected via | Entrypoints added |
|
|
234
|
+
|---|---|---|
|
|
235
|
+
| **Next.js** | `next` dependency, `next.config.*` | `app/page.*`, `app/layout.*`, `pages/**` |
|
|
236
|
+
| **Vite** | `vite` devDependency, `vite.config.*` | `vite.config.*` |
|
|
237
|
+
| **Vitest** | `vitest` devDependency | `vitest.config.*`, `**/*.test.*` |
|
|
238
|
+
| **Jest** | `jest` devDependency | `jest.config.*`, `**/*.test.*` |
|
|
239
|
+
| **Storybook** | `@storybook/*` packages | `.storybook/main.*`, `**/*.stories.*` |
|
|
240
|
+
|
|
241
|
+
Override with `"frameworks": { "next": "off" }` in config.
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## Migrating from other tools
|
|
246
|
+
|
|
247
|
+
```sh
|
|
248
|
+
# From knip
|
|
249
|
+
pruneguard migrate knip
|
|
250
|
+
|
|
251
|
+
# From dependency-cruiser
|
|
252
|
+
pruneguard migrate depcruise
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
Both commands read your existing config and emit an equivalent `pruneguard.json` with migration notes.
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Output formats
|
|
260
|
+
|
|
261
|
+
| Format | Flag | Use case |
|
|
262
|
+
|---|---|---|
|
|
263
|
+
| **Text** | `--format text` | Human-readable terminal output (default) |
|
|
264
|
+
| **JSON** | `--format json` | CI pipelines, scripts, programmatic consumption |
|
|
265
|
+
| **SARIF** | `--format sarif` | GitHub Code Scanning, Azure DevOps, IDE integrations |
|
|
266
|
+
| **DOT** | `--format dot` | Graph visualization with Graphviz |
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## Requirements
|
|
271
|
+
|
|
272
|
+
- Node.js >= 18
|
|
273
|
+
- Supported platforms: macOS (ARM64, x64), Linux (x64 glibc/musl, ARM64 glibc/musl), Windows (x64, ARM64)
|
|
274
|
+
|
|
275
|
+
---
|
|
276
|
+
|
|
277
|
+
## License
|
|
278
|
+
|
|
279
|
+
[MIT](https://github.com/ferc/pruneguard/blob/main/LICENSE)
|
package/dist/bin.mjs
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pruneguard",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Repo truth engine for JS/TS monorepos",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"javascript",
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
"dependency-graph",
|
|
13
13
|
"architecture"
|
|
14
14
|
],
|
|
15
|
-
"homepage": "https://github.com/
|
|
16
|
-
"bugs": "https://github.com/
|
|
15
|
+
"homepage": "https://github.com/ferc/pruneguard",
|
|
16
|
+
"bugs": "https://github.com/ferc/pruneguard/issues",
|
|
17
17
|
"license": "MIT",
|
|
18
18
|
"author": "pruneguard contributors",
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
21
|
-
"url": "git+https://github.com/
|
|
21
|
+
"url": "git+https://github.com/ferc/pruneguard",
|
|
22
22
|
"directory": "npm/pruneguard"
|
|
23
23
|
},
|
|
24
24
|
"bin": {
|
|
@@ -41,14 +41,14 @@
|
|
|
41
41
|
}
|
|
42
42
|
},
|
|
43
43
|
"optionalDependencies": {
|
|
44
|
-
"@pruneguard/cli-darwin-arm64": "0.
|
|
45
|
-
"@pruneguard/cli-darwin-x64": "0.
|
|
46
|
-
"@pruneguard/cli-linux-arm64-gnu": "0.
|
|
47
|
-
"@pruneguard/cli-linux-arm64-musl": "0.
|
|
48
|
-
"@pruneguard/cli-linux-x64-gnu": "0.
|
|
49
|
-
"@pruneguard/cli-linux-x64-musl": "0.
|
|
50
|
-
"@pruneguard/cli-win32-arm64-msvc": "0.
|
|
51
|
-
"@pruneguard/cli-win32-x64-msvc": "0.
|
|
44
|
+
"@pruneguard/cli-darwin-arm64": "0.2.0",
|
|
45
|
+
"@pruneguard/cli-darwin-x64": "0.2.0",
|
|
46
|
+
"@pruneguard/cli-linux-arm64-gnu": "0.2.0",
|
|
47
|
+
"@pruneguard/cli-linux-arm64-musl": "0.2.0",
|
|
48
|
+
"@pruneguard/cli-linux-x64-gnu": "0.2.0",
|
|
49
|
+
"@pruneguard/cli-linux-x64-musl": "0.2.0",
|
|
50
|
+
"@pruneguard/cli-win32-arm64-msvc": "0.2.0",
|
|
51
|
+
"@pruneguard/cli-win32-x64-msvc": "0.2.0"
|
|
52
52
|
},
|
|
53
53
|
"engines": {
|
|
54
54
|
"node": ">=18.0.0"
|