pruneguard 0.2.1 → 0.3.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.
- package/README.md +234 -120
- package/bin/pruneguard +0 -0
- package/configuration_schema.json +110 -0
- package/dist/bin.mjs +5 -1
- package/dist/index.d.mts +177 -4
- package/dist/index.mjs +64 -5
- package/dist/{runtime-BxlGT_W-.mjs → runtime-BSHQsTbN.mjs} +71 -9
- package/package.json +11 -9
- package/report_schema.json +216 -0
- package/review_report_schema.json +624 -0
- package/safe_delete_report_schema.json +200 -0
package/README.md
CHANGED
|
@@ -1,37 +1,31 @@
|
|
|
1
1
|
# pruneguard
|
|
2
2
|
|
|
3
|
-
**One graph. Every answer.** Find unused exports, dead files, phantom dependencies, import cycles, and boundary violations across your entire JS/TS monorepo
|
|
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
5
|
[](https://www.npmjs.com/package/pruneguard)
|
|
6
6
|
[](https://github.com/ferc/pruneguard/blob/main/LICENSE)
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## Install
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
```sh
|
|
13
|
+
npm install -D pruneguard # or: npx pruneguard scan
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The package automatically installs the correct platform-specific native binary. No Rust toolchain, no compilation, no native addons -- just `npm install` and go.
|
|
13
17
|
|
|
14
|
-
|
|
18
|
+
**Supported platforms:** macOS (ARM64, x64), Linux (x64/ARM64, glibc and musl), Windows (x64, ARM64). Requires Node.js >= 18.
|
|
15
19
|
|
|
16
|
-
###
|
|
20
|
+
### How it works
|
|
17
21
|
|
|
18
|
-
|
|
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
|
|
22
|
+
pruneguard ships a compiled Rust binary for each platform. The JS API and CLI both spawn this binary. Locally the daemon keeps the graph warm for instant queries. In CI every invocation is a fresh one-shot run.
|
|
26
23
|
|
|
27
24
|
---
|
|
28
25
|
|
|
29
26
|
## Quick start
|
|
30
27
|
|
|
31
28
|
```sh
|
|
32
|
-
# Install
|
|
33
|
-
npm install -D pruneguard # or: npx pruneguard scan
|
|
34
|
-
|
|
35
29
|
# Scan your repo
|
|
36
30
|
pruneguard scan
|
|
37
31
|
|
|
@@ -53,28 +47,31 @@ pruneguard init
|
|
|
53
47
|
pruneguard [OPTIONS] <COMMAND>
|
|
54
48
|
|
|
55
49
|
Commands:
|
|
56
|
-
scan [PATHS...]
|
|
57
|
-
impact <TARGET>
|
|
58
|
-
explain <QUERY>
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
50
|
+
scan [PATHS...] Analyze the repo (default command)
|
|
51
|
+
impact <TARGET> Compute blast radius for a file or export
|
|
52
|
+
explain <QUERY> Show proof chain for a finding, file, or export
|
|
53
|
+
review Branch review gate (blocking vs advisory findings)
|
|
54
|
+
safe-delete <TARGETS...> Evaluate targets for safe deletion
|
|
55
|
+
fix-plan <TARGETS...> Generate structured remediation plan
|
|
56
|
+
suggest-rules Auto-suggest governance rules from graph analysis
|
|
57
|
+
init Generate a default pruneguard.json
|
|
58
|
+
print-config Display the resolved configuration
|
|
59
|
+
debug resolve Debug module resolution
|
|
60
|
+
debug entrypoints List detected entrypoints
|
|
61
|
+
debug runtime Print runtime diagnostics
|
|
62
|
+
daemon start|stop|status Manage the background daemon
|
|
67
63
|
Options:
|
|
68
64
|
-c, --config <FILE> Config file path [default: pruneguard.json]
|
|
69
65
|
--format <FORMAT> Output format: text, json, sarif, dot
|
|
70
66
|
--profile <PROFILE> Analysis profile: production, development, all
|
|
71
|
-
--changed-since <REF> Only
|
|
67
|
+
--changed-since <REF> Only report findings for changed files
|
|
72
68
|
--focus <GLOB> Filter findings to matching files
|
|
73
69
|
--severity <SEVERITY> Minimum severity: error, warn, info
|
|
74
70
|
--no-cache Disable incremental cache
|
|
75
71
|
--no-baseline Disable baseline suppression
|
|
76
72
|
--require-full-scope Fail if scan is partial-scope
|
|
77
73
|
--max-findings <N> Cap the number of reported findings
|
|
74
|
+
--daemon <MODE> Daemon mode: auto, off, required
|
|
78
75
|
-V, --version Print version
|
|
79
76
|
-h, --help Print help
|
|
80
77
|
```
|
|
@@ -83,24 +80,151 @@ Options:
|
|
|
83
80
|
|
|
84
81
|
```sh
|
|
85
82
|
# Full scan with JSON output for CI
|
|
86
|
-
pruneguard
|
|
83
|
+
pruneguard --format json scan
|
|
87
84
|
|
|
88
|
-
# PR check
|
|
85
|
+
# PR check -- only findings from changed files
|
|
89
86
|
pruneguard --changed-since origin/main scan
|
|
90
87
|
|
|
91
88
|
# Deterministic CI (no cache, no baseline)
|
|
92
89
|
pruneguard --no-baseline --no-cache scan
|
|
93
90
|
|
|
91
|
+
# Branch review gate
|
|
92
|
+
pruneguard --changed-since origin/main review
|
|
93
|
+
|
|
94
|
+
# Safe-delete check before cleanup
|
|
95
|
+
pruneguard safe-delete src/old.ts src/legacy/widget.ts
|
|
96
|
+
|
|
94
97
|
# Focus on a specific area without narrowing analysis scope
|
|
95
98
|
pruneguard --focus "packages/core/**" scan
|
|
96
99
|
|
|
97
100
|
# SARIF for GitHub Code Scanning
|
|
98
|
-
pruneguard
|
|
101
|
+
pruneguard --format sarif scan > results.sarif
|
|
99
102
|
|
|
100
103
|
# Visualize the module graph
|
|
101
|
-
pruneguard
|
|
104
|
+
pruneguard --format dot scan | dot -Tsvg -o graph.svg
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Programmatic API
|
|
110
|
+
|
|
111
|
+
All functions spawn the native binary and return typed results.
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
import {
|
|
115
|
+
scan,
|
|
116
|
+
review,
|
|
117
|
+
safeDelete,
|
|
118
|
+
fixPlan,
|
|
119
|
+
impact,
|
|
120
|
+
explain,
|
|
121
|
+
suggestRules,
|
|
122
|
+
run,
|
|
123
|
+
binaryPath,
|
|
124
|
+
loadConfig,
|
|
125
|
+
schemaPath,
|
|
126
|
+
scanDot,
|
|
127
|
+
} from "pruneguard";
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### scan
|
|
131
|
+
|
|
132
|
+
```js
|
|
133
|
+
const report = await scan({
|
|
134
|
+
profile: "production",
|
|
135
|
+
changedSince: "origin/main",
|
|
136
|
+
});
|
|
137
|
+
console.log(`${report.summary.totalFindings} findings`);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
### review
|
|
141
|
+
|
|
142
|
+
```js
|
|
143
|
+
const result = await review({ baseRef: "origin/main", noCache: true });
|
|
144
|
+
if (result.blockingFindings.length > 0) {
|
|
145
|
+
console.error("Blocking findings exist");
|
|
146
|
+
process.exit(1);
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### safeDelete
|
|
151
|
+
|
|
152
|
+
```js
|
|
153
|
+
const result = await safeDelete({ targets: ["src/old.ts"] });
|
|
154
|
+
console.log("Safe:", result.safe.map(e => e.target));
|
|
155
|
+
console.log("Blocked:", result.blocked.map(e => e.target));
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### fixPlan
|
|
159
|
+
|
|
160
|
+
```js
|
|
161
|
+
const plan = await fixPlan({ targets: ["src/old.ts"] });
|
|
162
|
+
for (const action of plan.actions) {
|
|
163
|
+
console.log(`${action.kind}: ${action.targets.join(", ")}`);
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### impact
|
|
168
|
+
|
|
169
|
+
```js
|
|
170
|
+
const blast = await impact({ target: "src/utils/helpers.ts" });
|
|
171
|
+
console.log(`Affects ${blast.affectedEntrypoints.length} entrypoints`);
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### explain
|
|
175
|
+
|
|
176
|
+
```js
|
|
177
|
+
const proof = await explain({ query: "src/old.ts#deprecatedFn" });
|
|
178
|
+
console.log(proof.proofs);
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### run
|
|
182
|
+
|
|
183
|
+
```js
|
|
184
|
+
const result = await run(["--format", "json", "--daemon", "off", "scan"]);
|
|
185
|
+
console.log(result.exitCode, result.durationMs);
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### binaryPath
|
|
189
|
+
|
|
190
|
+
```js
|
|
191
|
+
console.log(binaryPath());
|
|
192
|
+
// => /path/to/node_modules/@pruneguard/cli-darwin-arm64/bin/pruneguard
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### Other functions
|
|
196
|
+
|
|
197
|
+
```js
|
|
198
|
+
const config = await loadConfig();
|
|
199
|
+
const schema = schemaPath();
|
|
200
|
+
const dot = await scanDot();
|
|
201
|
+
const rules = await suggestRules();
|
|
102
202
|
```
|
|
103
203
|
|
|
204
|
+
### Error handling
|
|
205
|
+
|
|
206
|
+
All functions throw `PruneguardExecutionError` with a `code` field:
|
|
207
|
+
|
|
208
|
+
| Code | Meaning |
|
|
209
|
+
|---|---|
|
|
210
|
+
| `PRUNEGUARD_BINARY_NOT_FOUND` | Native binary not found |
|
|
211
|
+
| `PRUNEGUARD_EXECUTION_FAILED` | Binary exited with unexpected code |
|
|
212
|
+
| `PRUNEGUARD_JSON_PARSE_FAILED` | Output was not valid JSON |
|
|
213
|
+
|
|
214
|
+
```js
|
|
215
|
+
import { scan, PruneguardExecutionError } from "pruneguard";
|
|
216
|
+
|
|
217
|
+
try {
|
|
218
|
+
await scan();
|
|
219
|
+
} catch (err) {
|
|
220
|
+
if (err instanceof PruneguardExecutionError) {
|
|
221
|
+
console.error(err.code, err.message);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Full TypeScript types are included via `dist/index.d.mts`.
|
|
227
|
+
|
|
104
228
|
---
|
|
105
229
|
|
|
106
230
|
## Configuration
|
|
@@ -116,47 +240,22 @@ Create `pruneguard.json` (or `.pruneguardrc.json`) in your project root. Run `pr
|
|
|
116
240
|
"packageManager": "pnpm"
|
|
117
241
|
},
|
|
118
242
|
|
|
119
|
-
"entrypoints": {
|
|
120
|
-
"auto": true,
|
|
121
|
-
"include": ["src/index.ts"],
|
|
122
|
-
"exclude": ["**/*.test.ts"]
|
|
123
|
-
},
|
|
124
|
-
|
|
125
243
|
"analysis": {
|
|
126
244
|
"unusedExports": "error",
|
|
127
245
|
"unusedFiles": "warn",
|
|
128
246
|
"unusedDependencies": "error",
|
|
129
|
-
"
|
|
130
|
-
"cycles": "warn",
|
|
131
|
-
"boundaries": "error"
|
|
247
|
+
"cycles": "warn"
|
|
132
248
|
},
|
|
133
249
|
|
|
134
250
|
"frameworks": {
|
|
135
251
|
"next": "auto",
|
|
136
252
|
"vitest": "auto",
|
|
137
253
|
"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
254
|
}
|
|
156
255
|
}
|
|
157
256
|
```
|
|
158
257
|
|
|
159
|
-
Full schema reference is bundled at `node_modules/pruneguard/configuration_schema.json
|
|
258
|
+
Full schema reference is bundled at `node_modules/pruneguard/configuration_schema.json`.
|
|
160
259
|
|
|
161
260
|
---
|
|
162
261
|
|
|
@@ -171,65 +270,105 @@ Full schema reference is bundled at `node_modules/pruneguard/configuration_schem
|
|
|
171
270
|
| **Cycles** | `cycles` | Circular dependency chains (strongly connected components) |
|
|
172
271
|
| **Boundary violations** | `boundaries` | Custom forbidden/required import rules |
|
|
173
272
|
| **Ownership** | `ownership` | Files without a matching team in CODEOWNERS or config |
|
|
174
|
-
| **Impact** |
|
|
273
|
+
| **Impact** | -- | Reverse-reachability blast radius (via `pruneguard impact`) |
|
|
175
274
|
|
|
176
|
-
Each finding includes a **confidence level** (high / medium / low)
|
|
275
|
+
Each finding includes a **confidence level** (high / medium / low) so you always know how much to trust a result.
|
|
177
276
|
|
|
178
277
|
---
|
|
179
278
|
|
|
180
279
|
## Trust model
|
|
181
280
|
|
|
182
|
-
Pruneguard is designed for safe, incremental adoption — not surprise bulk deletions.
|
|
183
|
-
|
|
184
281
|
| Mode | Behavior | Use case |
|
|
185
282
|
|---|---|---|
|
|
186
283
|
| `pruneguard scan` | Full-repo analysis, high-confidence findings | Deletion decisions, CI gating |
|
|
187
284
|
| `--focus "glob"` | Full analysis, findings filtered to matching files | Scoping reports to a team or area |
|
|
188
285
|
| `scan <paths...>` | Partial-scope, findings marked advisory | Quick local checks |
|
|
189
|
-
| `--changed-since ref` |
|
|
286
|
+
| `--changed-since ref` | Full graph, only changed-file findings reported | PR review, fast CI |
|
|
190
287
|
| `--require-full-scope` | Fails if scan would be partial-scope | Strict CI enforcement |
|
|
191
288
|
| `--no-baseline` | No baseline suppression | Deterministic CI, benchmarks |
|
|
192
289
|
|
|
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
290
|
---
|
|
201
291
|
|
|
202
|
-
##
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
292
|
+
## GitHub Actions
|
|
293
|
+
|
|
294
|
+
### Branch review gate
|
|
295
|
+
|
|
296
|
+
```yaml
|
|
297
|
+
name: pruneguard
|
|
298
|
+
on: [pull_request]
|
|
299
|
+
|
|
300
|
+
jobs:
|
|
301
|
+
review:
|
|
302
|
+
runs-on: ubuntu-latest
|
|
303
|
+
steps:
|
|
304
|
+
- uses: actions/checkout@v5
|
|
305
|
+
with:
|
|
306
|
+
fetch-depth: 0
|
|
307
|
+
- uses: actions/setup-node@v6
|
|
308
|
+
with:
|
|
309
|
+
node-version: 24
|
|
310
|
+
- run: npm install pruneguard
|
|
311
|
+
- name: Branch review
|
|
312
|
+
run: npx pruneguard --changed-since origin/main --format json review
|
|
223
313
|
```
|
|
224
314
|
|
|
225
|
-
|
|
315
|
+
### Baseline-gated CI
|
|
316
|
+
|
|
317
|
+
```yaml
|
|
318
|
+
name: pruneguard-baseline
|
|
319
|
+
on:
|
|
320
|
+
push:
|
|
321
|
+
branches: [main]
|
|
322
|
+
pull_request:
|
|
323
|
+
|
|
324
|
+
jobs:
|
|
325
|
+
scan:
|
|
326
|
+
runs-on: ubuntu-latest
|
|
327
|
+
steps:
|
|
328
|
+
- uses: actions/checkout@v5
|
|
329
|
+
with:
|
|
330
|
+
fetch-depth: 0
|
|
331
|
+
- uses: actions/setup-node@v6
|
|
332
|
+
with:
|
|
333
|
+
node-version: 24
|
|
334
|
+
- run: npm install pruneguard
|
|
335
|
+
|
|
336
|
+
- name: Save baseline
|
|
337
|
+
if: github.ref == 'refs/heads/main'
|
|
338
|
+
run: npx pruneguard --no-cache --no-baseline --format json scan > baseline.json
|
|
339
|
+
|
|
340
|
+
- uses: actions/upload-artifact@v6
|
|
341
|
+
if: github.ref == 'refs/heads/main'
|
|
342
|
+
with:
|
|
343
|
+
name: pruneguard-baseline
|
|
344
|
+
path: baseline.json
|
|
345
|
+
|
|
346
|
+
- uses: actions/download-artifact@v7
|
|
347
|
+
if: github.event_name == 'pull_request'
|
|
348
|
+
with:
|
|
349
|
+
name: pruneguard-baseline
|
|
350
|
+
continue-on-error: true
|
|
351
|
+
|
|
352
|
+
- name: Check for new findings
|
|
353
|
+
if: github.event_name == 'pull_request'
|
|
354
|
+
run: |
|
|
355
|
+
npx pruneguard --no-cache --no-baseline --format json scan > current.json
|
|
356
|
+
node -e "
|
|
357
|
+
const fs = require('fs');
|
|
358
|
+
if (!fs.existsSync('baseline.json')) { console.log('No baseline, skipping'); process.exit(0); }
|
|
359
|
+
const base = JSON.parse(fs.readFileSync('baseline.json','utf-8'));
|
|
360
|
+
const curr = JSON.parse(fs.readFileSync('current.json','utf-8'));
|
|
361
|
+
const ids = new Set(base.findings.map(f => f.id));
|
|
362
|
+
const n = curr.findings.filter(f => !ids.has(f.id));
|
|
363
|
+
if (n.length) { n.forEach(f => console.error(f.id+': '+f.message)); process.exit(1); }
|
|
364
|
+
console.log('No new findings.');
|
|
365
|
+
"
|
|
366
|
+
```
|
|
226
367
|
|
|
227
368
|
---
|
|
228
369
|
|
|
229
370
|
## Framework detection
|
|
230
371
|
|
|
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
372
|
| Framework | Auto-detected via | Entrypoints added |
|
|
234
373
|
|---|---|---|
|
|
235
374
|
| **Next.js** | `next` dependency, `next.config.*` | `app/page.*`, `app/layout.*`, `pages/**` |
|
|
@@ -242,31 +381,6 @@ Override with `"frameworks": { "next": "off" }` in config.
|
|
|
242
381
|
|
|
243
382
|
---
|
|
244
383
|
|
|
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
384
|
## Requirements
|
|
271
385
|
|
|
272
386
|
- Node.js >= 18
|
package/bin/pruneguard
CHANGED
|
File without changes
|
|
@@ -259,6 +259,46 @@
|
|
|
259
259
|
"FrameworksConfig": {
|
|
260
260
|
"type": "object",
|
|
261
261
|
"properties": {
|
|
262
|
+
"angular": {
|
|
263
|
+
"anyOf": [
|
|
264
|
+
{
|
|
265
|
+
"$ref": "#/definitions/FrameworkToggle"
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"type": "null"
|
|
269
|
+
}
|
|
270
|
+
]
|
|
271
|
+
},
|
|
272
|
+
"astro": {
|
|
273
|
+
"anyOf": [
|
|
274
|
+
{
|
|
275
|
+
"$ref": "#/definitions/FrameworkToggle"
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
"type": "null"
|
|
279
|
+
}
|
|
280
|
+
]
|
|
281
|
+
},
|
|
282
|
+
"cypress": {
|
|
283
|
+
"anyOf": [
|
|
284
|
+
{
|
|
285
|
+
"$ref": "#/definitions/FrameworkToggle"
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
"type": "null"
|
|
289
|
+
}
|
|
290
|
+
]
|
|
291
|
+
},
|
|
292
|
+
"docusaurus": {
|
|
293
|
+
"anyOf": [
|
|
294
|
+
{
|
|
295
|
+
"$ref": "#/definitions/FrameworkToggle"
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
"type": "null"
|
|
299
|
+
}
|
|
300
|
+
]
|
|
301
|
+
},
|
|
262
302
|
"jest": {
|
|
263
303
|
"anyOf": [
|
|
264
304
|
{
|
|
@@ -279,6 +319,46 @@
|
|
|
279
319
|
}
|
|
280
320
|
]
|
|
281
321
|
},
|
|
322
|
+
"nuxt": {
|
|
323
|
+
"anyOf": [
|
|
324
|
+
{
|
|
325
|
+
"$ref": "#/definitions/FrameworkToggle"
|
|
326
|
+
},
|
|
327
|
+
{
|
|
328
|
+
"type": "null"
|
|
329
|
+
}
|
|
330
|
+
]
|
|
331
|
+
},
|
|
332
|
+
"nx": {
|
|
333
|
+
"anyOf": [
|
|
334
|
+
{
|
|
335
|
+
"$ref": "#/definitions/FrameworkToggle"
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
"type": "null"
|
|
339
|
+
}
|
|
340
|
+
]
|
|
341
|
+
},
|
|
342
|
+
"playwright": {
|
|
343
|
+
"anyOf": [
|
|
344
|
+
{
|
|
345
|
+
"$ref": "#/definitions/FrameworkToggle"
|
|
346
|
+
},
|
|
347
|
+
{
|
|
348
|
+
"type": "null"
|
|
349
|
+
}
|
|
350
|
+
]
|
|
351
|
+
},
|
|
352
|
+
"remix": {
|
|
353
|
+
"anyOf": [
|
|
354
|
+
{
|
|
355
|
+
"$ref": "#/definitions/FrameworkToggle"
|
|
356
|
+
},
|
|
357
|
+
{
|
|
358
|
+
"type": "null"
|
|
359
|
+
}
|
|
360
|
+
]
|
|
361
|
+
},
|
|
282
362
|
"storybook": {
|
|
283
363
|
"anyOf": [
|
|
284
364
|
{
|
|
@@ -289,6 +369,26 @@
|
|
|
289
369
|
}
|
|
290
370
|
]
|
|
291
371
|
},
|
|
372
|
+
"sveltekit": {
|
|
373
|
+
"anyOf": [
|
|
374
|
+
{
|
|
375
|
+
"$ref": "#/definitions/FrameworkToggle"
|
|
376
|
+
},
|
|
377
|
+
{
|
|
378
|
+
"type": "null"
|
|
379
|
+
}
|
|
380
|
+
]
|
|
381
|
+
},
|
|
382
|
+
"turborepo": {
|
|
383
|
+
"anyOf": [
|
|
384
|
+
{
|
|
385
|
+
"$ref": "#/definitions/FrameworkToggle"
|
|
386
|
+
},
|
|
387
|
+
{
|
|
388
|
+
"type": "null"
|
|
389
|
+
}
|
|
390
|
+
]
|
|
391
|
+
},
|
|
292
392
|
"vite": {
|
|
293
393
|
"anyOf": [
|
|
294
394
|
{
|
|
@@ -299,6 +399,16 @@
|
|
|
299
399
|
}
|
|
300
400
|
]
|
|
301
401
|
},
|
|
402
|
+
"vitepress": {
|
|
403
|
+
"anyOf": [
|
|
404
|
+
{
|
|
405
|
+
"$ref": "#/definitions/FrameworkToggle"
|
|
406
|
+
},
|
|
407
|
+
{
|
|
408
|
+
"type": "null"
|
|
409
|
+
}
|
|
410
|
+
]
|
|
411
|
+
},
|
|
302
412
|
"vitest": {
|
|
303
413
|
"anyOf": [
|
|
304
414
|
{
|
package/dist/bin.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as binaryPath, t as PruneguardExecutionError } from "./runtime-
|
|
2
|
+
import { n as binaryPath, t as PruneguardExecutionError } from "./runtime-BSHQsTbN.mjs";
|
|
3
3
|
import { spawn } from "node:child_process";
|
|
4
4
|
//#region src-js/bin.ts
|
|
5
5
|
try {
|
|
@@ -9,6 +9,10 @@ try {
|
|
|
9
9
|
"SIGTERM",
|
|
10
10
|
"SIGHUP"
|
|
11
11
|
]) process.on(sig, () => child.kill(sig));
|
|
12
|
+
child.on("error", (err) => {
|
|
13
|
+
console.error(`pruneguard: failed to execute binary: ${err.message}`);
|
|
14
|
+
process.exitCode = 2;
|
|
15
|
+
});
|
|
12
16
|
child.on("close", (code, signal) => {
|
|
13
17
|
if (signal) process.kill(process.pid, signal);
|
|
14
18
|
else process.exitCode = code ?? 1;
|