maybeai-sheet-cli 0.7.0__tar.gz → 0.9.0__tar.gz

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 (62) hide show
  1. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/PKG-INFO +115 -44
  2. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/README.md +114 -43
  3. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/pyproject.toml +1 -1
  4. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/__init__.py +1 -1
  5. maybeai_sheet_cli-0.9.0/src/maybeai_sheet/chart_config.py +59 -0
  6. maybeai_sheet_cli-0.9.0/src/maybeai_sheet/chart_style_summary.py +461 -0
  7. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/cli.py +6 -0
  8. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/client.py +44 -3
  9. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/_phase2.py +43 -1
  10. maybeai_sheet_cli-0.7.0/src/maybeai_sheet/commands/style.py → maybeai_sheet_cli-0.9.0/src/maybeai_sheet/commands/chart.py +127 -65
  11. maybeai_sheet_cli-0.9.0/src/maybeai_sheet/commands/dashboard.py +492 -0
  12. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/excel_worksheet.py +50 -0
  13. maybeai_sheet_cli-0.9.0/src/maybeai_sheet/commands/image.py +505 -0
  14. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/range.py +42 -0
  15. maybeai_sheet_cli-0.9.0/src/maybeai_sheet/commands/style.py +587 -0
  16. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/workbook.py +24 -0
  17. maybeai_sheet_cli-0.9.0/src/maybeai_sheet/dashboard_plan.py +398 -0
  18. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/endpoints.py +47 -0
  19. maybeai_sheet_cli-0.9.0/tests/fixtures/benchmarks/build_fixtures.py +213 -0
  20. maybeai_sheet_cli-0.9.0/tests/fixtures/benchmarks/flat-records.xlsx +0 -0
  21. maybeai_sheet_cli-0.9.0/tests/fixtures/benchmarks/mixed-engine.xlsx +0 -0
  22. maybeai_sheet_cli-0.9.0/tests/fixtures/benchmarks/multi-table-layout.xlsx +0 -0
  23. maybeai_sheet_cli-0.9.0/tests/fixtures/benchmarks/rows.json +12 -0
  24. maybeai_sheet_cli-0.9.0/tests/fixtures/benchmarks/simple-grid.xlsx +0 -0
  25. maybeai_sheet_cli-0.9.0/tests/fixtures/benchmarks/simple-values.json +17 -0
  26. maybeai_sheet_cli-0.9.0/tests/test_benchmark_runner.py +154 -0
  27. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/tests/test_cli.py +81 -0
  28. maybeai_sheet_cli-0.9.0/tests/test_dashboard_plan.py +558 -0
  29. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/tests/test_endpoints.py +20 -0
  30. maybeai_sheet_cli-0.9.0/tests/test_phase2_cli.py +1984 -0
  31. maybeai_sheet_cli-0.7.0/tests/test_phase2_cli.py +0 -649
  32. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/.gitignore +0 -0
  33. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/__init__.py +0 -0
  34. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/cell.py +0 -0
  35. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/column.py +0 -0
  36. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/db_table.py +0 -0
  37. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/excel_table.py +0 -0
  38. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/file.py +0 -0
  39. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/formula.py +0 -0
  40. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/history.py +0 -0
  41. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/raw.py +0 -0
  42. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/row.py +0 -0
  43. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/share.py +0 -0
  44. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/sheet.py +0 -0
  45. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/table.py +0 -0
  46. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/commands/worksheet.py +0 -0
  47. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/config.py +0 -0
  48. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/errors.py +0 -0
  49. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/formatters.py +0 -0
  50. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/models/__init__.py +0 -0
  51. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/models/share.py +0 -0
  52. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/models/sheet.py +0 -0
  53. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/models/workbook.py +0 -0
  54. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/options.py +0 -0
  55. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/protocol.py +0 -0
  56. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/resolver.py +0 -0
  57. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/table_resolver.py +0 -0
  58. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/src/maybeai_sheet/update.py +0 -0
  59. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/tests/test_formatters.py +0 -0
  60. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/tests/test_resolver.py +0 -0
  61. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/tests/test_two_engine_cli.py +0 -0
  62. {maybeai_sheet_cli-0.7.0 → maybeai_sheet_cli-0.9.0}/tests/test_update.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maybeai-sheet-cli
3
- Version: 0.7.0
3
+ Version: 0.9.0
4
4
  Summary: CLI for common MaybeAI spreadsheet operations
5
5
  Project-URL: Homepage, https://github.com/OmniMCP-AI/maybeai-sheet-cli
6
6
  Project-URL: Repository, https://github.com/OmniMCP-AI/maybeai-sheet-cli
@@ -88,6 +88,12 @@ Optional global flags:
88
88
  - `--timeout <seconds>`
89
89
  - `--verbose`
