diskdiet 0.0.0-stage → 0.6.2
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 +23 -2
- package/bin/diskdiet.js +26 -0
- package/checksums.json +8 -0
- package/lib/install.js +113 -0
- package/package.json +46 -4
package/README.md
CHANGED
|
@@ -1,3 +1,24 @@
|
|
|
1
|
-
#
|
|
1
|
+
# diskdiet
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
See where your developer disk space went, and get it back safely.
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npx diskdiet # what's using space, and what can go (changes nothing)
|
|
7
|
+
npx diskdiet clean # free what's older than 30 days, after showing the list
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
diskdiet measures the caches developer tools leave behind (npm, Yarn, pnpm, Bun, pip,
|
|
11
|
+
uv, Cargo, Go, Gradle, Maven, Playwright, Cypress, Xcode, Docker) and the
|
|
12
|
+
`node_modules` and `target` folders of projects you haven't touched, then removes only
|
|
13
|
+
what you haven't used lately.
|
|
14
|
+
|
|
15
|
+
This package downloads the diskdiet binary for your OS and CPU from the
|
|
16
|
+
[GitHub release](https://github.com/roystondwork-dev/diskdiet/releases) on first use,
|
|
17
|
+
checks it against the checksums published with the package, and caches it.
|
|
18
|
+
|
|
19
|
+
For AI assistants: `claude mcp add diskdiet -- npx -y diskdiet mcp`.
|
|
20
|
+
|
|
21
|
+
Full documentation, the desktop app and other ways to install:
|
|
22
|
+
<https://github.com/roystondwork-dev/diskdiet>
|
|
23
|
+
|
|
24
|
+
MIT © 2026 Royston D and diskdiet contributors
|
package/bin/diskdiet.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Runs diskdiet with the given arguments: `npx diskdiet 3000`.
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const { spawnSync } = require("node:child_process");
|
|
6
|
+
const { ensureBinary } = require("../lib/install.js");
|
|
7
|
+
const { version } = require("../package.json");
|
|
8
|
+
const checksums = require("../checksums.json");
|
|
9
|
+
|
|
10
|
+
ensureBinary({ version, checksums }).then(
|
|
11
|
+
(bin) => {
|
|
12
|
+
const r = spawnSync(bin, process.argv.slice(2), { stdio: "inherit" });
|
|
13
|
+
if (r.error) {
|
|
14
|
+
console.error(`diskdiet: couldn't run diskdiet: ${r.error.message}`);
|
|
15
|
+
process.exit(3);
|
|
16
|
+
}
|
|
17
|
+
if (r.signal) {
|
|
18
|
+
process.kill(process.pid, r.signal); // e.g. Ctrl-C: exit the way diskdiet did
|
|
19
|
+
}
|
|
20
|
+
process.exit(r.status ?? 1);
|
|
21
|
+
},
|
|
22
|
+
(err) => {
|
|
23
|
+
console.error(`diskdiet: ${err.message}`);
|
|
24
|
+
process.exit(3);
|
|
25
|
+
},
|
|
26
|
+
);
|
package/checksums.json
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
{
|
|
2
|
+
"diskdiet_0.6.2_darwin_amd64.tar.gz": "867d507756bff28361393f982cb73576e996df047a82f2cb16960bc8887d32f9",
|
|
3
|
+
"diskdiet_0.6.2_darwin_arm64.tar.gz": "6a695ae8817b3ba92fd452a54daa4d2697893fd170a6d45e8f33c35ccf5b6a72",
|
|
4
|
+
"diskdiet_0.6.2_linux_amd64.tar.gz": "7f39ff28aaf11f528f90d83f2849cf1c13c440435a456470736c5707f2707abe",
|
|
5
|
+
"diskdiet_0.6.2_linux_arm64.tar.gz": "bf7da5811f0b44183d241c6a28b929ea4bf077b038339dc5c193c26c93c07a70",
|
|
6
|
+
"diskdiet_0.6.2_windows_amd64.zip": "04836688cc671321968ab3ee95a8679fdc799853fcbefd4e1c989487408ccda4",
|
|
7
|
+
"diskdiet_0.6.2_windows_arm64.zip": "7da5e92324b150022a5ad53939b79df7c81ae1d0784f8a01459017e6408372c9"
|
|
8
|
+
}
|
package/lib/install.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// Finds diskdiet for this OS and CPU, downloading it from the GitHub release
|
|
2
|
+
// on first use. The archive is checked against the checksums published with
|
|
3
|
+
// this package (checksums.json, from the release's signed checksums.txt)
|
|
4
|
+
// before anything is extracted, then cached per version.
|
|
5
|
+
"use strict";
|
|
6
|
+
|
|
7
|
+
const crypto = require("node:crypto");
|
|
8
|
+
const fs = require("node:fs");
|
|
9
|
+
const os = require("node:os");
|
|
10
|
+
const path = require("node:path");
|
|
11
|
+
const { execFileSync } = require("node:child_process");
|
|
12
|
+
|
|
13
|
+
const REPO = "roystondwork-dev/diskdiet";
|
|
14
|
+
|
|
15
|
+
/** The release archive for a platform, e.g. diskdiet_0.9.0_darwin_arm64.tar.gz. */
|
|
16
|
+
function archiveName(version, platform, arch) {
|
|
17
|
+
const goos = { darwin: "darwin", linux: "linux", win32: "windows" }[platform];
|
|
18
|
+
const goarch = { x64: "amd64", arm64: "arm64" }[arch];
|
|
19
|
+
if (!goos || !goarch) {
|
|
20
|
+
throw new Error(`diskdiet isn't available for ${platform}/${arch} (macOS, Linux and Windows on x64 or arm64 are)`);
|
|
21
|
+
}
|
|
22
|
+
return `diskdiet_${version}_${goos}_${goarch}.${goos === "windows" ? "zip" : "tar.gz"}`;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** Where downloaded binaries are kept: DISKDIET_NPM_CACHE, else the OS's cache directory. */
|
|
26
|
+
function cacheDir(env = process.env, platform = process.platform, home = os.homedir()) {
|
|
27
|
+
if (env.DISKDIET_NPM_CACHE) {
|
|
28
|
+
return env.DISKDIET_NPM_CACHE;
|
|
29
|
+
}
|
|
30
|
+
if (platform === "win32") {
|
|
31
|
+
return path.join(env.LOCALAPPDATA || path.join(home, "AppData", "Local"), "diskdiet-npm");
|
|
32
|
+
}
|
|
33
|
+
if (platform === "darwin") {
|
|
34
|
+
return path.join(home, "Library", "Caches", "diskdiet-npm");
|
|
35
|
+
}
|
|
36
|
+
return path.join(env.XDG_CACHE_HOME || path.join(home, ".cache"), "diskdiet-npm");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function sha256(file) {
|
|
40
|
+
return crypto.createHash("sha256").update(fs.readFileSync(file)).digest("hex");
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Extracts one file from a release archive. On Windows, the system's bsdtar
|
|
45
|
+
* (Windows 10+) reads the .zip; the tar on PATH may be Git Bash's GNU tar,
|
|
46
|
+
* which can't, so it isn't used. PowerShell is the fallback.
|
|
47
|
+
*/
|
|
48
|
+
function extract(archive, dir, file, platform = process.platform, env = process.env, run = execFileSync) {
|
|
49
|
+
if (platform !== "win32") {
|
|
50
|
+
run("tar", ["-xf", archive, "-C", dir, file], { stdio: "ignore" });
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const tar = path.join(env.SystemRoot || "C:\\Windows", "System32", "tar.exe");
|
|
54
|
+
if (fs.existsSync(tar)) {
|
|
55
|
+
run(tar, ["-xf", archive, "-C", dir, file], { stdio: "ignore" });
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const q = (s) => "'" + s.replace(/'/g, "''") + "'";
|
|
59
|
+
run("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command", `Expand-Archive -LiteralPath ${q(archive)} -DestinationPath ${q(dir)} -Force`], {
|
|
60
|
+
stdio: "ignore",
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Returns the path of the diskdiet binary, downloading it if needed.
|
|
66
|
+
* fetchFn and log are injectable for tests.
|
|
67
|
+
*/
|
|
68
|
+
async function ensureBinary({
|
|
69
|
+
version,
|
|
70
|
+
checksums,
|
|
71
|
+
platform = process.platform,
|
|
72
|
+
arch = process.arch,
|
|
73
|
+
dir = cacheDir(),
|
|
74
|
+
fetchFn = fetch,
|
|
75
|
+
baseUrl = `https://github.com/${REPO}/releases/download/v${version}`,
|
|
76
|
+
log = (m) => process.stderr.write(m + "\n"),
|
|
77
|
+
}) {
|
|
78
|
+
const exe = platform === "win32" ? "diskdiet.exe" : "diskdiet";
|
|
79
|
+
const target = path.join(dir, version, exe);
|
|
80
|
+
if (fs.existsSync(target)) {
|
|
81
|
+
return target;
|
|
82
|
+
}
|
|
83
|
+
const name = archiveName(version, platform, arch);
|
|
84
|
+
const want = checksums[name];
|
|
85
|
+
if (!want) {
|
|
86
|
+
throw new Error(`no checksum for ${name}; reinstall diskdiet`);
|
|
87
|
+
}
|
|
88
|
+
log(`diskdiet: downloading diskdiet ${version} (${name})...`);
|
|
89
|
+
const res = await fetchFn(`${baseUrl}/${name}`);
|
|
90
|
+
if (!res.ok) {
|
|
91
|
+
throw new Error(`download failed: HTTP ${res.status} for ${baseUrl}/${name}`);
|
|
92
|
+
}
|
|
93
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
94
|
+
const work = fs.mkdtempSync(path.join(dir, ".tmp-"));
|
|
95
|
+
try {
|
|
96
|
+
const archive = path.join(work, name);
|
|
97
|
+
fs.writeFileSync(archive, Buffer.from(await res.arrayBuffer()));
|
|
98
|
+
const got = sha256(archive);
|
|
99
|
+
if (got !== want) {
|
|
100
|
+
throw new Error(`checksum mismatch for ${name} (expected ${want}, got ${got}); not using it`);
|
|
101
|
+
}
|
|
102
|
+
extract(archive, work, exe, platform);
|
|
103
|
+
fs.chmodSync(path.join(work, exe), 0o755);
|
|
104
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
105
|
+
// Atomic, so a concurrent run never sees a half-written binary.
|
|
106
|
+
fs.renameSync(path.join(work, exe), target);
|
|
107
|
+
} finally {
|
|
108
|
+
fs.rmSync(work, { recursive: true, force: true });
|
|
109
|
+
}
|
|
110
|
+
return target;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
module.exports = { archiveName, cacheDir, ensureBinary, extract, sha256 };
|
package/package.json
CHANGED
|
@@ -1,6 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "diskdiet",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.6.2",
|
|
4
|
+
"description": "See where your developer disk space went and get it back safely: npm, Yarn, pnpm, Bun, pip, uv, Cargo, Go, Gradle, Maven, Playwright, Cypress, Xcode and Docker caches, plus forgotten node_modules and target folders.",
|
|
5
|
+
"mcpName": "io.github.roystondwork-dev/diskdiet",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"disk-space",
|
|
8
|
+
"cache",
|
|
9
|
+
"clean",
|
|
10
|
+
"npm-cache",
|
|
11
|
+
"node-modules",
|
|
12
|
+
"npkill",
|
|
13
|
+
"pnpm",
|
|
14
|
+
"yarn",
|
|
15
|
+
"docker",
|
|
16
|
+
"cargo",
|
|
17
|
+
"gradle",
|
|
18
|
+
"free-space",
|
|
19
|
+
"cleanup",
|
|
20
|
+
"cli",
|
|
21
|
+
"mcp"
|
|
22
|
+
],
|
|
23
|
+
"homepage": "https://github.com/roystondwork-dev/diskdiet",
|
|
24
|
+
"bugs": "https://github.com/roystondwork-dev/diskdiet/issues",
|
|
25
|
+
"repository": {
|
|
26
|
+
"type": "git",
|
|
27
|
+
"url": "git+https://github.com/roystondwork-dev/diskdiet.git",
|
|
28
|
+
"directory": "packaging/npm"
|
|
29
|
+
},
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"author": "Royston D",
|
|
32
|
+
"bin": {
|
|
33
|
+
"diskdiet": "bin/diskdiet.js"
|
|
34
|
+
},
|
|
35
|
+
"main": "lib/install.js",
|
|
36
|
+
"files": [
|
|
37
|
+
"bin",
|
|
38
|
+
"lib",
|
|
39
|
+
"checksums.json",
|
|
40
|
+
"README.md"
|
|
41
|
+
],
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18"
|
|
44
|
+
},
|
|
45
|
+
"scripts": {
|
|
46
|
+
"test": "node --test test/*.test.js"
|
|
47
|
+
}
|
|
48
|
+
}
|