@metabase/cli 0.1.15 → 0.1.17
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.
- package/README.md +69 -32
- package/dist/{add-collection-CXhrMjXU.mjs → add-collection-C-t9SQBk.mjs} +5 -5
- package/dist/add-collection-Dek6kiRI.mjs +11 -0
- package/dist/{archive-BUwiCFnd.mjs → archive-C7dnyzVY.mjs} +9 -7
- package/dist/{archive-Blc1dz8Z.mjs → archive-CaoUUTIb.mjs} +8 -7
- package/dist/{archive-D-Ovk0-E.mjs → archive-D1FX-sbU.mjs} +7 -6
- package/dist/{archive-CQiaCBSj.mjs → archive-DS-KEB4a.mjs} +7 -6
- package/dist/{archive-yTvDRQUZ.mjs → archive-LG8u7ec5.mjs} +7 -6
- package/dist/{archive-BxGSR7El.mjs → archive-qSOcACQo.mjs} +8 -6
- package/dist/{archive-Drt-rWvU.mjs → archive-wNXwIiF0.mjs} +8 -7
- package/dist/auth-Kv2MRkRk.mjs +22 -0
- package/dist/{body-B9XTTDEu.mjs → body-IcJ5kFtk.mjs} +3 -3
- package/dist/{branches-Ct3PK5U3.mjs → branches-BlNCTmFB.mjs} +7 -6
- package/dist/{cancel-tST8Bh0w.mjs → cancel-BnveTPNw.mjs} +6 -5
- package/dist/{cancel-task-BHnzRQKL.mjs → cancel-task-CSVI8Zgl.mjs} +7 -6
- package/dist/{capabilities-BX1rnVuH.mjs → capabilities-N0jo5U7S.mjs} +1 -1
- package/dist/card-Bp58WEUF.mjs +26 -0
- package/dist/{card-wCPcuKSi.mjs → card-DEmcRlNO.mjs} +6 -5
- package/dist/{cards-BySIFsLG.mjs → cards-CMgGA8OZ.mjs} +8 -6
- package/dist/cli.mjs +54 -26
- package/dist/collection-D8TI20Ir.mjs +23 -0
- package/dist/{collection-namespace-D8ohM5gD.mjs → collection-namespace-CsaxEqOb.mjs} +2 -2
- package/dist/command-augment-DdZIfx1V.mjs +11 -0
- package/dist/{create-HZ-9GMLx.mjs → create-AeWNv0v-.mjs} +9 -8
- package/dist/create-B1xfaZJB.mjs +35 -0
- package/dist/{create-DxDD6n1d.mjs → create-B6LQutd0.mjs} +17 -12
- package/dist/{create-C7FPeJqF.mjs → create-B79M8YpX.mjs} +10 -9
- package/dist/{create-DGxZmbxh.mjs → create-Bg_uMu0p.mjs} +9 -8
- package/dist/{create-C43RQYgj.mjs → create-BpkWlgoR.mjs} +18 -12
- package/dist/{create-DnT1Sayk.mjs → create-C7u3umLj.mjs} +9 -8
- package/dist/{create-4mAGsBd0.mjs → create-FZOrCw5k.mjs} +21 -12
- package/dist/{create-fIDFkdox.mjs → create-I5Cv-MBa.mjs} +16 -11
- package/dist/{create-D3cVDtxM.mjs → create-LHqwcVbS.mjs} +16 -11
- package/dist/{create-BDWthCYq.mjs → create-SHKlj0z3.mjs} +9 -8
- package/dist/{create-branch-jPE7nW-E.mjs → create-branch-CGyT99Ny.mjs} +7 -6
- package/dist/{current-task-rW54KJax.mjs → current-task-C-0hw2Ae.mjs} +7 -6
- package/dist/dashboard-C9pQCnX6.mjs +28 -0
- package/dist/{dashboard-B4bn3z6t.mjs → dashboard-DOplbKyQ.mjs} +7 -5
- package/dist/{database-BmsxuRmO.mjs → database-D9fftP-i.mjs} +1 -1
- package/dist/db-DWykmBOh.mjs +28 -0
- package/dist/{delete-BWO6uB4P.mjs → delete--NYYN6wv.mjs} +8 -7
- package/dist/{delete-CeigtfRI.mjs → delete-Do3nn9sl.mjs} +8 -7
- package/dist/{delete-runtime-PzLFavb0.mjs → delete-runtime-B0ha5QR4.mjs} +3 -3
- package/dist/{delete-CBwztF6P.mjs → delete-tCVrYjKD.mjs} +8 -7
- package/dist/{delete-table-BXzvDEPG.mjs → delete-table-CWSGPw0i.mjs} +8 -7
- package/dist/{dependencies-D2N9eqm1.mjs → dependencies-CyFocD8I.mjs} +7 -6
- package/dist/{dirty-DoEZRSGB.mjs → dirty-BXM0YJ_a.mjs} +7 -6
- package/dist/document-DNDm8_Py.mjs +22 -0
- package/dist/{eid-1mROiwJr.mjs → eid-p-zn_1RJ.mjs} +13 -7
- package/dist/{error-D5bZ5BUX.mjs → error-5H_tcfL8.mjs} +2 -2
- package/dist/{export-Bgv5B4_F.mjs → export-B_8wghyo.mjs} +9 -8
- package/dist/field-CFt1-KDR.mjs +21 -0
- package/dist/{fields-VA7tXHJz.mjs → fields-BsufL9kv.mjs} +8 -7
- package/dist/{get-DAsaor0n.mjs → get-4lufgahL.mjs} +7 -6
- package/dist/{get-B8etVxWD.mjs → get-68P-L4ja.mjs} +7 -6
- package/dist/{get-qnGGGRTa.mjs → get-B45uYMAs.mjs} +8 -6
- package/dist/get-B67pe00Z.mjs +36 -0
- package/dist/{get-DvQoDU2m.mjs → get-BJoZkATD.mjs} +7 -6
- package/dist/{get-BgIE_YEg.mjs → get-BTKeO4vE.mjs} +7 -6
- package/dist/{get-RQFSmnpY.mjs → get-C7mq17-2.mjs} +7 -6
- package/dist/{get-CGkhSY5L.mjs → get-CDLa6LiC.mjs} +9 -8
- package/dist/{get-D9o38nK5.mjs → get-CPw0ROO4.mjs} +7 -6
- package/dist/{get-Wj88mnhn.mjs → get-Cl5Ak73C.mjs} +9 -7
- package/dist/{get-CqnCaosn.mjs → get-D3k2JUsa.mjs} +7 -6
- package/dist/{get-C-UeGtgW.mjs → get-DTqBuIf3.mjs} +6 -5
- package/dist/{get-eUYDNALt.mjs → get-DeLnNVQE.mjs} +8 -7
- package/dist/{get-DLRBq8kR.mjs → get-Df_3LCVC.mjs} +7 -6
- package/dist/{get-BtAD26gc.mjs → get-DurjkUKJ.mjs} +7 -6
- package/dist/{get-run-CATz-XMS.mjs → get-run-Dq4qfGfD.mjs} +7 -6
- package/dist/git-sync-ByvjqSiy.mjs +31 -0
- package/dist/group-BNE_RiH5.mjs +28 -0
- package/dist/{has-remote-changes-B6YEMC90.mjs → has-remote-changes-E-4N_O_t.mjs} +7 -6
- package/dist/{import-Bl2Wj9Xf.mjs → import-Dg0j3HCP.mjs} +9 -8
- package/dist/{input-BXWgdKiS.mjs → input-7Sj85_K7.mjs} +1 -1
- package/dist/is-dirty-D7UMN0mt.mjs +10 -0
- package/dist/{is-dirty-D9MoFj0T.mjs → is-dirty-DWw1yBeR.mjs} +4 -4
- package/dist/{items-LjtICjvX.mjs → items-CQtt9X4M.mjs} +9 -8
- package/dist/{key-C8q5oIr5.mjs → key-bltP32Pm.mjs} +1 -1
- package/dist/library-B5AvpACG.mjs +24 -0
- package/dist/{list-ChK06rJh.mjs → list-B1uVWy6A.mjs} +8 -6
- package/dist/{list-DaJk60dd.mjs → list-BAOTQHst.mjs} +6 -5
- package/dist/{list-C410Ptw_.mjs → list-BF-W4jOZ.mjs} +9 -7
- package/dist/{list-DMik04Dh.mjs → list-BFVuPodI.mjs} +6 -5
- package/dist/{list-DfoNv0gb.mjs → list-BHAWYZ1z.mjs} +6 -5
- package/dist/{list-DcjenlTM.mjs → list-BKUvhAs4.mjs} +6 -5
- package/dist/{list-Dq86BAMG.mjs → list-BgUWqZa2.mjs} +8 -7
- package/dist/{list-CfWblVHJ.mjs → list-C4bALfCs.mjs} +7 -6
- package/dist/{list-CoRX8Ruc.mjs → list-C9O2RY5u.mjs} +6 -5
- package/dist/{list-cnqPlJgC.mjs → list-CfqpDTna.mjs} +6 -5
- package/dist/{list-C6U3Ftg8.mjs → list-CvhVYOVl.mjs} +7 -6
- package/dist/{list-B5Q7E2Km.mjs → list-D3TSAqwl.mjs} +6 -5
- package/dist/list-D5Gdz8hi.mjs +100 -0
- package/dist/{list-Bjp9nd0o.mjs → list-DG0FIhTK.mjs} +6 -5
- package/dist/{list-DtrfE0sF.mjs → list-KxQNqp4T.mjs} +8 -7
- package/dist/{login-Cn2UtFUt.mjs → login-Bt6j6yBM.mjs} +10 -9
- package/dist/{logout-_HXgEmqA.mjs → logout-ANkL02p0.mjs} +6 -5
- package/dist/{manifest-DYeLri80.mjs → manifest-BVf8P4bl.mjs} +9 -2
- package/dist/measure-CgFwtL1r.mjs +25 -0
- package/dist/{metadata-8yqT8OZI.mjs → metadata-ClehtgZj.mjs} +9 -8
- package/dist/{metadata-DHODjg1d.mjs → metadata-DplshwI3.mjs} +8 -7
- package/dist/{command-augment-CAur0XOQ.mjs → notice-DyVl5aYB.mjs} +1 -11
- package/dist/parameter-CiJ4CwWE.mjs +118 -0
- package/dist/parameter-values-D4J8Ctu0.mjs +56 -0
- package/dist/{parse-enum-BatHQ-Gs.mjs → parse-enum-BL9i_brN.mjs} +1 -1
- package/dist/{parse-id-DNPeV0Iu.mjs → parse-id-D4LeTUsP.mjs} +1 -1
- package/dist/{parse-ref-CZr1bYIl.mjs → parse-ref-CB_KvF9h.mjs} +1 -1
- package/dist/{path-BflajM08.mjs → path-5nQgdvrs.mjs} +6 -5
- package/dist/{poll-CYkX02Bm.mjs → poll-BpAJpvb-.mjs} +2 -2
- package/dist/{poll-task-oXpl3wzp.mjs → poll-task-TilgciQn.mjs} +2 -2
- package/dist/{preflight-BdJr2amA.mjs → preflight-OfHU3Toi.mjs} +4 -4
- package/dist/{process-DsGf7Mg5.mjs → process-j8UHMHc2.mjs} +1 -1
- package/dist/{prompt-Bc_bHSD0.mjs → prompt-C85xd9HR.mjs} +1 -1
- package/dist/publish-DKiqyDwo.mjs +67 -0
- package/dist/{query-CxTjguwp.mjs → query-BWJ5h1g3.mjs} +19 -13
- package/dist/{query-DWQaN7hO.mjs → query-CQ3xXa9P.mjs} +10 -8
- package/dist/{query-result-L5_NrwQR.mjs → query-result-D6mfoVfQ.mjs} +1 -1
- package/dist/{remove-collection-BwcFi8Fs.mjs → remove-collection-CO-aMzTO.mjs} +9 -8
- package/dist/{rescan-values-B9Qtsd32.mjs → rescan-values-DpL6LGAK.mjs} +9 -8
- package/dist/resolve-Dj2MTBkn.mjs +84 -0
- package/dist/{run-C-vftXCu.mjs → run-DUcdaZs3.mjs} +6 -5
- package/dist/{run-3eFtdI2Z.mjs → run-QYJ-mAaG.mjs} +9 -8
- package/dist/{runs-CpRTkn1W.mjs → runs-DgasTnGd.mjs} +8 -7
- package/dist/{runtime-C1QgWHM7.mjs → runtime-BJtuxWM8.mjs} +5 -3
- package/dist/{schema-tables-rdeupgsu.mjs → schema-tables-ooYjimrV.mjs} +8 -7
- package/dist/{schemas-Cr7RjYqV.mjs → schemas-HjFPzsd-.mjs} +6 -5
- package/dist/{search-D7Yq2MDu.mjs → search-vaT5EwhG.mjs} +11 -5
- package/dist/segment-BPC725mo.mjs +25 -0
- package/dist/{selectors-DPc2ZDdd.mjs → selectors-DlmZpo2L.mjs} +4 -4
- package/dist/{set-X2N6x7pe.mjs → set-CLHJauzG.mjs} +9 -8
- package/dist/{set-active-BoBa3pOw.mjs → set-active-oZOUe9V7.mjs} +6 -5
- package/dist/setting-DHYO-W5g.mjs +20 -0
- package/dist/{setup-C47WUieB.mjs → setup-D1de5Sbc.mjs} +8 -7
- package/dist/{skills-CJ8g8fhQ.mjs → skills-B6gfH0iR.mjs} +1 -1
- package/dist/{skills-Po0YPVU5.mjs → skills-NhgVypJ7.mjs} +3 -3
- package/dist/snippet-DtLmHr2J.mjs +22 -0
- package/dist/{stash-BV4sEp73.mjs → stash-DoRwelwY.mjs} +9 -8
- package/dist/{status-BKF9rRnk.mjs → status-BpMOlfsA.mjs} +8 -7
- package/dist/{status-Cf8c0NON.mjs → status-CmRgHTrV.mjs} +6 -5
- package/dist/{summary-RgLcBcEh.mjs → summary-BEu7pmpq.mjs} +7 -6
- package/dist/{sync-schema-DKEel2Sv.mjs → sync-schema-DTUXubMg.mjs} +11 -10
- package/dist/table-B1iBqmNu.mjs +22 -0
- package/dist/{table-qDD2kApF.mjs → table-DE3i82T_.mjs} +9 -2
- package/dist/transform-BuIooRQh.mjs +31 -0
- package/dist/transform-job-C3yz0krA.mjs +25 -0
- package/dist/transform-tag-CJD6mJUe.mjs +21 -0
- package/dist/{transforms-BOQ9CG0l.mjs → transforms-CWvMpLc9.mjs} +7 -6
- package/dist/{tree-CF8mscd9.mjs → tree-D18vYSe4.mjs} +6 -5
- package/dist/{unpublish-CmaRNjK3.mjs → unpublish-CJbL4ZsC.mjs} +20 -18
- package/dist/{update-Kz4kyqY_.mjs → update-7DacwIvi.mjs} +10 -9
- package/dist/{update-CgQOSuZt.mjs → update-BjjZIe2W.mjs} +10 -9
- package/dist/{update-nwXgVNQa.mjs → update-Bos8nnv0.mjs} +18 -13
- package/dist/{update-BXZBEeUp.mjs → update-BvsvyBw9.mjs} +17 -12
- package/dist/{update-DQPg0_-d.mjs → update-CSxwZ2us.mjs} +11 -10
- package/dist/{update-BuypOaXq.mjs → update-Ck0Kxv8u.mjs} +10 -9
- package/dist/{update-B59h7KmS.mjs → update-DV7IY7IQ.mjs} +10 -9
- package/dist/{update-DERsb0eO.mjs → update-DhOfrW1j.mjs} +19 -13
- package/dist/{update-DR4WkAET.mjs → update-Doia9MP_.mjs} +17 -12
- package/dist/{update-rhfPHALN.mjs → update-Dxa_6H2A.mjs} +22 -13
- package/dist/{update-dashcard-BJVeSGvO.mjs → update-dashcard-CZUWZhal.mjs} +11 -9
- package/dist/{update-DoQpy9SA.mjs → update-mr9todHq.mjs} +10 -9
- package/dist/{upgrade-CNrkJF6s.mjs → upgrade-CBW8V9qZ.mjs} +7 -6
- package/dist/{uuid-Dpl3ALKq.mjs → uuid-D6JVJ-R1.mjs} +10 -5
- package/dist/{validate-VawhJ5Sc.mjs → validate-BqNW4Sk1.mjs} +2 -2
- package/dist/{validate-query-CSV-TTnd.mjs → validate-query-CcZVKYPV.mjs} +3 -3
- package/dist/{values-DMYpkoEH.mjs → values-DBvuGnnA.mjs} +7 -6
- package/dist/{verify-By9ZYzx4.mjs → verify-LIShMNZ2.mjs} +2 -2
- package/dist/{wait-BzIAj8lJ.mjs → wait-DUHze3_B.mjs} +8 -7
- package/dist/{wait-flags-DQrxnlwv.mjs → wait-flags-Ybpt98PK.mjs} +2 -2
- package/package.json +1 -1
- package/skill-data/core/SKILL.md +45 -57
- package/skill-data/data-workflow/SKILL.md +116 -0
- package/skill-data/{data-analysis/SKILL.md → data-workflow/references/answering-questions.md} +7 -13
- package/skill-data/{data-transformation/SKILL.md → data-workflow/references/building-clean-tables.md} +46 -48
- package/skill-data/{semantic-layer/SKILL.md → data-workflow/references/reusable-definitions.md} +29 -54
- package/skill-data/document/SKILL.md +10 -20
- package/skill-data/git-sync/SKILL.md +36 -36
- package/skill-data/mbql/SKILL.md +3 -15
- package/skill-data/mbql/references/operators.md +9 -0
- package/skill-data/transform/SKILL.md +26 -42
- package/skill-data/visualization/SKILL.md +6 -6
- package/skill-data/visualization/references/settings.md +12 -0
- package/skills/metabase-cli/SKILL.md +2 -2
- package/dist/add-collection-Bnuh0d4j.mjs +0 -10
- package/dist/auth-Bkue4Psy.mjs +0 -19
- package/dist/card-faWo9ZWU.mjs +0 -20
- package/dist/collection-DcRz7fmf.mjs +0 -20
- package/dist/dashboard-pXAxJTTx.mjs +0 -21
- package/dist/db-CmHHj5eI.mjs +0 -22
- package/dist/document-DQIhL75C.mjs +0 -19
- package/dist/field-B-UcqFzm.mjs +0 -18
- package/dist/git-sync-CwOvcUI2.mjs +0 -28
- package/dist/is-dirty-MT0BT4CS.mjs +0 -9
- package/dist/list-Cx8JxS2C.mjs +0 -42
- package/dist/measure-BIAoqgcS.mjs +0 -19
- package/dist/publish-CGUkIqSm.mjs +0 -70
- package/dist/segment-BN8sFunv.mjs +0 -19
- package/dist/setting-zZjcOPyE.mjs +0 -17
- package/dist/snippet-DK0ZA8m5.mjs +0 -19
- package/dist/table-COAKXNuj.mjs +0 -21
- package/dist/transform-Bto4U82j.mjs +0 -25
- package/dist/transform-job-_fW1y2tg.mjs +0 -22
- package/dist/transform-tag-C8n1oTr1.mjs +0 -18
- package/skill-data/robot-data-engineer/SKILL.md +0 -142
- /package/dist/{body-flags-D7q87Btw.mjs → body-flags-DWTTxJpP.mjs} +0 -0
- /package/dist/{collection-Deiziuu2.mjs → collection-DrLpA1SO.mjs} +0 -0
- /package/dist/{document-qfwR0r63.mjs → document-1W7NRaO_.mjs} +0 -0
- /package/dist/{field-E0IBy4Uw.mjs → field-CMY_LWUe.mjs} +0 -0
- /package/dist/{measure-JJAdFoqK.mjs → measure-DoJvtCaA.mjs} +0 -0
- /package/dist/{paginate-BexjkjbY.mjs → paginate-FVZUxL4J.mjs} +0 -0
- /package/dist/{render-CkuFkWlQ.mjs → render-BTKnWL0d.mjs} +0 -0
- /package/dist/{revision-message-flag-C7zBeWEt.mjs → revision-message-flag-CHrJgFFx.mjs} +0 -0
- /package/dist/{segment-B9SEv9V_.mjs → segment-TXktTCfU.mjs} +0 -0
- /package/dist/{setting-i0pugNHl.mjs → setting-m46MUtW5.mjs} +0 -0
- /package/dist/{snippet-NNzqlksR.mjs → snippet-CtA2Pkoa.mjs} +0 -0
- /package/dist/{transform-n376akp8.mjs → transform-DEF38FWe.mjs} +0 -0
- /package/dist/{transform-job-C8lIS-7Q.mjs → transform-job-CtixL4An.mjs} +0 -0
- /package/dist/{transform-tag-DB46AhAj.mjs → transform-tag-rsIrckCM.mjs} +0 -0
|
@@ -6,39 +6,11 @@ allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
|
6
6
|
|
|
7
7
|
# git-sync (representations ↔ instance)
|
|
8
8
|
|
|
9
|
-
Metabase content (cards, dashboards, transforms, snippets, collections, …) can live in a git repo as YAML and round-trip in and out of a Metabase instance via the `git-sync` verbs. The instance is configured with a `remote-sync-*` settings block (URL, branch, token, type read-only/read-write); the CLI drives the sync tasks against `/api/ee/remote-sync/*`.
|
|
9
|
+
Metabase content (cards, dashboards, transforms, snippets, collections, …) can live in a git repo as YAML and round-trip in and out of a Metabase instance via the `git-sync` verbs. The instance is configured with a `remote-sync-*` settings block (URL, branch, token, type read-only/read-write); the CLI drives the sync tasks against `/api/ee/remote-sync/*`. Only collections flagged for sync serialize; everything else is local-only.
|
|
10
10
|
|
|
11
|
-
This skill covers the import/export workflow.
|
|
11
|
+
This skill covers the import/export workflow. Flag conventions and auth setup live in `core` (`mb skills get core`). To author content YAML by hand: the per-resource clause and settings shapes mirror the API form — query bodies follow the `mbql` skill, `visualization_settings` follow the `visualization` skill — except the portable YAML uses **name-based** references (e.g. `[Sample Database, PUBLIC, ORDERS, TOTAL]`, and entity-ids for cross-entity FKs) where the API form uses numeric ids. For the on-disk folder layout, model new files on what the synced repo already contains.
|
|
12
12
|
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
The set of directories under sync is governed by which **collections** carry `is_remote_synced: true`. Every collection so flagged serializes to its own folder under `collections/` in the repo; everything outside that set is local-only. The CLI exposes per-collection toggles that route to the underlying bulk endpoint (`PUT /api/ee/remote-sync/settings`):
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
mb git-sync add-collection <collection-id> --profile <n> --json
|
|
19
|
-
mb git-sync remove-collection <collection-id> --profile <n> --json
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
`<collection-id>` is a **positive integer**. The bulk endpoint's schema is `pos-int? → boolean`; nano-id / `root` / `trash` refs (which `collection get` accepts) are not supported here. Get the id from `mb collection list --profile <n> --json` first.
|
|
23
|
-
|
|
24
|
-
Both verbs return `{ success: true, task_id?: <id> }`. The optional `task_id` only appears when the toggle triggered a follow-up task (e.g., a finalization import after switching to read-only mode); for a normal add/remove in read-write, expect `{ success: true }` and nothing else.
|
|
25
|
-
|
|
26
|
-
**Cascade.** A toggle on a parent cascades to every descendant by `location` prefix — `add-collection 4` flips `4` plus every collection nested under it. `remove-collection 4` is the symmetric inverse. There is no per-leaf-only mode.
|
|
27
|
-
|
|
28
|
-
**Mode prerequisite.** The server rejects toggles while `remote-sync-type` is `:read-only` (the install default). If `mb git-sync add-collection 12` returns `Metabase returned 400 … Cannot change synced collections when remote-sync-type is read-only.`, switch first with:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
mb setting set remote-sync-type '"read-write"' --profile <n>
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
(Mind the inner double quotes — `setting set` parses the value as strict JSON.) The server also rejects switching to `:read-only` while the Remote Sync collection is dirty; export or `--force` import first if you're going the other way.
|
|
35
|
-
|
|
36
|
-
**Verifying the result.** The CLI's `Collection` schema doesn't yet expose `is_remote_synced`, so `collection get --json` won't show the flag. The pragmatic confirmation paths are:
|
|
37
|
-
|
|
38
|
-
- `mb git-sync is-dirty --profile <n> --json` after editing a card in the now-synced collection — a `true` reading proves it's tracked.
|
|
39
|
-
- The Metabase Admin UI's Remote Sync page renders the per-collection toggles.
|
|
40
|
-
|
|
41
|
-
## Read state before mutating
|
|
13
|
+
## Precondition: read state before mutating
|
|
42
14
|
|
|
43
15
|
Always run `status` (or `is-dirty` + `has-remote-changes`) before `import` or `export`. Importing on a dirty instance silently rejects unless you pass `--force`; exporting when the instance is behind the remote pushes a stale state.
|
|
44
16
|
|
|
@@ -50,7 +22,7 @@ mb git-sync dirty --profile <n> --json # → list the dirty obje
|
|
|
50
22
|
mb git-sync current-task --profile <n> --json # → in-flight task (or idle)
|
|
51
23
|
```
|
|
52
24
|
|
|
53
|
-
**Clean up before exporting.** If you've created entities you intend to delete (a failed transform you're going to retry, a card you authored to test a body shape, a draft dashboard) — do the deletes _before_ the first `git-sync export`. Once committed, the cleanup needs a second commit, and the failed entity stays visible in `git log` forever. For
|
|
25
|
+
**Clean up before exporting.** If you've created entities you intend to delete (a failed transform you're going to retry, a card you authored to test a body shape, a draft dashboard) — do the deletes _before_ the first `git-sync export`. Once committed, the cleanup needs a second commit, and the failed entity stays visible in `git log` forever. For transforms, prefer `transform update <id>` over delete + create (see the `transform` skill).
|
|
54
26
|
|
|
55
27
|
## Import (remote → instance)
|
|
56
28
|
|
|
@@ -71,8 +43,8 @@ Pulls the configured branch and applies it to the instance. Polls until the task
|
|
|
71
43
|
|
|
72
44
|
Workflow:
|
|
73
45
|
|
|
74
|
-
1.
|
|
75
|
-
2. `
|
|
46
|
+
1. Read state (above) — confirm `dirty: false` (or `--force` is intended).
|
|
47
|
+
2. Confirm `has-remote-changes` reports there's actually something to import.
|
|
76
48
|
3. `git-sync import --branch <branch>` — runs to terminal status by default.
|
|
77
49
|
|
|
78
50
|
## Export (instance → remote)
|
|
@@ -93,7 +65,7 @@ Pushes Metabase-side changes back to the configured remote. `-m` is the commit m
|
|
|
93
65
|
Workflow:
|
|
94
66
|
|
|
95
67
|
1. **Branch guard** (below) — confirm the instance isn't tracking `main`/`master`, or that the user has explicitly accepted exporting to it.
|
|
96
|
-
2. `
|
|
68
|
+
2. Read state (above) — confirm `is-dirty` reports there's something to export.
|
|
97
69
|
3. `git-sync export -m "..."` — pushes and polls.
|
|
98
70
|
4. (Optional) `git-sync status` — verify `dirty: false` after.
|
|
99
71
|
|
|
@@ -131,6 +103,34 @@ mb git-sync cancel-task --profile <n> # cancel the in-flight task
|
|
|
131
103
|
|
|
132
104
|
Use `wait` after `import --no-wait` / `export --no-wait`. Use `cancel-task` if a git-sync task hangs and you want to abandon it.
|
|
133
105
|
|
|
106
|
+
## Adding / removing a directory (collection) to sync
|
|
107
|
+
|
|
108
|
+
The set of directories under sync is governed by which **collections** carry `is_remote_synced: true`. Every collection so flagged serializes to its own folder under `collections/` in the repo; everything outside that set is local-only. The CLI exposes per-collection toggles that route to the underlying bulk endpoint (`PUT /api/ee/remote-sync/settings`):
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
mb git-sync add-collection <collection-id> --profile <n> --json
|
|
112
|
+
mb git-sync remove-collection <collection-id> --profile <n> --json
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
`<collection-id>` is a **positive integer** (the bulk endpoint's schema is `pos-int? → boolean`; nano-id / `root` / `trash` refs are not supported). Get the id from `collection list` (see `core`).
|
|
116
|
+
|
|
117
|
+
Both verbs return `{ success: true, task_id?: <id> }`. The optional `task_id` only appears when the toggle triggered a follow-up task (e.g., a finalization import after switching to read-only mode); for a normal add/remove in read-write, expect `{ success: true }` and nothing else.
|
|
118
|
+
|
|
119
|
+
**Cascade.** A toggle on a parent cascades to every descendant by `location` prefix — `add-collection 4` flips `4` plus every collection nested under it. `remove-collection 4` is the symmetric inverse. There is no per-leaf-only mode.
|
|
120
|
+
|
|
121
|
+
**Mode prerequisite.** The server rejects toggles while `remote-sync-type` is `:read-only` (the install default). If `mb git-sync add-collection 12` returns `Metabase returned 400 … Cannot change synced collections when remote-sync-type is read-only.`, switch first with:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
mb setting set remote-sync-type '"read-write"' --profile <n>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
(`setting set` parses the value as strict JSON — mind the inner double quotes; see `core`.) The server also rejects switching to `:read-only` while the Remote Sync collection is dirty; export or `--force` import first if you're going the other way.
|
|
128
|
+
|
|
129
|
+
**Verifying the result.** The CLI's `Collection` schema doesn't yet expose `is_remote_synced`, so `collection get --json` won't show the flag. The pragmatic confirmation paths are:
|
|
130
|
+
|
|
131
|
+
- `mb git-sync is-dirty --profile <n> --json` after editing a card in the now-synced collection — a `true` reading proves it's tracked.
|
|
132
|
+
- The Metabase Admin UI's Remote Sync page renders the per-collection toggles.
|
|
133
|
+
|
|
134
134
|
## Don't (git-sync-specific)
|
|
135
135
|
|
|
136
136
|
- Don't run `git-sync import --force` or `git-sync export --force` without explicit user confirmation. Both are lossy — `--force` import discards instance-side work, `--force` export overwrites the remote branch.
|
|
@@ -138,4 +138,4 @@ Use `wait` after `import --no-wait` / `export --no-wait`. Use `cancel-task` if a
|
|
|
138
138
|
- Don't author content directly via `card create` / `transform create` and then assume `git-sync export` will commit it cleanly — the instance and repo can drift if you mix direct API writes with sync-tracked changes. If you do, follow direct writes immediately with `git-sync export -m "..."` to keep them in step.
|
|
139
139
|
- Don't omit `-m` on `export` if the user wants a meaningful commit message — the default server-generated message is generic.
|
|
140
140
|
- Don't `git-sync export` to `main`/`master` without explicit user confirmation — sync work is conventionally on a feature branch. See "Branch guard" above.
|
|
141
|
-
- Don't reach for `mb setting set` to mark a collection as remote-synced — that endpoint writes single-key settings, not the bulk `collections` map. Use `mb git-sync add-collection <id>` / `mb git-sync remove-collection <id>` (
|
|
141
|
+
- Don't reach for `mb setting set` to mark a collection as remote-synced — that endpoint writes single-key settings, not the bulk `collections` map. Use `mb git-sync add-collection <id>` / `mb git-sync remove-collection <id>` (above), and remember the toggle cascades to descendants.
|
package/skill-data/mbql/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: mbql
|
|
3
|
-
description: Author
|
|
3
|
+
description: Author and debug MBQL 5 query bodies for the `mb` CLI — the only hand-authorable query format. Covers the JSON shape (flat numeric-id stages, options-object-second clauses, optional lib/uuid), joins and FK traversal, multi-stage pipelines, aggregation naming, the flat-vs-legacy-envelope footgun, and the print-schema → dry-run → run validation loop. Use when writing or fixing any query body — `mb query`, a card's `dataset_query`, a transform's `source.query`, or a segment/measure `definition` — or when `--dry-run`/run reports validation errors. Triggers — "write an MBQL query", "the dataset_query is wrong", "aggregate and group by", "join two tables", "month-over-month".
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ MBQL 5 is the **only query format you can author by hand** with confidence — i
|
|
|
10
10
|
|
|
11
11
|
Prefer MBQL over native SQL: portable across warehouse engines and pre-flight-validated. Try it first; fall back to native SQL when MBQL can't express what you need, or when an MBQL body keeps failing server-side and you can't resolve it.
|
|
12
12
|
|
|
13
|
-
General flag conventions, body-input precedence,
|
|
13
|
+
General flag conventions, body-input precedence, output flags, `./.scratch`, and `mb uuid` mechanics live in `core` (`mb skills get core`).
|
|
14
14
|
|
|
15
15
|
## The shape
|
|
16
16
|
|
|
@@ -64,11 +64,7 @@ Set an explicit `lib/uuid` only when you must **reference a clause from elsewher
|
|
|
64
64
|
|
|
65
65
|
(`AGG_UUID` is both the aggregation's own `lib/uuid` and the string the ref points at — one value, by string equality. Every other clause omits its UUID. Expression refs work the same way but key off the expression's `lib/expression-name` string, so expressions rarely need an explicit `lib/uuid`.)
|
|
66
66
|
|
|
67
|
-
When you do need one, **always mint it with `mb uuid` — never write, guess, or copy a UUID yourself.** A hand-authored value is rejected pre-flight as not-a-v4 (`"a1"`, `"uuid-1"`, `"agg-uuid-001"` →
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
mb uuid --count 2 --json # mint only the clauses you actually reference
|
|
71
|
-
```
|
|
67
|
+
When you do need one, **always mint it with `mb uuid` — never write, guess, or copy a UUID yourself.** A hand-authored value is rejected pre-flight as not-a-v4 (`"a1"`, `"uuid-1"`, `"agg-uuid-001"` → ``must be a UUID v4 (RFC 4122) — run `mb uuid` ``), or if it looks valid risks colliding with another clause. Mint just the few you reference (`mb uuid --count 2 --json`; this also covers native template-tag ids and any other `format: "uuid"` slot).
|
|
72
68
|
|
|
73
69
|
## Authoring loop: print-schema → dry-run → run
|
|
74
70
|
|
|
@@ -213,11 +209,3 @@ mb skills path mbql # → the skill dir; then Read references/operator
|
|
|
213
209
|
```
|
|
214
210
|
|
|
215
211
|
`mb query --print-schema` is the exhaustive-but-heavy fallback (the full JSON Schema, ~1600 lines). The cheat-sheet covers the vocabulary; the `--dry-run` loop settles any disagreement.
|
|
216
|
-
|
|
217
|
-
## Don't
|
|
218
|
-
|
|
219
|
-
- Don't mint a `lib/uuid` for every clause — they're optional; omit them and the server fills them in. Mint (with `mb uuid`) only the clause you need to reference; never invent, hard-code, or copy a UUID (duplicates are rejected server-side).
|
|
220
|
-
- Keep the options object in slot 1 of every clause — `[op, {options}, ...args]`, id last (`["field", {}, 1779]`). The legacy `["field", id, opts]` order (id second) is rejected pre-flight.
|
|
221
|
-
- Don't wrap an MBQL 5 body in `{type:"query", query:…}` — `dataset_query` / `source.query` / `definition` is the flat `mbql/query`.
|
|
222
|
-
- Don't author MBQL 4 by hand — build it in the UI and pull it with `… get <id> --full --json`.
|
|
223
|
-
- Don't skip the `--dry-run` loop on a non-trivial query — it's free and exact.
|
|
@@ -11,6 +11,15 @@ when noted: an operator-specific option named in the row, or an explicit `lib/uu
|
|
|
11
11
|
you mint to reference the clause. Field refs are numeric: `["field", {…}, <field-id>]`.
|
|
12
12
|
Everything here passes `mb query --dry-run`; when in doubt, that loop is the authority.
|
|
13
13
|
|
|
14
|
+
**Contents**
|
|
15
|
+
|
|
16
|
+
- [Filter operators](#filter-operators) — Logical, Comparison, Null/empty, String match, Temporal, Segment
|
|
17
|
+
- [Aggregation functions](#aggregation-functions) — including naming and the `offset` window function
|
|
18
|
+
- [Expression operators](#expression-operators) — Arithmetic, Math, String, Temporal, Type conversion, Conditional
|
|
19
|
+
- [References (within clauses)](#references-within-clauses) — field, expression, aggregation
|
|
20
|
+
- [Field option: temporal bucketing](#field-option-temporal-bucketing)
|
|
21
|
+
- [Field option: binning](#field-option-binning)
|
|
22
|
+
|
|
14
23
|
> For relative date filters, prefer **`time-interval`** / **`relative-time-interval`**
|
|
15
24
|
> (below). `relative-datetime` / `absolute-datetime` literals (e.g. from a UI-built
|
|
16
25
|
> query) also work.
|
|
@@ -8,7 +8,7 @@ allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
|
8
8
|
|
|
9
9
|
A **transform** persists the result of a query (native SQL or MBQL) to a warehouse table the user can read from cards, dashboards, and other transforms. It runs on a schedule (via `transform-job`) or on-demand (`transform run`).
|
|
10
10
|
|
|
11
|
-
Flag conventions, body-input precedence, and
|
|
11
|
+
Flag conventions, body-input precedence, and the `./.scratch` convention live in `core` (`mb skills get core`). Deciding _which_ transforms to build — modeling a whole raw database into clean, analysis-ready tables — is the `data-workflow` skill's build-clean-tables stage (`mb skills get data-workflow`).
|
|
12
12
|
|
|
13
13
|
## Body shape
|
|
14
14
|
|
|
@@ -17,14 +17,13 @@ A transform has two halves:
|
|
|
17
17
|
- `source` — the query to run (`type: "query"`, with `query.type` of `native` or `mbql`).
|
|
18
18
|
- `target` — the warehouse destination (`type: "table"`, with `database`, `schema`, `name`).
|
|
19
19
|
|
|
20
|
-
Native SQL is the simplest source and the easiest to author by hand. MBQL is
|
|
21
|
-
|
|
22
|
-
For an **MBQL 5** `source.query` (`lib/type: "mbql/query"`), the body shape, the "options object is always second" clause rule, UUID minting, aggregation/order-by refs, naming aggregation output columns, and the `--print-schema` → `--dry-run` validation loop are all in the `mbql` skill — **`mb skills get mbql`**. The MBQL-5 pre-flight on `transform create`/`update` is documented there too (legacy MBQL 4 and native sources skip it). For a transform target, naming your aggregation output columns matters more than usual — a bare `count` / `avg_2` becomes the warehouse column name; see the `mbql` skill's "Naming aggregation output columns".
|
|
20
|
+
Native SQL is the simplest source and the easiest to author by hand. For an **MBQL 5** `source.query` (`lib/type: "mbql/query"`) — the body shape, the options-object-is-always-second clause rule, UUID minting, aggregation/order-by refs, naming aggregation output columns, the `--print-schema` → `--dry-run` validation loop, and the MBQL-5 pre-flight that `transform create`/`update` run (legacy MBQL 4 and native sources skip it) — see `mbql` (**`mb skills get mbql`**). Pull a sample MBQL body with `mb transform get <id> --full --json`. For a transform target, naming aggregation output columns matters more than usual: a bare `count` / `avg_2` becomes the warehouse column name.
|
|
23
21
|
|
|
24
22
|
## Create + run (native SQL)
|
|
25
23
|
|
|
24
|
+
**Keep the SQL formatted.** Author it multi-line in `./.scratch/<name>.sql` and embed with `jq --rawfile` (jq ≥1.6, which JSON-encodes the file so newlines become `\n`). The stored `native.query` is what `mb transform get` and the Metabase editor render — a single-line blob is valid JSON but unreadable when anyone opens the transform. Single-quote the heredoc delimiter (`<<'SQL'`) so the shell leaves `$vars` in the query alone (e.g. Postgres `$1`, `$$`).
|
|
25
|
+
|
|
26
26
|
```bash
|
|
27
|
-
# Author the SQL formatted — it's what `mb transform get` and the Metabase editor show.
|
|
28
27
|
cat > ./.scratch/user_counts_by_signup_year.sql <<'SQL'
|
|
29
28
|
SELECT
|
|
30
29
|
date_trunc('year', created_at)::date AS signup_year,
|
|
@@ -34,7 +33,6 @@ GROUP BY 1
|
|
|
34
33
|
ORDER BY 1
|
|
35
34
|
SQL
|
|
36
35
|
|
|
37
|
-
# Embed it with jq --rawfile so the newlines survive as \n in valid JSON (don't hand-write the SQL as one line).
|
|
38
36
|
jq -n --rawfile q ./.scratch/user_counts_by_signup_year.sql \
|
|
39
37
|
'{ name: "user_counts_by_signup_year",
|
|
40
38
|
description: "Sample transform: counts users by year of signup",
|
|
@@ -46,17 +44,13 @@ TRANSFORM_ID=$(mb transform create --file ./.scratch/transform.json --profile <n
|
|
|
46
44
|
mb transform run "$TRANSFORM_ID" --wait --profile <name> --json
|
|
47
45
|
```
|
|
48
46
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
53
|
-
-
|
|
54
|
-
-
|
|
55
|
-
-
|
|
56
|
-
- **Keep the SQL formatted.** Author it multi-line in `./.scratch/<name>.sql` and embed with `jq --rawfile` (jq ≥1.6, which JSON-encodes the file so newlines become `\n`). The stored `native.query` is what `mb transform get` and the Metabase editor render — a single-line blob is valid JSON but unreadable when anyone opens the transform. Single-quote the heredoc delimiter (`<<'SQL'`) so the shell leaves `$vars` in the query alone (e.g. Postgres `$1`, `$$`).
|
|
57
|
-
- `transform create --json` returns the agent-facing compact projection: `{id, name, description, source_type, target: {type, database, schema, name}, target_db_id}`. Read `target.schema`/`target.name` directly off the create output — no follow-up `transform get` needed to verify where the transform will write.
|
|
58
|
-
- If a transform with the same `name` already has a YAML representation on disk under the configured remote-sync repo, `create` mints a `_2` suffix on the exported filename (the new transform gets a fresh `entity_id`; the prior one isn't touched). For "iterate on the same concept" workflows, prefer `transform update <id>` — see "Iterating on a failing transform" below.
|
|
59
|
-
- **`collection_id` only accepts a collection in the `:transforms` namespace.** Transforms aren't filed next to cards and dashboards — passing a normal analytics collection id (the kind a dashboard lives in) fails create/update with `collection_id: A Transform can only go in Collections in the :transforms namespace.` Omit `collection_id` to leave the transform uncollected (the common case), or create one with `mb collection create --body '{"name":"…"}' --namespace transforms --json` and pass the returned `id`. Cards and dashboards you build **on top of** the transform's output table go in ordinary collections as usual — so "put the transform and its dashboard in collection X" generally means _X holds the dashboard + cards; the transform stays in the transforms namespace._
|
|
47
|
+
- `<db-id>` comes from `mb database list --profile <name> --json`; ids are per-instance. Target `schema` is the schema the result table is written into (e.g. `public`).
|
|
48
|
+
- `--wait` polls until status is `succeeded` or `failed`. Without it you get only `{message: "Transform run started", run_id, final: null}` and must poll yourself — don't put bare `transform run` in a tight loop; let `--wait` do the polling.
|
|
49
|
+
- `--sync` implies `--wait`, then waits until the run registers its output table (the run registers it itself — no `db sync-schema` needed), adding `target_table_id` to the envelope. Use it when you'll build MBQL on the output (see "Inspect").
|
|
50
|
+
- The `--json` envelope is shape-stable: `{message, run_id, final}` (plus `target_table_id` under `--sync` — a number, or `null` if the table didn't register before the timeout). `final` is `null` when `--wait` is omitted or the run never started, otherwise a full `TransformRun` with `status` and `message`. On a failed run (`final.status` ∈ {`failed`, `timeout`, `canceled`}) the CLI exits 1 and writes a one-line `transform run <id> failed` to stderr; the failure detail lives only in `final.message` on stdout, so `jq -r '.final.message'` is where to look.
|
|
51
|
+
- `transform create --json` returns the agent-facing compact projection: `{id, name, description, source_type, target: {type, database, schema, name}, target_db_id}`. Read `target.schema`/`target.name` directly off it — no follow-up `transform get`.
|
|
52
|
+
- If a transform with the same `name` already has a YAML representation on disk under the configured remote-sync repo, `create` mints a `_2` suffix on the exported filename (the new transform gets a fresh `entity_id`; the prior one isn't touched). For "iterate on the same concept", prefer `transform update <id>` — see "Iterating on a failing transform".
|
|
53
|
+
- **`collection_id` only accepts a collection in the `:transforms` namespace.** Transforms aren't filed next to cards and dashboards — a normal analytics collection id fails create/update with `collection_id: A Transform can only go in Collections in the :transforms namespace.` Omit `collection_id` to leave the transform uncollected (the common case), or provision one with `mb collection create --body '{"name":"…"}' --namespace transforms --json` (see `core`) and pass the returned `id`. Cards and dashboards you build **on top of** the output table go in ordinary collections — so "put the transform and its dashboard in collection X" means _X holds the dashboard + cards; the transform stays in the transforms namespace._
|
|
60
54
|
|
|
61
55
|
## Inspect
|
|
62
56
|
|
|
@@ -66,7 +60,7 @@ mb transform get <id> --profile <name> --full --json # full transform i
|
|
|
66
60
|
mb transform dependencies <id> --profile <name> --json # upstream transforms this one must run after
|
|
67
61
|
```
|
|
68
62
|
|
|
69
|
-
After a run the table physically exists in the warehouse, but Metabase addresses tables/columns by numeric id, so **MBQL and the UI can't reference a brand-new table until the instance syncs** (native SQL — a native `card` or `mb query` against `<schema>.<name>` — reads it immediately). Run and register in one step with `--sync
|
|
63
|
+
After a run the table physically exists in the warehouse, but Metabase addresses tables/columns by numeric id, so **MBQL and the UI can't reference a brand-new table until the instance syncs** (native SQL — a native `card` or `mb query` against `<schema>.<name>` — reads it immediately). Run and register in one step with `--sync`:
|
|
70
64
|
|
|
71
65
|
```bash
|
|
72
66
|
TABLE_ID=$(mb transform run <id> --sync --profile <name> --json | jq -r '.target_table_id')
|
|
@@ -91,12 +85,10 @@ mb transform get-run <run-id> --profile <name> --json
|
|
|
91
85
|
mb transform cancel <id> --profile <name> --json
|
|
92
86
|
```
|
|
93
87
|
|
|
94
|
-
Notes:
|
|
95
|
-
|
|
96
88
|
- `transform runs` and `transform get-run` parse against the same `TransformRun` schema, so `get-run` returns the same per-run shape as one entry of `runs`. The compact projection is `{id, transform_id, status, run_method, start_time, end_time, message}`. Pass `--full` on `get-run` for the hydrated row including `is_active`, `user_id`, `transform_name`, `transform_entity_id`, `checkpoint_*` fields, and a nested `transform: {id, name, …}` block.
|
|
97
|
-
- `transform cancel` takes the **transform** id and 404s with `Endpoint not found — is this a Metabase instance?` if there is no active run.
|
|
98
|
-
- For native
|
|
99
|
-
- The `--transform-id` filter on `runs` accepts a single integer
|
|
89
|
+
- `transform cancel` takes the **transform** id and returns `{canceled: true, id: <transform-id>}`. It 404s with `Endpoint not found — is this a Metabase instance?` if there is no active run.
|
|
90
|
+
- **Cancel semantics differ by source.** For native SQL, cancel marks the run `canceling` but does **not** kill the warehouse query mid-flight — the query runs to completion, then the run lands as `canceled` (or stays `succeeded` if the cancel arrived after the writer committed). For Python transforms the worker is interrupted directly. Don't expect cancel to free warehouse resources instantly on long native queries; expect it to flip state and prevent downstream consumers from treating the result as good.
|
|
91
|
+
- The `--transform-id` filter on `runs` accepts a single integer (translated to the server's `transform-ids` vector). To cross-filter multiple transforms, run `transform runs --json` and `jq` post-hoc.
|
|
100
92
|
|
|
101
93
|
## Update body: send only writable keys, never round-trip the GET body
|
|
102
94
|
|
|
@@ -107,7 +99,7 @@ name, description, source, target, run_trigger,
|
|
|
107
99
|
tag_ids, collection_id, owner_user_id, owner_email
|
|
108
100
|
```
|
|
109
101
|
|
|
110
|
-
**
|
|
102
|
+
**Never paste the output of `transform get` into a `transform update` body.** The GET response carries server-side fields (`id`, `entity_id`, `created_at`, `updated_at`, `creator_id`, `last_run`, `target_db_id`, `target_table_id`, `source_type`, `source_database_id`, `source_readable`, `creator`, `owner`, `table`, …) that the PUT endpoint isn't built to handle. Unknown top-level keys flow into `t2/update!` and leak a raw H2 SQL error like:
|
|
111
103
|
|
|
112
104
|
```
|
|
113
105
|
Column "TAGS" not found; SQL statement:
|
|
@@ -116,11 +108,11 @@ UPDATE "TRANSFORM" SET "TAGS" = (), "UPDATED_AT" = NOW() WHERE "ID" = ? [42122-2
|
|
|
116
108
|
|
|
117
109
|
Three specific footguns:
|
|
118
110
|
|
|
119
|
-
- **`tags` is not a
|
|
111
|
+
- **`tags` is not a REST key.** The serdes/YAML representation uses `tags`; the REST contract uses `tag_ids` (an array of integer ids). If you pulled a YAML representation and want to PUT it, translate `tags: [...]` → `tag_ids: [...]` first (or omit it if you're not changing tag membership).
|
|
120
112
|
- **`source_type`, `target_db_id`, `target_table_id`, `entity_id`** are derived/computed by the server. They appear in GET responses for the agent's benefit; the server doesn't accept them on update.
|
|
121
|
-
- **`collection_id` must be a `:transforms`-namespace collection** — a regular card/dashboard collection id is rejected with `A Transform can only go in Collections in the :transforms namespace.`
|
|
113
|
+
- **`collection_id` must be a `:transforms`-namespace collection** — a regular card/dashboard collection id is rejected with `A Transform can only go in Collections in the :transforms namespace.` Round-tripping the existing value is safe; setting it to an ordinary collection is what fails.
|
|
122
114
|
|
|
123
|
-
|
|
115
|
+
Patch only what changes:
|
|
124
116
|
|
|
125
117
|
```bash
|
|
126
118
|
# Rename only:
|
|
@@ -140,7 +132,7 @@ mb transform update <id> --file ./.scratch/patch.json --profile <name> --json
|
|
|
140
132
|
mb transform update <id> --body '{"tag_ids":[1,3]}' --profile <name> --json
|
|
141
133
|
```
|
|
142
134
|
|
|
143
|
-
`tag_ids` are the integer ids of **transform tags** —
|
|
135
|
+
`tag_ids` are the integer ids of **transform tags** — manage them with the `transform-tag` group: `mb transform-tag list --json` (find ids; the four built-ins `hourly`/`daily`/`weekly`/`monthly` are seeded), `mb transform-tag create --body '{"name":"nightly"}' --json`, `mb transform-tag update <id>`, `mb transform-tag delete <id>`. Tags are also how a `transform-job` selects what to run — a job executes every transform carrying one of the job's tags (see "Transform jobs").
|
|
144
136
|
|
|
145
137
|
If you really must round-trip, project to the writable subset:
|
|
146
138
|
|
|
@@ -153,13 +145,11 @@ mb transform get <id> --full --profile <name> --json \
|
|
|
153
145
|
|
|
154
146
|
## Iterating on a failing transform
|
|
155
147
|
|
|
156
|
-
When `transform run` fails and you want to retry with a fixed body, **prefer `transform update <id> --file body.json` over `transform delete <id>` + `transform create`.** Update keeps the same row,
|
|
148
|
+
When `transform run` fails and you want to retry with a fixed body, **prefer `transform update <id> --file body.json` over `transform delete <id>` + `transform create`.** Update keeps the same row, `entity_id`, materialized table, and on-disk YAML filename:
|
|
157
149
|
|
|
158
150
|
- `git-sync export` produces **one** clean commit containing only the fix, instead of "broken transform" + "remove broken transform" landing as two commits in `git log`.
|
|
159
|
-
- You don't
|
|
160
|
-
- The materialized output table either updates in place or, if the SELECT shape changed incompatibly, errors loudly on the next run rather than landing in a parallel `..._2` table
|
|
161
|
-
|
|
162
|
-
Recipe:
|
|
151
|
+
- You don't chase `_2` suffixes minted when two YAMLs share a `name` on disk.
|
|
152
|
+
- The materialized output table either updates in place or, if the SELECT shape changed incompatibly, errors loudly on the next run rather than landing in a parallel `..._2` table you have to clean up. (`transform delete-table <id>` resets the column shape for a clean slate.)
|
|
163
153
|
|
|
164
154
|
```bash
|
|
165
155
|
# 1. Try once
|
|
@@ -180,7 +170,7 @@ mb transform update "$ID" --file ./.scratch/source-patch.json --profile <n> --js
|
|
|
180
170
|
mb transform run "$ID" --wait --profile <n> --json # → succeeded
|
|
181
171
|
```
|
|
182
172
|
|
|
183
|
-
If you really must `create + delete` instead, do the `delete` **before** the first `git-sync export` so the failed entity never lands in git history
|
|
173
|
+
If you really must `create + delete` instead, do the `delete` **before** the first `git-sync export` so the failed entity never lands in git history — an export of a soft-failed state is noise that needs a follow-up cleanup commit. See `git-sync`, "Read state before mutating", for the ordering rule.
|
|
184
174
|
|
|
185
175
|
## Drop the materialized table (keep the transform)
|
|
186
176
|
|
|
@@ -188,7 +178,7 @@ If you really must `create + delete` instead, do the `delete` **before** the fir
|
|
|
188
178
|
mb transform delete-table <id> --yes --profile <name>
|
|
189
179
|
```
|
|
190
180
|
|
|
191
|
-
Useful when you've changed the SELECT and want a fresh `CREATE TABLE` on the next run. **`--yes` is required**
|
|
181
|
+
Useful when you've changed the SELECT and want a fresh `CREATE TABLE` on the next run. **`--yes` is required** non-interactively; without it the command exits with `refusing to delete <id> without confirmation — pass --yes to proceed non-interactively`.
|
|
192
182
|
|
|
193
183
|
## Delete the transform
|
|
194
184
|
|
|
@@ -196,7 +186,7 @@ Useful when you've changed the SELECT and want a fresh `CREATE TABLE` on the nex
|
|
|
196
186
|
mb transform delete <id> --yes --profile <name>
|
|
197
187
|
```
|
|
198
188
|
|
|
199
|
-
Removes the definition. Whether the materialized table is dropped depends on the server — check with `mb table list --db-id <db-id> --profile <name> --json` if it matters. Same `--yes` rule as `delete-table`.
|
|
189
|
+
Removes the definition. Whether the materialized table is dropped depends on the server — check with `mb table list --db-id <db-id> --profile <name> --json` if it matters. Same `--yes` rule and message as `delete-table`.
|
|
200
190
|
|
|
201
191
|
## Transform jobs (schedules)
|
|
202
192
|
|
|
@@ -212,9 +202,3 @@ mb transform-job set-active false --profile <name> --json # disable every job a
|
|
|
212
202
|
```
|
|
213
203
|
|
|
214
204
|
`transform-job run` is fire-and-forget — the server returns `{message, job_run_id}` immediately, with no per-job-run polling (no `--wait`). Most ad-hoc agent work is one-off `transform run`, not job authoring.
|
|
215
|
-
|
|
216
|
-
## Don't (transform-specific)
|
|
217
|
-
|
|
218
|
-
- Don't put `transform run` calls in tight polling loops — pass `--wait` and let the CLI handle the polling. Manual loops without `--wait` will hammer the server.
|
|
219
|
-
- Don't author MBQL 4 (the legacy nested `{ type: "query", query: {...} }` shape) by hand — pull a sample with `mb transform get <id> --full --json`. MBQL 5 (`lib/type: "mbql/query"`) **is** authorable by hand thanks to the `mb query --print-schema` + `--dry-run` feedback loop; for non-trivial pipelines you may still prefer building in the UI and exporting.
|
|
220
|
-
- Don't paste a `transform get` body into `transform update` — the PUT endpoint only accepts writable keys, and unknown keys (notably `tags`, `source_type`, `entity_id`, `created_at`, `last_run`) leak as raw SQL errors. See "Update body: send only writable keys" above. Use `tag_ids` (not `tags`) on the REST contract.
|
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: visualization
|
|
3
|
-
description:
|
|
3
|
+
description: Choose a card's `display` (chart type) and author its `visualization_settings` for the `mb` CLI — which chart fits which data shape, the required keys per chart, the rule that settings name OUTPUT columns, and the `column_settings` JSON-string-key footgun; the full per-chart key catalog is in references. Use when deciding or fixing how a card renders — "what chart should I use", "make this a bar/line/pie chart", "map this by state", "format this column as currency", "add conditional formatting", "the card renders as a table instead of a chart", or any `display` / `visualization_settings` work.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Visualization: pick the chart, then set it
|
|
8
8
|
|
|
9
|
-
> **
|
|
9
|
+
> **Building charts as part of a guided data project?** Follow the `data-workflow` **Shared Contract** — answer-first with detail on demand, ask before showing PII, honor the autonomy mode, name what the CLI can't do instead of erroring into raw SQL: `mb skills get data-workflow`.
|
|
10
10
|
|
|
11
11
|
A card has two presentation fields alongside its `dataset_query`:
|
|
12
12
|
|
|
13
|
-
- **`display`** — the chart type (`bar`, `line`, `pie`, `scalar`, `map`, `table`, …)
|
|
13
|
+
- **`display`** — the chart type (`bar`, `line`, `pie`, `scalar`, `map`, `table`, …); pick from the valid values below.
|
|
14
14
|
- **`visualization_settings`** — a map whose keys are **namespaced by `display`** (`graph.*` for bar/line/area/combo, `pie.*` for pie, `table.*` for table, …). The server stores almost anything and **silently ignores keys that don't apply** to the chosen `display`.
|
|
15
15
|
|
|
16
16
|
Nothing validates `visualization_settings` — there is no pre-flight to fail past. A `display` typo or a misnamed key is accepted by the API; the card just renders as a default table or drops the setting. So **the feedback loop is read-back, not pre-flight**: after `card create`/`update`, confirm with `mb card get <id> --full --json` (or open the card) that it rendered as intended.
|
|
17
17
|
|
|
18
|
-
Flag conventions and body-input precedence live in
|
|
18
|
+
Flag conventions and body-input precedence live in `core` (`mb skills get core`); the `dataset_query` itself is the `mbql` skill's job (`mb skills get mbql`). This skill is only about how the result is displayed.
|
|
19
19
|
|
|
20
20
|
Two steps: **(1) pick the `display` that fits the data**, then **(2) bind the data columns and set options**.
|
|
21
21
|
|
|
@@ -35,7 +35,7 @@ Decide which relationship in the data matters most, then pick the chart. The sha
|
|
|
35
35
|
- **Geographic** → `map`: region/choropleth (a region dimension + a measure), pin (lat + long), or grid/heat (coordinates + measure).
|
|
36
36
|
- **Precise values, many columns, mixed types, or no chart fits** → `table`; `pivot` for a cross-tab of two dimensions; `object` for a single record's detail.
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
Valid `display` values — the registered visualizations: `table`, `bar`, `line`, `area`, `row`, `pie`, `scalar`, `smartscalar`, `combo`, `pivot`, `funnel`, `map`, `scatter`, `waterfall`, `progress`, `gauge`, `object`, `sankey`, `boxplot`. The API types `display` as a plain string and accepts any value — it renders an unknown one as nothing. (`scalar` **is** the "Number" viz — `display: number` is a legacy serialization alias, not a registered visualization; use `scalar`. `list` exists but is hidden — don't pick it. `heading`/`text`/`link`/`iframe`/`action` are dashcard virtuals, not standalone cards — see references.) A typo like `bargraph`/`linechart` is accepted and renders blank — the most common "why is my chart blank" cause.
|
|
39
39
|
|
|
40
40
|
## Step 2 — bind data columns and set options
|
|
41
41
|
|
|
@@ -151,7 +151,7 @@ mb skills path visualization # → the skill dir; then Read references
|
|
|
151
151
|
|
|
152
152
|
## Don't
|
|
153
153
|
|
|
154
|
-
- Don't invent `display` values (`bargraph`, `linechart`, `histogram`) or use `number`/`list` — use
|
|
154
|
+
- Don't invent `display` values (`bargraph`, `linechart`, `histogram`) or use `number`/`list` — use a registered value; the API accepts a typo and renders nothing.
|
|
155
155
|
- Don't put numeric field ids in `graph.dimensions`/`pie.metric`/`scalar.field`/`map.latitude_column` etc. — they take **output column-name strings**.
|
|
156
156
|
- Don't reach for a `pie` with >5 slices, a `combo` of unrelated metrics, or a `pie`/`scalar` to show a trend — see Step 1.
|
|
157
157
|
- Don't write a `column_settings` key as an object — it's a JSON **string** (`"[\"name\",\"COL\"]"`), inner quotes escaped.
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# visualization_settings — per-chart key reference
|
|
2
2
|
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- [Cartesian — `bar`, `line`, `area`, `combo`, `scatter`, `waterfall`, `row`, `boxplot`](#cartesian--bar-line-area-combo-scatter-waterfall-row-boxplot) — shared keys (binding, stacking, goal/trend, data labels, axes, tooltip) plus `scatter`, `waterfall`, `row`, `boxplot` extras
|
|
6
|
+
- [Part-to-whole & single value — `pie`, `funnel`, `gauge`, `progress`, `scalar`, `smartscalar`](#part-to-whole--single-value--pie-funnel-gauge-progress-scalar-smartscalar)
|
|
7
|
+
- [Tabular, geographic & flow — `table`, `pivot`, `object`, `map`, `sankey`](#tabular-geographic--flow--table-pivot-object-map-sankey) — includes `table.column_formatting` conditional formatting
|
|
8
|
+
- [`column_settings` — per-column formatting](#column_settings--per-column-formatting) — number/date/currency, `view_as`, alignment, mini bars
|
|
9
|
+
- [`series_settings` — per-series styling (cartesian)](#series_settings--per-series-styling-cartesian)
|
|
10
|
+
- [Virtual cards (dashcards only, `card_id: null`)](#virtual-cards-dashcards-only-card_id-null) — heading/text/link/iframe
|
|
11
|
+
- [Click behavior (dashcards only)](#click-behavior-dashcards-only)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
3
15
|
Authorable keys per `display`, plus the data shape each chart suits and the minimum needed to render. Set keys only to override defaults — an empty `{}` works for a simple aggregate.
|
|
4
16
|
|
|
5
17
|
All column-naming keys (`graph.dimensions`, `pie.dimension`, `table.columns[].name`, `map.latitude_column`, …) take **output column-name strings** — the names the query produces. Every key and value below is identical in the API form (`mb card create`) and the portable git-sync form, with two exceptions: `column_settings` `["ref", …]` keys and click-behavior dimension targets carry a numeric field id in the API form and a name-path in the portable form. In a JSON body, `column_settings` keys are escaped strings: `"[\"name\",\"TOTAL\"]"`.
|
|
@@ -20,8 +20,8 @@ mb skills get core # auth, flag conventions, every command group
|
|
|
20
20
|
mb skills list # everything available on the installed version
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
**Doing a whole job, not one command?** If the user wants an outcome — "make sense of my data", "build a data model", "go from raw data to a dashboard", "answer questions about my data", "be my data analyst", "set up analytics for X" — load the
|
|
23
|
+
**Doing a whole job, not one command?** If the user wants an outcome — "make sense of my data", "build a data model", "go from raw data to a dashboard", "answer questions about my data", "be my data analyst", "set up analytics for X" — load the guided end-to-end skill instead and let it drive:
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
mb skills get
|
|
26
|
+
mb skills get data-workflow
|
|
27
27
|
```
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import "./error-D5bZ5BUX.mjs";
|
|
3
|
-
import "./runtime-C1QgWHM7.mjs";
|
|
4
|
-
import "./capabilities-BX1rnVuH.mjs";
|
|
5
|
-
import "./parse-id-DNPeV0Iu.mjs";
|
|
6
|
-
import "./poll-CYkX02Bm.mjs";
|
|
7
|
-
import "./poll-task-oXpl3wzp.mjs";
|
|
8
|
-
import { SyncSettingsUpdateResult, add_collection_default, setCollectionRemoteSynced, syncSettingsUpdateView } from "./add-collection-CXhrMjXU.mjs";
|
|
9
|
-
|
|
10
|
-
export { add_collection_default as default };
|
package/dist/auth-Bkue4Psy.mjs
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
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-Cn2UtFUt.mjs").then((m) => m.default),
|
|
12
|
-
status: () => import("./status-Cf8c0NON.mjs").then((m) => m.default),
|
|
13
|
-
list: () => import("./list-C6U3Ftg8.mjs").then((m) => m.default),
|
|
14
|
-
logout: () => import("./logout-_HXgEmqA.mjs").then((m) => m.default)
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
//#endregion
|
|
19
|
-
export { auth_default as default };
|
package/dist/card-faWo9ZWU.mjs
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
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-C410Ptw_.mjs").then((mod) => mod.default),
|
|
11
|
-
get: () => import("./get-Wj88mnhn.mjs").then((mod) => mod.default),
|
|
12
|
-
query: () => import("./query-DWQaN7hO.mjs").then((mod) => mod.default),
|
|
13
|
-
create: () => import("./create-4mAGsBd0.mjs").then((mod) => mod.default),
|
|
14
|
-
update: () => import("./update-rhfPHALN.mjs").then((mod) => mod.default),
|
|
15
|
-
archive: () => import("./archive-BUwiCFnd.mjs").then((mod) => mod.default)
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
//#endregion
|
|
20
|
-
export { card_default as default };
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { defineCommand } from "citty";
|
|
2
|
-
|
|
3
|
-
//#region src/commands/collection/index.ts
|
|
4
|
-
var collection_default = defineCommand({
|
|
5
|
-
meta: {
|
|
6
|
-
name: "collection",
|
|
7
|
-
description: "Manage Metabase collections"
|
|
8
|
-
},
|
|
9
|
-
subCommands: {
|
|
10
|
-
list: () => import("./list-CfWblVHJ.mjs").then((mod) => mod.default),
|
|
11
|
-
get: () => import("./get-DAsaor0n.mjs").then((mod) => mod.default),
|
|
12
|
-
items: () => import("./items-LjtICjvX.mjs").then((mod) => mod.default),
|
|
13
|
-
tree: () => import("./tree-CF8mscd9.mjs").then((mod) => mod.default),
|
|
14
|
-
create: () => import("./create-C7FPeJqF.mjs").then((mod) => mod.default),
|
|
15
|
-
archive: () => import("./archive-CQiaCBSj.mjs").then((mod) => mod.default)
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
//#endregion
|
|
20
|
-
export { collection_default as default };
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { defineCommand } from "citty";
|
|
2
|
-
|
|
3
|
-
//#region src/commands/dashboard/index.ts
|
|
4
|
-
var dashboard_default = defineCommand({
|
|
5
|
-
meta: {
|
|
6
|
-
name: "dashboard",
|
|
7
|
-
description: "Manage Metabase dashboards"
|
|
8
|
-
},
|
|
9
|
-
subCommands: {
|
|
10
|
-
list: () => import("./list-ChK06rJh.mjs").then((mod) => mod.default),
|
|
11
|
-
get: () => import("./get-qnGGGRTa.mjs").then((mod) => mod.default),
|
|
12
|
-
cards: () => import("./cards-BySIFsLG.mjs").then((mod) => mod.default),
|
|
13
|
-
create: () => import("./create-C43RQYgj.mjs").then((mod) => mod.default),
|
|
14
|
-
update: () => import("./update-DERsb0eO.mjs").then((mod) => mod.default),
|
|
15
|
-
"update-dashcard": () => import("./update-dashcard-BJVeSGvO.mjs").then((mod) => mod.default),
|
|
16
|
-
archive: () => import("./archive-BxGSR7El.mjs").then((mod) => mod.default)
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
//#endregion
|
|
21
|
-
export { dashboard_default as default };
|
package/dist/db-CmHHj5eI.mjs
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { defineCommand } from "citty";
|
|
2
|
-
|
|
3
|
-
//#region src/commands/db/index.ts
|
|
4
|
-
var db_default = defineCommand({
|
|
5
|
-
meta: {
|
|
6
|
-
name: "db",
|
|
7
|
-
description: "Inspect and sync Metabase databases",
|
|
8
|
-
alias: "database"
|
|
9
|
-
},
|
|
10
|
-
subCommands: {
|
|
11
|
-
list: () => import("./list-Dq86BAMG.mjs").then((m) => m.default),
|
|
12
|
-
get: () => import("./get-CGkhSY5L.mjs").then((m) => m.default),
|
|
13
|
-
metadata: () => import("./metadata-8yqT8OZI.mjs").then((m) => m.default),
|
|
14
|
-
schemas: () => import("./schemas-Cr7RjYqV.mjs").then((m) => m.default),
|
|
15
|
-
"schema-tables": () => import("./schema-tables-rdeupgsu.mjs").then((m) => m.default),
|
|
16
|
-
"sync-schema": () => import("./sync-schema-DKEel2Sv.mjs").then((m) => m.default),
|
|
17
|
-
"rescan-values": () => import("./rescan-values-B9Qtsd32.mjs").then((m) => m.default)
|
|
18
|
-
}
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
//#endregion
|
|
22
|
-
export { db_default as default };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { defineCommand } from "citty";
|
|
2
|
-
|
|
3
|
-
//#region src/commands/document/index.ts
|
|
4
|
-
var document_default = defineCommand({
|
|
5
|
-
meta: {
|
|
6
|
-
name: "document",
|
|
7
|
-
description: "Manage Metabase documents"
|
|
8
|
-
},
|
|
9
|
-
subCommands: {
|
|
10
|
-
list: () => import("./list-Bjp9nd0o.mjs").then((mod) => mod.default),
|
|
11
|
-
get: () => import("./get-BtAD26gc.mjs").then((mod) => mod.default),
|
|
12
|
-
create: () => import("./create-DnT1Sayk.mjs").then((mod) => mod.default),
|
|
13
|
-
update: () => import("./update-CgQOSuZt.mjs").then((mod) => mod.default),
|
|
14
|
-
archive: () => import("./archive-yTvDRQUZ.mjs").then((mod) => mod.default)
|
|
15
|
-
}
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
//#endregion
|
|
19
|
-
export { document_default as default };
|