dev-prune 1.16.0 → 1.18.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 +56 -27
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ gigabytes hostage for a build you are not running.
|
|
|
28
28
|
|
|
29
29
|
`dev-prune` finds those directories across every Git repository you register, and deletes
|
|
30
30
|
them — but only after proving the exact command that puts them back would succeed. It
|
|
31
|
-
knows twenty-
|
|
31
|
+
knows twenty-five package managers, not just the obvious four: Composer, Bundler, Mix,
|
|
32
32
|
CocoaPods and Terraform are as first-class as npm and pip. It is a single Rust binary,
|
|
33
33
|
installs its own background schedule, and answers to two names: `dev-prune` and `devp`.
|
|
34
34
|
|
|
@@ -91,6 +91,11 @@ All three download the prebuilt binary for your platform, verify its published S
|
|
|
91
91
|
put it on `PATH`, and run `dev-prune setup`. Pass `--no-auto-setup` / `-NoAutoSetup` to
|
|
92
92
|
skip that last step.
|
|
93
93
|
|
|
94
|
+
A binary you download and run by hand asks first instead: the first attended run opens
|
|
95
|
+
the settings walkthrough before anything is installed, finishing it is the yes, and
|
|
96
|
+
quitting it means nothing is installed — durably, until you say otherwise with
|
|
97
|
+
`devp setup`.
|
|
98
|
+
|
|
94
99
|
Re-run any of them whenever you like. An install that is already current, complete and on
|
|
95
100
|
`PATH` is left exactly as it is and exits `0` without downloading; an older one is updated
|
|
96
101
|
in place; a newer one is not downgraded. `--force` / `-Force` writes it again regardless.
|
|
@@ -327,9 +332,12 @@ devp restore --last-run # put back exactly what that pass deleted
|
|
|
327
332
|
A few more worth knowing on day one:
|
|
328
333
|
|
|
329
334
|
```bash
|
|
330
|
-
devp stats # how much has been reclaimed so far, and by
|
|
335
|
+
devp stats # how much has been reclaimed so far, by repository and by package manager
|
|
336
|
+
devp history # which pass reclaimed it, and what started that pass
|
|
337
|
+
devp history --pass 1 # the exact command line, and every directory it took
|
|
331
338
|
devp caches # every package manager cache, sized. The report deletes nothing
|
|
332
|
-
devp caches docker # what Docker holds, and the prune commands
|
|
339
|
+
devp caches docker # what Docker holds, and the prune commands
|
|
340
|
+
devp caches clear docker # run the narrow ones — never a volume, never on a schedule
|
|
333
341
|
devp status --drift # anything installed that the lockfiles don't record?
|
|
334
342
|
devp doctor . # why is this repository not being pruned?
|
|
335
343
|
devp doctor --fix # repair a broken integration — never a first-time install
|
|
@@ -476,16 +484,27 @@ Container engines
|
|
|
476
484
|
```
|
|
477
485
|
|
|
478
486
|
Clearing 6 GiB of npm cache while a Docker install nobody has looked at in a year sits on
|
|
479
|
-
40 GiB is the mistake this exists to prevent. `devp caches podman
|
|
480
|
-
nerdctl`
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
487
|
+
40 GiB is the mistake this exists to prevent. `devp caches podman`, `devp caches
|
|
488
|
+
nerdctl`, `devp caches finch` and `devp caches containers container` — Apple's engine, on
|
|
489
|
+
Apple silicon — are the same report for those engines, and `devp caches containers` runs
|
|
490
|
+
every one it finds and lists any local Kubernetes clusters (kind, k3d, minikube) by name.
|
|
491
|
+
|
|
492
|
+
**The report deletes nothing, and nothing on a schedule ever will** — no daemon, no Git
|
|
493
|
+
hook and no `devp run` path reaches container disk, with or without `--yes`. What used to
|
|
494
|
+
end there now has a second half: `devp caches clear docker` runs the narrow commands for
|
|
495
|
+
you — `builder prune -a -f`, `image prune -a -f`, `container prune -f` — after printing
|
|
496
|
+
them and asking, and counts what came back on its own line in `devp stats`. Printing four
|
|
497
|
+
commands and asking you to go and type one in another window meant the 20 GiB you
|
|
498
|
+
reclaimed on its advice was yours to have remembered, and dev-prune could not account for
|
|
499
|
+
it.
|
|
500
|
+
|
|
501
|
+
**It will not touch a volume, and no flag makes it.** There is no argument anywhere in
|
|
502
|
+
that table containing the word, and a unit test fails the build if one appears. That is a
|
|
503
|
+
different promise from the lockfile rule: an image can be pulled again and a build cache
|
|
504
|
+
rebuilt, so those are a question of consent and the prompt is the consent. What is inside
|
|
505
|
+
a named volume is the only copy. `docker volume prune` stays a command this prints and
|
|
506
|
+
you type — and the estimate says how much unused-volume space it is leaving alone rather
|
|
507
|
+
than folding it into a number these commands cannot deliver.
|
|
489
508
|
|
|
490
509
|
The figures come from the engine's own `system df`, not a walk of the disk. On Docker
|
|
491
510
|
Desktop and Podman the store lives inside a VM disk image the host filesystem cannot see,
|
|
@@ -576,10 +595,10 @@ process that leaves a dirty working tree is a surprise.
|
|
|
576
595
|
| 🧩 **Any number of ecosystems per repository** | uv, npm and cargo in one root, or spread across `frontend/`, `services/api/` and `tools/cli/` — each discovered, verified and pruned on its own terms |
|
|
577
596
|
| ↩️ **One-command restore** | `devp restore .` reinstalls a tree; `devp restore --last-run` puts back exactly what the most recent pass deleted, across every repository it touched |
|
|
578
597
|
| 🕒 **Activity-aware** | Combines `git log` timestamps with source-file `mtime`, so uncommitted work protects a repository just as a commit does |
|
|
579
|
-
| 🐳 **Container report** | `devp caches docker` (also `podman`, `nerdctl`, or `containers` for all of them plus local Kubernetes clusters) breaks a container engine's disk into images, containers, local volumes and build cache, each with what the engine itself calls reclaimable, and prints the prune commands narrowest first with what each takes with it.
|
|
580
|
-
| 📊 **Cache report** | `devp caches` sizes every package manager cache and store on the machine — npm to cargo to conda, Maven, Gradle, NuGet, vcpkg, Conan, Composer, CocoaPods and
|
|
598
|
+
| 🐳 **Container report** | `devp caches docker` (also `podman`, `nerdctl`, `finch`, Apple's `container`, or `containers` for all of them plus local Kubernetes clusters) breaks a container engine's disk into images, containers, local volumes and build cache, each with what the engine itself calls reclaimable, and prints the prune commands narrowest first with what each takes with it. `devp caches clear docker` then runs the narrow ones for you, after asking, and counts them in `devp stats` — **never a volume**, and never from a scheduler or a hook. `devp caches` carries a one-line summary per engine, outside its own total |
|
|
599
|
+
| 📊 **Cache report** | `devp caches` sizes every package manager cache and store on the machine — npm to cargo to conda, Maven, Gradle, NuGet, vcpkg, Conan, Composer, CocoaPods, Hex, Bundler, pub, SwiftPM, Terraform, Poetry, PDM and Deno — and prints the command that clears each. It also finds the stores that belong to no package manager at all and are routinely the largest things in the list: the Playwright and Puppeteer browser bundles, the Cypress binary cache, the Electron and electron-builder download caches, and the HuggingFace hub — a whole browser or model per version, and nothing ever removes the old one. The report is read-only; `devp caches clear <manager>` runs that command for you, after asking. `devp config set cache_max_gb default=10` says how big is too big — for every manager at once, or per manager with `default=10,npm=4` — and marks the ones past it — `devp caches clear --over-cap all` then empties exactly those, still only when you type it. Each manager also says how many of your registered repositories use it and what that works out to per repository, and `devp caches clear --unused all` empties the ones nothing uses at all. pnpm is reported once per filesystem, because a store it hardlinks into `node_modules` cannot cross one and projects kept off the system disk get a store of their own. Nothing on a schedule ever touches a cache, and Maven's `~/.m2/repository` is never cleared at all — it holds artifacts `mvn install:install-file` put there that no remote can hand back |
|
|
581
600
|
| 🩺 **`devp doctor`** | One read-only pass that ends by naming the *single* reason a repository would or would not be pruned. Runs no package manager, repairs nothing, safe to run twice. `devp doctor --fix` then mends what it found — installed-but-broken only |
|
|
582
|
-
| 🤖 **Self-installing automation** | OS-native scheduler (Task Scheduler, LaunchAgent, systemd user timer) and non-blocking Git hooks, installed
|
|
601
|
+
| 🤖 **Self-installing automation** | OS-native scheduler (Task Scheduler, LaunchAgent, systemd user timer) and non-blocking Git hooks, installed once the first run’s walkthrough is accepted (quitting it installs nothing) and restored after an upgrade. `auto_setup`, `auto_hooks`, `auto_daemon` or `DEV_PRUNE_NO_AUTO_SETUP=1` turn it off |
|
|
583
602
|
| ⚡ **0ms opt-out** | An `ignore.devprune.json` in a repository root is honoured by file presence alone — no read, no parse. It applies at registration as well: a bulk scan (`devp init`, and the scheduled pass's own discovery) will not register a repository that holds it, so a repository can decline before it ever reaches `devp status`. `devp link <path>` still registers one, because naming a single repository is not a bulk scan |
|
|
584
603
|
| 🔌 **`--json` on every reporting command** | `run`, `status`, `stats`, `trust` and `caches` each emit one versioned document on stdout, diagnostics on stderr. Built for scripts and agents |
|
|
585
604
|
| 🧠 **AI agent skill** | A token-lean `SKILL.md` embedded in the binary; `devp skill` exports it and prints onboarding prompts for Claude Code, Gemini Antigravity, Cursor, Windsurf, Copilot and OpenClaw, and the repository doubles as a Claude Code plugin marketplace |
|
|
@@ -600,11 +619,12 @@ process that leaves a dirty working tree is a surprise.
|
|
|
600
619
|
| `devp undo` | :------------------------------------------------------------------ | Reverts the most recent `init` or `link` |
|
|
601
620
|
| `devp run [PATH]` | `--dry-run`, `--only`, `--skip`, `--except`, `--min-size`, `--json` | Prunes every registered repository, or one target |
|
|
602
621
|
| `devp status` | `--top N`, `--drift`, `--json` | Interactive dashboard; a plain table when there is no TTY. `--top N` shows only the N biggest repositories; `--drift` lists every environment holding packages its lockfile never recorded |
|
|
603
|
-
| `devp stats` | `--json` | What has already been reclaimed: lifetime total from pruning, a separate lifetime total from `devp caches clear`, prune passes, the last pass,
|
|
622
|
+
| `devp stats` | `--json` | What has already been reclaimed: lifetime total from pruning, a separate lifetime total from `devp caches clear`, prune passes, the last pass, the biggest contributors, which package managers the space came from, and how many passes you typed rather than scheduled |
|
|
623
|
+
| `devp history` | `--pass N`, `--limit N`, `--all`, `--json`, `--export [PATH]` | Which pass deleted what, and what asked it to — one line per pass, then `--pass N` for the command line that ran it and every directory it removed. `--export` writes the lot to your documents folder |
|
|
604
624
|
| `devp completions` | `bash`, `zsh`, `fish`, `powershell`, `elvish` | Prints a shell completion script to stdout, generated from the same argument definitions the binary parses with |
|
|
605
625
|
| `devp caches` | `clear <manager\|all>`, `--json` | Sizes every package manager cache on the machine and prints the command that clears each. The report deletes nothing and nothing on a schedule ever will; `clear` empties one when you type it, after asking |
|
|
606
|
-
| `devp caches docker` | `podman`, `nerdctl`, `containers [ENGINE]`, `--json`
|
|
607
|
-
| `devp trust` | `--json` | What dev-prune may do on this machine: the guarantees the code enforces, then the scheduler, hooks and settings read live. Read-only
|
|
626
|
+
| `devp caches docker` | `podman`, `nerdctl`, `finch`, `container`, `containers [ENGINE]`, `--json` | What a container engine holds — images, containers, volumes, build cache — each sized, with what the engine calls reclaimable, then the prune commands. The report deletes nothing; `devp caches clear <engine>` runs the narrow ones when you name it, never a volume |
|
|
627
|
+
| `devp trust` | `--json` | What dev-prune may do on this machine: the guarantees the code enforces, then the scheduler, hooks and settings read live, then every copy of dev-prune on the machine with the manager that installed it and its SHA-256. Read-only |
|
|
608
628
|
| `devp restore [PATH]` | `--last-run` | Reinstalls dependencies for every project in a tree; `--last-run` undoes the last prune pass |
|
|
609
629
|
| `devp doctor [PATH]` | `--fix` | Diagnoses the installation, or one repository — ending with the single reason a pass would or would not touch it. `--fix` repairs what the checks found; it never performs a first-time install |
|
|
610
630
|
| `devp config [ACTION]` | `get`, `set`, `show`, `wizard`, `project`, `daemon`, `hook`, `icon` | Global settings, per-repository `.devprune.json`, scheduler, Git hooks, file manager icons |
|
|
@@ -639,6 +659,7 @@ Adapters detect the project, verify the lockfile, and own the bloat directories:
|
|
|
639
659
|
| **pnpm** | `pnpm-lock.yaml` | `node_modules` | `pnpm install --lockfile-only --frozen-lockfile` | `pnpm install --frozen-lockfile` |
|
|
640
660
|
| **Yarn** | `yarn.lock` | `node_modules` | `yarn install --immutable --mode update-lockfile` (Berry); on Classic an existing `yarn.lock` is itself the proof | `yarn install --immutable` |
|
|
641
661
|
| **Bun** | `bun.lockb`, `bun.lock` | `node_modules` | `bun install --frozen-lockfile --dry-run --ignore-scripts` | `bun install --frozen-lockfile` |
|
|
662
|
+
| **Deno** | `deno.lock` | `node_modules`, `vendor` *(when the config asked for one)* | `deno.lock` parses and carries its `version`, and is no older than the config it came from | `deno install` |
|
|
642
663
|
| **uv** (Python) | `uv.lock`, `[tool.uv]` in `pyproject.toml` | `.venv` | `uv lock --locked` | `uv sync` |
|
|
643
664
|
| **Poetry** (Python) | `poetry.lock`, `[tool.poetry]` in `pyproject.toml` | `.venv` | `poetry check --lock`, plus no installed package the lockfile never recorded | `poetry install` |
|
|
644
665
|
| **PDM** (Python) | `pdm.lock`, `[tool.pdm]` or `pdm.backend` in `pyproject.toml` | `.venv`, `__pypackages__` | `pdm lock --check` | `pdm install` |
|
|
@@ -662,11 +683,11 @@ Adapters detect the project, verify the lockfile, and own the bloat directories:
|
|
|
662
683
|
A required binary that is missing is a reason to skip, never a reason to delete: if `npm`
|
|
663
684
|
is not on `PATH`, the `node_modules` it owns is left exactly where it is.
|
|
664
685
|
|
|
665
|
-
The
|
|
686
|
+
The nine build-tool adapters ship **disabled**, because a build tree is regenerated
|
|
666
687
|
by recompiling, not downloading — it costs more to get back. `devp config set
|
|
667
688
|
enable_cargo true` / `enable_gradle true` / `enable_maven true` / `enable_swift true` /
|
|
668
689
|
`enable_dart true` / `enable_mix_build true` / `enable_vcpkg true` /
|
|
669
|
-
`enable_cmake_build true` switches them on, and their candidates wait for
|
|
690
|
+
`enable_cmake_build true` / `enable_dotnet_build true` switches them on, and their candidates wait for
|
|
670
691
|
`build_idle_days` (45 by default), applied as the *maximum* of it and `idle_days` — the
|
|
671
692
|
build-tool gate only ever makes pruning later, never earlier.
|
|
672
693
|
|
|
@@ -677,10 +698,13 @@ it beside the adapter checklist, grouped by language, where one heading sets the
|
|
|
677
698
|
window for every adapter under it.
|
|
678
699
|
|
|
679
700
|
A download cache is a bet that re-downloading costs less than the disk it occupies,
|
|
680
|
-
and somewhere the bet stops paying. `devp config set cache_max_gb
|
|
701
|
+
and somewhere the bet stops paying. `devp config set cache_max_gb default=10` is
|
|
681
702
|
where you say where: a ceiling in gibibytes — GiB, the unit the report prints —
|
|
682
|
-
|
|
683
|
-
manager's whole footprint.
|
|
703
|
+
for every manager at once, measured against each
|
|
704
|
+
manager's whole footprint. `default=10,npm=4` gives one of them a figure of its own,
|
|
705
|
+
and a manager named outright is held to that rather than to both. The first run
|
|
706
|
+
suggests `default=10`, and any ceiling you have already set counts as the suggestion
|
|
707
|
+
taken — `devp config recommended` never overwrites a number you chose. A manager over its cap is **marked** in `devp caches` —
|
|
684
708
|
setting one deletes nothing — and `devp caches clear --over-cap all` empties exactly
|
|
685
709
|
what is marked, when you type it. It is keyed by the names `devp caches clear` takes
|
|
686
710
|
(`npm`, `pnpm`, `uv`, `pip`, `cargo`, `go`, `nuget`, …) rather than by adapter name,
|
|
@@ -773,7 +797,7 @@ once on a first install — so the defaults are something you agreed to rather t
|
|
|
773
797
|
inherited — and again after an upgrade adds a setting you have never been shown.
|
|
774
798
|
|
|
775
799
|
If you already know what you want, `devp config recommended` is the one-command version:
|
|
776
|
-
it turns on the
|
|
800
|
+
it turns on the nine adapters and build trees that are off by default because they are
|
|
777
801
|
not universally wanted, and leaves `allow_manifest_rewrite` — the one recommendation
|
|
778
802
|
that edits files Git tracks — named, explained and off unless you add
|
|
779
803
|
`--with-cautious`. `devp config show` lists whatever you have not taken yet.
|
|
@@ -811,13 +835,13 @@ rather than downloading. That is the whole reason each one is a switch.
|
|
|
811
835
|
|
|
812
836
|
| Key | Default | Meaning |
|
|
813
837
|
| :--- | :---: | :--- |
|
|
814
|
-
| `enable_cargo` … `
|
|
838
|
+
| `enable_cargo` … `enable_dotnet_build` | `false` | Turn on an opt-in build-tool adapter; `build_idle_days` (`45`) gates all nine |
|
|
815
839
|
|
|
816
840
|
**Shared download caches** — one key, because the cap only ever marks.
|
|
817
841
|
|
|
818
842
|
| Key | Default | Meaning |
|
|
819
843
|
| :--- | :---: | :--- |
|
|
820
|
-
| `cache_max_gb` | *(none)* | Per-manager cache caps in GiB, as `
|
|
844
|
+
| `cache_max_gb` | *(none)* | Per-manager cache caps in GiB, as `default=10,npm=4` — `default` covers every manager not named separately, and the cap itself deletes nothing |
|
|
821
845
|
|
|
822
846
|
**Running without being asked** — what dev-prune may install here, and how often it may
|
|
823
847
|
act on its own.
|
|
@@ -959,6 +983,11 @@ non-blocking `post-commit`, `post-checkout` and `post-merge` Git hooks that regi
|
|
|
959
983
|
repositories as you visit them. Both are reinstated after an upgrade if anything went
|
|
960
984
|
missing.
|
|
961
985
|
|
|
986
|
+
None of it arrives unasked. A machine that has never agreed opens the settings
|
|
987
|
+
walkthrough on its first attended run, before anything is installed: finishing the
|
|
988
|
+
walkthrough is the yes, quitting it is a durable no, and `devp setup` changes the
|
|
989
|
+
answer whenever you like.
|
|
990
|
+
|
|
962
991
|
```bash
|
|
963
992
|
devp setup --status # what is installed, what is not, and why
|
|
964
993
|
devp config set auto_setup false # stop the unattended pass entirely
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dev-prune",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.18.0",
|
|
4
4
|
"description": "Universal, lockfile-safe workspace pruner. Reclaims disk space from idle Git repositories by deleting only dependency and build directories a lockfile can rebuild.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"dev-prune": "./bin/dev-prune.js",
|
|
@@ -12,13 +12,13 @@
|
|
|
12
12
|
"LICENSE.md"
|
|
13
13
|
],
|
|
14
14
|
"optionalDependencies": {
|
|
15
|
-
"dev-prune-darwin-arm64": "1.
|
|
16
|
-
"dev-prune-darwin-x64": "1.
|
|
17
|
-
"dev-prune-linux-arm64": "1.
|
|
18
|
-
"dev-prune-linux-x64": "1.
|
|
19
|
-
"dev-prune-windows-arm64": "1.
|
|
20
|
-
"dev-prune-windows-x64": "1.
|
|
21
|
-
"dev-prune-windows-x86": "1.
|
|
15
|
+
"dev-prune-darwin-arm64": "1.18.0",
|
|
16
|
+
"dev-prune-darwin-x64": "1.18.0",
|
|
17
|
+
"dev-prune-linux-arm64": "1.18.0",
|
|
18
|
+
"dev-prune-linux-x64": "1.18.0",
|
|
19
|
+
"dev-prune-windows-arm64": "1.18.0",
|
|
20
|
+
"dev-prune-windows-x64": "1.18.0",
|
|
21
|
+
"dev-prune-windows-x86": "1.18.0"
|
|
22
22
|
},
|
|
23
23
|
"engines": {
|
|
24
24
|
"node": ">=20"
|