90
90
 
91
+ Alias note:
92
+
93
+ - Prefer nested worksheet media/layout commands such as `mbs excel-worksheet style ...`
94
+ - The CLI also exposes compatibility shortcuts `mbs style ...`, `mbs image ...`,
95
+ `mbs chart ...`, and `mbs dashboard ...` for the same command groups
96
+
91
97
  ## Quick Start
92
98
 
93
99
  The examples below follow the target protocol names.
@@ -167,11 +173,33 @@ Search, style, inspect history, and export:
167
173
  ```bash
168
174
  mbs excel-worksheet range search --doc-id abc123 --worksheet-name Sheet1 --query revenue --max-results 20
169
175
  mbs excel-worksheet style freeze-panes --doc-id abc123 --worksheet-name Sheet1 --cell B2
176
+ mbs excel-worksheet style worksheet plan --doc-id abc123 --worksheet-name Sheet1 --mode auto_detect --spec worksheet_style.json
177
+ mbs excel-worksheet style worksheet apply --doc-id abc123 --worksheet-name Sheet1 --mode auto_detect --spec worksheet_style.json
178
+ mbs excel-worksheet image list --doc-id abc123 --worksheet-name Dashboard
179
+ mbs excel-worksheet chart list --doc-id abc123 --worksheet-name Dashboard
180
+ mbs excel-worksheet dashboard manifest --doc-id abc123 --worksheet-name Dashboard
181
+ mbs workbook calculate --doc-id abc123
182
+ mbs excel-worksheet calculate --doc-id abc123 --worksheet-name Sheet1
170
183
  mbs excel-worksheet range calculate --doc-id abc123 --worksheet-name Sheet1 --cell E2 --formula "=SUM(B2:D2)"
171
184
  mbs version list --doc-id abc123 --limit 10
172
185
  mbs workbook export --doc-id abc123 --out workbook.xlsx
173
186
  ```
174
187
 
188
+ The worksheet media/layout groups are available in both forms:
189
+
190
+ ```bash
191
+ mbs excel-worksheet chart list --doc-id abc123 --worksheet-name Dashboard
192
+ mbs chart list --doc-id abc123 --worksheet-name Dashboard
193
+ ```
194
+
195
+ Prefer the nested `excel-worksheet ...` form in docs and agent prompts when you
196
+ want the object model to stay explicit.
197
+
198
+ For chart specs authored as `type: "json"`, keep metadata `title` when the chart
199
+ needs an internal or custom-rendered title, and hide the visible container title
200
+ with `hide_title: true` or `spec.style.showContainerTitle: false` rather than
201
+ deleting `title`.
202
+
175
203
  ## Relationship
176
204
  1 workbok
177
205
  | \
@@ -216,6 +244,7 @@ mbs
216
244
  │ ├── list-user-workbooks API List user workbooks with bounded output.
217
245
  | list-worksheets API List worksheets, including engine.
218
246
  │ ├── search NOW Search user workbooks with bounded output.
247
+ │ ├── calculate NOW Recalculate formulas across the workbook.
219
248
  │ ├── export API Export workbook bytes.
220
249
  │ └── copy API Copy a workbook.
221
250
  │ ├── upload API Upload a file through workbook import flow.
@@ -226,6 +255,7 @@ mbs
226
255
 
227
256
  ├── excel_worksheet
228
257
  │ ├── read API Read the full range of the worksheet.
258
+ │ ├── calculate NOW Recalculate formulas in one worksheet.
229
259
  │ ├── list-table API Detect content-backed tables in a worksheet.
230
260
  │ ├── create API Create a worksheet, optionally with starter values.
231
261
  │ ├── update API Update worksheet metadata.
@@ -281,39 +311,40 @@ mbs
281
311
  │ └── append API Append columns.
282
312
 
283
313
  ├── excel_worksheet chart
284
- │ ├── list API List charts in a workbook or dashboard.
285
- │ ├── get API Read one chart spec and source binding.
314
+ │ ├── list NOW List charts in one worksheet.
315
+ │ ├── get NOW Read one chart spec and source binding.
286
316
  │ ├── preview PLAN Preview one chart from its spec/source binding.
287
- │ ├── create-config API Create one chart from a chart spec.
288
- │ ├── update API Update one chart from a chart spec.
317
+ │ ├── create-config NOW Create one chart from a chart spec.
318
+ │ ├── update NOW Update one chart from a chart spec.
289
319
  │ ├── refresh PLAN Refresh one chart from its current source binding.
290
- │ └── delete API Delete one chart.
320
+ │ └── delete NOW Delete one chart.
291
321
 
292
322
  ├── excel_worksheet dashboard
