@wafflebase/cli 0.3.5 → 0.3.7

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 (51) hide show
  1. package/README.md +129 -0
  2. package/dist/bin.js +6 -12
  3. package/dist/client/http-client.d.ts +4 -1
  4. package/dist/client/http-client.js +12 -2
  5. package/dist/commands/api-keys.d.ts +2 -0
  6. package/dist/commands/{api-key.js → api-keys.js} +5 -2
  7. package/dist/commands/cells.d.ts +2 -0
  8. package/dist/commands/{cell.js → cells.js} +5 -2
  9. package/dist/commands/docs.d.ts +3 -0
  10. package/dist/commands/docs.js +306 -0
  11. package/dist/commands/sheets-export.d.ts +2 -0
  12. package/dist/commands/{export.js → sheets-export.js} +2 -2
  13. package/dist/commands/sheets-import.d.ts +2 -0
  14. package/dist/commands/{import.js → sheets-import.js} +2 -2
  15. package/dist/commands/sheets.d.ts +2 -0
  16. package/dist/commands/sheets.js +17 -0
  17. package/dist/commands/tabs.d.ts +2 -0
  18. package/dist/commands/{tab.js → tabs.js} +2 -2
  19. package/dist/docs/content.d.ts +37 -0
  20. package/dist/docs/content.js +90 -0
  21. package/dist/docs/docx-export.d.ts +23 -0
  22. package/dist/docs/docx-export.js +14 -0
  23. package/dist/docs/docx-import.d.ts +36 -0
  24. package/dist/docs/docx-import.js +70 -0
  25. package/dist/docs/dom-polyfill.d.ts +1 -0
  26. package/dist/docs/dom-polyfill.js +29 -0
  27. package/dist/docs/fontkit-measurer.d.ts +41 -0
  28. package/dist/docs/fontkit-measurer.js +64 -0
  29. package/dist/docs/import.d.ts +72 -0
  30. package/dist/docs/import.js +146 -0
  31. package/dist/docs/page-range.d.ts +29 -0
  32. package/dist/docs/page-range.js +74 -0
  33. package/dist/docs/page-slice.d.ts +45 -0
  34. package/dist/docs/page-slice.js +61 -0
  35. package/dist/docs/paginate.d.ts +13 -0
  36. package/dist/docs/paginate.js +19 -0
  37. package/dist/docs/pdf-export.d.ts +38 -0
  38. package/dist/docs/pdf-export.js +91 -0
  39. package/dist/output/binary.d.ts +37 -0
  40. package/dist/output/binary.js +47 -0
  41. package/dist/output/formatter.js +15 -1
  42. package/dist/schema/registry.d.ts +27 -0
  43. package/dist/schema/registry.js +103 -23
  44. package/package.json +7 -2
  45. package/dist/commands/api-key.d.ts +0 -2
  46. package/dist/commands/cell.d.ts +0 -2
  47. package/dist/commands/document.d.ts +0 -2
  48. package/dist/commands/document.js +0 -93
  49. package/dist/commands/export.d.ts +0 -2
  50. package/dist/commands/import.d.ts +0 -2
  51. package/dist/commands/tab.d.ts +0 -2
@@ -38,33 +38,40 @@ const registry = [
38
38
  },
39
39
  response: { workspace: 'string' },
40
40
  },
41
+ // Docs (word-processor) namespace
41
42
  {
42
- name: 'doc.list',
43
+ name: 'docs.list',
43
44
  description: 'List documents in workspace',
44
45
  safety: 'read-only',
45
- parameters: {},
46
- response: { type: 'array', items: { id: 'string', title: 'string', createdAt: 'string' } },
46
+ parameters: {
47
+ '--type': { type: 'string', required: false, description: 'Filter by document type (doc|sheet)' },
48
+ },
49
+ response: { type: 'array', items: { id: 'string', title: 'string', type: 'string', createdAt: 'string' } },
50
+ aliases: ['doc.list', 'document.list', 'documents.list'],
47
51
  },
