@metabase/cli 0.1.0-alpha.workspaces-commands.5ab9ca6 → 0.1.0-alpha.workspaces-commands.78747d1

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 (131) hide show
  1. package/README.md +138 -31
  2. package/dist/{api-key-aNbgDn-8.mjs → api-key-DJpqrAGZ.mjs} +1 -1
  3. package/dist/{archive-WGVkPuf8.mjs → archive-B6TbWbK1.mjs} +5 -5
  4. package/dist/auth-BZofbzqG.mjs +19 -0
  5. package/dist/{body-Diijawme.mjs → body-CPnypu0_.mjs} +2 -2
  6. package/dist/{branches-BlSi3TBx.mjs → branches-C_X-mZ8y.mjs} +5 -5
  7. package/dist/{cancel-task-IE1xGzfI.mjs → cancel-task-IPOp8B8w.mjs} +5 -5
  8. package/dist/{card-2XdaHHSS.mjs → card-BOGKT258.mjs} +22 -1
  9. package/dist/card-m-ve7168.mjs +20 -0
  10. package/dist/{cards-DnUcsvj8.mjs → cards-DbwnvuDl.mjs} +5 -5
  11. package/dist/cli.mjs +29 -20
  12. package/dist/collection-BsiGRKXh.mjs +170 -0
  13. package/dist/collection-D3B90qam.mjs +19 -0
  14. package/dist/{create-DmakvRrX.mjs → create-9c1KP2P_.mjs} +6 -6
  15. package/dist/create-BkjrL_vd.mjs +44 -0
  16. package/dist/{create-DYo4lbI2.mjs → create-BoA0MYoT.mjs} +7 -7
  17. package/dist/{create-D-ByDVsB.mjs → create-CWvjvAOe.mjs} +6 -6
  18. package/dist/{create-3d18k8Id.mjs → create-Ck-p0-JC.mjs} +7 -7
  19. package/dist/{create-QXhhxZr5.mjs → create-Iv9ear8t.mjs} +22 -9
  20. package/dist/{create-branch-C2Bdsd5R.mjs → create-branch-CiRVRb7v.mjs} +5 -5
  21. package/dist/{create-D62m-Ubn.mjs → create-dMsrFkvP.mjs} +6 -6
  22. package/dist/{credentials-QKZob37v.mjs → credentials-BXRf0UmM.mjs} +7 -7
  23. package/dist/{current-task-DGuhFVZr.mjs → current-task-gQAv_ckM.mjs} +5 -5
  24. package/dist/{dashboard-DVCLGg3X.mjs → dashboard-BJXi1tGr.mjs} +3 -1
  25. package/dist/dashboard-DE6DQnco.mjs +20 -0
  26. package/dist/{database-Bw72HWEJ.mjs → database-DXjVIlkG.mjs} +3 -3
  27. package/dist/{db-BA6VieA7.mjs → db-DGqKQygl.mjs} +2 -2
  28. package/dist/{delete-CYvfBnPq.mjs → delete-BYx2ESK6.mjs} +6 -6
  29. package/dist/{delete-CTl8JxXL.mjs → delete-BoysG9pE.mjs} +6 -6
  30. package/dist/{delete-runtime-ZDxlvZa6.mjs → delete-runtime-KieND_CX.mjs} +3 -5
  31. package/dist/{delete-table-CZZncGrk.mjs → delete-table-C5B5PRaE.mjs} +6 -6
  32. package/dist/{deprovision-C_UQ1JgA.mjs → deprovision-Dr32FAG9.mjs} +10 -10
  33. package/dist/{dirty-B798WgvJ.mjs → dirty-CID5k_DG.mjs} +5 -5
  34. package/dist/{docker-CJur3rjL.mjs → docker-BcabfnHb.mjs} +21 -7
  35. package/dist/{eid-DANih6Hk.mjs → eid-BnfaFBmk.mjs} +1 -1
  36. package/dist/{export-DdkQHl4m.mjs → export-BDUJ63cz.mjs} +25 -20
  37. package/dist/{field-CAvHQkzI.mjs → field-wJ5IyjF9.mjs} +1 -1
  38. package/dist/{get-C7lv9SOO.mjs → get-2TjBzT5V.mjs} +6 -6
  39. package/dist/{get-Ldui5Vyl.mjs → get-BGtgG85S.mjs} +5 -5
  40. package/dist/{get-D7DCc-zR.mjs → get-BN7AGZLk.mjs} +6 -6
  41. package/dist/{get-BIzIOb3U.mjs → get-BavuL0j2.mjs} +5 -5
  42. package/dist/{get-CuiofGwZ.mjs → get-BhmsDqFa.mjs} +5 -5
  43. package/dist/{get-HNKc0k5G.mjs → get-Br99VIyw.mjs} +5 -5
  44. package/dist/{get-soL4Z2jq.mjs → get-CEmt6JU1.mjs} +5 -5
  45. package/dist/get-Caif_PQa.mjs +41 -0
  46. package/dist/{get-BrpB_58I.mjs → get-gTFLoU81.mjs} +5 -5
  47. package/dist/{has-remote-changes-6bXwJa7C.mjs → has-remote-changes-DCfaGb5v.mjs} +5 -5
  48. package/dist/{import-ys-pzibQ.mjs → import-Dx6kme_2.mjs} +6 -6
  49. package/dist/{input-DkgCMNA9.mjs → input-DMcm_A5s.mjs} +1 -0
  50. package/dist/{is-dirty-AUZADvDx.mjs → is-dirty-DZBRX_uM.mjs} +3 -3
  51. package/dist/is-dirty-FkBul4cr.mjs +10 -0
  52. package/dist/items-BhLxpz31.mjs +123 -0
  53. package/dist/{license-Cr24Ibp3.mjs → license-DfgahRiB.mjs} +3 -3
  54. package/dist/list-B1nz8LEB.mjs +55 -0
  55. package/dist/{list-owVW2jma.mjs → list-B5KP2eXN.mjs} +4 -4
  56. package/dist/{list-SQESC1Z9.mjs → list-BN1iCMfc.mjs} +4 -4
  57. package/dist/{list-C737c643.mjs → list-BeNzesw7.mjs} +4 -4
  58. package/dist/{list-CeqlehZp.mjs → list-CXUd-LO7.mjs} +4 -4
  59. package/dist/{list-DD0dVVEl.mjs → list-Cjst618J.mjs} +6 -6
  60. package/dist/list-CqeNnBHu.mjs +52 -0
  61. package/dist/{list-Cwcz1wg7.mjs → list-DDWzIVi0.mjs} +4 -4
  62. package/dist/{list-DxOceJmQ.mjs → list-DfuhW3--.mjs} +4 -4
  63. package/dist/{list-DI9--PcL.mjs → list-kWLAMOPg.mjs} +4 -4
  64. package/dist/{login-Bw7TcgTG.mjs → login-xppXbffQ.mjs} +5 -5
  65. package/dist/{logout-DEzazQMO.mjs → logout-XtEgcO-n.mjs} +6 -7
  66. package/dist/{logs-QMdzAnlJ.mjs → logs-Dm86UFD5.mjs} +5 -5
  67. package/dist/{manifest-IMg51yb7.mjs → manifest-C7lnUosz.mjs} +1 -1
  68. package/dist/{package-ROuZ4tbw.mjs → package-B4PhZz9R.mjs} +1 -1
  69. package/dist/{parse-id-CGyF8OPI.mjs → parse-id-Dm8zjjx_.mjs} +1 -1
  70. package/dist/parse-ref-CyeuK_yM.mjs +17 -0
  71. package/dist/{poll-B5RO0ias.mjs → poll-DYp_Lzph.mjs} +1 -1
  72. package/dist/{poll-task-BU0gpBIk.mjs → poll-task-kULwF-eM.mjs} +3 -3
  73. package/dist/{provision-CH7aVxXn.mjs → provision-DzsbOQoP.mjs} +10 -10
  74. package/dist/ps-CUp-aAvT.mjs +10 -0
  75. package/dist/{ps-DP5XSIOy.mjs → ps-jLYH2ARi.mjs} +3 -3
  76. package/dist/{query-DwBWeir4.mjs → query-BkUL9HyQ.mjs} +7 -7
  77. package/dist/{query-DNiw6JKA.mjs → query-DCnXxe9y.mjs} +5 -5
  78. package/dist/{remove-CmF7i1Jq.mjs → remove-BXHoDhhy.mjs} +8 -8
  79. package/dist/{remove-WGIoTwsl.mjs → remove-DMRyYIs2.mjs} +6 -7
  80. package/dist/{render-CZNR2MNK.mjs → render-BYWlZPEH.mjs} +7 -4
  81. package/dist/{run-CabruqrJ.mjs → run-qmPGT-44.mjs} +7 -7
  82. package/dist/{runtime-8SAm0dHE.mjs → runtime-DyNvyYvx.mjs} +99 -3
  83. package/dist/{search-DNvad2hL.mjs → search-CiDweQ6X.mjs} +6 -20
  84. package/dist/{set-BclYXZNW.mjs → set-B_IyoHCE.mjs} +7 -7
  85. package/dist/{set-Cog7mkJT.mjs → set-DHdbtWuT.mjs} +5 -5
  86. package/dist/{setting-jFe6Zt2S.mjs → setting-Cp6Tw2QN.mjs} +3 -3
  87. package/dist/{setup-Cw5pIrBj.mjs → setup-4WZU9ihX.mjs} +5 -5
  88. package/dist/{start-CNn99SQU.mjs → start-DHWpzHu6.mjs} +10 -10
  89. package/dist/{stash-BWCuQzmR.mjs → stash-DXrx6JPU.mjs} +6 -6
  90. package/dist/{status-CSAGf0mB.mjs → status-B88vwQzu.mjs} +3 -3
  91. package/dist/{status-yZk5nUq3.mjs → status-C0lb8dVk.mjs} +6 -6
  92. package/dist/{status-CCqjWCFF.mjs → status-CsFspRut.mjs} +3 -3
  93. package/dist/{stop-DMZey9PG.mjs → stop-AYfxmMoS.mjs} +7 -7
  94. package/dist/sync-BpO2GELG.mjs +26 -0
  95. package/dist/{table-BGLcZjyq.mjs → table-BsdEHMog.mjs} +2 -2
  96. package/dist/{table-BbNgtqbd.mjs → table-y0J2_gix.mjs} +1 -1
  97. package/dist/transform-BP8y4jRr.mjs +21 -0
  98. package/dist/transform-job-CjH6-qNC.mjs +19 -0
  99. package/dist/{translate-p5_8y0R7.mjs → translate-DY6xrnmJ.mjs} +5 -5
  100. package/dist/tree-Db0BjcFK.mjs +32 -0
  101. package/dist/{update-Bh9gTZQA.mjs → update-DFlshvJ5.mjs} +7 -7
  102. package/dist/{update-Bz63bSR3.mjs → update-DK8856uS.mjs} +7 -7
  103. package/dist/{update-DbY0q1Ja.mjs → update-DMpYV7ev.mjs} +8 -8
  104. package/dist/update-I04IOKMm.mjs +57 -0
  105. package/dist/{update-dashcard-oH6KxEfS.mjs → update-dashcard-BM3GfQot.mjs} +7 -7
  106. package/dist/{update-CBaL4nmE.mjs → update-voSJcEL1.mjs} +10 -10
  107. package/dist/{url-rF80dSIr.mjs → url-Bdz6hIfi.mjs} +6 -6
  108. package/dist/{validate-query-DE4UouY3.mjs → validate-query-D0aAFTUs.mjs} +49 -3
  109. package/dist/{wait-BMxAPnb0.mjs → wait-DwjJh_Jp.mjs} +2 -2
  110. package/dist/{wait-flags-lGEHf-vx.mjs → wait-flags-jG_4uL02.mjs} +2 -2
  111. package/dist/{wait-CLNtd-on.mjs → wait-y8rVUrfH.mjs} +6 -6
  112. package/dist/workspace-CRVS-7vV.mjs +24 -0
  113. package/package.json +1 -1
  114. package/dist/auth-BV8kyXup.mjs +0 -18
  115. package/dist/card-Dj-6OZZT.mjs +0 -19
  116. package/dist/dashboard-DG6URsA8.mjs +0 -20
  117. package/dist/is-dirty-DG5Samxj.mjs +0 -10
  118. package/dist/ps-D930MtWo.mjs +0 -10
  119. package/dist/sync-BgVaAyuq.mjs +0 -26
  120. package/dist/transform-DpYeGyik.mjs +0 -21
  121. package/dist/transform-job-B1s0Q-rD.mjs +0 -19
  122. package/dist/workspace-BVCgMRZS.mjs +0 -24
  123. /package/dist/{database-B9-7QAXE.mjs → database-C5LkxQ5G.mjs} +0 -0
  124. /package/dist/{field-D_g4xvH9.mjs → field-C1ai7Y05.mjs} +0 -0
  125. /package/dist/{key-CpWh7W8M.mjs → key-CS6durfH.mjs} +0 -0
  126. /package/dist/{prompt-D8p00XDp.mjs → prompt-k9s4Ntk5.mjs} +0 -0
  127. /package/dist/{setting-Bm84ixxW.mjs → setting-DEHSnsEV.mjs} +0 -0
  128. /package/dist/{transform-CRRW0mFp.mjs → transform-MkVM3WhG.mjs} +0 -0
  129. /package/dist/{transform-job-BtCoVYsb.mjs → transform-job-DiK7MZXZ.mjs} +0 -0
  130. /package/dist/{workspace-C3tGVQ6_.mjs → workspace-C8Kgp6BZ.mjs} +0 -0
  131. /package/dist/{workspace-credentials-BxrU2xZb.mjs → workspace-credentials-DuTmzpvd.mjs} +0 -0
