stow-cli 1.0.1 → 1.0.3

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.
Files changed (56) hide show
  1. package/dist/{app-2A2CFVBC.js → app-JPUDM4LJ.js} +1 -1
  2. package/dist/backfill-QZTVNJZM.js +61 -0
  3. package/dist/buckets-JQKZ3PH3.js +63 -0
  4. package/dist/{chunk-ZDVARBCV.js → chunk-ELSDWMEB.js} +8 -2
  5. package/dist/chunk-WAQSCS57.js +38 -0
  6. package/dist/cli.js +508 -15
  7. package/dist/drops-QXGTYB5E.js +39 -0
  8. package/dist/files-OCYICIAM.js +165 -0
  9. package/dist/health-YMZTZUFX.js +52 -0
  10. package/dist/jobs-6JY4SVV5.js +92 -0
  11. package/dist/jobs-OKKGKSIH.js +83 -0
  12. package/dist/maintenance-EZUHQK5Q.js +86 -0
  13. package/dist/profiles-GWLBEEIT.js +50 -0
  14. package/dist/queues-EQX7EJZF.js +51 -0
  15. package/dist/search-2PXM6XQ6.js +108 -0
  16. package/dist/tags-LSVEIIUF.js +46 -0
  17. package/dist/{upload-MI6VFGTC.js → upload-ESYKBYHA.js} +3 -3
  18. package/dist/{whoami-754O5IML.js → whoami-4UYMSRVP.js} +1 -1
  19. package/package.json +1 -1
  20. package/dist/app-2H4TLSN7.js +0 -239
  21. package/dist/app-HYCPA7GA.js +0 -239
  22. package/dist/app-IZGSPZPX.js +0 -239
  23. package/dist/app-UGUM75MC.js +0 -239
  24. package/dist/app-XPOEAZJC.js +0 -239
  25. package/dist/app-YITP5APT.js +0 -233
  26. package/dist/chunk-2AORPTQB.js +0 -23
  27. package/dist/chunk-FEMMZ4YZ.js +0 -125
  28. package/dist/chunk-LYCXXF2T.js +0 -79
  29. package/dist/chunk-MHRMBH4Y.js +0 -36
  30. package/dist/chunk-R5CCBTXZ.js +0 -79
  31. package/dist/chunk-YRHPOFJT.js +0 -115
  32. package/dist/cli.d.ts +0 -1
  33. package/dist/delete-AECEJX5W.js +0 -18
  34. package/dist/delete-KYOZEODD.js +0 -18
  35. package/dist/delete-OLOAJRRO.js +0 -18
  36. package/dist/delete-V4EY4UBG.js +0 -18
  37. package/dist/list-7A3VZA2T.js +0 -97
  38. package/dist/list-DHXVIMRI.js +0 -94
  39. package/dist/list-DJEAKEZJ.js +0 -106
  40. package/dist/list-DQRU6QHO.js +0 -106
  41. package/dist/list-I5A6LTHX.js +0 -106
  42. package/dist/list-KEQPJY7I.js +0 -109
  43. package/dist/list-Z3MPT6MI.js +0 -109
  44. package/dist/open-2YNHG3MA.js +0 -15
  45. package/dist/upload-3NS5O3UL.js +0 -120
  46. package/dist/upload-B2PGW3AN.js +0 -125
  47. package/dist/upload-DQDBDIDI.js +0 -92
  48. package/dist/upload-FGNGNPC3.js +0 -93
  49. package/dist/upload-HKUPWTK2.js +0 -173
  50. package/dist/upload-JDVSJVWK.js +0 -173
  51. package/dist/upload-K4H7ZVRW.js +0 -98
  52. package/dist/whoami-2SLCNVKP.js +0 -27
  53. package/dist/whoami-DOMX3Z5K.js +0 -28
  54. package/dist/whoami-IPMCUEUH.js +0 -27
  55. package/dist/whoami-JSQA2IDN.js +0 -27
  56. package/dist/whoami-RKH5HHPR.js +0 -27
package/dist/cli.js CHANGED
@@ -14,11 +14,14 @@ var CLI_DOCS = {
14
14
  "stow upload ./photo.jpg --bucket photos",
15
15
  "stow drop ./screenshot.png",
16
16
  "stow buckets",
17
- "stow files photos --limit 50"
17
+ "stow files photos --limit 50",
18
+ "stow search text 'sunset beach'",
19
+ "stow admin health"
18
20
  ],
19
21
  notes: [
20
22
  "Set STOW_API_KEY before running commands that call the API.",
21
- "Set STOW_API_URL to target a non-default environment."
23
+ "Set STOW_API_URL to target a non-default environment.",
24
+ "Set STOW_ADMIN_SECRET for admin commands."
22
25
  ]
23
26
  },
