@wafflebase/cli 0.6.3 → 0.6.4

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 (3) hide show
  1. package/README.md +9 -2
  2. package/dist/bin.js +255 -150
  3. package/package.json +3 -3
package/README.md CHANGED
@@ -53,7 +53,10 @@ wafflebase
53
53
  │ └── import <file> --replace <id> --yes for in-place
54
54
  │
55
55
  ├── sheets (aliases: sheet, spreadsheet, spreadsheets)
56
- │ ├── tabs (alias: tab) list <doc-id>
56
+ │ ├── tabs (alias: tab)
57
+ │ │ ├── list <doc-id>
58
+ │ │ ├── create <doc-id> [name] --type sheet
59
+ │ │ └── rename <doc-id> <tab-id> <name>
57
60
  │ ├── cells (alias: cell)
58
61
  │ │ ├── get <doc-id> [<range>]
59
62
  │ │ ├── set <doc-id> <ref> <value> --formula
@@ -71,7 +74,9 @@ wafflebase
71
74
  ```
72
75
 
73
76
  **Global flags**: `--server`, `--api-key`, `--workspace`, `--profile`,
74
- `--format json|table|csv` (default `json`), `--quiet`, `--verbose`,
77
+ `--format json|table|csv|yaml` (default `json`), `--quiet` (suppresses
78
+ progress notices only — the result body and the JSON error envelope are
79
+ always emitted), `--verbose`,
75
80
  `--dry-run`. The `--format` flag also doubles as the per-content shape
76
81
  on `docs content` (`json|md|text`) and the export type override on
77
82
  `docs export` (`pdf|docx`).
@@ -84,6 +89,8 @@ wafflebase docs list
84
89
  wafflebase docs create "Q1 Notes" --type doc
85
90
 
86
91
  # Spreadsheets
92
+ wafflebase sheets tabs create abc-123 "History"
93
+ wafflebase sheets tabs rename abc-123 tab-1 "Summary"
87
94
  wafflebase sheets cells get abc-123 A1:D100
88
95
  echo '{"A1":"Name","B1":"Score"}' | wafflebase sheets cells batch abc-123
89
96
  wafflebase sheets export abc-123 out.csv
package/dist/bin.js CHANGED
@@ -271,7 +271,7 @@ var HttpClient = class {
271
271
  // blob and creates the document in one call; see the controller comment in
272
272
  // `packages/backend/src/api/v1/files.controller.ts` for why it is not the
273
273
  // browser's two-step flow.
274
- async uploadFileDocument(bytes, fileName, mimeType, title) {
274
+ async uploadFileDocument(bytes, fileName, mimeType, fields = {}) {
275
275
  const { res, sessionExpired } = await this.send(
276
276
  `${this.base}/files`,
277
277
  (auth) => {
@@ -282,7 +282,8 @@ var HttpClient = class {
282
282
  bytes.byteLength
283
283
  );
284
284
  form.append("file", new Blob([part], { type: mimeType }), fileName);
285
- if (title) form.append("title", title);
285
+ if (fields.title) form.append("title", fields.title);
286
+ if (fields.folderId) form.append("folderId", fields.folderId);
286
287
  return { method: "POST", headers: auth, body: form };
287
288
  }
288
289
  );
@@ -370,6 +371,12 @@ var HttpClient = class {
370
371
  listTabs(docId) {
371
372
  return this.request("GET", `/documents/${docId}/tabs`);
372
373
  }
374
+ createTab(docId, body) {
375
+ return this.request("POST", `/documents/${docId}/tabs`, body);
376
+ }
377
+ renameTab(docId, tabId, name) {
378
+ return this.request("PATCH", `/documents/${docId}/tabs/${tabId}`, { name });
379
+ }
373
380
  // Cells
374
381
  getCells(docId, tabId, range) {
375
382
  const query = range ? `?range=${encodeURIComponent(range)}` : "";
@@ -419,7 +426,7 @@ var HttpClient = class {
419
426
  };
420
427
 
421
428
  // package.json
422
- var version = "0.6.3";
429
+ var version = "0.6.4";
423
430
 
424
431
  // src/commands/root.ts
425
432
  function getGlobalOpts(cmd) {
@@ -438,9 +445,13 @@ function getClient(opts) {
438
445
  return new HttpClient(getConfig(opts));
439
446
  }
440
447
  function createProgram() {
441
- const program2 = new Command();
442
- program2.name("wafflebase").description("CLI for Wafflebase spreadsheet API").version(version).option("--server <url>", "Server URL").option("--api-key <key>", "API key").option("--workspace <id>", "Workspace ID").option("--profile <name>", "Config profile", "default").option("--format <fmt>", "Output format (json, table, csv)", "json").option("--quiet", "Suppress output", false).option("--verbose", "Verbose output", false).option("--dry-run", "Show request without executing", false);
443
- return program2;
448
+ const program = new Command();
449
+ program.name("wafflebase").description("CLI for Wafflebase spreadsheet API").version(version).option("--server <url>", "Server URL").option("--api-key <key>", "API key").option("--workspace <id>", "Workspace ID").option("--profile <name>", "Config profile", "default").option("--format <fmt>", "Output format (json, table, csv, yaml)", "json").option(
450
+ "--quiet",
451
+ "Suppress progress notices (result body and errors still print)",
452
+ false
453
+ ).option("--verbose", "Verbose output", false).option("--dry-run", "Show request without executing", false);
454
+ return program;
444
455
  }
445
456
 
446
457
  // src/commands/docs.ts
@@ -487,6 +498,12 @@ function formatCsv(data) {
487
498
  return [header, ...lines].join("\n");
488
499
  }
489
500
 
501
+ // src/output/yaml.ts
502
+ import { stringify } from "yaml";
503
+ function formatYaml(data) {
504
+ return stringify(data).replace(/\n$/, "");
505
+ }
506
+
490
507
  // src/output/formatter.ts
491
508
  function format(data, fmt) {
492
509
  switch (fmt) {
@@ -496,10 +513,13 @@ function format(data, fmt) {
496
513
  return formatTable(data);
497
514
  case "csv":
498
515
  return formatCsv(data);
516
+ case "yaml":
517
+ return formatYaml(data);
518
+ default:
519
+ throw new Error(`Unsupported output format: ${String(fmt)}`);
499
520
  }
500
521
  }
501
- function output(data, fmt, quiet) {
502
- if (quiet) return;
522
+ function output(data, fmt) {
503
523
  console.log(format(data, fmt));
504
524
  }
505
525
  function errorCode(error) {
@@ -509,11 +529,7 @@ function errorCode(error) {
509
529
  }
510
530
  return "ERROR";
511
531
  }
512
- function outputError(error, quiet) {
513
- if (quiet) {
514
- process.exitCode = 1;
515
- return;
516
- }
532
+ function outputError(error) {
517
533
  const message = error instanceof Error ? error.message : String(error);
518
534
  console.error(
519
535
  JSON.stringify({ error: { code: errorCode(error), message } }, null, 2)
@@ -43569,8 +43585,8 @@ function detectExportFormat(file, formatFlag) {
43569
43585
  `Cannot infer format from "${file}". Pass --format pdf|docx, or use a .pdf/.docx extension.`
43570
43586
  );
43571
43587
  }
43572
- function registerDocsCommand(program2) {
43573
- const doc = program2.command("docs").alias("doc").alias("document").alias("documents").description("Manage documents");
43588
+ function registerDocsCommand(program) {
43589
+ const doc = program.command("docs").alias("doc").alias("document").alias("documents").description("Manage documents");
43574
43590
  doc.command("list").description("List documents in workspace").option("--type <type>", "Filter by document type (doc|sheet)").action(async function() {
43575
43591
  const opts = getGlobalOpts(this);
43576
43592
  const { type: typeStr } = this.opts();
@@ -43584,9 +43600,9 @@ function registerDocsCommand(program2) {
43584
43600
  (d) => (d.type ?? "sheet") === filterType
43585
43601
  );
43586
43602
  }
43587
- output(data, opts.format, opts.quiet);
43603
+ output(data, opts.format);
43588
43604
  } catch (e) {
43589
- outputError(e, opts.quiet);
43605
+ outputError(e);
43590
43606
  }
43591
43607
  });
43592
43608
  doc.command("create <title>").description("Create a new document").option("--type <type>", "Document type (doc|sheet)", "sheet").action(async function(title) {
@@ -43600,9 +43616,9 @@ function registerDocsCommand(program2) {
43600
43616
  }
43601
43617
  const res = await getClient(opts).createDocument(title, type);
43602
43618
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
43603
- output(res.data, opts.format, opts.quiet);
43619
+ output(res.data, opts.format);
43604
43620
  } catch (e) {
43605
- outputError(e, opts.quiet);
43621
+ outputError(e);
43606
43622
  }
43607
43623
  });
43608
43624
  doc.command("get <doc-id>").description("Show document metadata").action(async function(docId) {
@@ -43610,9 +43626,9 @@ function registerDocsCommand(program2) {
43610
43626
  try {
43611
43627
  const res = await getClient(opts).getDocument(docId);
43612
43628
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
43613
- output(res.data, opts.format, opts.quiet);
43629
+ output(res.data, opts.format);
43614
43630
  } catch (e) {
43615
- outputError(e, opts.quiet);
43631
+ outputError(e);
43616
43632
  }
43617
43633
  });
43618
43634
  doc.command("rename <doc-id> <title>").description("Rename a document").action(async function(docId, title) {
@@ -43624,9 +43640,9 @@ function registerDocsCommand(program2) {
43624
43640
  try {
43625
43641
  const res = await getClient(opts).updateDocument(docId, title);
43626
43642
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
43627
- output(res.data, opts.format, opts.quiet);
43643
+ output(res.data, opts.format);
43628
43644
  } catch (e) {
43629
- outputError(e, opts.quiet);
43645
+ outputError(e);
43630
43646
  }
43631
43647
  });
43632
43648
  doc.command("delete <doc-id>").description("Delete a document").action(async function(docId) {
@@ -43638,9 +43654,9 @@ function registerDocsCommand(program2) {
43638
43654
  try {
43639
43655
  const res = await getClient(opts).deleteDocument(docId);
43640
43656
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
43641
- output(res.data, opts.format, opts.quiet);
43657
+ output(res.data, opts.format);
43642
43658
  } catch (e) {
43643
- outputError(e, opts.quiet);
43659
+ outputError(e);
43644
43660
  }
43645
43661
  });
43646
43662
  doc.command("content <doc-id>").description("Read document content as JSON, Markdown, or plain text").option("--pages <range>", "Page range to include (e.g. 1-3,5)").option("--include-header-footer", "Include header/footer (md/text)", false).option("--inline-images", "Inline data: image URLs (md only)", false).option("--out <file>", "Output file (- for stdout)").option("--force", "Overwrite existing output file", false).action(async function(docId) {
@@ -43677,7 +43693,7 @@ function registerDocsCommand(program2) {
43677
43693
  quiet: opts.quiet
43678
43694
  });
43679
43695
  } catch (e) {
43680
- outputError(e, opts.quiet);
43696
+ outputError(e);
43681
43697
  }
43682
43698
  });
43683
43699
  doc.command("export <doc-id> <file>").description("Export a document to PDF or DOCX").option("--pages <range>", "Page range to export (PDF only)").option("--include-header-footer", "Include header/footer regions", true).option("--force", "Overwrite existing output file", false).action(async function(docId, file) {
@@ -43746,7 +43762,7 @@ function registerDocsCommand(program2) {
43746
43762
  }
43747
43763
  writeBinary(bytes, file, { force: local.force, quiet: opts.quiet });
43748
43764
  } catch (e) {
43749
- outputError(e, opts.quiet);
43765
+ outputError(e);
43750
43766
  }
43751
43767
  });
43752
43768
  registerDocsImportCommand(doc);
@@ -43774,7 +43790,7 @@ function registerDocsImportCommand(doc) {
43774
43790
  );
43775
43791
  if (result.exitCode !== 0) process.exitCode = result.exitCode;
43776
43792
  } catch (e) {
43777
- outputError(e, opts.quiet);
43793
+ outputError(e);
43778
43794
  }
43779
43795
  });
43780
43796
  }
@@ -43788,9 +43804,9 @@ function registerCellsCommand(parent) {
43788
43804
  try {
43789
43805
  const res = range?.includes(":") ? await getClient(opts).getCells(docId, tab, range) : range ? await getClient(opts).getCell(docId, tab, range) : await getClient(opts).getCells(docId, tab);
43790
43806
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
43791
- output(res.data, opts.format, opts.quiet);
43807
+ output(res.data, opts.format);
43792
43808
  } catch (e) {
43793
- outputError(e, opts.quiet);
43809
+ outputError(e);
43794
43810
  }
43795
43811
  });
43796
43812
  cell.command("set <doc-id> <ref> <value>").description("Set a single cell value").option("--tab <tab-id>", "Tab ID", "tab-1").option("--formula", "Treat value as a formula").action(async function(docId, ref, value) {
@@ -43815,9 +43831,9 @@ function registerCellsCommand(parent) {
43815
43831
  formula ? value : void 0
43816
43832
  );
43817
43833
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
43818
- output(res.data, opts.format, opts.quiet);
43834
+ output(res.data, opts.format);
43819
43835
  } catch (e) {
43820
- outputError(e, opts.quiet);
43836
+ outputError(e);
43821
43837
  }
43822
43838
  });
43823
43839
  cell.command("delete <doc-id> <ref>").description("Delete a single cell").option("--tab <tab-id>", "Tab ID", "tab-1").action(async function(docId, ref) {
@@ -43834,43 +43850,43 @@ function registerCellsCommand(parent) {
43834
43850
  try {
43835
43851
  const res = await getClient(opts).deleteCell(docId, tab, ref);
43836
43852
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
43837
- output(res.data, opts.format, opts.quiet);
43853
+ output(res.data, opts.format);
43838
43854
  } catch (e) {
43839
- outputError(e, opts.quiet);
43855
+ outputError(e);
43840
43856
  }
43841
43857
  });
43842
43858
  cell.command("batch <doc-id>").description("Batch update cells (JSON from stdin or --data)").option("--tab <tab-id>", "Tab ID", "tab-1").option("--data <json>", "Cell data as JSON string").action(async function(docId) {
43843
43859
  const opts = getGlobalOpts(this);
43844
43860
  const { tab, data: dataStr } = this.opts();
43845
- let cells;
43846
- if (dataStr) {
43847
- cells = JSON.parse(dataStr);
43848
- } else {
43849
- const chunks = [];
43850
- for await (const chunk of process.stdin) {
43851
- chunks.push(chunk);
43852
- }
43853
- cells = JSON.parse(Buffer.concat(chunks).toString("utf-8"));
43854
- }
43855
- if (opts.dryRun) {
43856
- printDryRun(
43857
- getConfig(opts),
43858
- "PATCH",
43859
- `/documents/${docId}/tabs/${tab}/cells`,
43860
- { cells }
43861
- );
43862
- return;
43863
- }
43864
43861
  try {
43862
+ let cells;
43863
+ if (dataStr) {
43864
+ cells = JSON.parse(dataStr);
43865
+ } else {
43866
+ const chunks = [];
43867
+ for await (const chunk of process.stdin) {
43868
+ chunks.push(chunk);
43869
+ }
43870
+ cells = JSON.parse(Buffer.concat(chunks).toString("utf-8"));
43871
+ }
43872
+ if (opts.dryRun) {
43873
+ printDryRun(
43874
+ getConfig(opts),
43875
+ "PATCH",
43876
+ `/documents/${docId}/tabs/${tab}/cells`,
43877
+ { cells }
43878
+ );
43879
+ return;
43880
+ }
43865
43881
  const res = await getClient(opts).batchCells(
43866
43882
  docId,
43867
43883
  tab,
43868
43884
  cells
43869
43885
  );
43870
43886
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
43871
- output(res.data, opts.format, opts.quiet);
43887
+ output(res.data, opts.format);
43872
43888
  } catch (e) {
43873
- outputError(e, opts.quiet);
43889
+ outputError(e);
43874
43890
  }
43875
43891
  });
43876
43892
  }
@@ -43883,9 +43899,48 @@ function registerTabsCommand(parent) {
43883
43899
  try {
43884
43900
  const res = await getClient(opts).listTabs(docId);
43885
43901
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
43886
- output(res.data, opts.format, opts.quiet);
43902
+ output(res.data, opts.format);
43903
+ } catch (e) {
43904
+ outputError(e);
43905
+ }
43906
+ });
43907
+ tab.command("create <doc-id> [name]").description("Create a new sheet tab (name optional -> next SheetN)").option("--type <type>", 'Tab type (only "sheet" is supported)', "sheet").action(async function(docId, name) {
43908
+ const opts = getGlobalOpts(this);
43909
+ const { type } = this.opts();
43910
+ if (type !== "sheet") {
43911
+ outputError(
43912
+ new Error(`Unsupported tab type "${type}"; only "sheet" is supported.`)
43913
+ );
43914
+ return;
43915
+ }
43916
+ const body = { type };
43917
+ if (name !== void 0) body.name = name;
43918
+ if (opts.dryRun) {
43919
+ printDryRun(getConfig(opts), "POST", `/documents/${docId}/tabs`, body);
43920
+ return;
43921
+ }
43922
+ try {
43923
+ const res = await getClient(opts).createTab(docId, body);
43924
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
43925
+ output(res.data, opts.format);
43926
+ } catch (e) {
43927
+ outputError(e);
43928
+ }
43929
+ });
43930
+ tab.command("rename <doc-id> <tab-id> <name>").description("Rename a tab").action(async function(docId, tabId, name) {
43931
+ const opts = getGlobalOpts(this);
43932
+ if (opts.dryRun) {
43933
+ printDryRun(getConfig(opts), "PATCH", `/documents/${docId}/tabs/${tabId}`, {
43934
+ name
43935
+ });
43936
+ return;
43937
+ }
43938
+ try {
43939
+ const res = await getClient(opts).renameTab(docId, tabId, name);
43940
+ if (!res.ok) throw new Error(`HTTP ${res.status}`);
43941
+ output(res.data, opts.format);
43887
43942
  } catch (e) {
43888
- outputError(e, opts.quiet);
43943
+ outputError(e);
43889
43944
  }
43890
43945
  });
43891
43946
  }
@@ -44031,9 +44086,9 @@ function registerSheetsImportCommand(parent) {
44031
44086
  const res = await getClient(opts).batchCells(docId, localOpts.tab, cells);
44032
44087
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
44033
44088
  const result = typeof res.data === "object" && res.data !== null ? { imported: cellCount, ...res.data } : { imported: cellCount };
44034
- output(result, opts.format, opts.quiet);
44089
+ output(result, opts.format);
44035
44090
  } catch (e) {
44036
- outputError(e, opts.quiet);
44091
+ outputError(e);
44037
44092
  }
44038
44093
  });
44039
44094
  }
@@ -44074,14 +44129,14 @@ function registerSheetsExportCommand(parent) {
44074
44129
  }
44075
44130
  }
44076
44131
  } catch (e) {
44077
- outputError(e, opts.quiet);
44132
+ outputError(e);
44078
44133
  }
44079
44134
  });
44080
44135
  }
44081
44136
 
44082
44137
  // src/commands/sheets.ts
44083
- function registerSheetsCommand(program2) {
44084
- const sheets = program2.command("sheets").alias("sheet").alias("spreadsheet").alias("spreadsheets").description("Spreadsheet commands");
44138
+ function registerSheetsCommand(program) {
44139
+ const sheets = program.command("sheets").alias("sheet").alias("spreadsheet").alias("spreadsheets").description("Spreadsheet commands");
44085
44140
  registerTabsCommand(sheets);
44086
44141
  registerCellsCommand(sheets);
44087
44142
  registerSheetsImportCommand(sheets);
@@ -99408,8 +99463,8 @@ async function exportPptxCli(deck, opts = {}) {
99408
99463
  }
99409
99464
 
99410
99465
  // src/commands/slides.ts
99411
- function registerSlidesCommand(program2) {
99412
- const slides = program2.command("slides").alias("slide").alias("deck").description("Manage slide decks");
99466
+ function registerSlidesCommand(program) {
99467
+ const slides = program.command("slides").alias("slide").alias("deck").description("Manage slide decks");
99413
99468
  slides.command("list").description("List slide decks in workspace").action(async function() {
99414
99469
  const opts = getGlobalOpts(this);
99415
99470
  try {
@@ -99421,9 +99476,9 @@ function registerSlidesCommand(program2) {
99421
99476
  (d) => d.type === "slides"
99422
99477
  );
99423
99478
  }
99424
- output(data, opts.format, opts.quiet);
99479
+ output(data, opts.format);
99425
99480
  } catch (e) {
99426
- outputError(e, opts.quiet);
99481
+ outputError(e);
99427
99482
  }
99428
99483
  });
99429
99484
  slides.command("create <title>").description("Create a new slide deck").action(async function(title) {
@@ -99438,9 +99493,9 @@ function registerSlidesCommand(program2) {
99438
99493
  }
99439
99494
  const res = await getClient(opts).createDocument(title, "slides");
99440
99495
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
99441
- output(res.data, opts.format, opts.quiet);
99496
+ output(res.data, opts.format);
99442
99497
  } catch (e) {
99443
- outputError(e, opts.quiet);
99498
+ outputError(e);
99444
99499
  }
99445
99500
  });
99446
99501
  slides.command("get <doc-id>").description("Show slide deck metadata").action(async function(docId) {
@@ -99448,9 +99503,9 @@ function registerSlidesCommand(program2) {
99448
99503
  try {
99449
99504
  const res = await getClient(opts).getDocument(docId);
99450
99505
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
99451
- output(res.data, opts.format, opts.quiet);
99506
+ output(res.data, opts.format);
99452
99507
  } catch (e) {
99453
- outputError(e, opts.quiet);
99508
+ outputError(e);
99454
99509
  }
99455
99510
  });
99456
99511
  slides.command("rename <doc-id> <title>").description("Rename a slide deck").action(async function(docId, title) {
@@ -99462,9 +99517,9 @@ function registerSlidesCommand(program2) {
99462
99517
  try {
99463
99518
  const res = await getClient(opts).updateDocument(docId, title);
99464
99519
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
99465
- output(res.data, opts.format, opts.quiet);
99520
+ output(res.data, opts.format);
99466
99521
  } catch (e) {
99467
- outputError(e, opts.quiet);
99522
+ outputError(e);
99468
99523
  }
99469
99524
  });
99470
99525
  slides.command("delete <doc-id>").description("Delete a slide deck").action(async function(docId) {
@@ -99476,9 +99531,9 @@ function registerSlidesCommand(program2) {
99476
99531
  try {
99477
99532
  const res = await getClient(opts).deleteDocument(docId);
99478
99533
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
99479
- output(res.data, opts.format, opts.quiet);
99534
+ output(res.data, opts.format);
99480
99535
  } catch (e) {
99481
- outputError(e, opts.quiet);
99536
+ outputError(e);
99482
99537
  }
99483
99538
  });
99484
99539
  slides.command("content <doc-id>").description("Read deck content as JSON, Markdown, or plain text").option("--notes", "Include speaker notes (md/text)", false).option("--out <file>", "Output file (- for stdout)").option("--force", "Overwrite existing output file", false).action(async function(docId) {
@@ -99509,7 +99564,7 @@ function registerSlidesCommand(program2) {
99509
99564
  quiet: opts.quiet
99510
99565
  });
99511
99566
  } catch (e) {
99512
- outputError(e, opts.quiet);
99567
+ outputError(e);
99513
99568
  }
99514
99569
  });
99515
99570
  slides.command("export <doc-id> <file>").description("Export a slide deck to PPTX").option("--force", "Overwrite existing output file", false).action(async function(docId, file) {
@@ -99540,7 +99595,7 @@ function registerSlidesCommand(program2) {
99540
99595
  const bytes = await exportPptxCli(res.data, { imageFetcher });
99541
99596
  writeBinary(bytes, file, { force: local.force, quiet: opts.quiet });
99542
99597
  } catch (e) {
99543
- outputError(e, opts.quiet);
99598
+ outputError(e);
99544
99599
  }
99545
99600
  });
99546
99601
  registerSlidesImportCommand(slides);
@@ -99565,7 +99620,7 @@ function registerSlidesImportCommand(slides) {
99565
99620
  );
99566
99621
  if (result.exitCode !== 0) process.exitCode = result.exitCode;
99567
99622
  } catch (e) {
99568
- outputError(e, opts.quiet);
99623
+ outputError(e);
99569
99624
  }
99570
99625
  });
99571
99626
  }
@@ -99762,8 +99817,8 @@ function runNotesContent(args, io2 = defaultNotesContentIO) {
99762
99817
  }
99763
99818
 
99764
99819
  // src/commands/notes.ts
99765
- function registerNotesCommand(program2) {
99766
- const notes = program2.command("notes").alias("note").description("Manage markdown notes");
99820
+ function registerNotesCommand(program) {
99821
+ const notes = program.command("notes").alias("note").description("Manage markdown notes");
99767
99822
  notes.command("list").description("List notes in workspace").action(async function() {
99768
99823
  const opts = getGlobalOpts(this);
99769
99824
  try {
@@ -99775,9 +99830,9 @@ function registerNotesCommand(program2) {
99775
99830
  (d) => d.type === "note"
99776
99831
  );
99777
99832
  }
99778
- output(data, opts.format, opts.quiet);
99833
+ output(data, opts.format);
99779
99834
  } catch (e) {
99780
- outputError(e, opts.quiet);
99835
+ outputError(e);
99781
99836
  }
99782
99837
  });
99783
99838
  notes.command("create <title>").description("Create a new note").action(async function(title) {
@@ -99792,9 +99847,9 @@ function registerNotesCommand(program2) {
99792
99847
  }
99793
99848
  const res = await getClient(opts).createDocument(title, "note");
99794
99849
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
99795
- output(res.data, opts.format, opts.quiet);
99850
+ output(res.data, opts.format);
99796
99851
  } catch (e) {
99797
- outputError(e, opts.quiet);
99852
+ outputError(e);
99798
99853
  }
99799
99854
  });
99800
99855
  notes.command("get <doc-id>").description("Show note metadata").action(async function(docId) {
@@ -99802,9 +99857,9 @@ function registerNotesCommand(program2) {
99802
99857
  try {
99803
99858
  const res = await getClient(opts).getDocument(docId);
99804
99859
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
99805
- output(res.data, opts.format, opts.quiet);
99860
+ output(res.data, opts.format);
99806
99861
  } catch (e) {
99807
- outputError(e, opts.quiet);
99862
+ outputError(e);
99808
99863
  }
99809
99864
  });
99810
99865
  notes.command("rename <doc-id> <title>").description("Rename a note").action(async function(docId, title) {
@@ -99816,9 +99871,9 @@ function registerNotesCommand(program2) {
99816
99871
  try {
99817
99872
  const res = await getClient(opts).updateDocument(docId, title);
99818
99873
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
99819
- output(res.data, opts.format, opts.quiet);
99874
+ output(res.data, opts.format);
99820
99875
  } catch (e) {
99821
- outputError(e, opts.quiet);
99876
+ outputError(e);
99822
99877
  }
99823
99878
  });
99824
99879
  notes.command("delete <doc-id>").description("Delete a note").action(async function(docId) {
@@ -99830,9 +99885,9 @@ function registerNotesCommand(program2) {
99830
99885
  try {
99831
99886
  const res = await getClient(opts).deleteDocument(docId);
99832
99887
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
99833
- output(res.data, opts.format, opts.quiet);
99888
+ output(res.data, opts.format);
99834
99889
  } catch (e) {
99835
- outputError(e, opts.quiet);
99890
+ outputError(e);
99836
99891
  }
99837
99892
  });
99838
99893
  notes.command("content <doc-id>").description("Read note content as JSON or Markdown").option("--out <file>", "Output file (- for stdout)").option("--force", "Overwrite existing output file", false).action(async function(docId) {
@@ -99862,7 +99917,7 @@ function registerNotesCommand(program2) {
99862
99917
  quiet: opts.quiet
99863
99918
  });
99864
99919
  } catch (e) {
99865
- outputError(e, opts.quiet);
99920
+ outputError(e);
99866
99921
  }
99867
99922
  });
99868
99923
  notes.command("export <doc-id> <file>").description("Export a note to Markdown").option("--force", "Overwrite existing output file", false).action(async function(docId, file) {
@@ -99902,7 +99957,7 @@ function registerNotesCommand(program2) {
99902
99957
  quiet: opts.quiet
99903
99958
  });
99904
99959
  } catch (e) {
99905
- outputError(e, opts.quiet);
99960
+ outputError(e);
99906
99961
  }
99907
99962
  });
99908
99963
  registerNotesImportCommand(notes);
@@ -99925,7 +99980,7 @@ function registerNotesImportCommand(notes) {
99925
99980
  );
99926
99981
  if (result.exitCode !== 0) process.exitCode = result.exitCode;
99927
99982
  } catch (e) {
99928
- outputError(e, opts.quiet);
99983
+ outputError(e);
99929
99984
  }
99930
99985
  });
99931
99986
  }
@@ -99978,7 +100033,11 @@ var defaultFilesUploadIO = {
99978
100033
  sizeOf: (path) => statSync(path).size
99979
100034
  };
99980
100035
  async function runFilesUpload(args, client, io2 = defaultFilesUploadIO) {
99981
- const { file, title, quiet = false, dryRun = false } = args;
100036
+ const { file, title, folder, quiet = false, dryRun = false } = args;
100037
+ const fields = {
100038
+ ...title ? { title } : {},
100039
+ ...folder ? { folderId: folder } : {}
100040
+ };
99982
100041
  if (file === "-") {
99983
100042
  io2.stderr(
99984
100043
  errorJson(
@@ -100015,7 +100074,10 @@ async function runFilesUpload(args, client, io2 = defaultFilesUploadIO) {
100015
100074
  path: "/files",
100016
100075
  body: {
100017
100076
  file: `<${size} bytes of ${fileName}>`,
100018
- title: title ?? basename4(fileName, extname9(fileName))
100077
+ // The server defaults the title to the whole filename, extension
100078
+ // included — a blob document *is* the file.
100079
+ title: title ?? fileName,
100080
+ ...folder ? { folderId: folder } : {}
100019
100081
  }
100020
100082
  },
100021
100083
  null,
@@ -100040,12 +100102,7 @@ async function runFilesUpload(args, client, io2 = defaultFilesUploadIO) {
100040
100102
  );
100041
100103
  return { exitCode: 1 };
100042
100104
  }
100043
- const res = await client.uploadFileDocument(
100044
- bytes,
100045
- fileName,
100046
- mimeType,
100047
- title
100048
- );
100105
+ const res = await client.uploadFileDocument(bytes, fileName, mimeType, fields);
100049
100106
  if (!res.ok) {
100050
100107
  io2.stderr(
100051
100108
  JSON.stringify(res.data ?? { error: { code: "HTTP_ERROR" } }, null, 2)
@@ -100086,9 +100143,15 @@ async function runFilesDownload(args, client, io2 = defaultBinaryIO) {
100086
100143
 
100087
100144
  // src/commands/files.ts
100088
100145
  var BLOB_TYPES = /* @__PURE__ */ new Set(["file", "pdf", "image"]);
100089
- function registerFilesCommand(program2) {
100090
- const files = program2.command("files").alias("file").description("Upload and download files stored as documents");
100091
- files.command("upload <file>").description("Upload any file as a document").option("--title <title>", "Document title (default: file basename)").action(async function(file) {
100146
+ function registerFilesCommand(program) {
100147
+ const files = program.command("files").alias("file").description("Upload and download files stored as documents");
100148
+ files.command("upload <file>").description("Upload any file as a document").option(
100149
+ "--title <title>",
100150
+ "Document title (default: the filename, extension included)"
100151
+ ).option(
100152
+ "--folder <id>",
100153
+ "Folder to upload into (default: the workspace root)"
100154
+ ).action(async function(file) {
100092
100155
  const opts = getGlobalOpts(this);
100093
100156
  const local = this.opts();
100094
100157
  try {
@@ -100096,6 +100159,7 @@ function registerFilesCommand(program2) {
100096
100159
  {
100097
100160
  file,
100098
100161
  title: local.title,
100162
+ folder: local.folder,
100099
100163
  quiet: opts.quiet,
100100
100164
  dryRun: opts.dryRun
100101
100165
  },
@@ -100103,7 +100167,7 @@ function registerFilesCommand(program2) {
100103
100167
  );
100104
100168
  if (result.exitCode !== 0) process.exitCode = result.exitCode;
100105
100169
  } catch (e) {
100106
- outputError(e, opts.quiet);
100170
+ outputError(e);
100107
100171
  }
100108
100172
  });
100109
100173
  files.command("download <doc-id> [out]").description(
@@ -100122,7 +100186,7 @@ function registerFilesCommand(program2) {
100122
100186
  );
100123
100187
  if (result.exitCode !== 0) process.exitCode = result.exitCode;
100124
100188
  } catch (e) {
100125
- outputError(e, opts.quiet);
100189
+ outputError(e);
100126
100190
  }
100127
100191
  });
100128
100192
  files.command("list").description("List blob documents (file, pdf, image) in workspace").option("--type <type>", "Filter by a single type (file|pdf|image)").action(async function() {
@@ -100142,9 +100206,9 @@ function registerFilesCommand(program2) {
100142
100206
  (d) => local.type ? d.type === local.type : BLOB_TYPES.has(d.type ?? "")
100143
100207
  );
100144
100208
  }
100145
- output(data, opts.format, opts.quiet);
100209
+ output(data, opts.format);
100146
100210
  } catch (e) {
100147
- outputError(e, opts.quiet);
100211
+ outputError(e);
100148
100212
  }
100149
100213
  });
100150
100214
  files.command("get <doc-id>").description("Show file document metadata").action(async function(docId) {
@@ -100152,9 +100216,9 @@ function registerFilesCommand(program2) {
100152
100216
  try {
100153
100217
  const res = await getClient(opts).getDocument(docId);
100154
100218
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
100155
- output(res.data, opts.format, opts.quiet);
100219
+ output(res.data, opts.format);
100156
100220
  } catch (e) {
100157
- outputError(e, opts.quiet);
100221
+ outputError(e);
100158
100222
  }
100159
100223
  });
100160
100224
  files.command("rename <doc-id> <title>").description("Rename a file document").action(async function(docId, title) {
@@ -100166,9 +100230,9 @@ function registerFilesCommand(program2) {
100166
100230
  try {
100167
100231
  const res = await getClient(opts).updateDocument(docId, title);
100168
100232
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
100169
- output(res.data, opts.format, opts.quiet);
100233
+ output(res.data, opts.format);
100170
100234
  } catch (e) {
100171
- outputError(e, opts.quiet);
100235
+ outputError(e);
100172
100236
  }
100173
100237
  });
100174
100238
  files.command("delete <doc-id>").description("Delete a file document (and its stored bytes)").action(async function(docId) {
@@ -100180,24 +100244,24 @@ function registerFilesCommand(program2) {
100180
100244
  try {
100181
100245
  const res = await getClient(opts).deleteDocument(docId);
100182
100246
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
100183
- output(res.data, opts.format, opts.quiet);
100247
+ output(res.data, opts.format);
100184
100248
  } catch (e) {
100185
- outputError(e, opts.quiet);
100249
+ outputError(e);
100186
100250
  }
100187
100251
  });
100188
100252
  }
100189
100253
 
100190
100254
  // src/commands/api-keys.ts
100191
- function registerApiKeysCommand(program2) {
100192
- const apiKey = program2.command("api-keys").alias("api-key").description("Manage API keys");
100255
+ function registerApiKeysCommand(program) {
100256
+ const apiKey = program.command("api-keys").alias("api-key").description("Manage API keys");
100193
100257
  apiKey.command("create <name>").description("Create a new API key").action(async function(name) {
100194
100258
  const opts = getGlobalOpts(this);
100195
100259
  try {
100196
100260
  const res = await getClient(opts).createApiKey(name);
100197
100261
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
100198
- output(res.data, opts.format, false);
100262
+ output(res.data, opts.format);
100199
100263
  } catch (e) {
100200
- outputError(e, opts.quiet);
100264
+ outputError(e);
100201
100265
  }
100202
100266
  });
100203
100267
  apiKey.command("list").description("List API keys in workspace").action(async function() {
@@ -100205,9 +100269,9 @@ function registerApiKeysCommand(program2) {
100205
100269
  try {
100206
100270
  const res = await getClient(opts).listApiKeys();
100207
100271
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
100208
- output(res.data, opts.format, opts.quiet);
100272
+ output(res.data, opts.format);
100209
100273
  } catch (e) {
100210
- outputError(e, opts.quiet);
100274
+ outputError(e);
100211
100275
  }
100212
100276
  });
100213
100277
  apiKey.command("revoke <key-id>").description("Revoke an API key").action(async function(keyId) {
@@ -100215,9 +100279,9 @@ function registerApiKeysCommand(program2) {
100215
100279
  try {
100216
100280
  const res = await getClient(opts).revokeApiKey(keyId);
100217
100281
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
100218
- output(res.data, opts.format, opts.quiet);
100282
+ output(res.data, opts.format);
100219
100283
  } catch (e) {
100220
- outputError(e, opts.quiet);
100284
+ outputError(e);
100221
100285
  }
100222
100286
  });
100223
100287
  }
@@ -100633,6 +100697,39 @@ var registry = [
100633
100697
  response: { type: "array", items: { id: "string", name: "string", type: "string" } },
100634
100698
  aliases: ["tab.list", "tabs.list", "sheet.tabs.list", "sheet.tab.list", "sheets.tab.list"]
100635
100699
  },
100700
+ {
100701
+ name: "sheets.tabs.create",
100702
+ description: "Create a new sheet tab",
100703
+ safety: "write",
100704
+ parameters: {
100705
+ "doc-id": { type: "string", required: true, description: "Document ID" },
100706
+ name: {
100707
+ type: "string",
100708
+ required: false,
100709
+ description: "Tab name (omit for the next SheetN)"
100710
+ },
100711
+ "--type": {
100712
+ type: "string",
100713
+ required: false,
100714
+ description: 'Tab type; only "sheet" is supported',
100715
+ default: "sheet"
100716
+ }
100717
+ },
100718
+ response: { id: "string", name: "string", type: "string" },
100719
+ aliases: ["tab.create", "tabs.create", "sheet.tabs.create", "sheet.tab.create", "sheets.tab.create"]
100720
+ },
100721
+ {
100722
+ name: "sheets.tabs.rename",
100723
+ description: "Rename a tab",
100724
+ safety: "write",
100725
+ parameters: {
100726
+ "doc-id": { type: "string", required: true, description: "Document ID" },
100727
+ "tab-id": { type: "string", required: true, description: "Tab ID" },
100728
+ name: { type: "string", required: true, description: "New tab name" }
100729
+ },
100730
+ response: { id: "string", name: "string", type: "string" },
100731
+ aliases: ["tab.rename", "tabs.rename", "sheet.tabs.rename", "sheet.tab.rename", "sheets.tab.rename"]
100732
+ },
100636
100733
  {
100637
100734
  name: "sheets.cells.get",
100638
100735
  description: "Get cells from a spreadsheet tab",
@@ -100756,8 +100853,8 @@ function getAllCommandSchemas() {
100756
100853
  function toSchemaListPayload(commands, format2) {
100757
100854
  return format2 === "json" ? { commands } : commands;
100758
100855
  }
100759
- function registerSchemaCommand(program2) {
100760
- program2.command("schema [command]").description("Describe command parameters and response shape").action(function(commandName) {
100856
+ function registerSchemaCommand(program) {
100857
+ program.command("schema [command]").description("Describe command parameters and response shape").action(function(commandName) {
100761
100858
  const opts = getGlobalOpts(this);
100762
100859
  if (commandName) {
100763
100860
  const schema = getCommandSchema(commandName);
@@ -100772,18 +100869,14 @@ function registerSchemaCommand(program2) {
100772
100869
  process.exitCode = 1;
100773
100870
  return;
100774
100871
  }
100775
- output(schema, opts.format, opts.quiet);
100872
+ output(schema, opts.format);
100776
100873
  } else {
100777
100874
  const commands = getAllCommandSchemas().map((c) => ({
100778
100875
  name: c.name,
100779
100876
  description: c.description,
100780
100877
  safety: c.safety
100781
100878
  }));
100782
- output(
100783
- toSchemaListPayload(commands, opts.format),
100784
- opts.format,
100785
- opts.quiet
100786
- );
100879
+ output(toSchemaListPayload(commands, opts.format), opts.format);
100787
100880
  }
100788
100881
  });
100789
100882
  }
@@ -100791,8 +100884,8 @@ function registerSchemaCommand(program2) {
100791
100884
  // src/commands/login.ts
100792
100885
  import { createServer } from "http";
100793
100886
  import { createInterface as createInterface4 } from "readline";
100794
- function registerLoginCommand(program2) {
100795
- program2.command("login").description("Log in via GitHub OAuth in the browser").action(async function() {
100887
+ function registerLoginCommand(program) {
100888
+ program.command("login").description("Log in via GitHub OAuth in the browser").action(async function() {
100796
100889
  const parentOpts = this.optsWithGlobals();
100797
100890
  const server = (parentOpts.server ?? DEFAULT_SERVER).replace(/\/$/, "");
100798
100891
  const existing = loadSession();
@@ -100997,16 +101090,16 @@ function startCallbackServer() {
100997
101090
  }
100998
101091
 
100999
101092
  // src/commands/logout.ts
101000
- function registerLogoutCommand(program2) {
101001
- program2.command("logout").description("Log out and clear session").action(() => {
101093
+ function registerLogoutCommand(program) {
101094
+ program.command("logout").description("Log out and clear session").action(() => {
101002
101095
  clearSession();
101003
101096
  console.log("Logged out.");
101004
101097
  });
101005
101098
  }
101006
101099
 
101007
101100
  // src/commands/status.ts
101008
- function registerStatusCommand(program2) {
101009
- program2.command("status").description("Show current auth state").action(() => {
101101
+ function registerStatusCommand(program) {
101102
+ program.command("status").description("Show current auth state").action(() => {
101010
101103
  const session = loadSession();
101011
101104
  if (!session) {
101012
101105
  console.log("Not logged in. Run `wafflebase login`.");
@@ -101046,8 +101139,8 @@ function findWorkspace(workspaces, query) {
101046
101139
  if (byPrefix.length === 1) return byPrefix[0];
101047
101140
  return void 0;
101048
101141
  }
101049
- function registerCtxCommand(program2) {
101050
- const ctx = program2.command("ctx").description("Workspace context switching");
101142
+ function registerCtxCommand(program) {
101143
+ const ctx = program.command("ctx").description("Workspace context switching");
101051
101144
  ctx.command("list").description("List workspaces").action(() => {
101052
101145
  const session = loadSession();
101053
101146
  if (!session) {
@@ -101075,20 +101168,32 @@ function registerCtxCommand(program2) {
101075
101168
  });
101076
101169
  }
101077
101170
 
101171
+ // src/cli.ts
101172
+ function buildProgram() {
101173
+ const program = createProgram();
101174
+ registerLoginCommand(program);
101175
+ registerLogoutCommand(program);
101176
+ registerStatusCommand(program);
101177
+ registerCtxCommand(program);
101178
+ registerDocsCommand(program);
101179
+ registerSheetsCommand(program);
101180
+ registerSlidesCommand(program);
101181
+ registerNotesCommand(program);
101182
+ registerFilesCommand(program);
101183
+ registerApiKeysCommand(program);
101184
+ registerSchemaCommand(program);
101185
+ return program;
101186
+ }
101187
+ async function runCli(program = buildProgram(), argv) {
101188
+ try {
101189
+ await program.parseAsync(argv);
101190
+ } catch (e) {
101191
+ outputError(e);
101192
+ }
101193
+ }
101194
+
101078
101195
  // src/bin.ts
101079
- var program = createProgram();
101080
- registerLoginCommand(program);
101081
- registerLogoutCommand(program);
101082
- registerStatusCommand(program);
101083
- registerCtxCommand(program);
101084
- registerDocsCommand(program);
101085
- registerSheetsCommand(program);
101086
- registerSlidesCommand(program);
101087
- registerNotesCommand(program);
101088
- registerFilesCommand(program);
101089
- registerApiKeysCommand(program);
101090
- registerSchemaCommand(program);
101091
- program.parse();
101196
+ void runCli();
101092
101197
  /*!
101093
101198
 
101094
101199
  JSZip v3.10.1 - A JavaScript class for generating and reading zip files
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wafflebase/cli",
3
- "version": "0.6.3",
3
+ "version": "0.6.4",
4
4
  "description": "CLI for Wafflebase spreadsheet API",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -31,8 +31,8 @@
31
31
  "tsx": "^4.19.0",
32
32
  "typescript": "^5.9.3",
33
33
  "vitest": "^4.1.8",
34
- "@wafflebase/docs": "0.6.3",
35
- "@wafflebase/slides": "0.6.3"
34
+ "@wafflebase/docs": "0.6.4",
35
+ "@wafflebase/slides": "0.6.4"
36
36
  },
37
37
  "scripts": {
38
38
  "build": "tsup",