package/README.md CHANGED
@@ -63,6 +63,19 @@ metabase auth status --profile staging
63
63
  | `--profile <name>` | Profile to inspect (default: `default`). |
64
64
  | `--json` | Emit JSON. Auto-enabled on non-TTY. |
65
65
 
66
+ ### `metabase auth list`
67
+
68
+ List configured authentication profiles. The index is maintained at `<configDir>/profiles.json` and updated on every `auth login` / `auth logout`. Profiles whose URL/API key were stored in the OS keychain before the index existed are picked up by a one-time backfill from `credentials.json`; profiles that exist only in the keyring (no entry in `credentials.json`) appear after the next `auth login` or `auth logout` against them.
69
+
70
+ ```sh
71
+ metabase auth list
72
+ metabase auth list --json
73
+ ```
74
+
75
+ | Flag | Description |
76
+ | -------- | ----------------------------------- |
77
+ | `--json` | Emit JSON. Auto-enabled on non-TTY. |
78
+
66
79
  ### `metabase auth logout`
67
80
 
68
81
  Clear stored credentials for a profile.
@@ -72,10 +85,10 @@ metabase auth logout --yes
72
85
  metabase auth logout --profile staging --yes
73
86
  ```
74
87
 
75
- | Flag | Description |
76
- | ------------------ | --------------------------------------- |
77
- | `--profile <name>` | Profile to clear (default: `default`). |
78
- | `--yes` | Skip confirmation. Required on non-TTY. |
88
+ | Flag | Description |
89
+ | ------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
90
+ | `--profile <name>` | Profile to clear (default: `default`). |
91
+ | `--yes` | Skip the interactive confirmation prompt. In non-TTY contexts the prompt is skipped automatically (kubectl/gh/docker convention). |
79
92
 
80
93
  ## License
81
94
 
@@ -113,9 +126,9 @@ Clear the stored license.
113
126
  metabase license remove --yes
114
127
  ```
