@lexmanh/shed-cli 0.2.0-beta.6 → 0.2.0-beta.8
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/cli.js +126 -59
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -8,18 +8,10 @@ import { Command } from "commander";
|
|
|
8
8
|
import { resolve } from "path";
|
|
9
9
|
import * as p from "@clack/prompts";
|
|
10
10
|
import {
|
|
11
|
-
AndroidDetector,
|
|
12
|
-
CocoaPodsDetector,
|
|
13
|
-
DockerDetector,
|
|
14
|
-
FlutterDetector,
|
|
15
|
-
IdeDetector,
|
|
16
|
-
NodeDetector,
|
|
17
|
-
PythonDetector,
|
|
18
11
|
RiskTier,
|
|
19
|
-
RustDetector,
|
|
20
12
|
SafetyChecker,
|
|
21
13
|
Scanner,
|
|
22
|
-
|
|
14
|
+
defaultDetectors
|
|
23
15
|
} from "@lexmanh/shed-core";
|
|
24
16
|
import pc from "picocolors";
|
|
25
17
|
|
|
@@ -61,17 +53,7 @@ async function cleanCommand(path = ".", options = {}) {
|
|
|
61
53
|
const spinner3 = p.spinner();
|
|
62
54
|
verbose(`clean root: ${rootDir}, dryRun=${isDryRun}, hardDelete=${options.hardDelete ?? false}`);
|
|
63
55
|
spinner3.start(`Scanning ${rootDir} \u2026`);
|
|
64
|
-
const scanner = new Scanner(
|
|
65
|
-
new NodeDetector(),
|
|
66
|
-
new PythonDetector(),
|
|
67
|
-
new RustDetector(),
|
|
68
|
-
new DockerDetector(),
|
|
69
|
-
new XcodeDetector(),
|
|
70
|
-
new FlutterDetector(),
|
|
71
|
-
new AndroidDetector(),
|
|
72
|
-
new CocoaPodsDetector(),
|
|
73
|
-
new IdeDetector()
|
|
74
|
-
]);
|
|
56
|
+
const scanner = new Scanner(defaultDetectors());
|
|
75
57
|
const ctx = { scanRoot: rootDir, maxDepth: 8 };
|
|
76
58
|
const [projects, globalItems] = await Promise.all([
|
|
77
59
|
scanner.scan(rootDir),
|
|
@@ -139,10 +121,11 @@ async function cleanCommand(path = ".", options = {}) {
|
|
|
139
121
|
label: `${pc.yellow("Yellow only")} ${pc.dim(`${yellowItems.length} items \xB7 ${formatBytes(yellowBytes)}`)}`
|
|
140
122
|
}
|
|
141
123
|
] : [],
|
|
142
|
-
{ value: "custom", label: "Custom (pick individual items)" }
|
|
124
|
+
{ value: "custom", label: "Custom (pick individual items)" },
|
|
125
|
+
{ value: "cancel", label: pc.dim("Cancel (do nothing, exit)") }
|
|
143
126
|
]
|
|
144
127
|
});
|
|
145
|
-
if (p.isCancel(preset)) {
|
|
128
|
+
if (p.isCancel(preset) || preset === "cancel") {
|
|
146
129
|
p.cancel("Cleanup cancelled.");
|
|
147
130
|
return;
|
|
148
131
|
}
|
|
@@ -230,6 +213,122 @@ async function cleanCommand(path = ".", options = {}) {
|
|
|
230
213
|
p.outro(outro6);
|
|
231
214
|
}
|
|
232
215
|
|
|
216
|
+
// src/commands/completions.ts
|
|
217
|
+
var BASH = `# shed bash completion
|
|
218
|
+
_shed_completions() {
|
|
219
|
+
local cur prev cmds
|
|
220
|
+
COMPREPLY=()
|
|
221
|
+
cur="\${COMP_WORDS[COMP_CWORD]}"
|
|
222
|
+
prev="\${COMP_WORDS[COMP_CWORD-1]}"
|
|
223
|
+
cmds="scan clean undo doctor config completions"
|
|
224
|
+
|
|
225
|
+
case "\${prev}" in
|
|
226
|
+
scan)
|
|
227
|
+
COMPREPLY=( $(compgen -W "--json --max-age --all" -- "\${cur}") )
|
|
228
|
+
return 0
|
|
229
|
+
;;
|
|
230
|
+
clean)
|
|
231
|
+
COMPREPLY=( $(compgen -W "--dry-run --execute --hard-delete --include-red --yes" -- "\${cur}") )
|
|
232
|
+
return 0
|
|
233
|
+
;;
|
|
234
|
+
config)
|
|
235
|
+
COMPREPLY=( $(compgen -W "get set list reset" -- "\${cur}") )
|
|
236
|
+
return 0
|
|
237
|
+
;;
|
|
238
|
+
completions)
|
|
239
|
+
COMPREPLY=( $(compgen -W "bash zsh fish" -- "\${cur}") )
|
|
240
|
+
return 0
|
|
241
|
+
;;
|
|
242
|
+
esac
|
|
243
|
+
|
|
244
|
+
if [ "\${COMP_CWORD}" -eq 1 ]; then
|
|
245
|
+
COMPREPLY=( $(compgen -W "\${cmds} --version --help --verbose" -- "\${cur}") )
|
|
246
|
+
return 0
|
|
247
|
+
fi
|
|
248
|
+
}
|
|
249
|
+
complete -F _shed_completions shed
|
|
250
|
+
`;
|
|
251
|
+
var ZSH = `#compdef shed
|
|
252
|
+
# shed zsh completion
|
|
253
|
+
|
|
254
|
+
_shed() {
|
|
255
|
+
local -a commands
|
|
256
|
+
commands=(
|
|
257
|
+
'scan:Scan for cleanable items without modifying anything'
|
|
258
|
+
'clean:Interactive cleanup of detected items'
|
|
259
|
+
'undo:List and restore items from previous cleanups'
|
|
260
|
+
'doctor:Check environment and configuration'
|
|
261
|
+
'config:Manage user preferences'
|
|
262
|
+
'completions:Print shell completion script (bash | zsh | fish)'
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
if (( CURRENT == 2 )); then
|
|
266
|
+
_describe -t commands 'shed command' commands
|
|
267
|
+
return
|
|
268
|
+
fi
|
|
269
|
+
|
|
270
|
+
case "\${words[2]}" in
|
|
271
|
+
scan)
|
|
272
|
+
_arguments \\
|
|
273
|
+
'--json[Output machine-readable JSON]' \\
|
|
274
|
+
'--max-age[Only include items older than N days]:days' \\
|
|
275
|
+
'--all[Show every item (default: compact summary)]'
|
|
276
|
+
;;
|
|
277
|
+
clean)
|
|
278
|
+
_arguments \\
|
|
279
|
+
'--dry-run[Preview operations without executing]' \\
|
|
280
|
+
'--execute[Actually perform the cleanup]' \\
|
|
281
|
+
'--hard-delete[Skip Trash, delete permanently]' \\
|
|
282
|
+
'--include-red[Include Red-tier (high-risk) items]' \\
|
|
283
|
+
'--yes[Skip interactive confirmations (CI mode)]'
|
|
284
|
+
;;
|
|
285
|
+
config)
|
|
286
|
+
_values 'config action' get set list reset
|
|
287
|
+
;;
|
|
288
|
+
completions)
|
|
289
|
+
_values 'shell' bash zsh fish
|
|
290
|
+
;;
|
|
291
|
+
esac
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
_shed "$@"
|
|
295
|
+
`;
|
|
296
|
+
var FISH = `# shed fish completion
|
|
297
|
+
complete -c shed -f
|
|
298
|
+
|
|
299
|
+
# subcommands
|
|
300
|
+
complete -c shed -n '__fish_use_subcommand' -a 'scan' -d 'Scan for cleanable items'
|
|
301
|
+
complete -c shed -n '__fish_use_subcommand' -a 'clean' -d 'Interactive cleanup'
|
|
302
|
+
complete -c shed -n '__fish_use_subcommand' -a 'undo' -d 'Restore from previous cleanups'
|
|
303
|
+
complete -c shed -n '__fish_use_subcommand' -a 'doctor' -d 'Check environment'
|
|
304
|
+
complete -c shed -n '__fish_use_subcommand' -a 'config' -d 'Manage preferences'
|
|
305
|
+
complete -c shed -n '__fish_use_subcommand' -a 'completions' -d 'Print shell completion script'
|
|
306
|
+
|
|
307
|
+
# scan flags
|
|
308
|
+
complete -c shed -n '__fish_seen_subcommand_from scan' -l json -d 'Output JSON'
|
|
309
|
+
complete -c shed -n '__fish_seen_subcommand_from scan' -l max-age -d 'Min age in days'
|
|
310
|
+
complete -c shed -n '__fish_seen_subcommand_from scan' -l all -d 'Show every item'
|
|
311
|
+
|
|
312
|
+
# clean flags
|
|
313
|
+
complete -c shed -n '__fish_seen_subcommand_from clean' -l dry-run -d 'Preview only'
|
|
314
|
+
complete -c shed -n '__fish_seen_subcommand_from clean' -l execute -d 'Actually delete'
|
|
315
|
+
complete -c shed -n '__fish_seen_subcommand_from clean' -l hard-delete -d 'Skip Trash'
|
|
316
|
+
complete -c shed -n '__fish_seen_subcommand_from clean' -l include-red -d 'Include Red tier'
|
|
317
|
+
complete -c shed -n '__fish_seen_subcommand_from clean' -l yes -d 'Skip confirmations'
|
|
318
|
+
|
|
319
|
+
# config + completions argument values
|
|
320
|
+
complete -c shed -n '__fish_seen_subcommand_from config' -a 'get set list reset'
|
|
321
|
+
complete -c shed -n '__fish_seen_subcommand_from completions' -a 'bash zsh fish'
|
|
322
|
+
`;
|
|
323
|
+
var SCRIPTS = { bash: BASH, zsh: ZSH, fish: FISH };
|
|
324
|
+
function completionsCommand(shell) {
|
|
325
|
+
if (shell !== "bash" && shell !== "zsh" && shell !== "fish") {
|
|
326
|
+
console.error("shed completions: shell must be one of: bash, zsh, fish");
|
|
327
|
+
process.exit(1);
|
|
328
|
+
}
|
|
329
|
+
process.stdout.write(SCRIPTS[shell]);
|
|
330
|
+
}
|
|
331
|
+
|
|
233
332
|
// src/commands/config.ts
|
|
234
333
|
import * as p2 from "@clack/prompts";
|
|
235
334
|
import Conf from "conf";
|
|
@@ -400,25 +499,9 @@ import { hostname } from "os";
|
|
|
400
499
|
import { resolve as resolve2 } from "path";
|
|
401
500
|
import * as p4 from "@clack/prompts";
|
|
402
501
|
import {
|
|
403
|
-
AndroidDetector as AndroidDetector2,
|
|
404
|
-
CocoaPodsDetector as CocoaPodsDetector2,
|
|
405
|
-
DatabaseDetector,
|
|
406
|
-
DockerDetector as DockerDetector2,
|
|
407
|
-
DotnetDetector,
|
|
408
|
-
FlutterDetector as FlutterDetector2,
|
|
409
|
-
GoDetector,
|
|
410
|
-
IdeDetector as IdeDetector2,
|
|
411
|
-
JavaGradleDetector,
|
|
412
|
-
JavaMavenDetector,
|
|
413
|
-
NodeDetector as NodeDetector2,
|
|
414
|
-
PythonDetector as PythonDetector2,
|
|
415
502
|
RiskTier as RiskTier2,
|
|
416
|
-
RubyDetector,
|
|
417
|
-
RustDetector as RustDetector2,
|
|
418
503
|
Scanner as Scanner2,
|
|
419
|
-
|
|
420
|
-
WebserverDetector,
|
|
421
|
-
XcodeDetector as XcodeDetector2
|
|
504
|
+
defaultDetectors as defaultDetectors2
|
|
422
505
|
} from "@lexmanh/shed-core";
|
|
423
506
|
import pc4 from "picocolors";
|
|
424
507
|
|
|
@@ -523,25 +606,7 @@ async function scanCommand(path = ".", options = {}) {
|
|
|
523
606
|
verbose(`scan root: ${rootDir}`);
|
|
524
607
|
spinner3?.start(`Scanning ${rootDir} \u2026`);
|
|
525
608
|
const scanStartedAt = Date.now();
|
|
526
|
-
const scanner = new Scanner2(
|
|
527
|
-
new NodeDetector2(),
|
|
528
|
-
new PythonDetector2(),
|
|
529
|
-
new RustDetector2(),
|
|
530
|
-
new GoDetector(),
|
|
531
|
-
new JavaMavenDetector(),
|
|
532
|
-
new JavaGradleDetector(),
|
|
533
|
-
new RubyDetector(),
|
|
534
|
-
new DotnetDetector(),
|
|
535
|
-
new DockerDetector2(),
|
|
536
|
-
new XcodeDetector2(),
|
|
537
|
-
new FlutterDetector2(),
|
|
538
|
-
new AndroidDetector2(),
|
|
539
|
-
new CocoaPodsDetector2(),
|
|
540
|
-
new IdeDetector2(),
|
|
541
|
-
new SystemDetector(),
|
|
542
|
-
new WebserverDetector(),
|
|
543
|
-
new DatabaseDetector()
|
|
544
|
-
]);
|
|
609
|
+
const scanner = new Scanner2(defaultDetectors2());
|
|
545
610
|
const ctx = { scanRoot: rootDir, maxDepth: 8 };
|
|
546
611
|
const [projects, globalItems] = await Promise.all([
|
|
547
612
|
scanner.scan(rootDir),
|
|
@@ -746,11 +811,13 @@ program.command("clean [path]").description("Interactive cleanup of detected ite
|
|
|
746
811
|
program.command("undo").description("List and restore items from previous cleanups").action(undoCommand);
|
|
747
812
|
program.command("doctor").description("Check environment and configuration").action(doctorCommand);
|
|
748
813
|
program.command("config").description("Manage user preferences").argument("[action]", "get | set | list | reset").argument("[key]", "Configuration key").argument("[value]", "Configuration value (for set)").action(configCommand);
|
|
814
|
+
program.command("completions").description("Print shell completion script").argument("<shell>", "bash | zsh | fish").action(completionsCommand);
|
|
749
815
|
program.hook("preAction", (_thisCommand, actionCommand) => {
|
|
750
816
|
const opts = program.opts();
|
|
751
817
|
setVerbose(opts.verbose ?? false);
|
|
752
818
|
const cmdOpts = actionCommand.opts();
|
|
753
|
-
|
|
819
|
+
const isCompletions = actionCommand.name() === "completions";
|
|
820
|
+
if (!cmdOpts.json && !isCompletions) printLogo(version);
|
|
754
821
|
});
|
|
755
822
|
program.parseAsync(process.argv).catch((err) => {
|
|
756
823
|
console.error("shed: fatal error:", err instanceof Error ? err.message : err);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lexmanh/shed-cli",
|
|
3
|
-
"version": "0.2.0-beta.
|
|
3
|
+
"version": "0.2.0-beta.8",
|
|
4
4
|
"description": "Safe disk cleanup CLI for dev machines and Linux servers — git-aware, cross-stack, trash-by-default",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"conf": "^13.1.0",
|
|
24
24
|
"execa": "^9.5.0",
|
|
25
25
|
"picocolors": "^1.1.1",
|
|
26
|
-
"@lexmanh/shed-core": "0.2.0-beta.
|
|
26
|
+
"@lexmanh/shed-core": "0.2.0-beta.8"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@types/node": "^22.10.0",
|