pruneguard 0.1.0 → 0.2.1

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.
Files changed (3) hide show
  1. package/README.md +276 -3
  2. package/dist/bin.mjs +0 -0
  3. package/package.json +12 -12
package/README.md CHANGED
@@ -1,6 +1,279 @@
1
1
  # pruneguard
2
2
 
3
- Rust-first repo truth engine for JS/TS monorepos.
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
- Build one accurate repo graph, then answer dead-code, dependency, boundary,
6
- ownership, impact, and explainability questions from the same analysis pass.
5
+ [![npm version](https://img.shields.io/npm/v/pruneguard)](https://www.npmjs.com/package/pruneguard)
6
+ [![license](https://img.shields.io/npm/l/pruneguard)](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.1.0",
3
+ "version": "0.2.1",
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/user/pruneguard",
16
- "bugs": "https://github.com/user/pruneguard/issues",
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/user/pruneguard",
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.1.0",
45
- "@pruneguard/cli-darwin-x64": "0.1.0",
46
- "@pruneguard/cli-linux-arm64-gnu": "0.1.0",
47
- "@pruneguard/cli-linux-arm64-musl": "0.1.0",
48
- "@pruneguard/cli-linux-x64-gnu": "0.1.0",
49
- "@pruneguard/cli-linux-x64-musl": "0.1.0",
50
- "@pruneguard/cli-win32-arm64-msvc": "0.1.0",
51
- "@pruneguard/cli-win32-x64-msvc": "0.1.0"
44
+ "@pruneguard/cli-darwin-arm64": "0.2.1",
45
+ "@pruneguard/cli-darwin-x64": "0.2.1",
46
+ "@pruneguard/cli-linux-arm64-gnu": "0.2.1",
47
+ "@pruneguard/cli-linux-arm64-musl": "0.2.1",
48
+ "@pruneguard/cli-linux-x64-gnu": "0.2.1",
49
+ "@pruneguard/cli-linux-x64-musl": "0.2.1",
50
+ "@pruneguard/cli-win32-arm64-msvc": "0.2.1",
51
+ "@pruneguard/cli-win32-x64-msvc": "0.2.1"
52
52
  },
53
53
  "engines": {
54
54
  "node": ">=18.0.0"