115
128
 
116
- | Flag | Description |
117
- | ------- | --------------------------------------- |
118
- | `--yes` | Skip confirmation. Required on non-TTY. |
129
+ | Flag | Description |
130
+ | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
131
+ | `--yes` | Skip the interactive confirmation prompt. In non-TTY contexts the prompt is skipped automatically (kubectl/gh/docker convention). |
119
132
 
120
133
  Common output flags (`--json`, `--format`, `--detail`, `--fields`, `--max-bytes`) are accepted; the result payload is rendered through the standard output layer.
121
134
 
@@ -162,9 +175,9 @@ Same `--body` / `--file` resolution as `create`. Stdin is auto-detected when not
162
175
  metabase transform delete 1 --yes
163
176
  ```
164
177
 
165
- | Flag | Description |
166
- | ------- | --------------------------------------- |
167
- | `--yes` | Skip confirmation. Required on non-TTY. |
178
+ | Flag | Description |
179
+ | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
180
+ | `--yes` | Skip the interactive confirmation prompt. In non-TTY contexts the prompt is skipped automatically (kubectl/gh/docker convention). |
168
181
 
169
182
  ### `metabase transform run <id>`
170
183
 
@@ -220,9 +233,9 @@ metabase transform-job update 1 --body '{"schedule":"0 0 6 * * ?"}'
220
233
  metabase transform-job delete 1 --yes
221
234
  ```