293
- │ ├── manifest PLAN Read dashboard, chart, metric, layout, and lineage metadata.
294
- │ ├── create-config PLAN Compose chart ids/specs into a dashboard config.
295
- │ ├── validate PLAN Validate dashboard layout, permissions, filters, and metrics.
296
- │ └── refresh PLAN Refresh dashboard charts from their current source bindings.
297
- │ └── delete
323
+ │ ├── manifest NOW Aggregate worksheet metadata and chart inventory for one dashboard sheet.
324
+ │ ├── create-config NOW Create a dashboard worksheet and compose charts from one spec.
325
+ │ ├── validate NOW Validate dashboard layout, worksheet target, and chart source fields locally.
326
+ │ └── refresh NOW Upsert dashboard charts from one spec and re-verify chart inventory.
298
327
 
299
328
 
300
- ├── excel_worksheet style
301
- │ ├── cell batch-set API Apply cell style batches from JSON.
302
- │ ├── columns-width API Set column widths.
303
- │ ├── rows-height API Set row heights.
304
- │ ├── freeze-panes API Freeze rows/columns using an A1 boundary.
305
- │ ├── gridlines toggle API Toggle worksheet gridlines.
306
- │ ├── auto-filter set API Set worksheet auto-filter range.
307
- │ ├── auto-filter remove API Remove worksheet auto-filter.
308
- │ ├── filter-values API Apply filter values.
309
- │ ├── conditional-formats set API Set conditional formatting rules.
310
- │ ├── worksheet plan API Generate a worksheet styling plan.
311
- │ └── worksheet apply API Apply a worksheet styling plan.
329
+ ├── excel-worksheet style
330
+ │ ├── cell batch-set NOW Apply cell style batches from JSON.
331
+ │ ├── columns-width NOW Set column widths.
332
+ │ ├── rows-height NOW Set row heights.
333
+ │ ├── freeze-panes NOW Freeze rows/columns using an A1 boundary.
334
+ │ ├── gridlines toggle NOW Toggle worksheet gridlines.
335
+ │ ├── auto-filter set NOW Set worksheet auto-filter range.
336
+ │ ├── auto-filter remove NOW Remove worksheet auto-filter.
337
+ │ ├── filter-values NOW Apply filter values.
338
+ │ ├── conditional-formats set NOW Set conditional formatting rules.
339
+ │ ├── worksheet plan NOW Generate a worksheet styling plan.
340
+ │ └── worksheet apply NOW Apply a worksheet styling plan.
312
341
 
313
- ├── excel_worksheet image
314
- │ ├── read API Read worksheet images.
315
- │ ├── insert API Add an image file.
316
- └── delete API Delete an image.
342
+ ├── excel_worksheet image
343
+ │ ├── list NOW List worksheet images from worksheet formatting metadata.
344
+ │ ├── read NOW Read one worksheet image by cell or picture id.
345
+ ├── replace NOW Replace one worksheet image in place.
346
+ │ ├── insert NOW Add an image file.
347
+ │ └── delete NOW Delete an image.
317
348
 
318
349
  ├── version
319
350
  │ ├── list API List workbook history with bounded output.
@@ -394,24 +425,65 @@ mbs excel-worksheet column append --doc-id abc123 --worksheet-name Actuals --val
394
425
  mbs excel-worksheet range lineage --doc-id abc123 --worksheet-name Model --cell E2 --format tree # API
395
426
 
396
427
  # formula
428
+ mbs workbook calculate --doc-id abc123 # API
429
+ mbs excel-worksheet calculate --doc-id abc123 --worksheet-name Model # API
397
430
  mbs excel-worksheet range calculate --doc-id abc123 --worksheet-name Model --cell E2 --formula "=SUM(B2:D2)" # API
398
431
  mbs excel-worksheet range set-formula --doc-id abc123 --worksheet-name Model --cell E2 --formula "=SUM(B2:D2)" # API
399
432
 
400
433
  # chart
401
- mbs excel-worksheet chart create-config --doc-id abc123 --worksheet-name Dashboard --cell J2 --spec chart.json # API
402
- mbs excel-worksheet chart refresh --doc-id abc123 --worksheet-name Dashboard --chart-id chart_monthly_revenue # PLAN
434
+ mbs excel-worksheet chart list --doc-id abc123 --worksheet-name Dashboard # NOW
435
+ mbs excel-worksheet chart get --doc-id abc123 --worksheet-name Dashboard --cell J2 # NOW
436
+ mbs excel-worksheet chart create-config --doc-id abc123 --worksheet-name Dashboard --cell J2 --spec chart.json # NOW
437
+ mbs excel-worksheet chart update --doc-id abc123 --worksheet-name Dashboard --cell J2 --chart-id rId1 --spec chart.json # NOW
438
+ mbs excel-worksheet chart delete --doc-id abc123 --worksheet-name Dashboard --chart-id rId1 # NOW
439
+
440
+ # recommended chart.json shape
441
+ # prefer top-level `"type": "json"` and put the renderer in `html`
442
+ # do not treat `"type": "line"` / `"bar"` / `"pie"` as the default authored form
443
+ # {
444
+ # "type": "json",
445
+ # "sql": "select Month, Revenue from Sheet1",
446
+ # "title": "Monthly Revenue",
447
+ # "legend": "bottom",
448
+ # "html": "{ library: 'echarts', handler: (data) => ({ xAxis: { type: 'category', data: data.map(r => r.Month) }, yAxis: { type: 'value' }, series: [{ type: 'line', data: data.map(r => Number(r.Revenue) || 0) }] }) }",
449
+ # "spec": { "style": { "title": "Monthly Revenue" } }
450
+ # }
403
451
 
