@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/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.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 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 status --watch Live system monitoring
59
- ${chalk.dim('$')} broom purge Clean project artifacts
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
  `;
@@ -8,7 +8,6 @@ export const DEFAULT_CONFIG = {
8
8
  blacklist: [],
9
9
  autoConfirm: false,
10
10
  safetyLevel: 'moderate',
11
- monitorPreset: 1,
12
11
  scanLocations: {
13
12
  userCache: true,
14
13
  systemCache: true,
@@ -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 null;
84
- }
85
- const choices = apps.map((app) => ({
86
- name: `${app.name} (${formatSize(app.size)})${app.bundleId ? chalk.dim(` - ${app.bundleId}`) : ''}`,
87
- value: app,
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 select({
91
- message: 'Select an application:',
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 null;
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.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
  }