222
235
 
223
- | Flag | Description |
224
- | ------- | --------------------------------------- |
225
- | `--yes` | Skip confirmation. Required on non-TTY. |
236
+ | Flag | Description |
237
+ | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
238
+ | `--yes` | Skip the interactive confirmation prompt. In non-TTY contexts the prompt is skipped automatically (kubectl/gh/docker convention). |
226
239
 
227
240
  ## Cards
228
241
 
@@ -279,9 +292,28 @@ metabase card create --body '{"name":"x","display":"table","dataset_query":{...}
279
292
  | `--body <json>` | Inline JSON body. |
280
293
  | `--file <path>` | Path to JSON body file. |
281
294
 
295
+ ### `metabase card update <id>`
296
+
297
+ Patch a card. Body is a partial subset of the create shape (`name`, `display`, `dataset_query`, `visualization_settings`, `description`, `archived`, `collection_id`, `dashboard_id`, `cache_ttl`, `parameters`, `parameter_mappings`, etc.). Only the keys you send are touched. If `dataset_query` is MBQL 5 (`lib/type: "mbql/query"`) it goes through the same pre-flight validation as `card create` and `metabase query`; pass `--skip-validate` to bypass.
298
+
299
+ ```sh
300
+ cat patch.json | metabase card update 1
301
+ metabase card update 1 --file patch.json
302
+ metabase card update 1 --body '{"name":"renamed"}'
303
+ metabase card update 1 --body '{"display":"bar"}'
304
+ metabase card update 1 --body '{"archived":true}'
305
+ metabase card update 1 --file patch.json --skip-validate
306
+ ```
307
+
308
+ | Flag | Description |
309
+ | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
310
+ | `--body <json>` | Inline JSON body. |
311
+ | `--file <path>` | Path to JSON body file. |
312
+ | `--skip-validate` | Skip the local MBQL 5 pre-flight validation; let the server be the authority. Use only when the bundled schema disagrees with what the server accepts. |
313
+
282
314
  ### `metabase card archive <id>`
283
315
 
284
- Soft-delete a card by setting `archived: true`. The archived card stays available via `card list --filter archived` and `card get <id>` until permanently deleted server-side.
316
+ Soft-delete a card by setting `archived: true`. The archived card stays available via `card list --filter archived` and `card get <id>` until permanently deleted server-side. To unarchive (or otherwise toggle the flag) use `metabase card update <id> --body '{"archived":false}'`.
285
317
 
286
318
  ```sh
287
319
  metabase card archive 1
@@ -325,16 +357,19 @@ metabase dashboard cards 1 --json
325
357
 
326
358
  ### `metabase dashboard create`
327
359
 
360
+ The body accepts the same dashboard-level fields as the underlying `POST /api/dashboard` (`name`, `description`, `parameters`, `cache_ttl`, `collection_id`, `collection_position`). It also accepts optional `dashcards` and `tabs`: when either is present, the CLI chains a `PUT /api/dashboard/:id` after the create and returns the updated dashboard with its dashcards/tabs applied. Use a negative `id` on a dashcard to indicate one the server should newly create.
361
+
328
362
  ```sh
329
363
  cat dashboard.json | metabase dashboard create
330
364
  metabase dashboard create --file dashboard.json
331
365
  metabase dashboard create --body '{"name":"My Dashboard","collection_id":4}'