404
452
  # dashboard
405
- mbs excel-worksheet dashboard manifest --doc-id abc123 --worksheet-name Dashboard --dashboard-id dash_revenue # PLAN
406
- mbs excel-worksheet dashboard create-config --doc-id abc123 --worksheet-name Dashboard --name "Revenue Dashboard" --spec dashboard.json # PLAN
407
- mbs excel-worksheet dashboard refresh --doc-id abc123 --worksheet-name Dashboard --dashboard-id dash_revenue # PLAN
453
+ mbs excel-worksheet dashboard validate --spec dashboard.json # NOW
454
+ mbs excel-worksheet dashboard manifest --doc-id abc123 --worksheet-name Dashboard # NOW
455
+ mbs excel-worksheet dashboard create-config --doc-id abc123 --spec dashboard.json --create-worksheet # NOW
456
+ mbs excel-worksheet dashboard refresh --doc-id abc123 --spec dashboard.json # NOW
457
+
458
+ # recommended dashboard.json chart entries
459
+ # {
460
+ # "worksheet_name": "Dashboard",
461
+ # "charts": [
462
+ # {
463
+ # "cell": "J2",
464
+ # "chart": {
465
+ # "type": "json",
466
+ # "sql": "select Month, Revenue from Sheet1",
467
+ # "title": "Monthly Revenue",
468
+ # "legend": "bottom",
469
+ # "html": "{ library: 'echarts', handler: (data) => ({ xAxis: { type: 'category', data: data.map(r => r.Month) }, yAxis: { type: 'value' }, series: [{ type: 'line', data: data.map(r => Number(r.Revenue) || 0) }] }) }"
470
+ # }
471
+ # }
472
+ # ]
473
+ # }
408
474
 
409
475
  # style
410
- mbs excel-worksheet style freeze-panes --doc-id abc123 --worksheet-name Actuals --cell B2 # API
411
- mbs excel-worksheet style conditional-formats set --doc-id abc123 --worksheet-name Actuals --spec conditional_formats.json # API
476
+ mbs excel-worksheet style freeze-panes --doc-id abc123 --worksheet-name Actuals --cell B2 # NOW
477
+ mbs excel-worksheet style cell batch-set --doc-id abc123 --worksheet-name Actuals --range A1:G1 --style header_style.json # NOW
478
+ mbs excel-worksheet style conditional-formats set --doc-id abc123 --worksheet-name Actuals --spec conditional_formats.json # NOW
479
+ mbs excel-worksheet style worksheet apply --doc-id abc123 --worksheet-name Actuals --mode auto_detect --spec worksheet_style.json # NOW
412
480
 
413
481
  # image
414
- mbs excel-worksheet image insert --doc-id abc123 --worksheet-name Dashboard --cell A1 --file logo.png # API
482
+ mbs excel-worksheet image list --doc-id abc123 --worksheet-name Dashboard # NOW
483
+ mbs excel-worksheet image read --doc-id abc123 --worksheet-name Dashboard --cell A1 --out logo.png # NOW
484
+ mbs excel-worksheet image insert --doc-id abc123 --worksheet-name Dashboard --cell A1 --file logo.png # NOW
485
+ mbs excel-worksheet image replace --doc-id abc123 --worksheet-name Dashboard --cell A1 --file logo_v2.png # NOW
486
+ mbs excel-worksheet image delete --doc-id abc123 --worksheet-name Dashboard --cell A1 # NOW
415
487
 
416
488
  # version
417
489
  mbs version list --doc-id abc123 --limit 10 # API
@@ -463,15 +535,14 @@ Relationship guide:
463
535
  - Use `excel-worksheet row` and `excel-worksheet column` for structural
464
536
  row/column changes.
465
537
  - Use `excel-worksheet style` for worksheet layout operations like freeze
