artshelf 0.8.0 → 0.9.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/CHANGELOG.md CHANGED
@@ -58,6 +58,29 @@
58
58
  pages backed by shared docs-site chrome, search, and navigation.
59
59
  - Added `artshelf update` plus cached npm update notices, with
60
60
  `ARTSHELF_NO_UPDATE_CHECK=1` for no-network scheduled jobs.
61
+ - Rewrote `artshelf help` into a compact, grouped command list (Create, Inspect,
62
+ Review, Clean, System) with one-line summaries and focused per-command help,
63
+ added nested help for `trash`/`ledgers` subcommands plus `artshelf trash help`
64
+ and `artshelf ledgers help` aliases, advertised short `-h`/`-v` flags, and
65
+ reclassified `--ledger`, `--registry`, and `--all` as command-specific scope
66
+ flags instead of global options.
67
+
68
+ ## [0.9.0](https://github.com/calvinnwq/artshelf/compare/artshelf-v0.8.0...artshelf-v0.9.0) (2026-06-11)
69
+
70
+
71
+ ### Features
72
+
73
+ * **cli:** rewrite help with grouped commands, focused per-command help, and short flags ([7310638](https://github.com/calvinnwq/artshelf/commit/73106385ce3e3d037921cdb4ff534614d024244f))
74
+ * **cli:** rewrite top-level help with grouped commands, focused per-command help, and subcommand routing ([c8dea22](https://github.com/calvinnwq/artshelf/commit/c8dea2255628915eb629c5cc4cbc2ef1ec31c3a7))
75
+
76
+
77
+ ### Bug Fixes
78
+
79
+ * **cli:** advertise short help flag ([825c4ae](https://github.com/calvinnwq/artshelf/commit/825c4ae38aa61209f22c702a82f51b93c5ea3d09))
80
+ * **cli:** advertise short version flag ([23ca99b](https://github.com/calvinnwq/artshelf/commit/23ca99b0ba7c596a8df89ec3c0384286c55d2a96))
81
+ * **cli:** polish nested help output ([109255d](https://github.com/calvinnwq/artshelf/commit/109255dfa3baa50c6aae837190adb19cfa7249b8))
82
+ * **cli:** support ledgers help subcommand ([18723ce](https://github.com/calvinnwq/artshelf/commit/18723ce384fbdeed33fe066ad0093093d30dc5a5))
83
+ * **cli:** support short help flag ([081b50f](https://github.com/calvinnwq/artshelf/commit/081b50f67a5e0821341aca4f98ab3244ab316338))
61
84
 
62
85
  ## [0.8.0](https://github.com/calvinnwq/artshelf/compare/artshelf-v0.7.0...artshelf-v0.8.0) (2026-06-11)
63
86
 
package/README.md CHANGED
@@ -120,8 +120,8 @@ destructive deletion.
120
120
 
121
121
  ```bash
122
122
  artshelf put <path> --reason "debug parser output" --ttl 3d --kind scratch
123
- artshelf ledgers list [--plain]
124
- artshelf ledgers add --ledger <path>
123
+ artshelf ledgers list [--plain] [--json]
124
+ artshelf ledgers add --ledger <path> [--name <project>] [--scope repo|user|other] [--json]
125
125
  artshelf list [--all] [--status active]
126
126
  artshelf find --path <path> --owner <agent-or-runtime> --label <task-or-run-id>
127
127
  artshelf find --all --owner <agent-or-runtime>
@@ -133,15 +133,18 @@ artshelf status [--all]
133
133
  artshelf doctor
134
134
  artshelf update [--json]
135
135
  artshelf cleanup --dry-run [--all]
136
- artshelf cleanup --execute --plan-id <id>
136
+ artshelf cleanup --execute --plan-id <id> [--ledger <path>] [--json]
137
137
  artshelf trash list [--all] [--ledger <path>] [--json]
138
138
  artshelf trash purge --older-than <ttl> --dry-run [--ledger <path>] [--json]
139
139
  artshelf trash purge --execute --plan-id <id> [--ledger <path>] [--json]
140
- artshelf resolve <id> --status resolved --reason "inspected and no longer needed"
140
+ artshelf resolve <id> --status resolved --reason "inspected and no longer needed" [--ledger <path>] [--json]
141
141
  ```
142
142
 
143
- Use `artshelf help` or `artshelf help <command>` for details. All core commands
144
- support `--json`.
143
+ Use `artshelf help` for a grouped command list, then `artshelf <command> --help`
144
+ or `artshelf help <command>` for focused details. Nested commands such as
145
+ `artshelf trash purge --help` and `artshelf ledgers add --help` show only that
146
+ subcommand. All core commands support `--json`; `--ledger`, `--registry`, and
147
+ `--all` are scope flags only on commands that list them.
145
148
  </details>
146
149
 
147
150
  <details>
@@ -159,7 +162,7 @@ artshelf list --ledger /tmp/artshelf-ledger.jsonl
159
162
  Artshelf keeps a small global registry of known ledgers at
160
163
  `~/.artshelf/ledgers.json` (override with `--registry <path>` or
161
164
  `ARTSHELF_REGISTRY`). `put` registers its ledger automatically; register an
162
- existing one with `artshelf ledgers add --ledger <path> --name <project>`.
165
+ existing one with `artshelf ledgers add --ledger <path> --name <project> --json`.
163
166
  `artshelf ledgers list` validates each registered ledger by default (ok/missing/invalid
164
167
  status with counts, non-zero exit when broken), so it doubles as a stale-entry
165
168
  check; add `--plain` to skip validation.
package/SPEC.md CHANGED
@@ -36,6 +36,35 @@ somewhere accountable, with an expiry tag and a cleanup plan.
36
36
 
37
37
  ## V1 CLI
38
38
 
39
+ ### Help and option presentation
40
+
41
+ Top-level help is compact and points readers to focused command help.
42
+
43
+ ```bash
44
+ artshelf help
45
+ artshelf --help
46
+ artshelf <command> --help
47
+ artshelf help <command>
48
+ artshelf <command> <subcommand> --help
49
+ artshelf help <command> <subcommand>
50
+ ```
51
+
52
+ Rules:
53
+
54
+ - `artshelf help`, `artshelf --help`, and `artshelf -h` show a grouped command
55
+ list with one-line summaries instead of dumping every command variant.
56
+ - Command groups are `Create`, `Inspect`, `Review`, `Clean`, and `System`.
57
+ - `artshelf <command> --help` and `artshelf help <command>` show focused help
58
+ for that command.
59
+ - Nested help is supported for `trash list`, `trash purge`, `ledgers list`, and
60
+ `ledgers add`.
61
+ - `artshelf trash help` and `artshelf ledgers help` are aliases for the focused
62
+ help of those commands, matching `artshelf help trash` and `artshelf help ledgers`.
63
+ - Top-level help presents `-h, --help` and `-v, --version` as global options,
64
+ `--json` as the output mode, and `--ledger`, `--registry`, and `--all` as
65
+ command-specific scope flags. The short `-h` and `-v` forms work both at the
66
+ top level and after a command.
67
+
39
68
  ### `artshelf put`
40
69
 
41
70
  Records an existing file or directory in the ledger.
@@ -79,8 +108,9 @@ Lists or registers known Artshelf ledgers.
79
108
 
80
109
  ```bash
81
110
  artshelf ledgers list
111
+ artshelf ledgers list --json
82
112
  artshelf ledgers list --plain
83
- artshelf ledgers add --ledger <path> --name <project> --scope repo
113
+ artshelf ledgers add --ledger <path> --name <project> --scope repo --json
84
114
  ```
85
115
 
86
116
  Rules:
@@ -361,8 +391,8 @@ plan id.
361
391
  Executes a previously generated cleanup plan.
362
392
 
363
393
  ```bash
364
- artshelf cleanup --execute --plan-id <id>
365
- artshelf cleanup --execute --plan-id <id> --json
394
+ artshelf cleanup --execute --plan-id <id> [--ledger <path>]
395
+ artshelf cleanup --execute --plan-id <id> [--ledger <path>] --json
366
396
  ```
367
397
 
368
398
  Rules:
package/dist/src/cli.js CHANGED
@@ -45,7 +45,7 @@ async function main(argv) {
45
45
  return maybeNotifyUpdateAndReturn(0, parsed);
46
46
  }
47
47
  if (parsed.command === "help" || parsed.command === "--help" || parsed.command === "-h" || boolFlag(parsed, "help")) {
48
- printHelp(parsed.command === "help" ? parsed.positionals[0] : parsed.command);
48
+ printHelp(resolveHelpKey(parsed));
49
49
  return maybeNotifyUpdateAndReturn(0, parsed);
50
50
  }
51
51
  switch (parsed.command) {
@@ -147,6 +147,10 @@ function handlePut(parsed, ledgerPath, json) {
147
147
  function handleLedgers(parsed, json) {
148
148
  const action = parsed.positionals[0] ?? "list";
149
149
  const registryPath = normalizeRegistryPath(stringFlag(parsed, "registry"));
150
+ if (action === "help") {
151
+ printHelp("ledgers");
152
+ return 0;
153
+ }
150
154
  if (action === "add") {
151
155
  const ledgerPath = normalizeLedgerPath(requiredStringFlag(parsed, "ledger"));
152
156
  if (!existsSync(ledgerPath))
@@ -950,6 +954,14 @@ function parseArgs(argv) {
950
954
  const arg = rest[index];
951
955
  if (!arg)
952
956
  continue;
957
+ if (arg === "-h") {
958
+ flags.set("help", true);
959
+ continue;
960
+ }
961
+ if (arg === "-v") {
962
+ flags.set("version", true);
963
+ continue;
964
+ }
953
965
  if (!arg.startsWith("--")) {
954
966
  positionals.push(arg);
955
967
  continue;
@@ -1174,7 +1186,93 @@ function printReview(results) {
1174
1186
  process.stdout.write(`ledger: ${result.ledger.path}\n`);
1175
1187
  }
1176
1188
  }
1177
- function printHelp(command) {
1189
+ const COMMAND_GROUPS = [
1190
+ {
1191
+ group: "Create",
1192
+ commands: [{ name: "put", summary: "Record an artifact with a reason and retention" }]
1193
+ },
1194
+ {
1195
+ group: "Inspect",
1196
+ commands: [
1197
+ { name: "list", summary: "List ledger records" },
1198
+ { name: "find", summary: "Find records by path, owner, label, or status" },
1199
+ { name: "get", summary: "Show one record by id" },
1200
+ { name: "due", summary: "Show due, manual-review, and missing-path records" },
1201
+ { name: "status", summary: "Summarize ledger and registry counts" }
1202
+ ]
1203
+ },
1204
+ {
1205
+ group: "Review",
1206
+ commands: [
1207
+ { name: "validate", summary: "Check ledger shape and report warnings" },
1208
+ { name: "review", summary: "Preview validate, due, and cleanup plans (read-only)" }
1209
+ ]
1210
+ },
1211
+ {
1212
+ group: "Clean",
1213
+ commands: [
1214
+ { name: "cleanup", summary: "Plan and execute approved cleanups" },
1215
+ { name: "trash", summary: "Inspect and purge Artshelf trash" },
1216
+ { name: "resolve", summary: "Mark a record manually resolved" }
1217
+ ]
1218
+ },
1219
+ {
1220
+ group: "System",
1221
+ commands: [
1222
+ { name: "ledgers", summary: "Manage the ledger registry" },
1223
+ { name: "doctor", summary: "Report Artshelf health on this machine" },
1224
+ { name: "update", summary: "Update the Artshelf CLI" }
1225
+ ]
1226
+ }
1227
+ ];
1228
+ // Commands with subcommands that carry their own focused help. Used to route
1229
+ // `artshelf <command> <subcommand> --help` to a nested help key.
1230
+ const NESTED_HELP = new Map([
1231
+ ["trash", new Set(["list", "purge"])],
1232
+ ["ledgers", new Set(["list", "add"])]
1233
+ ]);
1234
+ function resolveHelpKey(parsed) {
1235
+ // `artshelf help [command [subcommand]]`
1236
+ if (parsed.command === "help") {
1237
+ return joinHelpKey(parsed.positionals[0], parsed.positionals[1]);
1238
+ }
1239
+ // `artshelf [--help|-h]` with no command resolves to the top-level help.
1240
+ if (!parsed.command || parsed.command === "--help" || parsed.command === "-h") {
1241
+ return "";
1242
+ }
1243
+ // `artshelf <command> [subcommand] --help`
1244
+ return joinHelpKey(parsed.command, parsed.positionals[0]);
1245
+ }
1246
+ function joinHelpKey(command, subcommand) {
1247
+ if (!command)
1248
+ return "";
1249
+ const subcommands = NESTED_HELP.get(command);
1250
+ if (subcommands && subcommand && subcommands.has(subcommand)) {
1251
+ return `${command} ${subcommand}`;
1252
+ }
1253
+ return command;
1254
+ }
1255
+ function renderTopLevelHelp() {
1256
+ const names = COMMAND_GROUPS.flatMap((entry) => entry.commands.map((command) => command.name));
1257
+ const width = Math.max(...names.map((name) => name.length)) + 2;
1258
+ const lines = [
1259
+ `Artshelf ${VERSION} — approval-first retention for the temporary files agents leave behind.`,
1260
+ "",
1261
+ "Usage:",
1262
+ " artshelf <command> [options]",
1263
+ "",
1264
+ "Available Commands:"
1265
+ ];
1266
+ for (const { group, commands } of COMMAND_GROUPS) {
1267
+ lines.push(` ${group}`);
1268
+ for (const command of commands) {
1269
+ lines.push(` ${command.name.padEnd(width)}${command.summary}`);
1270
+ }
1271
+ }
1272
+ lines.push("", "Global Options:", " -h, --help Show help for artshelf or a specific command", " -v, --version Show the Artshelf version", "", "Output:", " --json Emit machine-readable JSON on commands that return data", "", "Scope (command-specific):", " --ledger <path> Target an explicit JSONL ledger", " --registry <path> Target an explicit ledger registry", " --all Read every registered ledger (on commands that support it)", "", `Use "artshelf <command> --help" for more information about a command.`, "");
1273
+ return lines.join("\n");
1274
+ }
1275
+ function printHelp(command = "") {
1178
1276
  if (command === "put") {
1179
1277
  process.stdout.write(`Usage:
1180
1278
  artshelf put <path> --reason <text> (--ttl <ttl>|--retain-until <date>|--manual-review) [options]
@@ -1208,30 +1306,36 @@ Global --all mode is dry-run only.
1208
1306
  return;
1209
1307
  }
1210
1308
  if (command === "trash") {
1211
- process.stdout.write(`Usage:
1212
- artshelf trash list [--ledger <path>] [--all] [--json]
1213
- artshelf trash purge --older-than <ttl> --dry-run [--ledger <path>] [--json]
1214
- artshelf trash purge --execute --plan-id <id> [--ledger <path>] [--json]
1309
+ process.stdout.write(`Inspect and purge Artshelf trash.
1310
+
1311
+ Usage:
1312
+ artshelf trash [command]
1313
+
1314
+ Available Commands:
1315
+ list List records currently held in Artshelf trash
1316
+ purge Plan or execute approved permanent trash deletion
1317
+
1318
+ Flags:
1319
+ -h, --help help for trash
1215
1320
 
1216
- Trash is approval-first. Use list to inspect what is currently in Artshelf trash and
1217
- dry-run purge to generate a reviewed plan id for age-based deletion. Purge
1218
- requires either --dry-run or --execute. Execute requires a reviewed plan id, and
1219
- trash purge is always scoped to one --ledger; --all is not supported for purge
1220
- (only for trash list).
1221
- Trash receipt artifacts are registered when purge executes. Completed receipts are
1222
- refused on repeat execute; started receipts from interrupted purges may be resumed
1223
- and reconciled. Purged records are resolved and no longer reappear as trashed.
1321
+ Use "artshelf trash <command> --help" for more information about a command.
1224
1322
  `);
1225
1323
  return;
1226
1324
  }
1227
1325
  if (command === "ledgers") {
1228
- process.stdout.write(`Usage:
1229
- artshelf ledgers list [--plain] [--registry <path>] [--json]
1230
- artshelf ledgers add --ledger <path> [--name <name>] [--scope repo|user|other] [--registry <path>] [--json]
1326
+ process.stdout.write(`Manage the ledger registry.
1231
1327
 
1232
- The ledger registry is a global index of known ledgers. It gives Artshelf one read-only entry point without moving project records into one global ledger.
1233
- By default \`list\` validates each registered ledger and reports ok/missing/invalid status, entry counts, and warning/error counts so agents can spot stale registry entries without a separate validate pass; it exits non-zero when the registry or any registered ledger is broken.
1234
- Use \`--plain\` for the fast path that lists registered ledgers without reading them.
1328
+ Usage:
1329
+ artshelf ledgers [command]
1330
+
1331
+ Available Commands:
1332
+ list List and validate registered ledgers
1333
+ add Register an existing ledger file
1334
+
1335
+ Flags:
1336
+ -h, --help help for ledgers
1337
+
1338
+ Use "artshelf ledgers <command> --help" for more information about a command.
1235
1339
  `);
1236
1340
  return;
1237
1341
  }
@@ -1341,50 +1445,99 @@ installs should update by pulling, rebuilding, and linking the checkout.
1341
1445
  `);
1342
1446
  return;
1343
1447
  }
1344
- process.stdout.write(`Artshelf ${VERSION}
1448
+ if (command === "due") {
1449
+ process.stdout.write(`Usage:
1450
+ artshelf due [--ledger <path>] [--json]
1451
+ artshelf due --all [--registry <path>] [--json]
1345
1452
 
1346
- Usage:
1347
- artshelf put <path> --reason <text> (--ttl <ttl>|--retain-until <date>|--manual-review)
1348
- artshelf ledgers list [--plain] [--json]
1349
- artshelf ledgers add --ledger <path> [--name <name>] [--json]
1350
- artshelf list [--json]
1351
- artshelf list --all [--json]
1352
- artshelf list --status active [--json]
1353
- artshelf find --path <path> [--json]
1354
- artshelf find --all --owner <name> [--json]
1355
- artshelf get <id> [--json]
1356
- artshelf get <id> --all [--json]
1357
- artshelf due [--json]
1358
- artshelf due --all [--json]
1359
- artshelf validate [--json]
1360
- artshelf validate --all [--json]
1361
- artshelf review [--json]
1362
- artshelf review --all [--json]
1363
- artshelf doctor [--json]
1364
- artshelf status [--json]
1365
- artshelf status --all [--json]
1366
- artshelf update [--json]
1367
- artshelf cleanup --dry-run [--json]
1368
- artshelf cleanup --dry-run --all [--json]
1369
- artshelf cleanup --execute --plan-id <id> [--json]
1370
- artshelf trash list [--all] [--ledger <path>] [--json]
1453
+ Due lists records whose retention has elapsed or that need attention: due,
1454
+ manual-review, and missing-path entries. Kept entries are hidden in human output.
1455
+ Due is read-only and never moves files or writes plans.
1456
+ `);
1457
+ return;
1458
+ }
1459
+ if (command === "validate") {
1460
+ process.stdout.write(`Usage:
1461
+ artshelf validate [--ledger <path>] [--json]
1462
+ artshelf validate --all [--registry <path>] [--json]
1463
+
1464
+ Validate checks ledger shape and reports errors and warnings, such as records
1465
+ that point at missing artifact paths, without changing anything. A clean ledger
1466
+ exits 0; shape errors exit non-zero. With --all it validates every registered
1467
+ ledger.
1468
+ `);
1469
+ return;
1470
+ }
1471
+ if (command === "trash list") {
1472
+ process.stdout.write(`Usage:
1473
+ artshelf trash list [--ledger <path>] [--all] [--registry <path>] [--json]
1474
+
1475
+ Options:
1476
+ --ledger <path> Use a specific ledger file
1477
+ --all Include records from all registered ledgers
1478
+ --registry <path> Registry path used with --all
1479
+ --json Emit machine-readable output
1480
+
1481
+ Trash list shows records currently held in Artshelf trash without deleting anything.
1482
+ With --all it reports trashed records across every registered ledger.
1483
+ `);
1484
+ return;
1485
+ }
1486
+ if (command === "trash purge") {
1487
+ process.stdout.write(`Usage:
1371
1488
  artshelf trash purge --older-than <ttl> --dry-run [--ledger <path>] [--json]
1372
1489
  artshelf trash purge --execute --plan-id <id> [--ledger <path>] [--json]
1373
- artshelf resolve <id> --status resolved --reason <text> [--json]
1374
1490
 
1375
- Global options:
1376
- --ledger <path> Use an explicit JSONL ledger
1377
- --registry <path> Use an explicit ledger registry
1378
- --all Read all registered ledgers for supported commands
1379
- --json Emit machine-readable JSON
1380
- --help Show help
1381
- --version Show version
1491
+ Options:
1492
+ --older-than <ttl> Purge trashed records older than this duration
1493
+ --dry-run Build a reviewed purge plan and output a plan id
1494
+ --execute Execute a reviewed purge plan
1495
+ --plan-id <id> Execute only this reviewed purge plan
1496
+ --ledger <path> Target one specific ledger
1497
+ --json Emit machine-readable output
1382
1498
 
1383
- Examples:
1384
- artshelf put tmp/run-output --reason "debug parser output" --ttl 3d --kind scratch
1385
- artshelf cleanup --dry-run --json
1386
- artshelf cleanup --execute --plan-id plan_20260601_120000_ab12
1499
+ Trash purge permanently deletes aged trash from a reviewed plan. --dry-run turns
1500
+ --older-than into a reviewed purge plan id; --execute deletes only that one reviewed
1501
+ plan id. Purge is always scoped to one --ledger; --all is not supported for purge.
1502
+ Completed receipts are refused on repeat execute; an interrupted purge may be resumed
1503
+ and reconciled.
1387
1504
  `);
1505
+ return;
1506
+ }
1507
+ if (command === "ledgers list") {
1508
+ process.stdout.write(`Usage:
1509
+ artshelf ledgers list [--plain] [--registry <path>] [--json]
1510
+
1511
+ Options:
1512
+ --plain Skip ledger validation and list registrations directly
1513
+ --registry <path> Registry path to use
1514
+ --json Emit machine-readable output
1515
+
1516
+ Ledgers list validates every registered ledger and reports ok/missing/invalid
1517
+ status, entry counts, and warnings so agents can spot stale registry entries
1518
+ without a separate validate pass. Use --plain for the fast path that lists
1519
+ registered ledgers without reading them. It exits non-zero when the registry or
1520
+ any registered ledger is broken.
1521
+ `);
1522
+ return;
1523
+ }
1524
+ if (command === "ledgers add") {
1525
+ process.stdout.write(`Usage:
1526
+ artshelf ledgers add --ledger <path> [--name <name>] [--scope repo|user|other] [--registry <path>] [--json]
1527
+
1528
+ Options:
1529
+ --ledger <path> Register this ledger file
1530
+ --name <name> Override the ledger display name
1531
+ --scope <scope> Registry scope: repo, user, or other
1532
+ --registry <path> Registry path to update
1533
+ --json Emit machine-readable output
1534
+
1535
+ Ledgers add registers an existing ledger file in the global registry so --all
1536
+ commands and the registry index can find it. The ledger file must already exist.
1537
+ `);
1538
+ return;
1539
+ }
1540
+ process.stdout.write(renderTopLevelHelp());
1388
1541
  }
1389
1542
  main(process.argv.slice(2))
1390
1543
  .then((status) => {
@@ -67,7 +67,7 @@
67
67
  plan id when attention exists.
68
68
  </p>
69
69
  <pre><code><span class="c"># register a project ledger so --all review can see it</span>
70
- artshelf ledgers add --ledger &lt;repo&gt;/.artshelf/ledger.jsonl --name &lt;project&gt; --scope repo
70
+ artshelf ledgers add --ledger &lt;repo&gt;/.artshelf/ledger.jsonl --name &lt;project&gt; --scope repo --json
71
71
 
72
72
  <span class="c"># list registered ledgers and their health</span>
73
73
  artshelf ledgers list --json
package/docs/index.html CHANGED
@@ -158,7 +158,7 @@ artshelf review --json</code></pre>
158
158
  ~/.artshelf/ledgers.json
159
159
 
160
160
  <span class="c"># put registers its ledger automatically; add existing ones explicitly</span>
161
- artshelf ledgers add --ledger &lt;repo&gt;/.artshelf/ledger.jsonl --name &lt;project&gt; --scope repo
161
+ artshelf ledgers add --ledger &lt;repo&gt;/.artshelf/ledger.jsonl --name &lt;project&gt; --scope repo --json
162
162
 
163
163
  <span class="c"># --all commands read across every registered ledger</span>
164
164
  artshelf review --all --json</code></pre>
@@ -42,6 +42,13 @@
42
42
  cleanup execution and trash purge. Every command below is tagged read-only,
43
43
  writes ledger, writes registry, npm install, or approval-gated.
44
44
  </p>
45
+ <p>
46
+ Run <code>artshelf help</code> for the grouped command list. Use
47
+ <code>artshelf &lt;command&gt; --help</code> or
48
+ <code>artshelf help &lt;command&gt;</code> for focused help; nested commands
49
+ such as <code>artshelf trash purge --help</code> and
50
+ <code>artshelf ledgers add --help</code> show only that subcommand.
51
+ </p>
45
52
 
46
53
  <section class="cmd">
47
54
  <div class="cmd-head"><h2>artshelf put</h2><span class="cmd-flag plan">writes ledger</span></div>
@@ -70,7 +77,7 @@ artshelf ledgers list [--plain] [--json]</code></pre>
70
77
  <section class="cmd">
71
78
  <div class="cmd-head"><h2>artshelf ledgers add</h2><span class="cmd-flag plan">writes registry</span></div>
72
79
  <pre><code><span class="c"># register an existing ledger for --all review</span>
73
- artshelf ledgers add --ledger &lt;path&gt; [--name &lt;project&gt;] [--scope repo|user|other]</code></pre>
80
+ artshelf ledgers add --ledger &lt;path&gt; [--name &lt;project&gt;] [--scope repo|user|other] [--json]</code></pre>
74
81
  <p>
75
82
  <code>add</code> registers an existing ledger so Artshelf can review it through one
76
83
  entry point; scope is inferred from the path when omitted.
@@ -153,7 +160,7 @@ artshelf update [--json]</code></pre>
153
160
  artshelf cleanup --dry-run [--all] [--json]
154
161
 
155
162
  <span class="c"># execute exactly one reviewed plan (approval only)</span>
156
- artshelf cleanup --execute --plan-id &lt;id&gt; [--ledger &lt;path&gt;]</code></pre>
163
+ artshelf cleanup --execute --plan-id &lt;id&gt; [--ledger &lt;path&gt;] [--json]</code></pre>
157
164
  <p>
158
165
  <code>--dry-run</code> creates and registers a cleanup plan without moving files;
159
166
  no-op dry-runs report <code>not-created</code>, and matching dry-runs reuse the
@@ -188,18 +195,51 @@ artshelf trash purge --execute --plan-id &lt;id&gt; [--ledger &lt;path&gt;] [--j
188
195
 
189
196
  <section class="cmd">
190
197
  <div class="cmd-head"><h2>artshelf resolve</h2><span class="cmd-flag plan">writes ledger</span></div>
191
- <pre><code>artshelf resolve &lt;id&gt; --status resolved --reason &lt;text&gt;</code></pre>
198
+ <pre><code>artshelf resolve &lt;id&gt; --status resolved --reason &lt;text&gt; [--json]</code></pre>
192
199
  <p>Mark a handled, missing, or no-longer-needed record as manually resolved. Updates the ledger only; never moves or deletes files.</p>
193
200
  </section>
194
201
 
195
202
  <section>
196
- <h2>Global options</h2>
203
+ <h2>Global flags</h2>
204
+ <p>Only these apply to every command.</p>
205
+ <table class="opts">
206
+ <tr><th>option</th><th>meaning</th></tr>
207
+ <tr><td>-h, --help</td><td>show help for artshelf or a specific command</td></tr>
208
+ <tr><td>-v, --version</td><td>show the Artshelf version</td></tr>
209
+ </table>
210
+ </section>
211
+
212
+ <section>
213
+ <h2>Output mode</h2>
214
+ <p>
215
+ <code>--json</code> is the agent contract: it switches commands that return data,
216
+ records, plans, receipts, or health output to machine-readable JSON on stdout.
217
+ Update notices and other diagnostics stay on stderr and never corrupt JSON output.
218
+ </p>
219
+ <table class="opts">
220
+ <tr><th>option</th><th>meaning</th></tr>
221
+ <tr><td>--json</td><td>emit machine-readable JSON on commands that return data</td></tr>
222
+ </table>
223
+ </section>
224
+
225
+ <section>
226
+ <h2>Scope flags (command-specific)</h2>
227
+ <p>
228
+ These select which ledger or registry a command reads or writes. They are not
229
+ universal global flags; each only applies to the commands that support it.
230
+ </p>
197
231
  <table class="opts">
198
232
  <tr><th>option</th><th>meaning</th></tr>
199
- <tr><td>--ledger &lt;path&gt;</td><td>use an explicit JSONL ledger</td></tr>
200
- <tr><td>--registry &lt;path&gt;</td><td>use an explicit ledger registry</td></tr>
201
- <tr><td>--all</td><td>read all registered ledgers for supported commands</td></tr>
202
- <tr><td>--json</td><td>emit machine-readable JSON</td></tr>
233
+ <tr><td>--ledger &lt;path&gt;</td><td>target an explicit JSONL ledger</td></tr>
234
+ <tr><td>--registry &lt;path&gt;</td><td>target an explicit ledger registry</td></tr>
235
+ <tr><td>--all</td><td>read every registered ledger on commands that support discovery (<code>list</code>, <code>find</code>, <code>get</code>, <code>due</code>, <code>validate</code>, <code>review</code>, <code>status</code>, <code>cleanup --dry-run</code>, <code>trash list</code>)</td></tr>
236
+ </table>
237
+ </section>
238
+
239
+ <section>
240
+ <h2>Environment</h2>
241
+ <table class="opts">
242
+ <tr><th>variable</th><th>meaning</th></tr>
203
243
  <tr><td>ARTSHELF_REGISTRY</td><td>override the default ledger registry path</td></tr>
204
244
  <tr><td>ARTSHELF_NOW</td><td>override current time for retention and due calculations</td></tr>
205
245
  <tr><td>ARTSHELF_NO_UPDATE_CHECK=1</td><td>disable automatic npm update checks</td></tr>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "artshelf",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Tiny CLI for accountable temporary artifact retention.",
5
5
  "type": "module",
6
6
  "author": "Calvin",