366
+ metabase dashboard create --body '{"name":"D","dashcards":[{"id":-1,"card_id":42,"row":0,"col":0,"size_x":12,"size_y":6}]}'
332
367
  ```
333
368
 
334
- | Flag | Description |
335
- | --------------- | ----------------------- |
336
- | `--body <json>` | Inline JSON body. |
337
- | `--file <path>` | Path to JSON body file. |
369
+ | Flag | Description |
370
+ | --------------- | --------------------------------------------------- |
371
+ | `--body <json>` | Inline JSON body. |
372
+ | `--file <path>` | Path to JSON body file. Use `-` to read from stdin. |
338
373
 
339
374
  ### `metabase dashboard update <id>`
340
375
 
@@ -368,6 +403,78 @@ cat patch.json | metabase dashboard update-dashcard 1 5
368
403
 
369
404
  The patch must contain at least one field; an empty object is rejected before the network round-trip.
370
405
 
406
+ ## Collections
407
+
408
+ Read collections on `/api/collection`. Collections are the folders that contain cards, dashboards, and other collections. The list endpoint surfaces a virtual root collection (id `"root"`) alongside regular numeric ids; the get endpoint accepts only the numeric id.
409
+
410
+ ### `metabase collection list`
411
+
412
+ ```sh
413
+ metabase collection list
414
+ metabase collection list --json
415
+ metabase collection list --filter archived --json
416
+ ```
417
+
418
+ | Flag | Description |
419
+ | ------------------- | --------------------------------------------------------------------------------------------------------------- |
420
+ | `--filter <preset>` | One of `all` (default), `archived` (returns the trash collection only), `personal` (only personal collections). |
421
+
422
+ ### `metabase collection get <id>`
423
+
424
+ `<id>` accepts any of: a positive integer collection id, the literal `root` (the virtual "Our analytics" root), the literal `trash` (the trash collection), or a 21-character entity id (NanoID). Anything else is rejected with a `ConfigError` before any HTTP call.
425
+
426
+ ```sh
427
+ metabase collection get 4
428
+ metabase collection get root --json
429
+ metabase collection get trash --json
430
+ metabase collection get voo1If9y8Sld0lXej6xl0 --json
431
+ metabase collection get 4 --json --full
432
+ ```
433
+
434
+ `--full` returns the full hydrated collection including `slug`, `entity_id`, `can_write`, `namespace`, and `personal_owner_id`. The default compact view returns `id`, `name`, `description`, `archived`, `location`, `parent_id`, `type`, `authority_level`, and `is_personal`. The root collection has a stripped-down shape — `archived`, `description`, `location`, `type`, etc. are absent rather than `null`.
435
+
436
+ ### `metabase collection items <id>`
437
+
438
+ List the cards, dashboards, sub-collections, and other content stored inside a collection. The CLI drains all pages of `/api/collection/:id/items`; pass `--limit` to cap the result. `<id>` accepts the same forms as `collection get` — including `root` for top-level content (items there have `collection_id: null`).
439
+
440
+ ```sh
441
+ metabase collection items 4
442
+ metabase collection items root --json
443
+ metabase collection items 4 --models card,dashboard --json
444
+ metabase collection items 4 --pinned-state is_pinned --json
445
+ ```
446
+
447
+ | Flag | Description |
448
+ | ------------------------ | ------------------------------------------------------------------------------------------------------------------ |
449
+ | `--models <csv>` | Restrict to one or more models (`card`, `dataset`, `metric`, `dashboard`, `snippet`, `collection`, `document`, …). |
450
+ | `--archived` | Return archived items instead of unarchived. |
451
+ | `--pinned-state <state>` | One of `all`, `is_pinned`, `is_not_pinned`. |
452
+ | `--limit <n>` | Cap total items returned. Default: drain all pages. |
453
+
454
+ ### `metabase collection tree`
455
+
456
+ Fetch the full collection hierarchy as a nested tree. Output is always JSON — the recursive structure does not render meaningfully as a key/value table.
457
+
458
+ ```sh
459
+ metabase collection tree
460
+ metabase collection tree --json
461
+ ```
462
+
463
+ ### `metabase collection create`
464
+
465
+ Create a collection from a JSON spec. The body accepts the same fields as `POST /api/collection`: `name` (required), `description`, `parent_id` (omit or `null` for the root), `namespace`, and `authority_level`.
466
+
467
+ ```sh
468
+ cat collection.json | metabase collection create
469
+ metabase collection create --file collection.json
470
+ metabase collection create --body '{"name":"My Collection","parent_id":4}'
471
+ ```
472
+
473
+ | Flag | Description |
474
+ | --------------- | --------------------------------------------------- |
475
+ | `--body <json>` | Inline JSON body. |
476
+ | `--file <path>` | Path to JSON body file. Use `-` to read from stdin. |
477
+
371
478
  ## Settings
372
479
 
373
480
  Read and write Metabase instance settings via `/api/setting`. Listing all settings requires admin privileges; per-key reads/writes additionally enforce per-setting access. Setting values are always JSON — `"main"` is the string `main`, `42` is a number, `null` deletes the override and resets the value to its default.
@@ -644,12 +751,12 @@ metabase workspace database deprovision 1 5 --yes
644
751
  metabase workspace database deprovision 1 5 --yes --wait
645
752
  ```
646
753
 
647
- | Flag | Description |
648
- | ----------------- | ------------------------------------------------------------ |
649
- | `--yes` | Skip confirmation. Required on non-TTY. |
650
- | `--wait` | Poll until the database entry is removed from the workspace. |
651
- | `--timeout <ms>` | Polling timeout in ms (default 600000). Used with `--wait`. |
652
- | `--interval <ms>` | Polling interval in ms (default 2000). Used with `--wait`. |
754
+ | Flag | Description |
755
+ | ----------------- | --------------------------------------------------------------------------------------------------------------------------------- |
756
+ | `--yes` | Skip the interactive confirmation prompt. In non-TTY contexts the prompt is skipped automatically (kubectl/gh/docker convention). |
757
+ | `--wait` | Poll until the database entry is removed from the workspace. |
758
+ | `--timeout <ms>` | Polling timeout in ms (default 600000). Used with `--wait`. |
759
+ | `--interval <ms>` | Polling interval in ms (default 2000). Used with `--wait`. |
653
760
 
654
761
  ### Local runtime
655
762
 
@@ -706,10 +813,10 @@ metabase workspace remove 1 --keep-volume --yes
706
813
 
707
814
  Stops and removes the container. By default, also removes the app-db volume — pass `--keep-volume` to preserve it across rebuilds. **Does not affect the remote workspace** on the parent.
708
815
 
709
- | Flag | Description |
710
- | --------------- | ------------------------------------------------------------- |
711
- | `--yes` | Skip confirmation. Required on non-TTY. |
712
- | `--keep-volume` | Preserve the app-db volume (`metabase-workspace-<id>-appdb`). |
816
+ | Flag | Description |
817
+ | --------------- | --------------------------------------------------------------------------------------------------------------------------------- |
818
+ | `--yes` | Skip the interactive confirmation prompt. In non-TTY contexts the prompt is skipped automatically (kubectl/gh/docker convention). |
819
+ | `--keep-volume` | Preserve the app-db volume (`metabase-workspace-<id>-appdb`). |
713
820
 
714
821
  ### `metabase workspace logs <id>`
715
822
 
@@ -849,13 +956,13 @@ Output by mode:
849
956
  - Run failure (no `--dry-run`) — same `{ ok, errors }` envelope on stdout, exit 2, no request made.