466
- panes, filter ranges, widths, and heights.
467
- - Use `excel-table style` when the same styling operation should be scoped to a
468
- table's resolved worksheet range.
469
- - Use `excel-worksheet chart` for CRUD, preview, and refresh of individual
470
- source-backed visualizations before composing dashboards.
471
- - Use `excel-worksheet dashboard` to compose chart ids/specs into BI asset or
472
- dashboard worksheet lifecycles.
473
- - Use `excel-worksheet image` for lower-level report workflows after routed
474
- public API verification.
538
+ panes, filter ranges, widths, heights, gridlines, conditional formats, and
539
+ worksheet style planning/apply.
540
+ - Use `excel-worksheet chart` for list/get/create/update/delete of individual
541
+ source-backed visualizations.
542
+ - Use `excel-worksheet dashboard` for local validation and worksheet-level chart
543
+ orchestration such as manifest, create-config, and refresh.
544
+ - Use `excel-worksheet image` for list/read/insert/replace/delete image
545
+ workflows.
475
546
  - Use `version` for workbook history inspection and restore.
476
547
  - Use `share` for visibility and collaborator access.
477
548
 
@@ -64,6 +64,12 @@ Optional global flags:
64
64
  - `--timeout <seconds>`
65
65
  - `--verbose`
66
66
 
67
+ Alias note:
68
+
69
+ - Prefer nested worksheet media/layout commands such as `mbs excel-worksheet style ...`
70
+ - The CLI also exposes compatibility shortcuts `mbs style ...`, `mbs image ...`,
71
+ `mbs chart ...`, and `mbs dashboard ...` for the same command groups
72
+
67
73
  ## Quick Start
68
74
 
69
75
  The examples below follow the target protocol names.
@@ -143,11 +149,33 @@ Search, style, inspect history, and export:
143
149
  ```bash
144
150
  mbs excel-worksheet range search --doc-id abc123 --worksheet-name Sheet1 --query revenue --max-results 20
145
151
  mbs excel-worksheet style freeze-panes --doc-id abc123 --worksheet-name Sheet1 --cell B2
152
+ mbs excel-worksheet style worksheet plan --doc-id abc123 --worksheet-name Sheet1 --mode auto_detect --spec worksheet_style.json
153
+ mbs excel-worksheet style worksheet apply --doc-id abc123 --worksheet-name Sheet1 --mode auto_detect --spec worksheet_style.json
154
+ mbs excel-worksheet image list --doc-id abc123 --worksheet-name Dashboard
155
+ mbs excel-worksheet chart list --doc-id abc123 --worksheet-name Dashboard
156
+ mbs excel-worksheet dashboard manifest --doc-id abc123 --worksheet-name Dashboard
157
+ mbs workbook calculate --doc-id abc123
158
+ mbs excel-worksheet calculate --doc-id abc123 --worksheet-name Sheet1
146
159
  mbs excel-worksheet range calculate --doc-id abc123 --worksheet-name Sheet1 --cell E2 --formula "=SUM(B2:D2)"
147
160
  mbs version list --doc-id abc123 --limit 10
148
161
  mbs workbook export --doc-id abc123 --out workbook.xlsx
149
162
  ```
150
163
 
164
+ The worksheet media/layout groups are available in both forms:
165
+
166
+ ```bash
167
+ mbs excel-worksheet chart list --doc-id abc123 --worksheet-name Dashboard
168
+ mbs chart list --doc-id abc123 --worksheet-name Dashboard
169
+ ```
170
+
171
+ Prefer the nested `excel-worksheet ...` form in docs and agent prompts when you
172
+ want the object model to stay explicit.
173
+
174
+ For chart specs authored as `type: "json"`, keep metadata `title` when the chart
175
+ needs an internal or custom-rendered title, and hide the visible container title
176
+ with `hide_title: true` or `spec.style.showContainerTitle: false` rather than
177
+ deleting `title`.
178
+
151
179
  ## Relationship
152
180
  1 workbok
153
181
  | \
@@ -192,6 +220,7 @@ mbs
192
220
  │ ├── list-user-workbooks API List user workbooks with bounded output.
193
221
  | list-worksheets API List worksheets, including engine.
194
222
  │ ├── search NOW Search user workbooks with bounded output.
223
+ │ ├── calculate NOW Recalculate formulas across the workbook.
195
224
  │ ├── export API Export workbook bytes.
196
225
  │ └── copy API Copy a workbook.
197
226
  │ ├── upload API Upload a file through workbook import flow.
@@ -202,6 +231,7 @@ mbs
202
231
 
203
232
  ├── excel_worksheet
204
233
  │ ├── read API Read the full range of the worksheet.
234
+ │ ├── calculate NOW Recalculate formulas in one worksheet.
205
235
  │ ├── list-table API Detect content-backed tables in a worksheet.
206
236
  │ ├── create API Create a worksheet, optionally with starter values.