48
52
  {
49
- name: 'doc.create',
53
+ name: 'docs.create',
50
54
  description: 'Create a new document',
51
55
  safety: 'write',
52
56
  parameters: {
53
57
  title: { type: 'string', required: true, description: 'Document title' },
58
+ '--type': { type: 'string', required: false, description: 'Document type (doc|sheet)', default: 'sheet' },
54
59
  },
55
- response: { id: 'string', title: 'string' },
60
+ response: { id: 'string', title: 'string', type: 'string' },
61
+ aliases: ['doc.create', 'document.create', 'documents.create'],
56
62
  },
57
63
  {
58
- name: 'doc.get',
64
+ name: 'docs.get',
59
65
  description: 'Show document metadata',
60
66
  safety: 'read-only',
61
67
  parameters: {
62
68
  'doc-id': { type: 'string', required: true, description: 'Document ID' },
63
69
  },
64
- response: { id: 'string', title: 'string', createdAt: 'string' },
70
+ response: { id: 'string', title: 'string', type: 'string', createdAt: 'string' },
71
+ aliases: ['doc.get', 'document.get', 'documents.get'],
65
72
  },
66
73
  {
67
- name: 'doc.rename',
74
+ name: 'docs.rename',
68
75
  description: 'Rename a document',
69
76
  safety: 'write',
70
77
  parameters: {
@@ -72,27 +79,81 @@ const registry = [
72
79
  title: { type: 'string', required: true, description: 'New title' },
73
80
  },
74
81
  response: { id: 'string', title: 'string' },
82
+ aliases: ['doc.rename', 'document.rename', 'documents.rename'],
75
83
  },
76
84
  {
77
- name: 'doc.delete',
85
+ name: 'docs.delete',
78
86
  description: 'Delete a document',
79
87
  safety: 'destructive',
80
88
  parameters: {
81
89
  'doc-id': { type: 'string', required: true, description: 'Document ID' },
82
90
  },
83
91
  response: { id: 'string' },
92
+ aliases: ['doc.delete', 'document.delete', 'documents.delete'],
93
+ },
94
+ {
95
+ name: 'docs.content',
96
+ description: 'Read document content as JSON, Markdown, or plain text',
97
+ safety: 'read-only',
98
+ parameters: {
99
+ 'doc-id': { type: 'string', required: true, description: 'Document ID' },
100
+ '--format': { type: 'string', required: false, description: 'Output format (json|md|text)', default: 'json' },
101
+ '--pages': { type: 'string', required: false, description: 'Page range (e.g. 1-3,5)' },
102
+ '--include-header-footer': { type: 'boolean', required: false, description: 'Include header/footer (md/text)', default: 'false' },
103
+ '--inline-images': { type: 'boolean', required: false, description: 'Inline data: image URLs (md only)', default: 'false' },
104
+ '--out': { type: 'string', required: false, description: 'Output file (- for stdout)' },
105
+ '--force': { type: 'boolean', required: false, description: 'Overwrite existing output file', default: 'false' },
106
+ },
107
+ response: { type: 'object', description: 'Document JSON, Markdown text, or plaintext per --format' },
108
+ aliases: ['doc.content', 'document.content', 'documents.content'],
109
+ },
110
+ {
111
+ name: 'docs.export',
112
+ description: 'Export a document to PDF or DOCX',
113
+ safety: 'read-only',
114
+ parameters: {
115
+ 'doc-id': { type: 'string', required: true, description: 'Document ID' },
116
+ file: { type: 'string', required: true, description: 'Output path or - for stdout' },
117
+ '--format': { type: 'string', required: false, description: 'Output format (pdf|docx); default from extension' },
118
+ '--pages': { type: 'string', required: false, description: 'Page range (PDF only)' },
119
+ '--include-header-footer': { type: 'boolean', required: false, description: 'Include header/footer regions', default: 'true' },
120
+ '--force': { type: 'boolean', required: false, description: 'Overwrite existing output file', default: 'false' },
121
+ },
122
+ response: { type: 'binary', description: 'PDF or DOCX bytes' },
123
+ aliases: ['doc.export', 'document.export', 'documents.export'],
124
+ },
125
+ {
126
+ name: 'docs.import',
127
+ description: 'Import a .docx file as a new (or replacement) document',
128
+ // Default safety is `write` (create new doc); `--replace` flips it
129
+ // to destructive. Variants spell this out for skill agents.
130
+ safety: 'write',
131
+ parameters: {
132
+ file: { type: 'string', required: true, description: 'Source .docx path or - for stdin' },
133
+ '--title': { type: 'string', required: false, description: 'Document title (default: file basename)' },
134
+ '--replace': { type: 'string', required: false, description: 'Existing document ID to replace' },
135
+ '--yes': { type: 'boolean', required: false, description: 'Skip --replace confirmation', default: 'false' },
136
+ },
137
+ response: { id: 'string', title: 'string', replaced: 'boolean' },
138
+ variants: [
139
+ { when: 'default', safety: 'write', creates: 'new document' },
140
+ { when: '--replace given', safety: 'destructive', modifies: 'existing document content' },
141
+ ],
142
+ aliases: ['doc.import', 'document.import', 'documents.import'],
84
143
  },
144
+ // Sheets namespace — canonical names live under sheets.*
85
145
  {
86
- name: 'tab.list',
87
- description: 'List tabs in a document',
146
+ name: 'sheets.tabs.list',
147
+ description: 'List tabs in a spreadsheet document',
88
148
  safety: 'read-only',
89
149
  parameters: {
90
150
  'doc-id': { type: 'string', required: true, description: 'Document ID' },
91
151
  },
92
152
  response: { type: 'array', items: { id: 'string', name: 'string', type: 'string' } },
153
+ aliases: ['tab.list', 'tabs.list', 'sheet.tabs.list', 'sheet.tab.list', 'sheets.tab.list'],
93
154
  },
94
155
  {
95
- name: 'cell.get',
156
+ name: 'sheets.cells.get',
96
157
  description: 'Get cells from a spreadsheet tab',
97
158
  safety: 'read-only',
98
159
  parameters: {
@@ -104,9 +165,10 @@ const registry = [
104
165
  type: 'array',
105
166
  items: { ref: 'string', value: 'string | null', formula: 'string | null', style: 'object | null' },
106
167
  },
168
+ aliases: ['cell.get', 'cells.get', 'sheet.cells.get', 'sheet.cell.get', 'sheets.cell.get'],
107
169
  },
108
170
  {
109
- name: 'cell.set',
171
+ name: 'sheets.cells.set',
110
172
  description: 'Set a single cell value',
111
173
  safety: 'write',
112
174
  parameters: {
@@ -116,9 +178,10 @@ const registry = [
116
178
  '--tab': { type: 'string', required: false, description: 'Tab ID', default: 'tab-1' },
117
179
  },
118
180
  response: { ref: 'string', value: 'string', formula: 'string | null' },
181
+ aliases: ['cell.set', 'cells.set', 'sheet.cells.set', 'sheet.cell.set', 'sheets.cell.set'],
119
182
  },
120
183
  {
121
- name: 'cell.batch',
184
+ name: 'sheets.cells.batch',
122
185
  description: 'Batch update cells',
123
186
  safety: 'write',
124
187
  parameters: {
@@ -127,9 +190,10 @@ const registry = [
127
190
  '--data': { type: 'string', required: false, description: 'JSON data (or pipe from stdin)' },
128
191
  },
129
192
  response: { updated: 'number' },
193
+ aliases: ['cell.batch', 'cells.batch', 'sheet.cells.batch', 'sheet.cell.batch', 'sheets.cell.batch'],
130
194
  },
131
195
  {
132
- name: 'cell.delete',
196
+ name: 'sheets.cells.delete',
133
197
  description: 'Delete a single cell',
134
198
  safety: 'destructive',
135
199
  parameters: {
@@ -138,10 +202,11 @@ const registry = [
138
202
  '--tab': { type: 'string', required: false, description: 'Tab ID', default: 'tab-1' },
139
203
  },
140
204
  response: { ref: 'string', deleted: 'boolean' },
205
+ aliases: ['cell.delete', 'cells.delete', 'sheet.cells.delete', 'sheet.cell.delete', 'sheets.cell.delete'],
141
206
  },
142
207
  {
143
- name: 'import',
144
- description: 'Import CSV/JSON into a tab',
208
+ name: 'sheets.import',
209
+ description: 'Import CSV/JSON into a spreadsheet tab',
145
210
  safety: 'write',
146
211
  parameters: {
147
212
  'doc-id': { type: 'string', required: true, description: 'Document ID' },
@@ -151,10 +216,11 @@ const registry = [
151
216
  '--start': { type: 'string', required: false, description: 'Top-left cell', default: 'A1' },
152
217
  },
153
218
  response: { imported: 'number' },
219
+ aliases: ['import', 'sheet.import'],
154
220
  },
155
221
  {
156
- name: 'export',
157
- description: 'Export tab data to CSV/JSON',
222
+ name: 'sheets.export',
223
+ description: 'Export spreadsheet tab data to CSV/JSON',
158
224
  safety: 'read-only',
159
225
  parameters: {
160
226
  'doc-id': { type: 'string', required: true, description: 'Document ID' },
@@ -164,35 +230,49 @@ const registry = [
164
230
  '--file-format': { type: 'string', required: false, description: 'File format (csv, json)' },
165
231
  },
166
232
  response: { type: 'string', description: 'Formatted cell data' },
233
+ aliases: ['export', 'sheet.export'],
167
234
  },
235
+ // API keys namespace
168
236
  {
169
- name: 'api-key.create',
237
+ name: 'api-keys.create',
170
238
  description: 'Create a new API key',
171
239
  safety: 'write',
172
240
  parameters: {
173
241
  name: { type: 'string', required: true, description: 'Key name' },
174
242
  },
175
243
  response: { id: 'string', name: 'string', prefix: 'string', key: 'string' },
244
+ aliases: ['api-key.create'],
176
245
  },
177
246
  {
178
- name: 'api-key.list',
247
+ name: 'api-keys.list',
179
248
  description: 'List API keys in workspace',
180
249
  safety: 'read-only',
181
250
  parameters: {},
182
251
  response: { type: 'array', items: { id: 'string', name: 'string', prefix: 'string' } },
252
+ aliases: ['api-key.list'],
183
253
  },
184
254
  {
185
- name: 'api-key.revoke',
255
+ name: 'api-keys.revoke',
186
256
  description: 'Revoke an API key',
187
257
  safety: 'destructive',
188
258
  parameters: {
189
259
  'key-id': { type: 'string', required: true, description: 'API key ID' },
190
260
  },
191
261
  response: { id: 'string' },
262
+ aliases: ['api-key.revoke'],
192
263
  },
193
264
  ];
265
+ /**
266
+ * Look up a schema entry by canonical name or any registered alias.
267
+ * Aliases let scripts and skills written against the v0.3.x singular
268
+ * names (`cell.get`, `doc.list`, `import`) keep working after the
269
+ * v0.3.7 namespace shuffle.
270
+ */
194
271
  export function getCommandSchema(name) {
195
- return registry.find((c) => c.name === name);
272
+ const direct = registry.find((c) => c.name === name);
273
+ if (direct)
274
+ return direct;
275
+ return registry.find((c) => c.aliases?.includes(name));
196
276
  }
197
277
  export function getAllCommandSchemas() {
198
278
  return registry;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wafflebase/cli",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
4
4
  "description": "CLI for Wafflebase spreadsheet API",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -14,11 +14,16 @@
14
14
  "dist"
15
15
  ],
16
16
  "dependencies": {
17
+ "@xmldom/xmldom": "^0.9.10",
17
18
  "commander": "^13.0.0",
19
+ "fontkit": "^2.0.4",
18
20
  "open": "^11.0.0",
19
- "yaml": "^2.0.0"
21
+ "pdf-lib": "^1.17.1",
22
+ "yaml": "^2.0.0",
23
+ "@wafflebase/docs": "0.3.7"
20
24
  },
21
25
  "devDependencies": {
26
+ "@types/fontkit": "^2.0.0",
22
27
  "@types/node": "^25.4.0",
23
28
  "@vitest/coverage-v8": "3.1.1",
24
29
  "eslint": "^9.18.0",
@@ -1,2 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function registerApiKeyCommand(program: Command): void;
@@ -1,2 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function registerCellCommand(program: Command): void;
@@ -1,2 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function registerDocumentCommand(program: Command): void;
@@ -1,93 +0,0 @@
1
- import { getGlobalOpts, getClient, getConfig } from './root.js';
2
- import { output, outputError } from '../output/formatter.js';
3
- import { printDryRun } from '../client/dry-run.js';
4
- export function registerDocumentCommand(program) {
5
- const doc = program.command('document').alias('doc').description('Manage documents');
6
- doc
7
- .command('list')
8
- .description('List documents in workspace')
9
- .action(async function () {
10
- const opts = getGlobalOpts(this);
11
- try {
12
- const res = await getClient(opts).listDocuments();
13
- if (!res.ok)
14
- throw new Error(`HTTP ${res.status}`);
15
- output(res.data, opts.format, opts.quiet);
16
- }
17
- catch (e) {
18
- outputError(e, opts.quiet);
19
- }
20
- });
21
- doc
22
- .command('create <title>')
23
- .description('Create a new document')
24
- .action(async function (title) {
25
- const opts = getGlobalOpts(this);
26
- if (opts.dryRun) {
27
- printDryRun(getConfig(opts), 'POST', '/documents', { title });
28
- return;
29
- }
30
- try {
31
- const res = await getClient(opts).createDocument(title);
32
- if (!res.ok)
33
- throw new Error(`HTTP ${res.status}`);
34
- output(res.data, opts.format, opts.quiet);
35
- }
36
- catch (e) {
37
- outputError(e, opts.quiet);
38
- }
39
- });
40
- doc
41
- .command('get <doc-id>')
42
- .description('Show document metadata')
43
- .action(async function (docId) {
44
- const opts = getGlobalOpts(this);
45
- try {
46
- const res = await getClient(opts).getDocument(docId);
47
- if (!res.ok)
48
- throw new Error(`HTTP ${res.status}`);
49
- output(res.data, opts.format, opts.quiet);
50
- }
51
- catch (e) {
52
- outputError(e, opts.quiet);
53
- }
54
- });
55
- doc
56
- .command('rename <doc-id> <title>')
57
- .description('Rename a document')
58
- .action(async function (docId, title) {
59
- const opts = getGlobalOpts(this);
60
- if (opts.dryRun) {
61
- printDryRun(getConfig(opts), 'PATCH', `/documents/${docId}`, { title });
62
- return;
63
- }
64
- try {
65
- const res = await getClient(opts).updateDocument(docId, title);
66
- if (!res.ok)
67
- throw new Error(`HTTP ${res.status}`);
68
- output(res.data, opts.format, opts.quiet);
69
- }
70
- catch (e) {
71
- outputError(e, opts.quiet);
72
- }
73
- });
74
- doc
75
- .command('delete <doc-id>')
76
- .description('Delete a document')
77
- .action(async function (docId) {
78
- const opts = getGlobalOpts(this);
79
- if (opts.dryRun) {
80
- printDryRun(getConfig(opts), 'DELETE', `/documents/${docId}`);
81
- return;
82
- }
83
- try {
84
- const res = await getClient(opts).deleteDocument(docId);
85
- if (!res.ok)
86
- throw new Error(`HTTP ${res.status}`);
87
- output(res.data, opts.format, opts.quiet);
88
- }
89
- catch (e) {
90
- outputError(e, opts.quiet);
91
- }
92
- });
93
- }
@@ -1,2 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function registerExportCommand(program: Command): void;
@@ -1,2 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function registerImportCommand(program: Command): void;
@@ -1,2 +0,0 @@
1
- import { Command } from 'commander';
2
- export declare function registerTabCommand(program: Command): void;