850
957
  - Run success — the streamed `CardQueryResult`.
851
958
 
852
- ### MBQL 5 pre-flight in `card create` and `transform create`/`update`
959
+ ### MBQL 5 pre-flight in `card create`/`update` and `transform create`/`update`
853
960
 
854
961
  When the embedded query (`card.dataset_query`, or `transform.source.query` for `source.type: "query"`) is MBQL 5 (`lib/type: "mbql/query"`), it is pre-flight-validated against the same schema as `metabase query`. Validation failure: `{ ok, errors }` envelope on stdout, exit 2, request not made. MBQL 4 (legacy) bodies and Python transform sources skip validation — they're still accepted by the server and we don't ship a schema for them.
855
962
 
856
- Pass `--skip-validate` to bypass the pre-flight on `card create`, `transform create`, or `transform update` — the body is sent as-is and the server is the authority. Same escape hatch as on `metabase query`; use only when the bundled schema disagrees with what the server actually accepts.
963
+ Pass `--skip-validate` to bypass the pre-flight on `card create`, `card update`, `transform create`, or `transform update` — the body is sent as-is and the server is the authority. Same escape hatch as on `metabase query`; use only when the bundled schema disagrees with what the server actually accepts.
857
964
 
858
- Agent discovery path: `metabase __manifest` lists every command's args and description; the description for `card create` and `transform create`/`update` references `metabase query --print-schema` so an agent can fetch the validating schema directly.
965
+ Agent discovery path: `metabase __manifest` lists every command's args and description; the description for `card create`/`update` and `transform create`/`update` references `metabase query --print-schema` so an agent can fetch the validating schema directly.
859
966
 
860
967
  The bundled query schema is synced from a pinned `@metabase/representations` release via `bun run sync:representations`; CI guards against drift.
861
968
 
@@ -6,7 +6,7 @@ var api_key_default = defineCommand({
6
6
  name: "api-key",
7
7
  description: "Manage Metabase API keys"
8
8
  },
9
- subCommands: { create: () => import("./create-DmakvRrX.mjs").then((mod) => mod.default) }
9
+ subCommands: { create: () => import("./create-9c1KP2P_.mjs").then((mod) => mod.default) }
10
10
  });
11
11
 
12
12
  //#endregion
@@ -1,10 +1,10 @@
1
- import "./package-ROuZ4tbw.mjs";
1
+ import "./package-B4PhZz9R.mjs";
2
2
  import "./command-augment-D9pI9Vbh.mjs";
3
- import { renderItem } from "./render-CZNR2MNK.mjs";
3
+ import { renderItem } from "./render-BYWlZPEH.mjs";
4
4
  import "./errors-C6w1eZ1F.mjs";
5
- import { connectionFlags, defineMetabaseCommand, outputFlags, profileFlag } from "./runtime-8SAm0dHE.mjs";
6
- import { parseId } from "./parse-id-CGyF8OPI.mjs";
7
- import { Card, cardView } from "./card-2XdaHHSS.mjs";
5
+ import { connectionFlags, defineMetabaseCommand, outputFlags, profileFlag } from "./runtime-DyNvyYvx.mjs";
6
+ import { parseId } from "./parse-id-Dm8zjjx_.mjs";
7
+ import { Card, cardView } from "./card-BOGKT258.mjs";
8
8
 
9
9
  //#region src/commands/card/archive.ts
