maybeai-sheet-cli 0.6.0__tar.gz → 0.7.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 (89) hide show
  1. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/PKG-INFO +3 -2
  2. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/README.md +2 -1
  3. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/pyproject.toml +9 -1
  4. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/__init__.py +1 -1
  5. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/cli.py +1 -0
  6. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/excel_worksheet.py +6 -1
  7. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/tests/test_cli.py +24 -0
  8. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/tests/test_two_engine_cli.py +24 -0
  9. maybeai_sheet_cli-0.6.0/.claude/settings.local.json +0 -9
  10. maybeai_sheet_cli-0.6.0/CLAUDE.md +0 -46
  11. maybeai_sheet_cli-0.6.0/cli-packaging-plan.md +0 -279
  12. maybeai_sheet_cli-0.6.0/cli-plan.md +0 -389
  13. maybeai_sheet_cli-0.6.0/docs/agent-friendly-command-tree.md +0 -1424
  14. maybeai_sheet_cli-0.6.0/docs/operation-plan-cli-no-dsl-plan.md +0 -459
  15. maybeai_sheet_cli-0.6.0/docs/superpowers/plans/2026-07-01-mbs-agent-friendly-command-tree.md +0 -1270
  16. maybeai_sheet_cli-0.6.0/docs/superpowers/plans/2026-07-01-mbs-agent-friendly-phase-2-routes.md +0 -57
  17. maybeai_sheet_cli-0.6.0/docs/superpowers/plans/2026-07-01-mbs-agent-friendly-phase-2.md +0 -708
  18. maybeai_sheet_cli-0.6.0/docs/superpowers/plans/2026-07-01-mbs-be-new-backend-contracts-plan.md +0 -928
  19. maybeai_sheet_cli-0.6.0/docs/superpowers/plans/2026-07-01-mbs-deferred-table-routing-plan.md +0 -713
  20. maybeai_sheet_cli-0.6.0/docs/superpowers/plans/2026-07-01-mbs-excel-worksheet-multi-table-plan.md +0 -683
  21. maybeai_sheet_cli-0.6.0/docs/superpowers/plans/2026-07-01-mbs-two-engine-command-refactor.md +0 -139
  22. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/2026-07-01-mbs-deferred-routing-e2e-report.html +0 -239
  23. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/2026-07-01-phase1-test-review.html +0 -326
  24. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/2026-07-01-phase2-test-review.html +0 -309
  25. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/20260701-130317-excel-table-empty-range-e2e.html +0 -99
  26. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/20260701-130447-excel-table-empty-range-e2e.html +0 -23
  27. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/20260701-130556-excel-table-empty-range-e2e.html +0 -204
  28. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/20260701-230803-local-cli-endpoint-verification.html +0 -52
  29. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/20260701-232511-local7011-cli-table-metadata-verification.html +0 -78
  30. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/e2e-artifacts/e2e-payloads-20260701-130317.json +0 -79
  31. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/e2e-artifacts/e2e-payloads-20260701-130447.json +0 -82
  32. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/e2e-artifacts/e2e-payloads-20260701-130556.json +0 -414
  33. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/e2e-artifacts/multi-table-empty-range-20260701-130317.xlsx +0 -0
  34. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/e2e-artifacts/openpyxl-multi-table-empty-range-20260701-130447.xlsx +0 -0
  35. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/import-engine-local-20260702-150800/import_engine_local_report.html +0 -74
  36. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/import-engine-local-20260702-150800/llm_cost_import_auto.json +0 -479
  37. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/import-engine-local-20260702-150800/llm_cost_import_mixed_forced.json +0 -0
  38. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/import-engine-local-20260702-150800/llm_cost_list_worksheets.json +0 -355
  39. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/import-engine-local-20260702-150800/llm_cost_read_detail_A1_T5.json +0 -549
  40. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/import-engine-local-20260702-150800/summary.json +0 -79
  41. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/import-engine-local-20260702-150800/yunling_import_auto.json +0 -602
  42. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/import-engine-local-20260702-150800/yunling_list_worksheets.json +0 -598
  43. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/import-engine-local-20260702-150800/yunling_read_T00_A1_F5.json +0 -343
  44. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/import-engine-merged-20260702-153018/import_auto.json +0 -587
  45. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/import-engine-merged-20260702-153018/list_worksheets.json +0 -112
  46. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/import-engine-merged-20260702-153018/merged_two_tables_report.html +0 -12
  47. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/import-engine-merged-20260702-153018/read_merged_1_A1_T5.json +0 -373
  48. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/import-engine-merged-20260702-153018/read_merged_2_A1_T5.json +0 -373
  49. maybeai_sheet_cli-0.6.0/docs/superpowers/reports/import-engine-merged-20260702-153018/summary.json +0 -145
  50. maybeai_sheet_cli-0.6.0/docs/verification-matrix-fallback.md +0 -35
  51. maybeai_sheet_cli-0.6.0/uv.lock +0 -415
  52. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/.gitignore +0 -0
  53. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/client.py +0 -0
  54. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/__init__.py +0 -0
  55. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/_phase2.py +0 -0
  56. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/cell.py +0 -0
  57. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/column.py +0 -0
  58. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/db_table.py +0 -0
  59. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/excel_table.py +0 -0
  60. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/file.py +0 -0
  61. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/formula.py +0 -0
  62. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/history.py +0 -0
  63. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/range.py +0 -0
  64. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/raw.py +0 -0
  65. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/row.py +0 -0
  66. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/share.py +0 -0
  67. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/sheet.py +0 -0
  68. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/style.py +0 -0
  69. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/table.py +0 -0
  70. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/workbook.py +0 -0
  71. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/commands/worksheet.py +0 -0
  72. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/config.py +0 -0
  73. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/endpoints.py +0 -0
  74. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/errors.py +0 -0
  75. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/formatters.py +0 -0
  76. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/models/__init__.py +0 -0
  77. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/models/share.py +0 -0
  78. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/models/sheet.py +0 -0
  79. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/models/workbook.py +0 -0
  80. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/options.py +0 -0
  81. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/protocol.py +0 -0
  82. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/resolver.py +0 -0
  83. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/table_resolver.py +0 -0
  84. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/src/maybeai_sheet/update.py +0 -0
  85. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/tests/test_endpoints.py +0 -0
  86. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/tests/test_formatters.py +0 -0
  87. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/tests/test_phase2_cli.py +0 -0
  88. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.0}/tests/test_resolver.py +0 -0
  89. {maybeai_sheet_cli-0.6.0 → maybeai_sheet_cli-0.7.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.6.0
3
+ Version: 0.7.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
@@ -226,7 +226,7 @@ mbs
226
226
 
227
227
  ├── excel_worksheet
228
228
  │ ├── read API Read the full range of the worksheet.
229
- │ ├── list-table API List worksheets in a workbook.
229
+ │ ├── list-table API Detect content-backed tables in a worksheet.
230
230
  │ ├── create API Create a worksheet, optionally with starter values.
231
231
  │ ├── update API Update worksheet metadata.
232
232
  │ ├── sample PLAN Return bounded worksheet/range sample rows.
@@ -351,6 +351,7 @@ mbs excel-worksheet read --doc-id abc123 --worksheet-name Actuals --range A1:D20
351
351
  mbs excel-worksheet create --doc-id abc123 --name Actuals # API
352
352
  mbs excel-worksheet update --doc-id abc123 --worksheet-name Actuals --title "Actuals FY26" # API
353
353
  mbs excel-worksheet metadata --doc-id abc123 --worksheet-name Actuals # API
354
+ mbs excel-worksheet list-table --doc-id abc123 --gid 3 # API
354
355
  mbs excel-worksheet sample --doc-id abc123 --worksheet-name Actuals --range A1:Z5000 --limit 50 # PLAN
355
356
 
356
357
  # excel-worksheet range
@@ -202,7 +202,7 @@ mbs
202
202
 
203
203
  ├── excel_worksheet
204
204
  │ ├── read API Read the full range of the worksheet.
205
- │ ├── list-table API List worksheets in a workbook.
205
+ │ ├── list-table API Detect content-backed tables in a worksheet.
206
206
  │ ├── create API Create a worksheet, optionally with starter values.
207
207
  │ ├── update API Update worksheet metadata.
208
208
  │ ├── sample PLAN Return bounded worksheet/range sample rows.
@@ -327,6 +327,7 @@ mbs excel-worksheet read --doc-id abc123 --worksheet-name Actuals --range A1:D20
327
327
  mbs excel-worksheet create --doc-id abc123 --name Actuals # API
328
328
  mbs excel-worksheet update --doc-id abc123 --worksheet-name Actuals --title "Actuals FY26" # API
329
329
  mbs excel-worksheet metadata --doc-id abc123 --worksheet-name Actuals # API
330
+ mbs excel-worksheet list-table --doc-id abc123 --gid 3 # API
330
331
  mbs excel-worksheet sample --doc-id abc123 --worksheet-name Actuals --range A1:Z5000 --limit 50 # PLAN
331
332
 
332
333
  # excel-worksheet range
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "maybeai-sheet-cli"
7
- version = "0.6.0"
7
+ version = "0.7.0"
8
8
  description = "CLI for common MaybeAI spreadsheet operations"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -39,3 +39,11 @@ mbs = "maybeai_sheet.cli:app"
39
39
 
40
40
  [tool.hatch.build.targets.wheel]
41
41
  packages = ["src/maybeai_sheet"]
42
+
43
+ [tool.hatch.build.targets.sdist]
44
+ include = [
45
+ "/src",
46
+ "/tests",
47
+ "/README.md",
48
+ "/pyproject.toml",
49
+ ]
@@ -2,4 +2,4 @@
2
2
 
3
3
  __all__ = ["__version__"]
4
4
 
5
- __version__ = "0.6.0"
5
+ __version__ = "0.7.0"
@@ -52,6 +52,7 @@ def main(
52
52
  base_url: str = typer.Option(
53
53
  "https://play-be.omnimcp.ai",
54
54
  "--base-url",
55
+ envvar="MAYBEAI_BASE_URL",
55
56
  help="MaybeAI API base URL.",
56
57
  ),
57
58
  doc_id: Optional[str] = typer.Option(
@@ -288,6 +288,7 @@ def list_table(
288
288
  doc_id: Optional[str] = typer.Option(None, "--doc-id", help="MaybeAI document ID."),
289
289
  url: Optional[str] = typer.Option(None, "--url", help="MaybeAI workbook URL."),
290
290
  uri: Optional[str] = typer.Option(None, "--uri", help="Resolved workbook URI."),
291
+ gid: Optional[int] = typer.Option(None, "--gid", help="Worksheet gid."),
291
292
  worksheet_name: Optional[str] = typer.Option(None, "--worksheet-name", help="Optional worksheet name filter."),
292
293
  output: Optional[str] = output_option(),
293
294
  verbose: Optional[bool] = verbose_option(),
@@ -299,12 +300,16 @@ def list_table(
299
300
  doc_id=doc_id,
300
301
  url=url,
301
302
  uri=uri,
303
+ gid=gid,
302
304
  worksheet_name=worksheet_name,
303
305
  output=output,
304
306
  verbose=verbose,
305
307
  timeout=timeout,
306
308
  )
307
- target = resolve_target(state)
309
+ target = resolve_target(
310
+ state,
311
+ force_gid_uri=bool(state.gid is not None and not state.worksheet_name),
312
+ )
308
313
  if target.worksheet_name or target.gid is not None:
309
314
  endpoint = "/api/v1/excel/table/metadata"
310
315
  payload: dict[str, object] = {
@@ -24,6 +24,30 @@ class CLITests(unittest.TestCase):
24
24
  self.runner = CliRunner()
25
25
  self.env = {"MAYBEAI_API_TOKEN": "test-token"}
26
26
 
27
+ def test_base_url_can_come_from_environment(self) -> None:
28
+ captured: dict[str, str] = {}
29
+
30
+ def capture_init(client: MaybeAIClient, state: CLIContext) -> None:
31
+ captured["base_url"] = state.base_url
32
+ client.state = state
33
+
34
+ with (
35
+ patch.object(MaybeAIClient, "__init__", capture_init),
36
+ patch.object(MaybeAIClient, "post_json") as post_json,
37
+ ):
38
+ post_json.return_value = {"success": True, "worksheets": []}
39
+ result = self.runner.invoke(
40
+ app,
41
+ ["workbook", "list-worksheets", "--doc-id", "doc1"],
42
+ env={
43
+ "MAYBEAI_API_TOKEN": "test-token",
44
+ "MAYBEAI_BASE_URL": "http://localhost:7011",
45
+ },
46
+ )
47
+
48
+ self.assertEqual(result.exit_code, 0, result.output)
49
+ self.assertEqual(captured["base_url"], "http://localhost:7011")
50
+
27
51
  def test_workbook_create_uses_blank_bootstrap_and_filename(self) -> None:
28
52
  with patch("maybeai_sheet.commands.workbook.MaybeAIClient.post_json") as post_json:
29
53
  post_json.return_value = {"success": True, "spreadsheet_id": "doc1"}
@@ -103,6 +103,30 @@ class TwoEngineCLITests(unittest.TestCase):
103
103
  self.assertEqual(post_json.call_args_list[0].args[1]["worksheet_name"], "Orders")
104
104
  self.assertEqual(post_json.call_args_list[1].args[0], "/api/v1/excel/list_worksheets")
105
105
 
106
+ def test_excel_worksheet_list_table_accepts_gid(self) -> None:
107
+ with patch("maybeai_sheet.commands.excel_worksheet.MaybeAIClient.post_json") as post_json:
108
+ post_json.return_value = {
109
+ "success": True,
110
+ "tables": [
111
+ {"range": "A1:I16", "row_count": 16, "column_count": 9},
112
+ {"range": "A20:I27", "row_count": 8, "column_count": 9},
113
+ ],
114
+ }
115
+ result = self.runner.invoke(
116
+ app,
117
+ ["excel-worksheet", "list-table", "--doc-id", "abc123", "--gid", "3"],
118
+ env=self.env,
119
+ )
120
+
121
+ self.assertEqual(result.exit_code, 0, result.output)
122
+ self.assertEqual(post_json.call_args_list[0].args[0], "/api/v1/excel/table/metadata")
123
+ payload = post_json.call_args_list[0].args[1]
124
+ self.assertEqual(payload["document_id"], "abc123")
125
+ self.assertEqual(payload["uri"], "https://www.maybe.ai/docs/spreadsheets/d/abc123?gid=3")
126
+ self.assertEqual(payload["gid"], 3)
127
+ self.assertEqual(payload["engine"], "excelize")
128
+ self.assertNotIn("worksheet_name", payload)
129
+
106
130
  def test_excel_worksheet_read_uses_v1_read_sheet(self) -> None:
107
131
  with patch("maybeai_sheet.commands.excel_worksheet.MaybeAIClient.post_json") as post_json:
108
132
  post_json.return_value = {"success": True, "values": [["Name"], ["Alice"]]}
@@ -1,9 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "mcp__google-search__performGoogleSearch",
5
- "WebFetch(domain:www.npmjs.com)",
6
- "WebFetch(domain:advenboost.com)"
7
- ]
8
- }
9
- }
@@ -1,46 +0,0 @@
1
- # CLAUDE.md
2
-
3
- ## Repo Purpose
4
-
5
- This repository contains the `maybeai-sheet` Python CLI for MaybeAI spreadsheet APIs.
6
-
7
- ## Working Rules
8
-
9
- - Keep docs and CLI behavior aligned with the actual code.
10
- - Prefer small, targeted changes.
11
- - Do not rename commands or flags unless the implementation changes too.
12
- - Preserve JSON as the default output format.
13
-
14
- ## Project Map
15
-
16
- - `src/maybeai_sheet/cli.py` - top-level Typer app and global options
17
- - `src/maybeai_sheet/update.py` - PyPI self-update helpers
18
- - `src/maybeai_sheet/commands/` - `workbook`, `sheet`, and `raw` command groups
19
- - `src/maybeai_sheet/client.py` - HTTP client and request helpers
20
- - `src/maybeai_sheet/resolver.py` - document and worksheet target resolution
21
- - `src/maybeai_sheet/formatters.py` - JSON, YAML, and table rendering
22
- - `tests/` - CLI, resolver, and formatter tests
23
-
24
- ## Common Commands
25
-
26
- ```bash
27
- python -m unittest discover -s tests -v
28
- ```
29
-
30
- ```bash
31
- python -m maybeai_sheet.cli --help
32
- ```
33
-
34
- ## Implementation Notes
35
-
36
- - Token source order is `--token` then `MAYBEAI_API_TOKEN`.
37
- - The default API base URL is `https://play-be.omnimcp.ai`.
38
- - `--doc-id` is converted to a MaybeAI workbook URL when needed.
39
- - `sheet headers` and formula reads rely on gid-aware URI resolution.
40
- - `--verify` on write/append/upsert commands reads the sheet back after the write.
41
-
42
- ## Editing Guidance
43
-
44
- - Update README examples when adding or changing commands.
45
- - Keep request/response examples consistent with the tests.
46
- - If behavior changes, add or update tests in `tests/` before finishing.
@@ -1,279 +0,0 @@
1
- # MaybeAI Sheet CLI Plan
2
-
3
- ## Recommendation
4
-
5
- Yes, a CLI is worth adding for the highest-frequency operations, especially:
6
-
7
- - `workbook_manifest`
8
- - `read_sheet`
9
- - `read_headers`
10
- - `list_worksheets`
11
- - `append_rows`
12
- - `update_range_by_lookup`
13
- - `update_range`
14
- - `clear_range`
15
- - `write_new_worksheet`
16
- - `formula_set`
17
- - `formula_batch_set`
18
- - `recalculate_formulas`
19
- - `workbook_profile`
20
- - `export`
21
-
22
- It is **not** a good replacement for the entire API surface. The repo already shows a large endpoint set, so the right design is:
23
-
24
- 1. First-class commands for the common workflows
25
- 2. Stable shared flags for auth, workbook, and worksheet targeting
26
- 3. A generic `api` or `raw` command for less-used endpoints
27
-
28
- That keeps the CLI small enough to publish and maintain.
29
-
30
- ## Why a CLI Helps
31
-
32
- For common sheet work, the current `curl` scripts have three recurring costs:
33
-
34
- - repeated auth and base URL boilerplate
35
- - repeated `uri` and `gid` handling
36
- - repeated JSON escaping for structured payloads
37
-
38
- A CLI improves:
39
-
40
- - usability for humans
41
- - repeatability in scripts and CI
42
- - discoverability through `--help`
43
- - safer worksheet targeting through shared options
44
-
45
- ## Product Scope
46
-
47
- Package identity:
48
-
49
- - distribution name: `maybeai-sheet-cli`
50
- - executable: `mbs`
51
- - import package: `maybeai_sheet`
52
-
53
- Recommended executable:
54
-
55
- ```bash
56
- mbs
57
- ```
58
-
59
- Recommended Python baseline:
60
-
61
- - Python `>=3.10`
62
-
63
- Recommended implementation:
64
-
65
- - `typer` for CLI
66
- - `httpx` for HTTP client
67
- - `pydantic` for payload validation
68
- - `rich` for readable table / JSON output
69
-
70
- ## CLI Shape
71
-
72
- ```bash
73
- mbs [global options] <resource> <command> [command options]
74
- ```
75
-
76
- Global options:
77
-
78
- - `--token` or env `MAYBEAI_API_TOKEN`
79
- - `--base-url` default `https://play-be.omnimcp.ai`
80
- - `--doc-id`
81
- - `--uri`
82
- - `--gid`
83
- - `--worksheet-name`
84
- - `--output json|table|yaml`
85
- - `--verbose`
86
-
87
- Resolution rules:
88
-
89
- 1. If `--uri` is provided, use it
90
- 2. Else if `--doc-id` is provided, build `https://www.maybe.ai/docs/spreadsheets/d/<doc_id>`
91
- 3. If `--gid` is provided, append `?gid=<gid>` where required
92
- 4. Prefer `--worksheet-name` for commands that support it
93
-
94
- ## Proposed Commands
95
-
96
- ### Read path
97
-
98
- ```bash
99
- mbs sheet read --doc-id <id> --worksheet-name Sheet1
100
- mbs sheet read --doc-id <id> --worksheet-name Sheet1 --range A1:C20
101
- mbs sheet read-many --doc-id <id> --targets targets.json
102
- mbs sheet named-range --doc-id <id> --name RevenueBlock
103
- mbs sheet headers --doc-id <id> --gid 0
104
- mbs sheet worksheets --doc-id <id>
105
- mbs sheet profile --doc-id <id> --force-refresh
106
- ```
107
-
108
- ### Write path
109
-
110
- ```bash
111
- mbs sheet append --doc-id <id> --gid 0 --rows rows.json
112
- mbs sheet upsert --doc-id <id> --gid 0 --key OrderID --rows rows.json
113
- mbs sheet write-range --doc-id <id> --worksheet-name Sheet1 --range A1:C3 --values values.json
114
- mbs sheet clear-range --doc-id <id> --worksheet-name Sheet1 --range A1:C3
115
- mbs sheet create-worksheet --doc-id <id> --name Summary --values values.json
116
- mbs sheet formula-set --doc-id <id> --worksheet-name Sheet1 --cell E2 --formula '=SUM(B2:D2)'
117
- mbs sheet formula-batch-set --doc-id <id> --operations ops.json --recalculate-mode worksheet
118
- mbs sheet recalculate --doc-id <id> --worksheet-name Sheet1
119
- ```
120
-
121
- ### File path
122
-
123
- ```bash
124
- mbs file upload ./report.xlsx
125
- mbs file export --doc-id <id> --out final.xlsx
126
- mbs file search "q2 forecast"
127
- ```
128
-
129
- ### Escape hatch
130
-
131
- ```bash
132
- mbs raw post /api/v3/excel/range/read --body body.json
133
- ```
134
-
135
- The `raw` command prevents CLI growth from tracking every niche endpoint.
136
-
137
- ## Command Mapping
138
-
139
- | CLI command | API endpoint |
140
- |---|---|
141
- | `workbook manifest` | `POST /api/v3/excel/workbook/manifest` |
142
- | `workbook capabilities` | `POST /api/v3/excel/workbook/capabilities` |
143
- | `sheet read` | `POST /api/v3/excel/range/read` |
144
- | `sheet read-range` | `POST /api/v3/excel/range/read` |
145
- | `sheet read-many` | `POST /api/v3/excel/range/read_many` |
146
- | `sheet named-range` | `POST /api/v3/excel/named_range/read` |
147
- | `sheet headers` | `POST /api/v3/excel/table/headers` |
148
- | `sheet worksheets` | `POST /api/v3/excel/worksheet/list` |
149
- | `sheet formulas` | `POST /api/v3/excel/formula/read` |
150
- | `sheet append` | `POST /api/v3/excel/table/append_rows` |
151
- | `sheet upsert` | `POST /api/v3/excel/table/upsert_rows` |
152
- | `sheet write-range` | `POST /api/v3/excel/range/write` |
153
- | `sheet clear-range` | `POST /api/v3/excel/range/clear` |
154
- | `sheet create-worksheet` | `POST /api/v3/excel/worksheet/create` |
155
- | `sheet formula-set` | `POST /api/v3/excel/formula/set` |
156
- | `sheet formula-batch-set` | `POST /api/v3/excel/formula/batch_set` |
157
- | `sheet recalculate` | `POST /api/v3/excel/formula/recalculate` |
158
- | `sheet profile` | `POST /api/v1/excel/workbook_profile` |
159
- | `file upload` | `POST /api/v1/excel/upload` |
160
- | `file export` | `GET /api/v1/excel/export/{document_id}` |
161
-
162
- ## UX Rules
163
-
164
- The CLI should encode the operational rules already documented in this repo:
165
-
166
- 1. Warn when neither `--worksheet-name` nor `--gid` is provided for worksheet-sensitive commands
167
- 2. Prefer `workbook manifest` before read/write commands when the target worksheet is not already known
168
- 3. Prefer `--worksheet-name` for `sheet read`, `sheet write-range`, and `sheet formula-set`
169
- 4. Prefer `--gid` for `sheet headers`, `sheet append`, and `sheet upsert`
170
- 5. Support `--verify` on write commands to automatically read back after write
171
- 6. Support `--dry-run` where payload generation can be previewed safely
172
-
173
- Example:
174
-
175
- ```bash
176
- mbs sheet upsert \
177
- --doc-id $DOC_ID \
178
- --gid 0 \
179
- --key OrderID \
180
- --rows sales.json \
181
- --verify
182
- ```
183
-
184
- ## Suggested Package Layout
185
-
186
- ```text
187
- src/maybeai_sheet/
188
- __init__.py
189
- cli.py
190
- config.py
191
- client.py
192
- models.py
193
- formatters.py
194
- commands/
195
- file.py
196
- sheet.py
197
- raw.py
198
- tests/
199
- pyproject.toml
200
- README.md
201
- ```
202
-
203
- ## `pyproject.toml` Direction
204
-
205
- Use a console script entry point:
206
-
207
- ```toml
208
- [project]
209
- name = "maybeai-sheet-cli"
210
- version = "0.3.0"
211
- description = "CLI for common MaybeAI spreadsheet operations"
212
- requires-python = ">=3.10"
213
- dependencies = ["typer", "httpx", "pydantic", "rich"]
214
-
215
- [project.scripts]
216
- mbs = "maybeai_sheet.cli:app"
217
- ```
218
-
219
- Build backend:
220
-
221
- - `hatchling` or `setuptools`
222
-
223
- Recommended:
224
-
225
- - `hatchling`
226
-
227
- ## Publish-to-PyPI Plan
228
-
229
- ### Phase 1
230
-
231
- Build a thin MVP around the most-used read/write flows:
232
-
233
- - `workbook manifest`
234
- - `sheet read`
235
- - `sheet headers`
236
- - `sheet worksheets`
237
- - `sheet append`
238
- - `sheet upsert`
239
- - `sheet write-range`
240
- - `sheet clear-range`
241
- - `sheet create-worksheet`
242
- - `sheet formula-set`
243
- - `sheet formula-batch-set`
244
- - `sheet recalculate`
245
- - `file upload`
246
- - `file export`
247
-
248
- ### Phase 2
249
-
250
- Add operator-safety and better UX:
251
-
252
- - `--verify`
253
- - `--output table`
254
- - better error messages for auth and wrong-sheet targeting
255
- - `sheet profile`
256
-
257
- ### Phase 3
258
-
259
- Publish:
260
-
261
- 1. reserve package name on PyPI
262
- 2. add `pyproject.toml`
263
- 3. add README with install and auth setup
264
- 4. add tests for request construction
265
- 5. build with `python -m build`
266
- 6. publish with `twine upload dist/*` or trusted publishing
267
-
268
- ## What Not To Do
269
-
270
- - Do not create one CLI command per endpoint on day one
271
- - Do not force users to hand-build JSON strings for common commands
272
- - Do not hide worksheet targeting semantics
273
- - Do not publish before adding at least smoke tests for the common commands
274
-
275
- ## Bottom Line
276
-
277
- Yes, a pip-published CLI is a good fit here, but only if it is opinionated around the top workflows and does not try to mirror the full backend surface.
278
-
279
- The first command to optimize is `read_sheet`, followed by the table-safe write commands.