@tukuyomil032/broom 1.0.0 → 1.0.5
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/dist/commands/analyze.js +432 -149
- package/dist/commands/clean.js +23 -2
- package/dist/commands/config.js +16 -46
- package/dist/commands/status.js +39 -211
- package/dist/commands/uninstall.js +51 -28
- package/dist/index.js +10 -9
- package/dist/types/index.js +0 -1
- package/dist/ui/prompts.js +21 -11
- package/dist/utils/icon.js +67 -0
- package/package.json +8 -4
package/dist/index.js
CHANGED
|
@@ -10,7 +10,7 @@ import chalk from 'chalk';
|
|
|
10
10
|
import { createCleanCommand, createUninstallCommand, createOptimizeCommand, createAnalyzeCommand, createStatusCommand, createPurgeCommand, createInstallerCommand, createTouchIdCommand, createCompletionCommand, createUpdateCommand, createRemoveCommand, createConfigCommand, createDoctorCommand, createBackupCommand, createRestoreCommand, createDuplicatesCommand, createScheduleCommand, createWatchCommand, createReportsCommand, createHelpCommand, setCommandsList, } from './commands/index.js';
|
|
11
11
|
import { enableDebug, debug } from './utils/debug.js';
|
|
12
12
|
import { getGlobalOptionsTable } from './utils/help.js';
|
|
13
|
-
const VERSION = '1.0.
|
|
13
|
+
const VERSION = '1.0.5';
|
|
14
14
|
// ASCII art logo
|
|
15
15
|
const logo = chalk.cyan(`
|
|
16
16
|
██████╗ ██████╗ ██████╗ ██████╗ ███╗ ███╗
|
|
@@ -49,14 +49,15 @@ ${chalk.bold('Commands:')}
|
|
|
49
49
|
reports Manage cleanup reports
|
|
50
50
|
|
|
51
51
|
${chalk.bold('Examples:')}
|
|
52
|
-
${chalk.dim('$')} broom clean
|
|
53
|
-
${chalk.dim('$')} broom clean --dry-run
|
|
54
|
-
${chalk.dim('$')} broom clean --all
|
|
55
|
-
${chalk.dim('$')} broom uninstall
|
|
56
|
-
${chalk.dim('$')} broom optimize
|
|
57
|
-
${chalk.dim('$')} broom analyze
|
|
58
|
-
${chalk.dim('$')} broom
|
|
59
|
-
${chalk.dim('$')} broom
|
|
52
|
+
${chalk.dim('$')} broom clean Interactive cleanup
|
|
53
|
+
${chalk.dim('$')} broom clean --dry-run Preview what would be cleaned
|
|
54
|
+
${chalk.dim('$')} broom clean --all Clean all categories
|
|
55
|
+
${chalk.dim('$')} broom uninstall Remove an app completely
|
|
56
|
+
${chalk.dim('$')} broom optimize Run system optimization tasks
|
|
57
|
+
${chalk.dim('$')} broom analyze See what's using disk space
|
|
58
|
+
${chalk.dim('$')} broom analyze --path ~/Library Analyze a Library
|
|
59
|
+
${chalk.dim('$')} broom status --watch Live system monitoring
|
|
60
|
+
${chalk.dim('$')} broom purge Clean project artifacts
|
|
60
61
|
|
|
61
62
|
${getGlobalOptionsTable()}
|
|
62
63
|
`;
|
package/dist/types/index.js
CHANGED
package/dist/ui/prompts.js
CHANGED
|
@@ -75,25 +75,35 @@ export async function selectFiles(items) {
|
|
|
75
75
|
return [];
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
|
+
// No app icon rendering here — removed per request. Formatting below aligns columns.
|
|
78
79
|
/**
|
|
79
|
-
* Select an application
|
|
80
|
+
* Select an application with custom navigation (no looping)
|
|
80
81
|
*/
|
|
81
82
|
export async function selectApp(apps) {
|
|
82
|
-
if (apps.length === 0)
|
|
83
|
-
return
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
83
|
+
if (apps.length === 0)
|
|
84
|
+
return [];
|
|
85
|
+
// Align columns: [Name padded] [Size right-aligned] [BundleId dimmed]
|
|
86
|
+
const maxName = Math.min(36, Math.max(...apps.map((a) => a.name.length), 10));
|
|
87
|
+
const sizeWidth = 10;
|
|
88
|
+
const choices = apps.map((app) => {
|
|
89
|
+
const namePad = app.name.padEnd(maxName);
|
|
90
|
+
const sizeStr = formatSize(app.size).padStart(sizeWidth);
|
|
91
|
+
const bundle = app.bundleId ? chalk.dim(` ${app.bundleId}`) : '';
|
|
92
|
+
return {
|
|
93
|
+
name: `${namePad} ${chalk.yellow(sizeStr)}${bundle}`,
|
|
94
|
+
value: app,
|
|
95
|
+
checked: false,
|
|
96
|
+
};
|
|
97
|
+
});
|
|
89
98
|
try {
|
|
90
|
-
return await
|
|
91
|
-
message: 'Select
|
|
99
|
+
return await checkbox({
|
|
100
|
+
message: 'Select applications to uninstall (space to toggle, Enter to confirm):',
|
|
92
101
|
choices,
|
|
102
|
+
loop: false,
|
|
93
103
|
});
|
|
94
104
|
}
|
|
95
105
|
catch {
|
|
96
|
-
return
|
|
106
|
+
return [];
|
|
97
107
|
}
|
|
98
108
|
}
|
|
99
109
|
/**
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { promises as fs } from 'fs';
|
|
2
|
+
import { tmpdir } from 'os';
|
|
3
|
+
import { join, basename, extname } from 'path';
|
|
4
|
+
import { execFile } from 'child_process';
|
|
5
|
+
import fg from 'fast-glob';
|
|
6
|
+
function execFileAsync(cmd, args) {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
execFile(cmd, args, (err, stdout, stderr) => {
|
|
9
|
+
if (err)
|
|
10
|
+
return reject(err);
|
|
11
|
+
resolve({ stdout, stderr });
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
export async function findIcnsFiles(appPath) {
|
|
16
|
+
const patterns = [
|
|
17
|
+
`${appPath}/Contents/Resources/*.icns`,
|
|
18
|
+
`${appPath}/Contents/Resources/*.*icon*`,
|
|
19
|
+
];
|
|
20
|
+
const results = await fg(patterns, { onlyFiles: true, unique: true });
|
|
21
|
+
return results;
|
|
22
|
+
}
|
|
23
|
+
export async function convertIcnsToPng(icnsPath, size, outPath) {
|
|
24
|
+
// Use sips to convert and resize
|
|
25
|
+
// sips -s format png <in> --out <out>
|
|
26
|
+
// then resize with sips -z <height> <width> <out>
|
|
27
|
+
await execFileAsync('sips', ['-s', 'format', 'png', icnsPath, '--out', outPath]);
|
|
28
|
+
await execFileAsync('sips', ['-z', String(size), String(size), outPath]);
|
|
29
|
+
}
|
|
30
|
+
export function supportsKitty() {
|
|
31
|
+
return Boolean(process.env.KITTY_WINDOW_ID);
|
|
32
|
+
}
|
|
33
|
+
export function supportsIterm() {
|
|
34
|
+
return Boolean(process.env.ITERM_SESSION_ID);
|
|
35
|
+
}
|
|
36
|
+
export function supportsWezTerm() {
|
|
37
|
+
return Boolean(process.env.WEZTERM_WINDOW || process.env.WEZTERM_EXECUTABLE || process.env.TERM_PROGRAM === 'WezTerm');
|
|
38
|
+
}
|
|
39
|
+
export async function getAppIconInline(appPath, size = 24) {
|
|
40
|
+
try {
|
|
41
|
+
const icns = await findIcnsFiles(appPath);
|
|
42
|
+
if (icns.length === 0)
|
|
43
|
+
return '';
|
|
44
|
+
const icnsPath = icns[0];
|
|
45
|
+
const tmpName = `broom-icon-${basename(icnsPath, extname(icnsPath))}-${size}.png`;
|
|
46
|
+
const outPath = join(tmpdir(), tmpName);
|
|
47
|
+
await convertIcnsToPng(icnsPath, size, outPath);
|
|
48
|
+
const buf = await fs.readFile(outPath);
|
|
49
|
+
const b64 = buf.toString('base64');
|
|
50
|
+
// iTerm2 / WezTerm protocol (OSC 1337)
|
|
51
|
+
if (supportsIterm() || supportsWezTerm()) {
|
|
52
|
+
// ESC ] 1337;File=...:<base64> BEL
|
|
53
|
+
return `\u001b]1337;File=inline=1;width=${size}px;height=${size}px;preserveAspectRatio=1;:${b64}\u0007 `;
|
|
54
|
+
}
|
|
55
|
+
// Kitty protocol
|
|
56
|
+
if (supportsKitty()) {
|
|
57
|
+
// ESC _ G ... base64 ESC \\
|
|
58
|
+
// Use minimal header; many kitty-compatible terminals accept this
|
|
59
|
+
return `\u001b_Gf=100,a=T;inline=1;width=${size}px;height=${size}px;${b64}\u001b\\ `;
|
|
60
|
+
}
|
|
61
|
+
// No supported inline image protocol
|
|
62
|
+
return '';
|
|
63
|
+
}
|
|
64
|
+
catch (e) {
|
|
65
|
+
return '';
|
|
66
|
+
}
|
|
67
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tukuyomil032/broom",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.5",
|
|
5
5
|
"description": "🧹 macOS Disk Cleanup CLI - Clean up caches, logs, trash, browser data, dev artifacts, and more",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -44,6 +44,12 @@
|
|
|
44
44
|
"url": "https://github.com/tukuyomil032/broom/issues"
|
|
45
45
|
},
|
|
46
46
|
"homepage": "https://github.com/tukuyomil032/broom#readme",
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18.0.0"
|
|
49
|
+
},
|
|
50
|
+
"os": [
|
|
51
|
+
"darwin"
|
|
52
|
+
],
|
|
47
53
|
"dependencies": {
|
|
48
54
|
"@inquirer/prompts": "^8.2.0",
|
|
49
55
|
"@types/handlebars": "^4.1.0",
|
|
@@ -61,7 +67,6 @@
|
|
|
61
67
|
"yargs": "^18.0.0"
|
|
62
68
|
},
|
|
63
69
|
"devDependencies": {
|
|
64
|
-
"@eslint/json": "^0.14.0",
|
|
65
70
|
"@types/blessed": "^0.1.27",
|
|
66
71
|
"@types/node": "^25.0.10",
|
|
67
72
|
"@typescript-eslint/eslint-plugin": "^8.53.1",
|
|
@@ -82,6 +87,5 @@
|
|
|
82
87
|
"eslint --fix",
|
|
83
88
|
"prettier --write"
|
|
84
89
|
]
|
|
85
|
-
}
|
|
86
|
-
"packageManager": "bun@1.3.6"
|
|
90
|
+
}
|
|
87
91
|
}
|