207
237
  │ ├── update API Update worksheet metadata.
@@ -257,39 +287,40 @@ mbs
257
287
  │ └── append API Append columns.
258
288
 
259
289
  ├── excel_worksheet chart
260
- │ ├── list API List charts in a workbook or dashboard.
261
- │ ├── get API Read one chart spec and source binding.
290
+ │ ├── list NOW List charts in one worksheet.
291
+ │ ├── get NOW Read one chart spec and source binding.
262
292
  │ ├── preview PLAN Preview one chart from its spec/source binding.
263
- │ ├── create-config API Create one chart from a chart spec.
264
- │ ├── update API Update one chart from a chart spec.
293
+ │ ├── create-config NOW Create one chart from a chart spec.
294
+ │ ├── update NOW Update one chart from a chart spec.
265
295
  │ ├── refresh PLAN Refresh one chart from its current source binding.
266
- │ └── delete API Delete one chart.
296
+ │ └── delete NOW Delete one chart.
267
297
 
268
298
  ├── excel_worksheet dashboard
269
- │ ├── manifest PLAN Read dashboard, chart, metric, layout, and lineage metadata.
270
- │ ├── create-config PLAN Compose chart ids/specs into a dashboard config.
271
- │ ├── validate PLAN Validate dashboard layout, permissions, filters, and metrics.
272
- │ └── refresh PLAN Refresh dashboard charts from their current source bindings.
273
- │ └── delete
299
+ │ ├── manifest NOW Aggregate worksheet metadata and chart inventory for one dashboard sheet.
300
+ │ ├── create-config NOW Create a dashboard worksheet and compose charts from one spec.
301
+ │ ├── validate NOW Validate dashboard layout, worksheet target, and chart source fields locally.
302
+ │ └── refresh NOW Upsert dashboard charts from one spec and re-verify chart inventory.
274
303
 
275
304
 
276
- ├── excel_worksheet style
277
- │ ├── cell batch-set API Apply cell style batches from JSON.
278
- │ ├── columns-width API Set column widths.
279
- │ ├── rows-height API Set row heights.
280
- │ ├── freeze-panes API Freeze rows/columns using an A1 boundary.
281
- │ ├── gridlines toggle API Toggle worksheet gridlines.
282
- │ ├── auto-filter set API Set worksheet auto-filter range.
283
- │ ├── auto-filter remove API Remove worksheet auto-filter.
284
- │ ├── filter-values API Apply filter values.
285
- │ ├── conditional-formats set API Set conditional formatting rules.
286
- │ ├── worksheet plan API Generate a worksheet styling plan.
287
- │ └── worksheet apply API Apply a worksheet styling plan.
305
+ ├── excel-worksheet style
306
+ │ ├── cell batch-set NOW Apply cell style batches from JSON.
307
+ │ ├── columns-width NOW Set column widths.
308
+ │ ├── rows-height NOW Set row heights.
309
+ │ ├── freeze-panes NOW Freeze rows/columns using an A1 boundary.
310
+ │ ├── gridlines toggle NOW Toggle worksheet gridlines.
311
+ │ ├── auto-filter set NOW Set worksheet auto-filter range.
312
+ │ ├── auto-filter remove NOW Remove worksheet auto-filter.
313
+ │ ├── filter-values NOW Apply filter values.
314
+ │ ├── conditional-formats set NOW Set conditional formatting rules.
315
+ │ ├── worksheet plan NOW Generate a worksheet styling plan.
316
+ │ └── worksheet apply NOW Apply a worksheet styling plan.
288
317
 
289
- ├── excel_worksheet image
290
- │ ├── read API Read worksheet images.
291
- │ ├── insert API Add an image file.
292
- └── delete API Delete an image.
318
+ ├── excel_worksheet image
319
+ │ ├── list NOW List worksheet images from worksheet formatting metadata.
320
+ │ ├── read NOW Read one worksheet image by cell or picture id.
321
+ ├── replace NOW Replace one worksheet image in place.
322
+ │ ├── insert NOW Add an image file.
323
+ │ └── delete NOW Delete an image.
293
324
 
294
325
  ├── version
295
326
  │ ├── list API List workbook history with bounded output.
@@ -370,24 +401,65 @@ mbs excel-worksheet column append --doc-id abc123 --worksheet-name Actuals --val
370
401
  mbs excel-worksheet range lineage --doc-id abc123 --worksheet-name Model --cell E2 --format tree # API
371
402
 
372
403
  # formula
404
+ mbs workbook calculate --doc-id abc123 # API
405
+ mbs excel-worksheet calculate --doc-id abc123 --worksheet-name Model # API
373
406
  mbs excel-worksheet range calculate --doc-id abc123 --worksheet-name Model --cell E2 --formula "=SUM(B2:D2)" # API