24
27
  drop: {
@@ -64,7 +67,46 @@ var CLI_DOCS = {
64
67
  usage: "stow files <bucket> [options]",
65
68
  examples: [
66
69
  "stow files photos",
67
- "stow files photos --search avatars/ --limit 100"
70
+ "stow files photos --search avatars/ --limit 100",
71
+ "stow files photos --json"
72
+ ]
73
+ },
74
+ filesGet: {
75
+ description: "Get details for a single file",
76
+ usage: "stow files get <bucket> <key>",
77
+ examples: [
78
+ "stow files get photos hero.png",
79
+ "stow files get photos hero.png --json"
80
+ ]
81
+ },
82
+ filesUpdate: {
83
+ description: "Update file metadata",
84
+ usage: "stow files update <bucket> <key> -m key=value",
85
+ examples: [
86
+ "stow files update photos hero.png -m alt='Hero image'",
87
+ "stow files update photos hero.png -m category=banner -m priority=high"
88
+ ]
89
+ },
90
+ filesMissing: {
91
+ description: "List files missing processing data",
92
+ usage: "stow files missing <bucket> <type>",
93
+ examples: [
94
+ "stow files missing brera dimensions",
95
+ "stow files missing brera embeddings --limit 200",
96
+ "stow files missing brera colors --json"
97
+ ],
98
+ notes: ["Valid types: dimensions, embeddings, colors"]
99
+ },
100
+ filesEnrich: {
101
+ description: "Generate title, description, and alt text for an image",
102
+ usage: "stow files enrich <bucket> <key>",
103
+ examples: [
104
+ "stow files enrich photos hero.jpg",
105
+ "stow files enrich next l5igro4iutep3"
106
+ ],
107
+ notes: [
108
+ "Triggers title, description, and alt text generation in parallel.",
109
+ "Requires a searchable bucket with image files."
68
110
  ]
69
111
  },
70
112
  drops: {
@@ -96,6 +138,179 @@ var CLI_DOCS = {
96
138
  description: "Launch interactive TUI mode",
97
139
  usage: "stow --interactive",
98
140
  examples: ["stow", "stow --interactive"]
141
+ },
142
+ search: {
143
+ description: "Search files across buckets",
144
+ usage: "stow search <subcommand>",
145
+ examples: [
146
+ "stow search text 'sunset beach' -b photos",
147
+ "stow search similar --file hero.png -b photos",
148
+ 'stow search color --hex "#ff0000" -b photos',
149
+ "stow search diverse -b photos"
150
+ ]
151
+ },
152
+ searchText: {
153
+ description: "Semantic text search",
154
+ usage: "stow search text <query> [options]",
155
+ examples: ["stow search text 'sunset beach' -b photos --limit 10 --json"]
156
+ },
157
+ searchSimilar: {
158
+ description: "Find files similar to a given file",
159
+ usage: "stow search similar --file <key> [options]",
160
+ examples: ["stow search similar --file hero.png -b photos"]
161
+ },
162
+ searchColor: {
163
+ description: "Search by color",
164
+ usage: 'stow search color --hex "#ff0000" [options]',
165
+ examples: ['stow search color --hex "#ff0000" -b photos --limit 20']
166
+ },
167
+ searchDiverse: {
168
+ description: "Diversity-aware search",
169
+ usage: "stow search diverse [options]",
170
+ examples: ["stow search diverse -b photos --limit 20"]
171
+ },
172
+ tags: {
173
+ description: "Manage tags",
174
+ usage: "stow tags",
175
+ examples: [
176
+ "stow tags",
177
+ "stow tags create 'Hero Images'",
178
+ "stow tags delete <id>"
179
+ ]
180
+ },
181
+ tagsCreate: {
182
+ description: "Create a new tag",
183
+ usage: "stow tags create <name> [options]",
184
+ examples: [
185
+ 'stow tags create "Hero Images"',
186
+ 'stow tags create "Featured" --color "#ff6600"'
187
+ ]
188
+ },
189
+ tagsDelete: {
190
+ description: "Delete a tag by ID",
191
+ usage: "stow tags delete <id>",
192
+ examples: ["stow tags delete tag_abc123"]
193
+ },
194
+ profiles: {
195
+ description: "Manage taste profiles",
196
+ usage: "stow profiles <subcommand>",
197
+ examples: [
198
+ 'stow profiles create --name "My Profile"',
199
+ "stow profiles get <id>",
200
+ "stow profiles delete <id>"
201
+ ]
202
+ },
203
+ profilesCreate: {
204
+ description: "Create a taste profile",
205
+ usage: 'stow profiles create --name "My Profile" [options]',
206
+ examples: ['stow profiles create --name "My Profile" -b photos']
207
+ },
208
+ profilesGet: {
209
+ description: "Get a taste profile with clusters",
210
+ usage: "stow profiles get <id>",
211
+ examples: ["stow profiles get profile_abc123 --json"]
212
+ },
213
+ profilesDelete: {
214
+ description: "Delete a taste profile",
215
+ usage: "stow profiles delete <id>",
216
+ examples: ["stow profiles delete profile_abc123"]
217
+ },
218
+ jobs: {
219
+ description: "List processing jobs for a bucket",
220
+ usage: "stow jobs --bucket <id> [options]",
221
+ examples: [
222
+ "stow jobs --bucket <id>",
223
+ "stow jobs --bucket <id> --status failed",
224
+ "stow jobs --bucket <id> --queue extract-colors --json"
225
+ ]
226
+ },
227
+ jobsRetry: {
228
+ description: "Retry a failed job",
229
+ usage: "stow jobs retry <id> --queue <name> --bucket <id>",
230
+ examples: ["stow jobs retry job123 --queue generate-title --bucket <id>"]
231
+ },
232
+ jobsDelete: {
233
+ description: "Remove a job",
234
+ usage: "stow jobs delete <id> --queue <name> --bucket <id>",
235
+ examples: ["stow jobs delete job123 --queue extract-colors --bucket <id>"]
236
+ },
237
+ admin: {
238
+ description: "Admin commands (requires STOW_ADMIN_SECRET)",
239
+ usage: "stow admin <subcommand>",
240
+ examples: [
241
+ "stow admin health",
242
+ "stow admin backfill dimensions --bucket <id> --dry-run",
243
+ "stow admin cleanup-drops --dry-run"
244
+ ],
245
+ notes: ["Requires STOW_ADMIN_SECRET environment variable."]
246
+ },
247
+ adminHealth: {
248
+ description: "Check system health and queue depths",
249
+ usage: "stow admin health",
250
+ examples: ["stow admin health", "stow admin health --json"]
251
+ },
252
+ adminBackfill: {
253
+ description: "Backfill processing data for files",
254
+ usage: "stow admin backfill <type> [options]",
255
+ examples: [
256
+ "stow admin backfill dimensions --bucket <id> --dry-run",
257
+ "stow admin backfill colors --bucket <id> --limit 200",
258
+ "stow admin backfill embeddings --bucket <id> --limit 100 --json"
259
+ ],
260
+ notes: ["Valid types: dimensions, colors, embeddings"]
261
+ },
262
+ adminCleanupDrops: {
263
+ description: "Remove expired drops",
264
+ usage: "stow admin cleanup-drops [options]",
265
+ examples: ["stow admin cleanup-drops --max-age-hours 24 --dry-run"]
266
+ },
267
+ adminPurgeEvents: {
268
+ description: "Purge old webhook events",
269
+ usage: "stow admin purge-events [options]",
270
+ examples: ["stow admin purge-events --dry-run"]
271
+ },
272
+ adminReconcileFiles: {
273
+ description: "Reconcile files between R2 and database",
274
+ usage: "stow admin reconcile-files --bucket <id>",
275
+ examples: ["stow admin reconcile-files --bucket <id> --dry-run"]
276
+ },
277
+ adminRetrySyncFailures: {
278
+ description: "Retry failed S3 sync operations",
279
+ usage: "stow admin retry-sync-failures",
280
+ examples: ["stow admin retry-sync-failures"]
281
+ },
282
+ adminJobs: {
283
+ description: "List and manage processing jobs",
284
+ usage: "stow admin jobs [options]",
285
+ examples: [
286
+ "stow admin jobs",
287
+ "stow admin jobs --status failed",
288
+ "stow admin jobs --org <id> --queue generate-title",
289
+ "stow admin jobs --json"
290
+ ]
291
+ },
292
+ adminJobsRetry: {
293
+ description: "Retry a failed job",
294
+ usage: "stow admin jobs retry <id> --queue <name>",
295
+ examples: ["stow admin jobs retry job123 --queue generate-title"]
296
+ },
297
+ adminJobsDelete: {
298
+ description: "Remove a job",
299
+ usage: "stow admin jobs delete <id> --queue <name>",
300
+ examples: ["stow admin jobs delete job123 --queue extract-colors"]
301
+ },
302
+ adminQueues: {
303
+ description: "Show queue depths and counts",
304
+ usage: "stow admin queues",
305
+ examples: ["stow admin queues", "stow admin queues --json"]
306
+ },
307
+ adminQueuesClean: {
308
+ description: "Clean jobs from a queue",
309
+ usage: "stow admin queues clean <name> --failed|--completed",
310
+ examples: [
311
+ "stow admin queues clean generate-title --failed",
312
+ "stow admin queues clean extract-colors --completed --grace 3600"
313
+ ]
99
314
  }
100
315
  };
101
316
  function renderCommandHelp(key) {
@@ -129,7 +344,7 @@ var program = new Command();
129
344
  program.name("stow").description(CLI_DOCS.root.description).version(VERSION).addHelpText("after", renderCommandHelp("root"));
130
345
  program.command("drop").description(CLI_DOCS.drop.description).argument("<file>", "File to upload").option("-q, --quiet", "Only output the URL").addHelpText("after", renderCommandHelp("drop")).action(async (file, options) => {
131
346
  try {
132
- const { uploadDrop } = await import("./upload-DQDBDIDI.js");
347
+ const { uploadDrop } = await import("./upload-ESYKBYHA.js");
133
348
  await uploadDrop(file, options);
134
349
  } catch (err) {
135
350
  handleError(err);
@@ -138,7 +353,7 @@ program.command("drop").description(CLI_DOCS.drop.description).argument("<file>"
138
353
  program.command("upload").description(CLI_DOCS.upload.description).argument("<file>", "File to upload").option("-b, --bucket <name>", "Bucket name or ID").option("-q, --quiet", "Only output the URL").addHelpText("after", renderCommandHelp("upload")).action(
139
354
  async (file, options) => {
140
355
  try {
141
- const { uploadFile } = await import("./upload-DQDBDIDI.js");
356
+ const { uploadFile } = await import("./upload-ESYKBYHA.js");
142
357
  await uploadFile(file, options);
143
358
  } catch (err) {
144
359
  handleError(err);
@@ -147,7 +362,7 @@ program.command("upload").description(CLI_DOCS.upload.description).argument("<fi
147
362
  );
148
363
  var bucketsCmd = program.command("buckets").description(CLI_DOCS.buckets.description).addHelpText("after", renderCommandHelp("buckets")).action(async () => {
149
364
  try {
150
- const { listBuckets } = await import("./list-KEQPJY7I.js");
365
+ const { listBuckets } = await import("./buckets-JQKZ3PH3.js");
151
366
  await listBuckets();
152
367
  } catch (err) {
153
368
  handleError(err);
@@ -156,7 +371,7 @@ var bucketsCmd = program.command("buckets").description(CLI_DOCS.buckets.descrip
156
371
  bucketsCmd.command("create").description(CLI_DOCS.bucketsCreate.description).argument("<name>", "Bucket name").option("-d, --description <text>", "Bucket description").option("--public", "Make bucket public").addHelpText("after", renderCommandHelp("bucketsCreate")).action(
157
372
  async (name, options) => {
158
373
  try {
159
- const { createBucket } = await import("./list-KEQPJY7I.js");
374
+ const { createBucket } = await import("./buckets-JQKZ3PH3.js");
160
375
  await createBucket(name, options);
161
376
  } catch (err) {
162
377
  handleError(err);
@@ -165,7 +380,7 @@ bucketsCmd.command("create").description(CLI_DOCS.bucketsCreate.description).arg
165
380
  );
166
381
  bucketsCmd.command("rename").description(CLI_DOCS.bucketsRename.description).argument("<name>", "Current bucket name").argument("<new-name>", "New bucket name").option("-y, --yes", "Skip confirmation warning").addHelpText("after", renderCommandHelp("bucketsRename")).action(async (name, newName, options) => {
167
382
  try {
168
- const { renameBucket } = await import("./list-KEQPJY7I.js");
383
+ const { renameBucket } = await import("./buckets-JQKZ3PH3.js");
169
384
  await renameBucket(name, newName, options);
170
385
  } catch (err) {
171
386
  handleError(err);
@@ -173,25 +388,65 @@ bucketsCmd.command("rename").description(CLI_DOCS.bucketsRename.description).arg
173
388
  });
174
389
  bucketsCmd.command("delete").description(CLI_DOCS.bucketsDelete.description).argument("<id>", "Bucket ID").addHelpText("after", renderCommandHelp("bucketsDelete")).action(async (id) => {
175
390
  try {
176
- const { deleteBucket } = await import("./list-KEQPJY7I.js");
391
+ const { deleteBucket } = await import("./buckets-JQKZ3PH3.js");
177
392
  await deleteBucket(id);
178
393
  } catch (err) {
179
394
  handleError(err);
180
395
  }
181
396
  });
182
- program.command("files").description(CLI_DOCS.files.description).argument("<bucket>", "Bucket name").option("-s, --search <prefix>", "Filter by prefix").option("-l, --limit <count>", "Max files to return").addHelpText("after", renderCommandHelp("files")).action(
397
+ var filesCmd = program.command("files").description(CLI_DOCS.files.description).argument("[bucket]", "Bucket name").option("-s, --search <prefix>", "Filter by prefix").option("-l, --limit <count>", "Max files to return").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("files")).action(
183
398
  async (bucket, options) => {
399
+ if (!bucket) {
400
+ filesCmd.help();
401
+ return;
402
+ }
184
403
  try {
185
- const { listFiles } = await import("./list-KEQPJY7I.js");
404
+ const { listFiles } = await import("./files-OCYICIAM.js");
186
405
  await listFiles(bucket, options);
187
406
  } catch (err) {
188
407
  handleError(err);
189
408
  }
190
409
  }
191
410
  );
411
+ filesCmd.command("get").description(CLI_DOCS.filesGet.description).argument("<bucket>", "Bucket name").argument("<key>", "File key").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("filesGet")).action(async (bucket, key, options) => {
412
+ try {
413
+ const { getFile } = await import("./files-OCYICIAM.js");
414
+ await getFile(bucket, key, options);
415
+ } catch (err) {
416
+ handleError(err);
417
+ }
418
+ });
419
+ filesCmd.command("update").description(CLI_DOCS.filesUpdate.description).argument("<bucket>", "Bucket name").argument("<key>", "File key").option("-m, --metadata <kv...>", "Metadata key=value pairs").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("filesUpdate")).action(
420
+ async (bucket, key, options) => {
421
+ try {
422
+ const { updateFile } = await import("./files-OCYICIAM.js");
423
+ await updateFile(bucket, key, options);
424
+ } catch (err) {
425
+ handleError(err);
426
+ }
427
+ }
428
+ );
429
+ filesCmd.command("enrich").description(CLI_DOCS.filesEnrich.description).argument("<bucket>", "Bucket name").argument("<key>", "File key").addHelpText("after", renderCommandHelp("filesEnrich")).action(async (bucket, key) => {
430
+ try {
431
+ const { enrichFile } = await import("./files-OCYICIAM.js");
432
+ await enrichFile(bucket, key);
433
+ } catch (err) {
434
+ handleError(err);
435
+ }
436
+ });
437
+ filesCmd.command("missing").description(CLI_DOCS.filesMissing.description).argument("<bucket>", "Bucket name").argument("<type>", "dimensions | embeddings | colors").option("-l, --limit <count>", "Max files to return").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("filesMissing")).action(
438
+ async (bucket, type, options) => {
439
+ try {
440
+ const { listMissing } = await import("./files-OCYICIAM.js");
441
+ await listMissing(bucket, type, options);
442
+ } catch (err) {
443
+ handleError(err);
444
+ }
445
+ }
446
+ );
192
447
  var dropsCmd = program.command("drops").description(CLI_DOCS.drops.description).addHelpText("after", renderCommandHelp("drops")).action(async () => {
193
448
  try {
194
- const { listDrops } = await import("./list-KEQPJY7I.js");
449
+ const { listDrops } = await import("./drops-QXGTYB5E.js");
195
450
  await listDrops();
196
451
  } catch (err) {
197
452
  handleError(err);
@@ -199,12 +454,250 @@ var dropsCmd = program.command("drops").description(CLI_DOCS.drops.description).
199
454
  });
200
455
  dropsCmd.command("delete").description(CLI_DOCS.dropsDelete.description).argument("<id>", "Drop ID").addHelpText("after", renderCommandHelp("dropsDelete")).action(async (id) => {
201
456
  try {
202
- const { deleteDrop } = await import("./list-KEQPJY7I.js");
457
+ const { deleteDrop } = await import("./drops-QXGTYB5E.js");
203
458
  await deleteDrop(id);
204
459
  } catch (err) {
205
460
  handleError(err);
206
461
  }
207
462
  });
463
+ var searchCmd = program.command("search").description(CLI_DOCS.search.description).addHelpText("after", renderCommandHelp("search"));
464
+ searchCmd.command("text").description(CLI_DOCS.searchText.description).argument("<query>", "Search query").option("-b, --bucket <name>", "Bucket name").option("-l, --limit <count>", "Max results").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("searchText")).action(
465
+ async (query, options) => {
466
+ try {
467
+ const { textSearch } = await import("./search-2PXM6XQ6.js");
468
+ await textSearch(query, options);
469
+ } catch (err) {
470
+ handleError(err);
471
+ }
472
+ }
473
+ );
474
+ searchCmd.command("similar").description(CLI_DOCS.searchSimilar.description).requiredOption("--file <key>", "File key to search from").option("-b, --bucket <name>", "Bucket name").option("-l, --limit <count>", "Max results").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("searchSimilar")).action(
475
+ async (options) => {
476
+ try {
477
+ const { similarSearch } = await import("./search-2PXM6XQ6.js");
478
+ await similarSearch(options);
479
+ } catch (err) {
480
+ handleError(err);
481
+ }
482
+ }
483
+ );
484
+ searchCmd.command("color").description(CLI_DOCS.searchColor.description).requiredOption("--hex <color>", "Hex color code").option("-b, --bucket <name>", "Bucket name").option("-l, --limit <count>", "Max results").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("searchColor")).action(
485
+ async (options) => {
486
+ try {
487
+ const { colorSearch } = await import("./search-2PXM6XQ6.js");
488
+ await colorSearch(options);
489
+ } catch (err) {
490
+ handleError(err);
491
+ }
492
+ }
493
+ );
494
+ searchCmd.command("diverse").description(CLI_DOCS.searchDiverse.description).option("-b, --bucket <name>", "Bucket name").option("-l, --limit <count>", "Max results").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("searchDiverse")).action(
495
+ async (options) => {
496
+ try {
497
+ const { diverseSearch } = await import("./search-2PXM6XQ6.js");
498
+ await diverseSearch(options);
499
+ } catch (err) {
500
+ handleError(err);
501
+ }
502
+ }
503
+ );
504
+ var tagsCmd = program.command("tags").description(CLI_DOCS.tags.description).option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("tags")).action(async (options) => {
505
+ try {
506
+ const { listTags } = await import("./tags-LSVEIIUF.js");
507
+ await listTags(options);
508
+ } catch (err) {
509
+ handleError(err);
510
+ }
511
+ });
512
+ tagsCmd.command("create").description(CLI_DOCS.tagsCreate.description).argument("<name>", "Tag name").option("--color <hex>", "Tag color (hex)").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("tagsCreate")).action(async (name, options) => {
513
+ try {
514
+ const { createTag } = await import("./tags-LSVEIIUF.js");
515
+ await createTag(name, options);
516
+ } catch (err) {
517
+ handleError(err);
518
+ }
519
+ });
520
+ tagsCmd.command("delete").description(CLI_DOCS.tagsDelete.description).argument("<id>", "Tag ID").addHelpText("after", renderCommandHelp("tagsDelete")).action(async (id) => {
521
+ try {
522
+ const { deleteTag } = await import("./tags-LSVEIIUF.js");
523
+ await deleteTag(id);
524
+ } catch (err) {
525
+ handleError(err);
526
+ }
527
+ });
528
+ var profilesCmd = program.command("profiles").description(CLI_DOCS.profiles.description).addHelpText("after", renderCommandHelp("profiles"));
529
+ profilesCmd.command("create").description(CLI_DOCS.profilesCreate.description).requiredOption("--name <name>", "Profile name").option("-b, --bucket <id>", "Bucket ID").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("profilesCreate")).action(
530
+ async (options) => {
531
+ try {
532
+ const { createProfile } = await import("./profiles-GWLBEEIT.js");
533
+ await createProfile(options);
534
+ } catch (err) {
535
+ handleError(err);
536
+ }
537
+ }
538
+ );
539
+ profilesCmd.command("get").description(CLI_DOCS.profilesGet.description).argument("<id>", "Profile ID").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("profilesGet")).action(async (id, options) => {
540
+ try {
541
+ const { getProfile } = await import("./profiles-GWLBEEIT.js");
542
+ await getProfile(id, options);
543
+ } catch (err) {
544
+ handleError(err);
545
+ }
546
+ });
547
+ profilesCmd.command("delete").description(CLI_DOCS.profilesDelete.description).argument("<id>", "Profile ID").addHelpText("after", renderCommandHelp("profilesDelete")).action(async (id) => {
548
+ try {
549
+ const { deleteProfile } = await import("./profiles-GWLBEEIT.js");
550
+ await deleteProfile(id);
551
+ } catch (err) {
552
+ handleError(err);
553
+ }
554
+ });
555
+ var jobsCmd = program.command("jobs").description(CLI_DOCS.jobs.description).requiredOption("-b, --bucket <id>", "Bucket ID (required)").option("-s, --status <status>", "Filter by status").option("-q, --queue <name>", "Filter by queue name").option("-l, --limit <count>", "Max jobs to return").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("jobs")).action(
556
+ async (options) => {
557
+ try {
558
+ const { listJobs } = await import("./jobs-6JY4SVV5.js");
559
+ await listJobs(options.bucket, options);
560
+ } catch (err) {
561
+ handleError(err);
562
+ }
563
+ }
564
+ );
565
+ jobsCmd.command("retry").description(CLI_DOCS.jobsRetry.description).argument("<id>", "Job ID").requiredOption("-q, --queue <name>", "Queue name").requiredOption("-b, --bucket <id>", "Bucket ID").addHelpText("after", renderCommandHelp("jobsRetry")).action(async (id, options) => {
566
+ try {
567
+ const { retryJob } = await import("./jobs-6JY4SVV5.js");
568
+ await retryJob(id, options);
569
+ } catch (err) {
570
+ handleError(err);
571
+ }
572
+ });
573
+ jobsCmd.command("delete").description(CLI_DOCS.jobsDelete.description).argument("<id>", "Job ID").requiredOption("-q, --queue <name>", "Queue name").requiredOption("-b, --bucket <id>", "Bucket ID").addHelpText("after", renderCommandHelp("jobsDelete")).action(async (id, options) => {
574
+ try {
575
+ const { deleteJob } = await import("./jobs-6JY4SVV5.js");
576
+ await deleteJob(id, options);
577
+ } catch (err) {
578
+ handleError(err);
579
+ }
580
+ });
581
+ var adminCmd = program.command("admin").description(CLI_DOCS.admin.description).addHelpText("after", renderCommandHelp("admin"));
582
+ adminCmd.command("health").description(CLI_DOCS.adminHealth.description).option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("adminHealth")).action(async (options) => {
583
+ try {
584
+ const { health } = await import("./health-YMZTZUFX.js");
585
+ await health(options);
586
+ } catch (err) {
587
+ handleError(err);
588
+ }
589
+ });
590
+ var backfillCmd = adminCmd.command("backfill").description(CLI_DOCS.adminBackfill.description).addHelpText("after", renderCommandHelp("adminBackfill"));
591
+ backfillCmd.command("dimensions").description("Backfill image dimensions").option("--bucket <id>", "Bucket ID").option("-l, --limit <count>", "Max files to enqueue").option("--dry-run", "Preview without enqueuing").option("--json", "Output as JSON").action(
592
+ async (options) => {
593
+ try {
594
+ const { backfillDimensions } = await import("./backfill-QZTVNJZM.js");
595
+ await backfillDimensions(options);
596
+ } catch (err) {
597
+ handleError(err);
598
+ }
599
+ }
600
+ );
601
+ backfillCmd.command("colors").description("Backfill color extraction").option("--bucket <id>", "Bucket ID").option("-l, --limit <count>", "Max files to enqueue").option("--dry-run", "Preview without enqueuing").option("--json", "Output as JSON").action(
602
+ async (options) => {
603
+ try {
604
+ const { backfillColors } = await import("./backfill-QZTVNJZM.js");
605
+ await backfillColors(options);
606
+ } catch (err) {
607
+ handleError(err);
608
+ }
609
+ }
610
+ );
611
+ backfillCmd.command("embeddings").description("Backfill embedding generation").option("--bucket <id>", "Bucket ID").option("-l, --limit <count>", "Max files to enqueue").option("--dry-run", "Preview without enqueuing").option("--json", "Output as JSON").action(
612
+ async (options) => {
613
+ try {
614
+ const { backfillEmbeddings } = await import("./backfill-QZTVNJZM.js");
615
+ await backfillEmbeddings(options);
616
+ } catch (err) {
617
+ handleError(err);
618
+ }
619
+ }
620
+ );
621
+ adminCmd.command("cleanup-drops").description(CLI_DOCS.adminCleanupDrops.description).option("--max-age-hours <hours>", "Max age in hours").option("--dry-run", "Preview without deleting").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("adminCleanupDrops")).action(
622
+ async (options) => {
623
+ try {
624
+ const { cleanupDrops } = await import("./maintenance-EZUHQK5Q.js");
625
+ await cleanupDrops(options);
626
+ } catch (err) {
627
+ handleError(err);
628
+ }
629
+ }
630
+ );
631
+ adminCmd.command("purge-events").description(CLI_DOCS.adminPurgeEvents.description).option("--dry-run", "Preview without deleting").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("adminPurgeEvents")).action(async (options) => {
632
+ try {
633
+ const { purgeEvents } = await import("./maintenance-EZUHQK5Q.js");
634
+ await purgeEvents(options);
635
+ } catch (err) {
636
+ handleError(err);
637
+ }
638
+ });
639
+ adminCmd.command("reconcile-files").description(CLI_DOCS.adminReconcileFiles.description).requiredOption("--bucket <id>", "Bucket ID").option("--dry-run", "Preview without reconciling").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("adminReconcileFiles")).action(
640
+ async (options) => {
641
+ try {
642
+ const { reconcileFiles } = await import("./maintenance-EZUHQK5Q.js");
643
+ await reconcileFiles(options);
644
+ } catch (err) {
645
+ handleError(err);
646
+ }
647
+ }
648
+ );
649
+ adminCmd.command("retry-sync-failures").description(CLI_DOCS.adminRetrySyncFailures.description).option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("adminRetrySyncFailures")).action(async (options) => {
650
+ try {
651
+ const { retrySyncFailures } = await import("./maintenance-EZUHQK5Q.js");
652
+ await retrySyncFailures(options);
653
+ } catch (err) {
654
+ handleError(err);
655
+ }
656
+ });
657
+ var adminJobsCmd = adminCmd.command("jobs").description(CLI_DOCS.adminJobs.description).option("--org <id>", "Filter by org ID").option("--bucket <id>", "Filter by bucket ID").option("-s, --status <status>", "Filter by status").option("-q, --queue <name>", "Filter by queue name").option("-l, --limit <count>", "Max jobs to return").option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("adminJobs")).action(
658
+ async (options) => {
659
+ try {
660
+ const { listAdminJobs } = await import("./jobs-OKKGKSIH.js");
661
+ await listAdminJobs(options);
662
+ } catch (err) {
663
+ handleError(err);
664
+ }
665
+ }
666
+ );
667
+ adminJobsCmd.command("retry").description(CLI_DOCS.adminJobsRetry.description).argument("<id>", "Job ID").requiredOption("-q, --queue <name>", "Queue name").addHelpText("after", renderCommandHelp("adminJobsRetry")).action(async (id, options) => {
668
+ try {
669
+ const { retryAdminJob } = await import("./jobs-OKKGKSIH.js");
670
+ await retryAdminJob(id, options);
671
+ } catch (err) {
672
+ handleError(err);
673
+ }
674
+ });
675
+ adminJobsCmd.command("delete").description(CLI_DOCS.adminJobsDelete.description).argument("<id>", "Job ID").requiredOption("-q, --queue <name>", "Queue name").addHelpText("after", renderCommandHelp("adminJobsDelete")).action(async (id, options) => {
676
+ try {
677
+ const { deleteAdminJob } = await import("./jobs-OKKGKSIH.js");
678
+ await deleteAdminJob(id, options);
679
+ } catch (err) {
680
+ handleError(err);
681
+ }
682
+ });
683
+ var adminQueuesCmd = adminCmd.command("queues").description(CLI_DOCS.adminQueues.description).option("--json", "Output as JSON").addHelpText("after", renderCommandHelp("adminQueues")).action(async (options) => {
684
+ try {
685
+ const { listQueues } = await import("./queues-EQX7EJZF.js");
686
+ await listQueues(options);
687
+ } catch (err) {
688
+ handleError(err);
689
+ }
690
+ });
691
+ adminQueuesCmd.command("clean").description(CLI_DOCS.adminQueuesClean.description).argument("<name>", "Queue name").option("--failed", "Clean failed jobs").option("--completed", "Clean completed jobs").option("--grace <seconds>", "Grace period in seconds").addHelpText("after", renderCommandHelp("adminQueuesClean")).action(
692
+ async (name, options) => {
693
+ try {
694
+ const { cleanQueue } = await import("./queues-EQX7EJZF.js");
695
+ await cleanQueue(name, options);
696
+ } catch (err) {
697
+ handleError(err);
698
+ }
699
+ }
700
+ );
208
701
  program.command("delete").description(CLI_DOCS.delete.description).argument("<bucket>", "Bucket name").argument("<key>", "File key").addHelpText("after", renderCommandHelp("delete")).action(async (bucket, key) => {
209
702
  try {
210
703
  const { deleteFile } = await import("./delete-NAV6P5O5.js");
@@ -215,7 +708,7 @@ program.command("delete").description(CLI_DOCS.delete.description).argument("<bu
215
708
  });
216
709
  program.command("whoami").description(CLI_DOCS.whoami.description).addHelpText("after", renderCommandHelp("whoami")).action(async () => {
217
710
  try {
218
- const { whoami } = await import("./whoami-754O5IML.js");
711
+ const { whoami } = await import("./whoami-4UYMSRVP.js");
219
712
  await whoami();
220
713
  } catch (err) {
221
714
  handleError(err);
@@ -234,5 +727,5 @@ program.parse();
234
727
  var opts = program.opts();
235
728
  var args = process.argv.slice(2);
236
729
  if (args.length === 0 || args.length === 1 && opts.interactive) {
237
- import("./app-2A2CFVBC.js").then(({ startInteractive }) => startInteractive()).catch(handleError);
730
+ import("./app-JPUDM4LJ.js").then(({ startInteractive }) => startInteractive()).catch(handleError);
238
731
  }
@@ -0,0 +1,39 @@
1
+ import {
2
+ formatBytes,
3
+ formatTable,
4
+ usageBar
5
+ } from "./chunk-ELSDWMEB.js";
6
+ import {
7
+ createStow
8
+ } from "./chunk-JYOMHKFS.js";
9
+ import "./chunk-OZ7QQTIZ.js";
10
+
11
+ // src/commands/drops.ts
12
+ async function listDrops() {
13
+ const stow = createStow();
14
+ const data = await stow.listDrops();
15
+ if (data.drops.length === 0) {
16
+ console.log("No drops yet. Create one with: stow drop <file>");
17
+ return;
18
+ }
19
+ const rows = data.drops.map((d) => [
20
+ d.filename,
21
+ formatBytes(Number(d.size)),
22
+ d.contentType,
23
+ d.url
24
+ ]);
25
+ console.log(formatTable(["Filename", "Size", "Type", "URL"], rows));
26
+ console.log(
27
+ `
28
+ Storage: ${usageBar(data.usage.bytes, data.usage.limit)} ${formatBytes(data.usage.bytes)} / ${formatBytes(data.usage.limit)}`
29
+ );
30
+ }
31
+ async function deleteDrop(id) {
32
+ const stow = createStow();
33
+ await stow.deleteDrop(id);
34
+ console.log(`Deleted drop: ${id}`);
35
+ }
36
+ export {
37
+ deleteDrop,
38
+ listDrops
39
+ };