10
10
  var archive_default = defineMetabaseCommand({
@@ -0,0 +1,19 @@
1
+ import { defineCommand } from "citty";
2
+
3
+ //#region src/commands/auth/index.ts
4
+ var auth_default = defineCommand({
5
+ meta: {
6
+ name: "auth",
7
+ description: "Authenticate against a Metabase instance"
8
+ },
9
+ default: "login",
10
+ subCommands: {
11
+ login: () => import("./login-xppXbffQ.mjs").then((m) => m.default),
12
+ status: () => import("./status-CsFspRut.mjs").then((m) => m.default),
13
+ list: () => import("./list-B1nz8LEB.mjs").then((m) => m.default),
14
+ logout: () => import("./logout-XtEgcO-n.mjs").then((m) => m.default)
15
+ }
16
+ });
17
+
18
+ //#endregion
19
+ export { auth_default as default };
@@ -1,6 +1,6 @@
1
1
  import { ConfigError } from "./errors-C6w1eZ1F.mjs";
2
- import { readInput } from "./input-DkgCMNA9.mjs";
3
- import { parseJson } from "./runtime-8SAm0dHE.mjs";
2
+ import { readInput } from "./input-DMcm_A5s.mjs";
3
+ import { parseJson } from "./runtime-DyNvyYvx.mjs";
4
4
 
5
5
  //#region src/runtime/body.ts
6
6
  async function readBody(sources, schema) {
@@ -1,10 +1,10 @@
1
- import "./package-ROuZ4tbw.mjs";
1
+ import "./package-B4PhZz9R.mjs";
2
2
  import "./command-augment-D9pI9Vbh.mjs";
3
- import { renderList } from "./render-CZNR2MNK.mjs";
3
+ import { renderList } from "./render-BYWlZPEH.mjs";
4
4
  import "./errors-C6w1eZ1F.mjs";
5
- import { connectionFlags, defineMetabaseCommand, listEnvelopeSchema, outputFlags, profileFlag, wrapList } from "./runtime-8SAm0dHE.mjs";
6
- import { REMOTE_SYNC_PATHS } from "./poll-task-BU0gpBIk.mjs";
7
- import "./poll-B5RO0ias.mjs";
5
+ import { connectionFlags, defineMetabaseCommand, listEnvelopeSchema, outputFlags, profileFlag, wrapList } from "./runtime-DyNvyYvx.mjs";
6
+ import { REMOTE_SYNC_PATHS } from "./poll-task-kULwF-eM.mjs";
7
+ import "./poll-DYp_Lzph.mjs";
8
8
  import { z } from "zod";
9
9
 
10
10
  //#region src/commands/sync/branches.ts
@@ -1,10 +1,10 @@
1
- import "./package-ROuZ4tbw.mjs";
1
+ import "./package-B4PhZz9R.mjs";
2
2
  import "./command-augment-D9pI9Vbh.mjs";
3
- import { renderItem } from "./render-CZNR2MNK.mjs";
3
+ import { renderItem } from "./render-BYWlZPEH.mjs";
4
4
  import "./errors-C6w1eZ1F.mjs";
5
- import { connectionFlags, defineMetabaseCommand, outputFlags, profileFlag } from "./runtime-8SAm0dHE.mjs";
6
- import { REMOTE_SYNC_PATHS, SyncTask, syncTaskView } from "./poll-task-BU0gpBIk.mjs";
7
- import "./poll-B5RO0ias.mjs";
5
+ import { connectionFlags, defineMetabaseCommand, outputFlags, profileFlag } from "./runtime-DyNvyYvx.mjs";
6
+ import { REMOTE_SYNC_PATHS, SyncTask, syncTaskView } from "./poll-task-kULwF-eM.mjs";
7
+ import "./poll-DYp_Lzph.mjs";
8
8
 
9
9
  //#region src/commands/sync/cancel-task.ts
10
10
  var cancel_task_default = defineMetabaseCommand({
@@ -80,6 +80,27 @@ const CardCreateInput = z.object({
80
80
  parameters: z.array(z.unknown()).optional(),
81
81
  parameter_mappings: z.array(z.unknown()).optional()
82
82
  }).loose();
83
+ const CardUpdateInput = z.object({
84
+ name: z.string().min(1).optional(),
85
+ type: CardType.optional(),
86
+ dataset_query: z.unknown().optional(),
87
+ display: z.string().min(1).optional(),
88
+ visualization_settings: z.unknown().optional(),
89
+ description: z.string().nullable().optional(),
90
+ archived: z.boolean().optional(),
91
+ enable_embedding: z.boolean().optional(),
92
+ embedding_type: z.string().optional(),
93
+ embedding_params: z.unknown().optional(),
94
+ collection_id: z.number().int().positive().nullable().optional(),
95
+ collection_position: z.number().int().positive().nullable().optional(),
96
+ collection_preview: z.boolean().optional(),
97
+ cache_ttl: z.number().int().positive().nullable().optional(),
98
+ dashboard_id: z.number().int().positive().nullable().optional(),
99
+ dashboard_tab_id: z.number().int().positive().nullable().optional(),
100
+ parameters: z.array(z.unknown()).optional(),
101
+ parameter_mappings: z.array(z.unknown()).optional(),
102
+ result_metadata: z.array(z.unknown()).nullable().optional()
103
+ }).loose();
83
104
  const QueryColumn = z.object({
84
105
  name: z.string(),
85
106
  display_name: z.string().optional(),
@@ -110,4 +131,4 @@ const cardQueryView = {
110
131
  };
111
132
 
112
133
  //#endregion
113
- export { Card, CardCompact, CardCreateInput, CardQueryResult, cardQueryView, cardView };
134
+ export { Card, CardCompact, CardCreateInput, CardQueryResult, CardUpdateInput, cardQueryView, cardView };
@@ -0,0 +1,20 @@
1
+ import { defineCommand } from "citty";
2
+
3
+ //#region src/commands/card/index.ts
4
+ var card_default = defineCommand({
5
+ meta: {
6
+ name: "card",
7
+ description: "Manage Metabase cards (questions, models, metrics)"
8
+ },
9
+ subCommands: {
10
+ list: () => import("./list-B5KP2eXN.mjs").then((mod) => mod.default),
11
+ get: () => import("./get-BavuL0j2.mjs").then((mod) => mod.default),
12
+ query: () => import("./query-DCnXxe9y.mjs").then((mod) => mod.default),
13
+ create: () => import("./create-Ck-p0-JC.mjs").then((mod) => mod.default),
14
+ update: () => import("./update-I04IOKMm.mjs").then((mod) => mod.default),
15
+ archive: () => import("./archive-B6TbWbK1.mjs").then((mod) => mod.default)
16
+ }
17
+ });
18
+
19
+ //#endregion
20
+ export { card_default as default };
@@ -1,10 +1,10 @@
1
- import "./package-ROuZ4tbw.mjs";
1
+ import "./package-B4PhZz9R.mjs";
2
2
  import "./command-augment-D9pI9Vbh.mjs";
3
- import { renderList } from "./render-CZNR2MNK.mjs";
3
+ import { renderList } from "./render-BYWlZPEH.mjs";
4
4
  import "./errors-C6w1eZ1F.mjs";
5
- import { connectionFlags, defineMetabaseCommand, listEnvelopeSchema, outputFlags, profileFlag, wrapList } from "./runtime-8SAm0dHE.mjs";
6
- import { parseId } from "./parse-id-CGyF8OPI.mjs";
7
- import { DashboardDetail, DashcardCompact, dashcardView } from "./dashboard-DVCLGg3X.mjs";
5
+ import { connectionFlags, defineMetabaseCommand, listEnvelopeSchema, outputFlags, profileFlag, wrapList } from "./runtime-DyNvyYvx.mjs";
6
+ import { parseId } from "./parse-id-Dm8zjjx_.mjs";
7
+ import { DashboardDetail, DashcardCompact, dashcardView } from "./dashboard-BJXi1tGr.mjs";
8
8
 
9
9
  //#region src/commands/dashboard/cards.ts
10
10
  const DashcardListEnvelope = listEnvelopeSchema(DashcardCompact);
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { package_default } from "./package-ROuZ4tbw.mjs";
2
+ import { package_default } from "./package-B4PhZz9R.mjs";
3
3
  import { getMetabaseAugment } from "./command-augment-D9pI9Vbh.mjs";
4
4
  import { defineCommand, renderUsage, runMain } from "citty";
5
5
 
@@ -11,24 +11,25 @@ const main = defineCommand({
11
11
  description: package_default.description
12
12
  },
13
13
  subCommands: {
14
- auth: () => import("./auth-BV8kyXup.mjs").then((mod) => mod.default),
15
- license: () => import("./license-Cr24Ibp3.mjs").then((mod) => mod.default),
16
- db: () => import("./db-BA6VieA7.mjs").then((mod) => mod.default),
17
- table: () => import("./table-BGLcZjyq.mjs").then((mod) => mod.default),
18
- field: () => import("./field-CAvHQkzI.mjs").then((mod) => mod.default),
19
- card: () => import("./card-Dj-6OZZT.mjs").then((mod) => mod.default),
20
- dashboard: () => import("./dashboard-DG6URsA8.mjs").then((mod) => mod.default),
21
- transform: () => import("./transform-DpYeGyik.mjs").then((mod) => mod.default),
22
- "transform-job": () => import("./transform-job-B1s0Q-rD.mjs").then((mod) => mod.default),
23
- setting: () => import("./setting-jFe6Zt2S.mjs").then((mod) => mod.default),
24
- search: () => import("./search-DNvad2hL.mjs").then((mod) => mod.default),
25
- sync: () => import("./sync-BgVaAyuq.mjs").then((mod) => mod.default),
26
- workspace: () => import("./workspace-BVCgMRZS.mjs").then((mod) => mod.default),
27
- setup: () => import("./setup-Cw5pIrBj.mjs").then((mod) => mod.default),
28
- "api-key": () => import("./api-key-aNbgDn-8.mjs").then((mod) => mod.default),
29
- eid: () => import("./eid-DANih6Hk.mjs").then((mod) => mod.default),
30
- query: () => import("./query-DwBWeir4.mjs").then((mod) => mod.default),
31
- __manifest: () => import("./manifest-IMg51yb7.mjs").then((mod) => mod.createManifestCommand(main))
14
+ auth: () => import("./auth-BZofbzqG.mjs").then((mod) => mod.default),
15
+ license: () => import("./license-DfgahRiB.mjs").then((mod) => mod.default),
16
+ db: () => import("./db-DGqKQygl.mjs").then((mod) => mod.default),
17
+ table: () => import("./table-BsdEHMog.mjs").then((mod) => mod.default),
18
+ field: () => import("./field-wJ5IyjF9.mjs").then((mod) => mod.default),
19
+ card: () => import("./card-m-ve7168.mjs").then((mod) => mod.default),
20
+ dashboard: () => import("./dashboard-DE6DQnco.mjs").then((mod) => mod.default),
21
+ collection: () => import("./collection-D3B90qam.mjs").then((mod) => mod.default),
22
+ transform: () => import("./transform-BP8y4jRr.mjs").then((mod) => mod.default),
23
+ "transform-job": () => import("./transform-job-CjH6-qNC.mjs").then((mod) => mod.default),
24
+ setting: () => import("./setting-Cp6Tw2QN.mjs").then((mod) => mod.default),
25
+ search: () => import("./search-CiDweQ6X.mjs").then((mod) => mod.default),
26
+ sync: () => import("./sync-BpO2GELG.mjs").then((mod) => mod.default),
27
+ workspace: () => import("./workspace-CRVS-7vV.mjs").then((mod) => mod.default),
28
+ setup: () => import("./setup-4WZU9ihX.mjs").then((mod) => mod.default),
29
+ "api-key": () => import("./api-key-DJpqrAGZ.mjs").then((mod) => mod.default),
30
+ eid: () => import("./eid-BnfaFBmk.mjs").then((mod) => mod.default),
31
+ query: () => import("./query-BkUL9HyQ.mjs").then((mod) => mod.default),
32
+ __manifest: () => import("./manifest-C7lnUosz.mjs").then((mod) => mod.createManifestCommand(main))
32
33
  }
33
34
  });
34
35
  var main_default = main;
@@ -43,7 +44,7 @@ async function showUsage(cmd, parent) {
43
44
  const stripped = first === void 0 ? "" : first.replace(BREADCRUMB_SUFFIX, "$1");
44
45
  const body = [stripped, ...rest].join("\n");
45
46
  const examples = getMetabaseAugment(cmd)?.examples ?? [];
46
- process.stdout.write(body + renderExamples(examples) + "\n");
47
+ process.stdout.write(body + renderExamples(examples) + renderSchemaHint() + "\n");
47
48
  }
48
49
  function renderExamples(examples) {
49
50
  if (examples.length === 0) return "";
@@ -55,6 +56,14 @@ function renderExamples(examples) {
55
56
  for (const example of examples) lines.push(` ${example}`);
56
57
  return lines.join("\n");
57
58
  }
59
+ function renderSchemaHint() {
60
+ return [
61
+ "",
62
+ "SCHEMA",
63
+ "",
64
+ " metabase __manifest # machine-readable command tree (flags, output, examples)"
65
+ ].join("\n");
66
+ }
58
67
 
59
68
  //#endregion
60
69
  //#region src/cli.ts