374
407
  mbs excel-worksheet range set-formula --doc-id abc123 --worksheet-name Model --cell E2 --formula "=SUM(B2:D2)" # API
375
408
 
376
409
  # chart
377
- mbs excel-worksheet chart create-config --doc-id abc123 --worksheet-name Dashboard --cell J2 --spec chart.json # API
378
- mbs excel-worksheet chart refresh --doc-id abc123 --worksheet-name Dashboard --chart-id chart_monthly_revenue # PLAN
410
+ mbs excel-worksheet chart list --doc-id abc123 --worksheet-name Dashboard # NOW
411
+ mbs excel-worksheet chart get --doc-id abc123 --worksheet-name Dashboard --cell J2 # NOW
412
+ mbs excel-worksheet chart create-config --doc-id abc123 --worksheet-name Dashboard --cell J2 --spec chart.json # NOW
413
+ mbs excel-worksheet chart update --doc-id abc123 --worksheet-name Dashboard --cell J2 --chart-id rId1 --spec chart.json # NOW
414
+ mbs excel-worksheet chart delete --doc-id abc123 --worksheet-name Dashboard --chart-id rId1 # NOW
415
+
416
+ # recommended chart.json shape
417
+ # prefer top-level `"type": "json"` and put the renderer in `html`
418
+ # do not treat `"type": "line"` / `"bar"` / `"pie"` as the default authored form
419
+ # {
420
+ # "type": "json",
421
+ # "sql": "select Month, Revenue from Sheet1",
422
+ # "title": "Monthly Revenue",
423
+ # "legend": "bottom",
424
+ # "html": "{ library: 'echarts', handler: (data) => ({ xAxis: { type: 'category', data: data.map(r => r.Month) }, yAxis: { type: 'value' }, series: [{ type: 'line', data: data.map(r => Number(r.Revenue) || 0) }] }) }",
425
+ # "spec": { "style": { "title": "Monthly Revenue" } }
426
+ # }
379
427
 
380
428
  # dashboard
381
- mbs excel-worksheet dashboard manifest --doc-id abc123 --worksheet-name Dashboard --dashboard-id dash_revenue # PLAN
382
- mbs excel-worksheet dashboard create-config --doc-id abc123 --worksheet-name Dashboard --name "Revenue Dashboard" --spec dashboard.json # PLAN
383
- mbs excel-worksheet dashboard refresh --doc-id abc123 --worksheet-name Dashboard --dashboard-id dash_revenue # PLAN
429
+ mbs excel-worksheet dashboard validate --spec dashboard.json # NOW
430
+ mbs excel-worksheet dashboard manifest --doc-id abc123 --worksheet-name Dashboard # NOW
431
+ mbs excel-worksheet dashboard create-config --doc-id abc123 --spec dashboard.json --create-worksheet # NOW
432
+ mbs excel-worksheet dashboard refresh --doc-id abc123 --spec dashboard.json # NOW
433
+
434
+ # recommended dashboard.json chart entries
435
+ # {
436
+ # "worksheet_name": "Dashboard",
437
+ # "charts": [
438
+ # {
439
+ # "cell": "J2",
440
+ # "chart": {
441
+ # "type": "json",
442
+ # "sql": "select Month, Revenue from Sheet1",
443
+ # "title": "Monthly Revenue",
444
+ # "legend": "bottom",
445
+ # "html": "{ library: 'echarts', handler: (data) => ({ xAxis: { type: 'category', data: data.map(r => r.Month) }, yAxis: { type: 'value' }, series: [{ type: 'line', data: data.map(r => Number(r.Revenue) || 0) }] }) }"
446
+ # }
447
+ # }
448
+ # ]
449
+ # }
384
450
 
385
451
  # style
386
- mbs excel-worksheet style freeze-panes --doc-id abc123 --worksheet-name Actuals --cell B2 # API
387
- mbs excel-worksheet style conditional-formats set --doc-id abc123 --worksheet-name Actuals --spec conditional_formats.json # API
452
+ mbs excel-worksheet style freeze-panes --doc-id abc123 --worksheet-name Actuals --cell B2 # NOW
453
+ mbs excel-worksheet style cell batch-set --doc-id abc123 --worksheet-name Actuals --range A1:G1 --style header_style.json # NOW
454
+ mbs excel-worksheet style conditional-formats set --doc-id abc123 --worksheet-name Actuals --spec conditional_formats.json # NOW
455
+ mbs excel-worksheet style worksheet apply --doc-id abc123 --worksheet-name Actuals --mode auto_detect --spec worksheet_style.json # NOW
388
456
 
389
457
  # image
390
- mbs excel-worksheet image insert --doc-id abc123 --worksheet-name Dashboard --cell A1 --file logo.png # API
458
+ mbs excel-worksheet image list --doc-id abc123 --worksheet-name Dashboard # NOW
459
+ mbs excel-worksheet image read --doc-id abc123 --worksheet-name Dashboard --cell A1 --out logo.png # NOW
460
+ mbs excel-worksheet image insert --doc-id abc123 --worksheet-name Dashboard --cell A1 --file logo.png # NOW
461
+ mbs excel-worksheet image replace --doc-id abc123 --worksheet-name Dashboard --cell A1 --file logo_v2.png # NOW
462
+ mbs excel-worksheet image delete --doc-id abc123 --worksheet-name Dashboard --cell A1 # NOW
391
463
 
392
464
  # version
393
465
  mbs version list --doc-id abc123 --limit 10 # API
@@ -439,15 +511,14 @@ Relationship guide:
439
511
  - Use `excel-worksheet row` and `excel-worksheet column` for structural
440
512
  row/column changes.
441
513
  - Use `excel-worksheet style` for worksheet layout operations like freeze
442
- panes, filter ranges, widths, and heights.
443
- - Use `excel-table style` when the same styling operation should be scoped to a
444
- table's resolved worksheet range.
445
- - Use `excel-worksheet chart` for CRUD, preview, and refresh of individual
446
- source-backed visualizations before composing dashboards.
447
- - Use `excel-worksheet dashboard` to compose chart ids/specs into BI asset or
448
- dashboard worksheet lifecycles.
449
- - Use `excel-worksheet image` for lower-level report workflows after routed
450
- public API verification.
514
+ panes, filter ranges, widths, heights, gridlines, conditional formats, and
515
+ worksheet style planning/apply.
516
+ - Use `excel-worksheet chart` for list/get/create/update/delete of individual
517
+ source-backed visualizations.
518
+ - Use `excel-worksheet dashboard` for local validation and worksheet-level chart
519
+ orchestration such as manifest, create-config, and refresh.
520
+ - Use `excel-worksheet image` for list/read/insert/replace/delete image
521
+ workflows.
451
522
  - Use `version` for workbook history inspection and restore.
452
523
  - Use `share` for visibility and collaborator access.
453
524
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "maybeai-sheet-cli"
7
- version = "0.7.0"
7
+ version = "0.9.0"
8
8
  description = "CLI for common MaybeAI spreadsheet operations"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -2,4 +2,4 @@
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "0.7.0"
5
+ __version__ = "0.9.0"
@@ -0,0 +1,59 @@
1
+ from __future__ import annotations
2
+
3
+ from copy import deepcopy
4
+ from typing import Any
5
+
6
+ from .errors import UsageError
7
+
8
+
9
+ def normalize_chart_payload(chart: dict[str, Any]) -> dict[str, Any]:
10
+ normalized = deepcopy(chart)
11
+ hide_title = _pop_optional_bool(normalized, "hide_title")
12
+ show_container_title = _pop_optional_bool(normalized, "show_container_title")
13
+
14
+ if hide_title is not None and show_container_title is not None:
15
+ expected_show = not hide_title
16
+ if show_container_title != expected_show:
17
+ raise UsageError("chart.hide_title conflicts with chart.show_container_title.")
18
+
19
+ desired_show: bool | None = None
20
+ if hide_title is not None:
21
+ desired_show = not hide_title
22
+ if show_container_title is not None:
23
+ desired_show = show_container_title
24
+ if desired_show is None and normalized.get("title") == "":
25
+ desired_show = False
26
+
27
+ spec = normalized.get("spec")
28
+ if spec is None:
29
+ spec_obj: dict[str, Any] = {}
30
+ elif isinstance(spec, dict):
31
+ spec_obj = deepcopy(spec)
32
+ else:
33
+ raise UsageError("chart.spec must be an object.")
34
+
35
+ style = spec_obj.get("style")
36
+ if style is None:
37
+ style_obj: dict[str, Any] = {}
38
+ elif isinstance(style, dict):
39
+ style_obj = deepcopy(style)
40
+ else:
41
+ raise UsageError("chart.spec.style must be an object.")
42
+
43
+ if desired_show is not None:
44
+ style_obj["showContainerTitle"] = desired_show
45
+
46
+ if style_obj:
47
+ spec_obj["style"] = style_obj
48
+ if spec_obj or "spec" in normalized:
49
+ normalized["spec"] = spec_obj
50
+ return normalized
51
+
52
+
53
+ def _pop_optional_bool(payload: dict[str, Any], key: str) -> bool | None:
54
+ value = payload.pop(key, None)
55
+ if value is None:
56
+ return None
57
+ if isinstance(value, bool):
58
+ return value
59
+ raise UsageError(f"chart.{key} must be a boolean.")