@metabase/cli 0.2.1-alpha.trust-system-ca.541e4e0 → 0.2.2-alpha.extract-api-client.27e2241
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 +4 -1715
- package/dist/add-collection-B3Ty8SzB.mjs +36 -0
- package/dist/alert-DT-ee7yf.mjs +23 -0
- package/dist/alerts-Bf2RH_p_.mjs +43 -0
- package/dist/{append-Cak5jykn.mjs → append-DFzQRPMd.mjs} +7 -12
- package/dist/{archive-BVY_jD_g.mjs → archive-4tmm946K.mjs} +8 -17
- package/dist/{archive-CytCvQpn.mjs → archive-B6eXiyER.mjs} +7 -13
- package/dist/{archive-op9pJRpg.mjs → archive-BxNPHxOY.mjs} +7 -13
- package/dist/archive-ByvA49Kz.mjs +34 -0
- package/dist/{archive-DfbI8DRB.mjs → archive-C7w49Grr.mjs} +7 -16
- package/dist/{archive-CPgWNCG3.mjs → archive-Cd29QC0c.mjs} +7 -13
- package/dist/{archive-BIEnBoE8.mjs → archive-ChORH5JH.mjs} +7 -13
- package/dist/archive-CwAdlv63.mjs +33 -0
- package/dist/{archive-CaKhG58H.mjs → archive-Dr9Xnx_Z.mjs} +7 -15
- package/dist/{archive-CjnCAM61.mjs → archive-gid9Y09v.mjs} +8 -17
- package/dist/{archive-BMbx6lt8.mjs → archive-lQqs13Uz.mjs} +7 -13
- package/dist/auth-Dltxua89.mjs +19 -0
- package/dist/{body-BW_CiL1d.mjs → body-Cur4NJt9.mjs} +5 -8
- package/dist/{body-flags-CgHgJBRC.mjs → body-flags-AqKpN01Y.mjs} +1 -2
- package/dist/{branches-gVRwKne4.mjs → branches-DchlyU0i.mjs} +7 -13
- package/dist/{cancel-CBOJSslz.mjs → cancel-BMQa5R1Z.mjs} +5 -12
- package/dist/{cancel-task-Djancczz.mjs → cancel-task-C5CU1pxU.mjs} +6 -10
- package/dist/card-CHI2bmds.mjs +24 -0
- package/dist/{card-B8G5jQQT.mjs → card-DZxRmver.mjs} +21 -48
- package/dist/card-zyUkr2nS.mjs +44 -0
- package/dist/cards-SccWvRQD.mjs +34 -0
- package/dist/cli.mjs +664 -83
- package/dist/client-BqhzKdLM.mjs +2194 -0
- package/dist/collection-CGoVLvcD.mjs +58 -0
- package/dist/collection-CY0AB99E.mjs +20 -0
- package/dist/{collection-C52Ndi_O.mjs → collection-CfulNRBG.mjs} +16 -61
- package/dist/{collection-namespace-w1y5D0Uh.mjs → collection-namespace-GwydWBF3.mjs} +3 -5
- package/dist/{create-VA58AF6A.mjs → create-BNQ_DytP.mjs} +8 -15
- package/dist/{create-CnT-L03B.mjs → create-BOLwWt8Q.mjs} +9 -17
- package/dist/{create-BkvdOecg.mjs → create-Beh-2uoN.mjs} +8 -15
- package/dist/{create-CvptjYVb.mjs → create-C79vErX0.mjs} +9 -20
- package/dist/{create-C_fyIHZU.mjs → create-CAQV2g6V.mjs} +9 -17
- package/dist/{create-q2QqkwEN.mjs → create-CAWytBE5.mjs} +9 -17
- package/dist/{create-CGsTL5aE.mjs → create-CCh_LyW9.mjs} +8 -15
- package/dist/{create-ldvT5L0W.mjs → create-CD008jdE.mjs} +13 -28
- package/dist/create-CHQx7jq4.mjs +45 -0
- package/dist/create-DF4QtgDL.mjs +44 -0
- package/dist/{create-D_eiLBqR.mjs → create-DJmXXQoq.mjs} +10 -18
- package/dist/{create-DbHIjWio.mjs → create-DV-Ln5Mo.mjs} +8 -15
- package/dist/create-branch-CYo6jZth.mjs +35 -0
- package/dist/{create-DZBtbGqj.mjs → create-i14Wv3Tj.mjs} +8 -15
- package/dist/{create-CnqGhtuF.mjs → create-tQbnuz-I.mjs} +8 -15
- package/dist/{create-BRK8TBzp.mjs → create-zeveFdnd.mjs} +6 -11
- package/dist/cron-LKRffEC-.mjs +5 -0
- package/dist/{csv-C3O1wTQ8.mjs → csv-B2Jgb1GM.mjs} +7 -19
- package/dist/{current-task-CZsZPe0o.mjs → current-task-MpBFGttd.mjs} +7 -12
- package/dist/{dashboard-BLihjDXg.mjs → dashboard-BCpSq_G-.mjs} +9 -60
- package/dist/dashboard-BHJBoaG7.mjs +33 -0
- package/dist/dashboard-CsIFFpzK.mjs +58 -0
- package/dist/database-B19qlLKZ.mjs +38 -0
- package/dist/database-C8G6ZKG0.mjs +26 -0
- package/dist/db-DsfojyeH.mjs +24 -0
- package/dist/{delete-BmT5C6eK.mjs → delete-B8e01xAG.mjs} +6 -11
- package/dist/{delete-Dkfu4e5K.mjs → delete-BApOjQvl.mjs} +6 -11
- package/dist/{delete-JeRzVISE.mjs → delete-Ck0q4Dzp.mjs} +6 -11
- package/dist/{delete-cF97pfFX.mjs → delete-DFmX7jTp.mjs} +6 -11
- package/dist/{delete-DgI03U43.mjs → delete-Ob06PPie.mjs} +6 -11
- package/dist/{delete-runtime-DiqKOEqi.mjs → delete-runtime-D74s6vhu.mjs} +6 -13
- package/dist/{delete-table-dnQs_Twm.mjs → delete-table-DuyhGrvA.mjs} +6 -11
- package/dist/{dependencies-BsMwFSxP.mjs → dependencies-Bj3QrGIm.mjs} +10 -13
- package/dist/dirty-DNYoM6Bp.mjs +31 -0
- package/dist/document-BbskZPTT.mjs +19 -0
- package/dist/{document-D4zB-5a0.mjs → document-Cd2mmqCp.mjs} +5 -33
- package/dist/document-D6OybtP2.mjs +29 -0
- package/dist/{eid-60sCZhQV.mjs → eid-WTZmDdsr.mjs} +12 -54
- package/dist/eid-translation-zEHtr5Oc.mjs +35 -0
- package/dist/{embedding-CKdw8q7p.mjs → embedding-i-KqpefC.mjs} +2 -4
- package/dist/events-Bn7jh5lP.mjs +39 -0
- package/dist/export-BjfoZRDJ.mjs +66 -0
- package/dist/field-BPsNa-TO.mjs +80 -0
- package/dist/{field-DsXTeqBy.mjs → field-Cr2DPUG9.mjs} +2 -81
- package/dist/field-Zau6Hc6X.mjs +18 -0
- package/dist/fields-CBBa-Prp.mjs +34 -0
- package/dist/{get-CaosV7j8.mjs → get-00lyLv6R.mjs} +7 -11
- package/dist/{get-DxAx-2C0.mjs → get-B7sMgsFs.mjs} +7 -11
- package/dist/get-B_xdF1kq.mjs +31 -0
- package/dist/{get-B_EinsrO.mjs → get-ByBOq30r.mjs} +7 -11
- package/dist/get-Bz99dAxK.mjs +35 -0
- package/dist/get-C2-Q3iQ5.mjs +31 -0
- package/dist/get-CDJFVvhj.mjs +35 -0
- package/dist/get-CDMGbgrh.mjs +31 -0
- package/dist/get-CnbUCzDM.mjs +31 -0
- package/dist/{get-L8c_h5EP.mjs → get-CvI--9S_.mjs} +16 -12
- package/dist/{get-CRXEqpar.mjs → get-DRvsATp-.mjs} +7 -11
- package/dist/{get-BNBRMNtC.mjs → get-DY03Azx9.mjs} +6 -11
- package/dist/get-DYO1kywc.mjs +32 -0
- package/dist/{get-CKnHNxak.mjs → get-D_h-G9bn.mjs} +7 -11
- package/dist/get-DdsoHaKH.mjs +31 -0
- package/dist/{get-Ct5TnofS.mjs → get-DkWO0EI0.mjs} +7 -11
- package/dist/{get-fGOQA0GF.mjs → get-Dmj9Ygz1.mjs} +7 -17
- package/dist/get-DmpB6J9g.mjs +31 -0
- package/dist/{get-Csa7Dz36.mjs → get-Dn9ZiSZr.mjs} +8 -16
- package/dist/{get-run-DqwPQRMJ.mjs → get-run-Cnux9ln0.mjs} +7 -11
- package/dist/git-sync-BDnxPrqU.mjs +104 -0
- package/dist/git-sync-DxD_ng48.mjs +136 -0
- package/dist/git-sync-MQQYRYLg.mjs +28 -0
- package/dist/{group-CILtQqCL.mjs → group-DBM87IgC.mjs} +2 -4
- package/dist/has-remote-changes-C684Redh.mjs +35 -0
- package/dist/import-Rmmttboo.mjs +56 -0
- package/dist/{input-D2-H-QKX.mjs → input-DH9i67x_.mjs} +6 -11
- package/dist/{is-dirty-B87YMLV2.mjs → is-dirty-DYeJYhBz.mjs} +4 -8
- package/dist/{items-DrP1b4Qj.mjs → items-CQlPXBXE.mjs} +13 -29
- package/dist/key-BEhqIzIQ.mjs +10 -0
- package/dist/{library-bUBWlweP.mjs → library-Bsm5KsFF.mjs} +6 -9
- package/dist/library-ClLgrAXy.mjs +19 -0
- package/dist/library-DfYAT2Ep.mjs +21 -0
- package/dist/{list-B8zgT05M.mjs → list-B4hJuMhA.mjs} +11 -27
- package/dist/list-B8nAGwP4.mjs +48 -0
- package/dist/list-BOET6zhP.mjs +36 -0
- package/dist/list-BP3MPq-M.mjs +36 -0
- package/dist/list-BpFp9Wre.mjs +28 -0
- package/dist/list-BtkWNtvY.mjs +34 -0
- package/dist/list-BtmsNOEn.mjs +28 -0
- package/dist/list-BzVTHOoH.mjs +28 -0
- package/dist/list-C5Zs8nrb.mjs +28 -0
- package/dist/list-CKK-s3Ty.mjs +28 -0
- package/dist/list-CMpoc2TN.mjs +70 -0
- package/dist/list-CNUiF8Z7.mjs +28 -0
- package/dist/list-CQDprvW0.mjs +39 -0
- package/dist/{list-DCl7zHCp.mjs → list-CQwOgIlj.mjs} +10 -24
- package/dist/list-DE9FM957.mjs +28 -0
- package/dist/{list-F_hMRbsa.mjs → list-DF2rvoO1.mjs} +22 -14
- package/dist/list-DMKDsBRd.mjs +38 -0
- package/dist/{list-TibX1b8i.mjs → list-UhpKG6_m.mjs} +15 -15
- package/dist/{login-C5Ug3BVC.mjs → login-CGHeSjlP.mjs} +47 -52
- package/dist/{logout-B_N1N2DV.mjs → logout-DAxOlbv4.mjs} +7 -12
- package/dist/measure-4P0bOlZ3.mjs +29 -0
- package/dist/measure-BsYv0p26.mjs +22 -0
- package/dist/{measure-ByY4U3ZK.mjs → measure-CtfjqJFP.mjs} +3 -30
- package/dist/network-error-CEb9ymDW.mjs +423 -0
- package/dist/notification-DaA4bBHW.mjs +138 -0
- package/dist/notification-Fcq1fIPw.mjs +67 -0
- package/dist/{parameter-BZ6y-Gfs.mjs → parameter-DUKR8NXo.mjs} +2 -11
- package/dist/{parameter-values-ZXKECrJk.mjs → parameter-values-CJTdqd8c.mjs} +17 -11
- package/dist/{parse-enum-D5h-JePs.mjs → parse-enum-D0Jfm_Bz.mjs} +2 -4
- package/dist/{parse-id-ySsF4nA3.mjs → parse-id-C_jmKFaa.mjs} +2 -4
- package/dist/{parse-ref-Ds8VxdKb.mjs → parse-ref-ibKVB0J4.mjs} +3 -5
- package/dist/{path-C6ucgeYs.mjs → path-B5gHvrYL.mjs} +8 -9
- package/dist/{poll-CgzD9_RH.mjs → poll-75SvT7Zv.mjs} +11 -15
- package/dist/predicates-Bkm2IoeX.mjs +170 -0
- package/dist/preflight-YpPQo-sa.mjs +29 -0
- package/dist/{process-jjR_DX5G.mjs → process-DBOOrmET.mjs} +4 -6
- package/dist/{publish-F-QbufXr.mjs → publish-DijrxaCW.mjs} +29 -24
- package/dist/pulse-BmsDenXm.mjs +133 -0
- package/dist/pulse-DhG6I9mI.mjs +57 -0
- package/dist/{query-DX4r0-uz.mjs → query-BbqECzmF.mjs} +20 -44
- package/dist/{query-DGBzATpV.mjs → query-Dc__-KJH.mjs} +13 -24
- package/dist/{query-result-D5J3Dlpn.mjs → query-result-DBDwk8TS.mjs} +4 -8
- package/dist/remove-collection-BOnxYvhj.mjs +36 -0
- package/dist/{render-CkuFkWlQ.mjs → render-CI93iP0I.mjs} +9 -11
- package/dist/{replace-xlQv9yl_.mjs → replace-Cq4CxVa-.mjs} +7 -12
- package/dist/rescan-values-Dr_j416g.mjs +31 -0
- package/dist/revision-message-flag-8TCHYJV6.mjs +8 -0
- package/dist/run-C3DkS6NP.mjs +82 -0
- package/dist/{run-opQkYIaT.mjs → run-DdGJ544X.mjs} +8 -18
- package/dist/runs-CUNWiidL.mjs +38 -0
- package/dist/runtime-DiKyBxOw.mjs +1007 -0
- package/dist/{schema-tables-8FjtkFIt.mjs → schema-tables-CV386fnC.mjs} +10 -14
- package/dist/{schemas-L9kMsEJL.mjs → schemas-DM-UqZBQ.mjs} +8 -12
- package/dist/search-DFBwUc6d.mjs +44 -0
- package/dist/{search-Csbb-u-_.mjs → search-DmGScXs8.mjs} +14 -73
- package/dist/segment-BzUGM2Fr.mjs +22 -0
- package/dist/segment-C_gl5ag6.mjs +29 -0
- package/dist/{segment-eeGhLo7_.mjs → segment-OsrbUDzw.mjs} +3 -30
- package/dist/{selectors-D34gXjQa.mjs → selectors-DGDn0Hto.mjs} +4 -6
- package/dist/send-CVxxEpDB.mjs +49 -0
- package/dist/{set-CfwncOI_.mjs → set-DFolTjbd.mjs} +10 -20
- package/dist/{set-active-gP4mjVDY.mjs → set-active-BD8L1lPX.mjs} +7 -18
- package/dist/setting-CwRYgHYN.mjs +35 -0
- package/dist/setting-DTiLCW8g.mjs +22 -0
- package/dist/setting-DyhaeICs.mjs +17 -0
- package/dist/setup-BbDQN8fe.mjs +44 -0
- package/dist/setup-CO7QV-ao.mjs +21 -0
- package/dist/signal-CMd0EFUa.mjs +16 -0
- package/dist/{skills-DvSQOPWg.mjs → skills--vK6J-e4.mjs} +4 -6
- package/dist/{skills-aRQfUvCq.mjs → skills-DTCrMcix.mjs} +13 -19
- package/dist/{snippet-CdjEhVCT.mjs → snippet-CyKAgIZl.mjs} +3 -32
- package/dist/snippet-DRwKb2x7.mjs +19 -0
- package/dist/snippet-oJLaYW9V.mjs +29 -0
- package/dist/stash-D0S4JmAz.mjs +61 -0
- package/dist/{status-BsEPyknG.mjs → status-BhswxJL1.mjs} +23 -23
- package/dist/{status-D1vtL5eW.mjs → status-hL1am-HV.mjs} +6 -8
- package/dist/subscription-_d5fB45F.mjs +22 -0
- package/dist/subscriptions-s4TF6Ax3.mjs +42 -0
- package/dist/summary-BytbDz6e.mjs +7 -0
- package/dist/summary-CsPvcUwW.mjs +31 -0
- package/dist/sync-schema-DaZ_MV-u.mjs +35 -0
- package/dist/sync-task-BACcrs0i.mjs +37 -0
- package/dist/{table-3onHpwcb.mjs → table-CeeTJgQb.mjs} +4 -38
- package/dist/table-CsIJNPFf.mjs +37 -0
- package/dist/table-DYoC1kPn.mjs +18 -0
- package/dist/{timeline-2ShuGr4f.mjs → timeline-CCSU2qOS.mjs} +2 -66
- package/dist/timeline-event-CNQdCTDg.mjs +19 -0
- package/dist/timeline-uDCmwGFT.mjs +66 -0
- package/dist/timeline-xlDbEKWg.mjs +21 -0
- package/dist/transform-Bs0EWijQ.mjs +28 -0
- package/dist/{transform-DNSMm1dV.mjs → transform-D3QX0jxA.mjs} +28 -74
- package/dist/transform-DoTyyXAu.mjs +74 -0
- package/dist/transform-job-50GZHhKH.mjs +37 -0
- package/dist/transform-job-BcLChRup.mjs +22 -0
- package/dist/{transform-job-CvE0MBBo.mjs → transform-job-DRrK28IH.mjs} +14 -41
- package/dist/{transform-tag-xdxjlDcD.mjs → transform-tag-CcElGp3C.mjs} +2 -21
- package/dist/transform-tag-Dmb4u3-Q.mjs +21 -0
- package/dist/transform-tag-_tgwlsdB.mjs +18 -0
- package/dist/{transforms-BQkmsPUR.mjs → transforms-oU4zizbO.mjs} +10 -13
- package/dist/{tree-CtufTBZY.mjs → tree-CH-f3bjP.mjs} +6 -10
- package/dist/{unpublish-CnLXPYR8.mjs → unpublish-BUl9RU5C.mjs} +7 -18
- package/dist/{update-BC-MLtiG.mjs → update-BCS5FxKr.mjs} +11 -19
- package/dist/{update-CqQj32ol.mjs → update-BZPllQoR.mjs} +9 -16
- package/dist/{update-DmQJqGvX.mjs → update-BiFDBcEH.mjs} +9 -16
- package/dist/update-BzMDeZiU.mjs +50 -0
- package/dist/{update-Dt9-3Tqf.mjs → update-C4YJQFDS.mjs} +9 -16
- package/dist/{update-C4P_YtGW.mjs → update-CHNSUHK4.mjs} +9 -16
- package/dist/{update-bz-FKwuR.mjs → update-CO4m4wH3.mjs} +10 -21
- package/dist/{update-BZxLyBVm.mjs → update-CVPAwJaH.mjs} +10 -18
- package/dist/{update-dJ2mlCXm.mjs → update-CmDTljK-.mjs} +9 -16
- package/dist/{update-DcYwxb-R.mjs → update-CvOO8TED.mjs} +9 -17
- package/dist/{update-QNuvGuS3.mjs → update-D-NE60AV.mjs} +9 -16
- package/dist/{update-DshCe-bl.mjs → update-Nfi44RrE.mjs} +10 -18
- package/dist/update-bD_Jh5-s.mjs +51 -0
- package/dist/{update-D6blsNGY.mjs → update-cYkvbqK8.mjs} +9 -16
- package/dist/update-dashcard-C3TuYO_k.mjs +50 -0
- package/dist/{update-CE-Z6E8V.mjs → update-tX9mKBN_.mjs} +10 -21
- package/dist/{upgrade--_g3bacj.mjs → upgrade-DXMV4AyP.mjs} +37 -44
- package/dist/upload-CH632qW6.mjs +46 -0
- package/dist/upload-DAtxBBms.mjs +13 -0
- package/dist/upload-Dey_8rLf.mjs +13 -0
- package/dist/{uuid-DBKkosBq.mjs → uuid-BJkDWj9p.mjs} +5 -7
- package/dist/validate-BWchyW0V.mjs +1469 -0
- package/dist/{validate-query-tECK019A.mjs → validate-query-DaGYSmpQ.mjs} +4 -5
- package/dist/{values-BAhMnVh6.mjs → values-Dxf1JEoA.mjs} +8 -13
- package/dist/verify-K96rItG5.mjs +89 -0
- package/dist/{wait-BJ_87Yz0.mjs → wait-DoMDH226.mjs} +10 -18
- package/dist/{wait-flags-DEn-3mjb.mjs → wait-flags-DWEF9tX4.mjs} +14 -11
- package/dist/window-BkvrP0gB.mjs +64 -0
- package/package.json +5 -35
- package/skill-data/core/SKILL.md +30 -25
- package/skill-data/dashboard/SKILL.md +6 -2
- package/skill-data/document/SKILL.md +2 -2
- package/skill-data/notification/SKILL.md +157 -0
- package/skill-data/transform/SKILL.md +1 -1
- package/.claude-plugin/marketplace.json +0 -19
- package/dist/add-collection-BZAVH5Wk.mjs +0 -60
- package/dist/add-collection-DByJYvGO.mjs +0 -9
- package/dist/auth-XfuGXI2K.mjs +0 -22
- package/dist/capabilities-CSjeWyLV.mjs +0 -684
- package/dist/card-B_kiDDil.mjs +0 -26
- package/dist/cards-23FtfL4S.mjs +0 -38
- package/dist/cli.d.mts +0 -1
- package/dist/collection-DNzM3u7n.mjs +0 -23
- package/dist/command-augment-D9pI9Vbh.mjs +0 -11
- package/dist/create-branch-BtqOfSRb.mjs +0 -57
- package/dist/dashboard-kb1oz7Z3.mjs +0 -35
- package/dist/database-BOqzcexD.mjs +0 -61
- package/dist/db-CHnqeJCo.mjs +0 -27
- package/dist/dirty-CN6sGKX3.mjs +0 -35
- package/dist/document-Y_DZNi4D.mjs +0 -22
- package/dist/events-CSZEAgs0.mjs +0 -44
- package/dist/export-CAxUJer6.mjs +0 -103
- package/dist/field-DAB2gImv.mjs +0 -21
- package/dist/fields-CLWtUlpR.mjs +0 -37
- package/dist/get-B22wjDxr.mjs +0 -38
- package/dist/get-BIHtWl2x.mjs +0 -35
- package/dist/get-B_QKP1vR.mjs +0 -35
- package/dist/get-Ca30K5_W.mjs +0 -35
- package/dist/get-DTjeTNGb.mjs +0 -49
- package/dist/get-DU8V-7S2.mjs +0 -35
- package/dist/get-H3X5e5-Y.mjs +0 -41
- package/dist/git-sync-BhhdNjq5.mjs +0 -31
- package/dist/has-remote-changes-D0ZIBHSk.mjs +0 -67
- package/dist/import-BcIcDPl9.mjs +0 -94
- package/dist/is-dirty-CXTS25Tk.mjs +0 -8
- package/dist/key-GP1gxZZD.mjs +0 -17
- package/dist/list-B-_PTqKw.mjs +0 -53
- package/dist/list-B8212eUr.mjs +0 -39
- package/dist/list-BhCahBEO.mjs +0 -39
- package/dist/list-CWQYaCp8.mjs +0 -31
- package/dist/list-Cbhx7N_t.mjs +0 -31
- package/dist/list-CoXeBm66.mjs +0 -49
- package/dist/list-D1pHJX7w.mjs +0 -31
- package/dist/list-DhT42e0q.mjs +0 -31
- package/dist/list-GeqRHx8g.mjs +0 -31
- package/dist/list-MPePXEWe.mjs +0 -31
- package/dist/list-TJjExx6e.mjs +0 -31
- package/dist/list-TQghfc-u.mjs +0 -39
- package/dist/listing-wFZuS5li.mjs +0 -10
- package/dist/measure-D9rKeA6Z.mjs +0 -25
- package/dist/paginate-FVZUxL4J.mjs +0 -49
- package/dist/poll-task-DF9xJl13.mjs +0 -194
- package/dist/preflight-Co2grgX_.mjs +0 -90
- package/dist/prompt-BSqji7Fo.mjs +0 -52
- package/dist/remove-collection-C-msSyas.mjs +0 -42
- package/dist/requests-COuEPJxE.mjs +0 -96
- package/dist/rescan-values-BC2SVtY6.mjs +0 -40
- package/dist/resolve-8iT-dXgX.mjs +0 -91
- package/dist/revision-message-flag-vt_V8ACy.mjs +0 -11
- package/dist/run-Cg6k3kHo.mjs +0 -135
- package/dist/runs-Cbqm1HYG.mjs +0 -53
- package/dist/runtime-MGH96fhp.mjs +0 -1695
- package/dist/segment-DCeafJwX.mjs +0 -25
- package/dist/setting-D5Y9sJha.mjs +0 -20
- package/dist/setting-DADuiF5W.mjs +0 -55
- package/dist/setup-D9HNfS7W.mjs +0 -71
- package/dist/snippet-CwRiMCfE.mjs +0 -22
- package/dist/stash-C_k1uZlf.mjs +0 -108
- package/dist/summary-h20AjhcO.mjs +0 -40
- package/dist/sync-schema-D67cYLhd.mjs +0 -54
- package/dist/sync-scope-CKx6xeF6.mjs +0 -55
- package/dist/table-CmKFWPvJ.mjs +0 -21
- package/dist/timeline-1ZphX3zj.mjs +0 -24
- package/dist/timeline-event-C6aKZ4EO.mjs +0 -22
- package/dist/transform-CvsBOTqB.mjs +0 -31
- package/dist/transform-job-D_8Kp772.mjs +0 -25
- package/dist/transform-tag-DhDnvbmq.mjs +0 -21
- package/dist/update-dashcard-CQP-qd6a.mjs +0 -73
- package/dist/upload-BOFc_eZD.mjs +0 -16
- package/dist/validate-Bpqt3ntH.mjs +0 -1496
- package/dist/verify-RLb2DoOX.mjs +0 -79
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ConfigError
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { i as ConfigError } from "./predicates-Bkm2IoeX.mjs";
|
|
2
|
+
import { l as writeJson } from "./cli.mjs";
|
|
3
|
+
import { i as validateQuery, r as isMbql5Query, t as assertNotLegacyEnvelopeWrappingMbql5 } from "./validate-BWchyW0V.mjs";
|
|
4
4
|
//#region src/commands/validate-query.ts
|
|
5
5
|
const skipValidateFlag = { "skip-validate": {
|
|
6
6
|
type: "boolean",
|
|
@@ -31,6 +31,5 @@ function preflightMbql5Query(query, labels, options) {
|
|
|
31
31
|
writeJson(outcome);
|
|
32
32
|
throw new ConfigError(`${labels.contextLabel}: ${outcome.errors.length} error(s) — pass valid MBQL 5 or use the legacy format`);
|
|
33
33
|
}
|
|
34
|
-
|
|
35
34
|
//#endregion
|
|
36
|
-
export {
|
|
35
|
+
export { preflightMbql5Query as a, TRANSFORM_SOURCE_QUERY_LABELS as i, MEASURE_DEFINITION_LABELS as n, skipValidateFlag as o, SEGMENT_DEFINITION_LABELS as r, CARD_DATASET_QUERY_LABELS as t };
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "./
|
|
3
|
-
import {
|
|
4
|
-
import { FieldValues
|
|
5
|
-
import {
|
|
6
|
-
|
|
1
|
+
import { F as outputFlags, I as profileFlag, M as connectionFlags, c as renderSummary, f as formatScalar } from "./cli.mjs";
|
|
2
|
+
import { t as defineMetabaseCommand } from "./runtime-DiKyBxOw.mjs";
|
|
3
|
+
import { t as parseId } from "./parse-id-C_jmKFaa.mjs";
|
|
4
|
+
import { s as FieldValues } from "./field-Cr2DPUG9.mjs";
|
|
5
|
+
import { n as fieldValuesView } from "./field-BPsNa-TO.mjs";
|
|
7
6
|
//#region src/commands/field/values.ts
|
|
8
7
|
var values_default = defineMetabaseCommand({
|
|
9
8
|
meta: {
|
|
@@ -25,19 +24,15 @@ var values_default = defineMetabaseCommand({
|
|
|
25
24
|
examples: ["mb field values 100", "mb field values 100 --json"],
|
|
26
25
|
async run({ args, ctx, getClient }) {
|
|
27
26
|
const id = parseId(args.id);
|
|
28
|
-
const
|
|
29
|
-
const values = await client.requestParsed(FieldValues, `/api/field/${id}/values`);
|
|
27
|
+
const values = await (await getClient()).field.values(id);
|
|
30
28
|
const fieldId = values.field_id ?? id;
|
|
31
29
|
const count = values.values.length;
|
|
32
30
|
renderSummary(values, fieldValuesView, () => {
|
|
33
31
|
if (count === 0) return `Field ${fieldId} has no cached values.`;
|
|
34
32
|
const more = values.has_more_values === true ? " (more available; rescan for the full set)" : "";
|
|
35
|
-
|
|
36
|
-
const lines = values.values.map((row) => ` ${formatScalar(row[0])}`);
|
|
37
|
-
return [header, ...lines].join("\n");
|
|
33
|
+
return [`Field ${fieldId} has ${count} cached value${count === 1 ? "" : "s"}${more}:`, ...values.values.map((row) => ` ${formatScalar(row[0])}`)].join("\n");
|
|
38
34
|
}, ctx);
|
|
39
35
|
}
|
|
40
36
|
});
|
|
41
|
-
|
|
42
37
|
//#endregion
|
|
43
|
-
export { values_default as default };
|
|
38
|
+
export { values_default as default };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { n as createClient } from "./client-BqhzKdLM.mjs";
|
|
2
|
+
import { f as errorMessage, l as TimeoutError, o as MetabaseError, s as NetworkError } from "./predicates-Bkm2IoeX.mjs";
|
|
3
|
+
import { F as tryParseTag, I as SessionProperties, u as USER_AGENT } from "./runtime-DiKyBxOw.mjs";
|
|
4
|
+
import { r as HttpError } from "./network-error-CEb9ymDW.mjs";
|
|
5
|
+
//#region ../client/src/version/probe.ts
|
|
6
|
+
const PROBE_PATH = "/api/session/properties";
|
|
7
|
+
const PROBE_TIMEOUT_MS = 1e4;
|
|
8
|
+
async function probeServer(client, opts = {}) {
|
|
9
|
+
const properties = await client.requestParsed(SessionProperties, PROBE_PATH, {
|
|
10
|
+
timeoutMs: PROBE_TIMEOUT_MS,
|
|
11
|
+
retries: opts.retries ?? 0
|
|
12
|
+
});
|
|
13
|
+
return {
|
|
14
|
+
version: tryParseTag(properties.version.tag),
|
|
15
|
+
tokenFeatures: properties["token-features"] ?? null
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/core/auth/verify.ts
|
|
20
|
+
const VERIFY_TIMEOUT_MS = 15e3;
|
|
21
|
+
async function verifyAndProbe(url, credential, options = {}) {
|
|
22
|
+
const { refresh, signal } = options;
|
|
23
|
+
const mb = createClient({
|
|
24
|
+
url,
|
|
25
|
+
credential
|
|
26
|
+
}, {
|
|
27
|
+
userAgent: USER_AGENT,
|
|
28
|
+
...refresh !== void 0 && { refreshCredential: refresh },
|
|
29
|
+
...signal !== void 0 && { signal }
|
|
30
|
+
});
|
|
31
|
+
const userPromise = mb.user.current({
|
|
32
|
+
timeoutMs: VERIFY_TIMEOUT_MS,
|
|
33
|
+
retries: 0
|
|
34
|
+
});
|
|
35
|
+
const serverPromise = probeServer(mb);
|
|
36
|
+
const [userResult, serverResult] = await Promise.allSettled([userPromise, serverPromise]);
|
|
37
|
+
if (userResult.status === "rejected") return failure(userResult.reason, "user");
|
|
38
|
+
if (serverResult.status === "rejected") return failure(serverResult.reason, "server");
|
|
39
|
+
return {
|
|
40
|
+
ok: true,
|
|
41
|
+
user: {
|
|
42
|
+
id: userResult.value.id,
|
|
43
|
+
name: userResult.value.common_name,
|
|
44
|
+
isAdmin: userResult.value.is_superuser
|
|
45
|
+
},
|
|
46
|
+
server: serverResult.value
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function failure(error, which) {
|
|
50
|
+
if (error instanceof HttpError) return {
|
|
51
|
+
ok: false,
|
|
52
|
+
which,
|
|
53
|
+
kind: error.status === 401 || error.status === 403 ? "auth" : "server",
|
|
54
|
+
status: error.status,
|
|
55
|
+
endpoint: error.developerDetail.url,
|
|
56
|
+
message: error.userMessage
|
|
57
|
+
};
|
|
58
|
+
if (error instanceof NetworkError) return {
|
|
59
|
+
ok: false,
|
|
60
|
+
which,
|
|
61
|
+
kind: "network",
|
|
62
|
+
endpoint: error.developerDetail.url,
|
|
63
|
+
message: error.userMessage
|
|
64
|
+
};
|
|
65
|
+
if (error instanceof TimeoutError) {
|
|
66
|
+
const detail = error.developerDetail;
|
|
67
|
+
return {
|
|
68
|
+
ok: false,
|
|
69
|
+
which,
|
|
70
|
+
kind: "network",
|
|
71
|
+
...detail.kind === "http" && { endpoint: detail.url },
|
|
72
|
+
message: error.userMessage
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (error instanceof MetabaseError) return {
|
|
76
|
+
ok: false,
|
|
77
|
+
which,
|
|
78
|
+
kind: "server",
|
|
79
|
+
message: error.userMessage
|
|
80
|
+
};
|
|
81
|
+
return {
|
|
82
|
+
ok: false,
|
|
83
|
+
which,
|
|
84
|
+
kind: "server",
|
|
85
|
+
message: errorMessage(error)
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
export { verifyAndProbe as t };
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "./
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
1
|
+
import { F as outputFlags, I as profileFlag, M as connectionFlags, c as renderSummary } from "./cli.mjs";
|
|
2
|
+
import { t as defineMetabaseCommand } from "./runtime-DiKyBxOw.mjs";
|
|
3
|
+
import { n as DEFAULT_TIMEOUT_MS, t as DEFAULT_INTERVAL_MS } from "./poll-75SvT7Zv.mjs";
|
|
4
|
+
import { r as parseWaitSchedule } from "./wait-flags-DWEF9tX4.mjs";
|
|
5
|
+
import { c as syncTaskView } from "./git-sync-DxD_ng48.mjs";
|
|
6
|
+
import { a as throwIfFailedTask, i as taskPollOptions, n as formatSyncTask, r as syncTaskIdleView, t as SyncTaskOrIdle } from "./sync-task-BACcrs0i.mjs";
|
|
8
7
|
//#region src/commands/git-sync/wait.ts
|
|
9
8
|
const WaitResult = SyncTaskOrIdle;
|
|
10
9
|
var wait_default = defineMetabaseCommand({
|
|
@@ -34,22 +33,15 @@ var wait_default = defineMetabaseCommand({
|
|
|
34
33
|
outputSchema: WaitResult,
|
|
35
34
|
examples: ["mb git-sync wait", "mb git-sync wait --timeout 300000 --json"],
|
|
36
35
|
async run({ args, ctx, getClient }) {
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const client = await getClient();
|
|
40
|
-
const final = await pollSyncTask(client, {
|
|
41
|
-
timeoutMs,
|
|
42
|
-
intervalMs
|
|
43
|
-
});
|
|
36
|
+
const schedule = parseWaitSchedule(args);
|
|
37
|
+
const final = await (await getClient()).gitSync.waitForTask(taskPollOptions(schedule));
|
|
44
38
|
if (final === null) {
|
|
45
|
-
|
|
46
|
-
renderSummary(idle, syncTaskIdleView, "No git-sync task is running.", ctx);
|
|
39
|
+
renderSummary({ status: "idle" }, syncTaskIdleView, "No git-sync task is running.", ctx);
|
|
47
40
|
return;
|
|
48
41
|
}
|
|
49
42
|
renderSummary(final, syncTaskView, formatSyncTask(final), ctx);
|
|
50
43
|
throwIfFailedTask(final, "task");
|
|
51
44
|
}
|
|
52
45
|
});
|
|
53
|
-
|
|
54
46
|
//#endregion
|
|
55
|
-
export { wait_default as default };
|
|
47
|
+
export { wait_default as default };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { t as interruptSignal } from "./cli.mjs";
|
|
2
|
+
import { t as parseId } from "./parse-id-C_jmKFaa.mjs";
|
|
3
|
+
import { n as DEFAULT_TIMEOUT_MS, t as DEFAULT_INTERVAL_MS } from "./poll-75SvT7Zv.mjs";
|
|
4
4
|
//#region src/commands/wait-flags.ts
|
|
5
5
|
const waitScheduleFlags = {
|
|
6
6
|
timeout: {
|
|
@@ -30,17 +30,20 @@ const gitSyncWaitFlags = {
|
|
|
30
30
|
},
|
|
31
31
|
...waitScheduleFlags
|
|
32
32
|
};
|
|
33
|
+
function parseWaitSchedule(args) {
|
|
34
|
+
const interval = args.interval ?? String(2e3);
|
|
35
|
+
const timeout = args.timeout ?? String(6e5);
|
|
36
|
+
return {
|
|
37
|
+
intervalMs: parseId(interval, "interval"),
|
|
38
|
+
timeoutMs: parseId(timeout, "timeout"),
|
|
39
|
+
signal: interruptSignal
|
|
40
|
+
};
|
|
41
|
+
}
|
|
33
42
|
function parseWaitFlags(args) {
|
|
34
|
-
const interval = args.interval ?? String(DEFAULT_INTERVAL_MS);
|
|
35
|
-
const timeout = args.timeout ?? String(DEFAULT_TIMEOUT_MS);
|
|
36
43
|
return {
|
|
37
44
|
enabled: args.wait === true,
|
|
38
|
-
schedule:
|
|
39
|
-
intervalMs: parseId(interval, "interval"),
|
|
40
|
-
timeoutMs: parseId(timeout, "timeout")
|
|
41
|
-
}
|
|
45
|
+
schedule: parseWaitSchedule(args)
|
|
42
46
|
};
|
|
43
47
|
}
|
|
44
|
-
|
|
45
48
|
//#endregion
|
|
46
|
-
export {
|
|
49
|
+
export { waitFlags as i, parseWaitFlags as n, parseWaitSchedule as r, gitSyncWaitFlags as t };
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { m as projectForList } from "./cli.mjs";
|
|
2
|
+
//#region src/output/window.ts
|
|
3
|
+
const MAX_REQUEST_PAGE_SIZE = 200;
|
|
4
|
+
function windowList(items, range, serverTotal) {
|
|
5
|
+
const held = items.length;
|
|
6
|
+
const start = Math.min(range.offset, held);
|
|
7
|
+
const end = range.limit === void 0 ? held : Math.min(start + range.limit, held);
|
|
8
|
+
const total = serverTotal ?? held;
|
|
9
|
+
const beyondWindow = end < held;
|
|
10
|
+
const withheldByServer = held < total;
|
|
11
|
+
return buildEnvelope(items.slice(start, end), range, total, beyondWindow || withheldByServer);
|
|
12
|
+
}
|
|
13
|
+
function windowServerPage(data, total, range) {
|
|
14
|
+
return buildEnvelope(data, range, total, range.offset + data.length < total);
|
|
15
|
+
}
|
|
16
|
+
async function collectForOutput(source, view, opts) {
|
|
17
|
+
const { range } = opts;
|
|
18
|
+
const budget = opts.maxBytes <= 0 ? Number.POSITIVE_INFINITY : opts.maxBytes;
|
|
19
|
+
const fetchMax = range.limit === void 0 ? void 0 : range.limit + 1;
|
|
20
|
+
const request = {
|
|
21
|
+
offset: range.offset,
|
|
22
|
+
...fetchMax !== void 0 && {
|
|
23
|
+
max: fetchMax,
|
|
24
|
+
pageSize: Math.min(fetchMax, MAX_REQUEST_PAGE_SIZE)
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
const items = [];
|
|
28
|
+
let total = null;
|
|
29
|
+
let bytes = 0;
|
|
30
|
+
let exhausted = true;
|
|
31
|
+
for await (const page of source(request)) {
|
|
32
|
+
total = page.total ?? total;
|
|
33
|
+
for (const item of page.items) {
|
|
34
|
+
items.push(item);
|
|
35
|
+
bytes += measure(item, view, opts);
|
|
36
|
+
}
|
|
37
|
+
const budgetSpent = bytes > budget;
|
|
38
|
+
const capReached = fetchMax !== void 0 && items.length >= fetchMax;
|
|
39
|
+
if (budgetSpent || capReached) {
|
|
40
|
+
exhausted = false;
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const limit = range.limit;
|
|
45
|
+
return buildEnvelope(limit !== void 0 && items.length > limit ? items.slice(0, limit) : items, range, total, !exhausted);
|
|
46
|
+
}
|
|
47
|
+
function buildEnvelope(data, range, total, moreAvailable) {
|
|
48
|
+
const returned = data.length;
|
|
49
|
+
const hasMore = returned > 0 && moreAvailable;
|
|
50
|
+
return {
|
|
51
|
+
data,
|
|
52
|
+
returned,
|
|
53
|
+
offset: range.offset,
|
|
54
|
+
...range.limit !== void 0 && { limit: range.limit },
|
|
55
|
+
total,
|
|
56
|
+
has_more: hasMore,
|
|
57
|
+
next_offset: hasMore ? range.offset + returned : null
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function measure(item, view, opts) {
|
|
61
|
+
return Buffer.byteLength(JSON.stringify(projectForList(item, view, opts)), "utf8");
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
export { windowList as n, windowServerPage as r, collectForOutput as t };
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metabase/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2-alpha.extract-api-client.27e2241",
|
|
4
4
|
"description": "Metabase CLI",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
|
-
"url": "git+https://github.com/metabase/mb-cli.git"
|
|
8
|
+
"url": "git+https://github.com/metabase/mb-cli.git",
|
|
9
|
+
"directory": "packages/cli"
|
|
9
10
|
},
|
|
10
11
|
"bin": {
|
|
11
12
|
"mb": "./dist/cli.mjs"
|
|
@@ -13,8 +14,7 @@
|
|
|
13
14
|
"files": [
|
|
14
15
|
"dist",
|
|
15
16
|
"skills",
|
|
16
|
-
"skill-data"
|
|
17
|
-
".claude-plugin"
|
|
17
|
+
"skill-data"
|
|
18
18
|
],
|
|
19
19
|
"type": "module",
|
|
20
20
|
"publishConfig": {
|
|
@@ -25,23 +25,7 @@
|
|
|
25
25
|
"build": "tsdown",
|
|
26
26
|
"dev": "tsdown --watch",
|
|
27
27
|
"start": "node dist/cli.mjs",
|
|
28
|
-
"
|
|
29
|
-
"test:watch": "vitest --project unit",
|
|
30
|
-
"test:e2e": "vitest run --project e2e",
|
|
31
|
-
"test:e2e:watch": "vitest --project e2e",
|
|
32
|
-
"e2e:up": "docker compose -f tests/e2e/docker-compose.yml up -d --wait",
|
|
33
|
-
"e2e:down": "docker compose -f tests/e2e/docker-compose.yml down -v",
|
|
34
|
-
"e2e:bootstrap": "bun tests/e2e/setup/bootstrap.ts",
|
|
35
|
-
"e2e:matrix": "bun scripts/e2e-matrix.ts",
|
|
36
|
-
"e2e:logs": "docker compose -f tests/e2e/docker-compose.yml logs -f metabase",
|
|
37
|
-
"typecheck": "tsc --noEmit",
|
|
38
|
-
"lint": "oxlint",
|
|
39
|
-
"lint:fix": "oxlint --fix",
|
|
40
|
-
"lint:skills": "uvx skillsaw lint skill-data/ --strict",
|
|
41
|
-
"format": "oxfmt",
|
|
42
|
-
"format:check": "oxfmt --check",
|
|
43
|
-
"sync:representations": "bun run scripts/sync-representations.ts",
|
|
44
|
-
"prepublishOnly": "tsdown && publint"
|
|
28
|
+
"prepublishOnly": "tsdown && publint && ! grep -rE \"(from|import|require)[[:space:]]*\\(?['\\\"]@metabase\" dist/"
|
|
45
29
|
},
|
|
46
30
|
"dependencies": {
|
|
47
31
|
"@clack/prompts": "^0.8.2",
|
|
@@ -54,20 +38,6 @@
|
|
|
54
38
|
"yaml": "^2.8.4",
|
|
55
39
|
"zod": "^4.0.0"
|
|
56
40
|
},
|
|
57
|
-
"devDependencies": {
|
|
58
|
-
"@types/js-yaml": "^4.0.9",
|
|
59
|
-
"@types/node": "^22.10.0",
|
|
60
|
-
"@types/semver": "^7.7.1",
|
|
61
|
-
"execa": "^9.5.2",
|
|
62
|
-
"fast-check": "^4.7.0",
|
|
63
|
-
"js-yaml": "^4.1.0",
|
|
64
|
-
"oxfmt": "^0.47.0",
|
|
65
|
-
"oxlint": "^1.62.0",
|
|
66
|
-
"publint": "^0.3.0",
|
|
67
|
-
"tsdown": "^0.9.0",
|
|
68
|
-
"typescript": "^5.7.2",
|
|
69
|
-
"vitest": "^2.1.8"
|
|
70
|
-
},
|
|
71
41
|
"engines": {
|
|
72
42
|
"node": ">=20.6"
|
|
73
43
|
}
|
package/skill-data/core/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: core
|
|
3
|
-
description: Foundations for driving Metabase from the terminal with the `mb` CLI — authentication and named profiles, the flag/output/`--json` conventions every command shares, JSON body input, command discovery via `--help` (add `--json` for machine-readable schemas), and the per-resource footguns (db, table, field, upload, card, dashboard, collection, segment, measure, timeline, library, setting, search, eid). Load first for any `mb` task; it routes to the specialized skills for deeper work.
|
|
3
|
+
description: Foundations for driving Metabase from the terminal with the `mb` CLI — authentication and named profiles, the flag/output/`--json` conventions every command shares, JSON body input, command discovery via `--help` (add `--json` for machine-readable schemas), and the per-resource footguns (db, table, field, upload, card, dashboard, collection, segment, measure, timeline, alert, subscription, library, setting, search, eid). Load first for any `mb` task; it routes to the specialized skills for deeper work.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -12,8 +12,8 @@ Top-level command groups (run `mb <group> --help` to discover verbs):
|
|
|
12
12
|
|
|
13
13
|
```
|
|
14
14
|
auth | db | table | field | upload | query | card | dashboard | snippet | segment | measure | collection | library
|
|
15
|
-
document | timeline | timeline-event | transform | transform-job | transform-tag |
|
|
16
|
-
eid | uuid | upgrade | skills
|
|
15
|
+
document | timeline | timeline-event | transform | transform-job | transform-tag | alert | subscription | setting
|
|
16
|
+
search | git-sync | setup | eid | uuid | upgrade | skills
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
The conventions below — auth, flags, output, body input — hold across **every** group. Per-command flags and examples live in each command's `--help`; add `--json` for the machine-readable form with the output JSON Schema. A few flows have their own skills (see "Specialized skills"). When a card needs a query, prefer MBQL over native SQL (portable, pre-flight-validated — load `mbql`); fall back to native SQL when MBQL can't express it.
|
|
@@ -23,7 +23,7 @@ The conventions below — auth, flags, output, body input — hold across **ever
|
|
|
23
23
|
**The agent does not log in for the user.** Authentication is the human's job — they pick the base URL, paste credentials, and store them as a named profile. The agent checks what profiles exist, asks which to use, and passes `--profile <name>` through every command.
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
|
-
mb auth list --json # →
|
|
26
|
+
mb auth list --json # → list envelope; data is [{profile,url,authenticated,status,…}]
|
|
27
27
|
mb auth status --json # → {profile, present, url} for the default profile
|
|
28
28
|
mb auth status --profile <name> --json # health probe for one profile
|
|
29
29
|
```
|
|
@@ -60,26 +60,29 @@ Every list/get verb supports the same output flags:
|
|
|
60
60
|
- `--json` — emit the full JSON envelope, safe for `jq`. Default is human-readable text.
|
|
61
61
|
- `--full` — include every field (the compact projection is the default, and is the agent-facing contract).
|
|
62
62
|
- `--fields a,b.c.d` — project specific dot-paths. Mutually exclusive with `--full`. **Paths are relative to each `data[]` item on list verbs, and to the root on single-item verbs.** So it's `--fields id,name` on `… list` / `database schema-tables` (`data.id` and `data[].id` both fail with `unknown field path: "data.id"`), and `--fields id,name,display` on `card get`, `--fields data.rows` on `mb query` (whose `data` is an object).
|
|
63
|
-
- `--max-bytes <n>` — cap
|
|
63
|
+
- `--max-bytes <n>` — cap output size. Default 24576 (sized to fit under agent-harness tool-output limits); `0` disables. On a list it drops trailing items and sets `truncated` (see below). Single-item commands (`get`) never truncate — over the cap they throw a `ConfigError` (exit 2: "output is N bytes, over the M-byte --max-bytes cap; …") whose tail names the remedy: on schema-shaped commands it is the exact narrower command to run instead — follow it rather than raising the cap.
|
|
64
64
|
- JSON output is a single line when stdout is piped (pretty-printed only at a TTY) — always parse it, never scrape by line position.
|
|
65
65
|
|
|
66
|
-
List
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
"data": [
|
|
75
|
-
/* items */
|
|
76
|
-
]
|
|
77
|
-
}
|
|
78
|
-
```
|
|
66
|
+
## List windows and resumption
|
|
67
|
+
|
|
68
|
+
Every list verb takes `--limit <n>` (items this call returns) and `--offset <n>` (where the window starts, default `0`), and answers with one envelope, metadata first so the counts and the resumption point survive a cut tail: `{returned, offset, limit?, total, has_more, next_offset, truncated?, data}`. `truncated` is `{reason: "max_bytes", bytes: N}`.
|
|
69
|
+
|
|
70
|
+
- **`has_more` decides whether to keep going — never compare counts.** `total` is the server's count on endpoints that report one and `null` on those that don't, so arithmetic over it is not a termination condition.
|
|
71
|
+
- **To continue, pass `next_offset` back as `--offset`.** When `has_more` is true `next_offset` is past the offset you sent, so the loop advances; when false the walk is over and `next_offset` is `null`.
|
|
72
|
+
- **`truncated` means the byte cap cut the output, not that the data ran out.** `has_more`/`next_offset` are recomputed to the cut point, so a capped list resumes like any window. Its `bytes` is what the untruncated answer would have measured, so it sizes the work left rather than the reply you hold. Narrow rows with `--fields` rather than raising `--max-bytes` — a bigger cap spends context on fields you didn't ask for, and the cap counts only what you asked for, so `--fields` buys rows directly. A capped list always returns at least one row; when not even one fits it exits 2 with "the smallest response this list can produce is N bytes, over the M-byte --max-bytes cap; …".
|
|
73
|
+
- `limit` is echoed only when you passed `--limit` — except `mb search`, which defaults to `--limit 20` (an unbounded search is expensive server-side) and so always reports one. On nouns the server doesn't page, one large `--limit` with narrow `--fields` is a single request; many small `--offset` hops are one request each.
|
|
79
74
|
|
|
80
|
-
|
|
75
|
+
The whole walk, literally:
|
|
81
76
|
|
|
82
|
-
|
|
77
|
+
```bash
|
|
78
|
+
offset=0
|
|
79
|
+
while : ; do
|
|
80
|
+
out=$(mb table list --db-id 1 --limit 50 --offset "$offset" --fields id,name --profile <n> --json)
|
|
81
|
+
echo "$out" | jq -c '.data[]'
|
|
82
|
+
[ "$(echo "$out" | jq -r '.has_more')" = "true" ] || break
|
|
83
|
+
offset=$(echo "$out" | jq -r '.next_offset')
|
|
84
|
+
done
|
|
85
|
+
```
|
|
83
86
|
|
|
84
87
|
## Body input (create / update / run)
|
|
85
88
|
|
|
@@ -87,10 +90,10 @@ Verbs that take a payload accept it from one of four sources, **first non-empty
|
|
|
87
90
|
|
|
88
91
|
1. `--body '<inline JSON>'`
|
|
89
92
|
2. `--file <path>` — JSON file
|
|
90
|
-
3. stdin (auto-detected when piped
|
|
93
|
+
3. stdin (auto-detected when piped; `--file -` names it explicitly)
|
|
91
94
|
4. positional argument
|
|
92
95
|
|
|
93
|
-
Exactly one required; passing
|
|
96
|
+
Exactly one required; passing more than one of `--body` / `--file` / a positional argument is rejected with a `ConfigError`.
|
|
94
97
|
|
|
95
98
|
```bash
|
|
96
99
|
cat > ./.scratch/body.json <<'EOF'
|
|
@@ -122,17 +125,18 @@ mb transform --help --json | jq -r '.commands[].command' # verbs under "transfo
|
|
|
122
125
|
|
|
123
126
|
Routine verb shapes (list / get / create / update), every flag, and output schemas live in each command's `--help` (add `--json` for output schemas). Below is only what help does _not_ tell you: footguns and non-obvious behaviors.
|
|
124
127
|
|
|
125
|
-
- **db traversal: the hydration ladder.** Start with `database get <db-id> --include tables` — the compact table map (id, name, schema, description per table), one call that fits most databases. Pick the relevant tables, then `table fields <table-id>` per table (bounded: fields are per-table). `--include tables.fields` is the full rollup — small databases only
|
|
128
|
+
- **db traversal: the hydration ladder.** Start with `database get <db-id> --include tables` — the compact table map (id, name, schema, description per table), one call that fits most databases. Pick the relevant tables, then `table fields <table-id>` per table (bounded: fields are per-table). `--include tables.fields` is the full rollup — small databases only. Hundreds of tables? Traverse by schema (`database schemas <db-id>` → `database schema-tables <db-id> <schema>`) or look tables up by name (`search <term> --models table --db-id <db-id> --limit 10`). `sync-schema` / `rescan-values` queue async work and return `{status:"ok"}` immediately; `sync-schema --wait` blocks until `initial_sync_status: complete`.
|
|
126
129
|
- **table fields.** `table get` never returns fields on its own — pass `--include fields` (compact; the underlying query_metadata response also carries FK targets and dimensions, visible under `--full`) or use `table fields <id>` (list envelope). `table update` patches table-level metadata only; physical columns aren't editable.
|
|
127
130
|
- **field has no `list`.** Fields are per-table — get them via `table get <id> --include fields`. Never enumerate fields across a whole db (context blow-up). `field summary` is live cardinality `{field_id, count, distincts}`; `field values` is the cached distinct set (`has_more_values: true` ⇒ truncated cache). `field update` patches metadata only (`base_type` isn't editable) — this is where you set a column's `semantic_type` or foreign-key target.
|
|
128
131
|
- **upload (CSV → tables).** `upload csv --file <path>` creates a new table + model (prints `{model_id, table_id}`); `upload append <table-id>` / `upload replace <table-id> --file <path>` add to / overwrite a table **previously created by upload** (columns must match). The destination db+schema is admin-configured, not per-call — check with `mb setting get uploads-settings --json` (`db_id: null` ⇒ uploads off/unconfigured; needs admin to read). `--collection <id|root>` only sets the model's collection. Max 50 MB. Errors: **"The uploads database is not configured."** = no db has uploads enabled; **"Uploads are not enabled."** = the append/replace target isn't an uploaded table.
|
|
129
132
|
- **card.** `dataset_query` is the **flat** `mbql/query` value, not a legacy `{type:"query",query:…}` envelope (→ `mbql`). `--export-format csv|xlsx` streams the raw export (pipe to a file), bypassing the JSON envelope. `archive` is the only delete; unarchive with `update --body '{"archived":false}'`. `visualization_settings` keys are scoped by `display` and aren't pre-flighted — see `visualization`.
|
|
130
133
|
- **dashboard.** Dashcards round-trip through `PUT /api/dashboard/:id` (no per-dashcard endpoint): `update-dashcard <dash-id> <dashcard-id>` patches one safely; `update --body '{"dashcards":[…]}'` replaces the whole set (omitted ids are deleted server-side; negative ids for new cards). `create` accepts the **same** `dashcards` array in its initial body — lay out the whole dashboard in one call: negative ids for new cards, and `card_id:null` plus a `visualization_settings.virtual_card` block (`{display:"text"|"heading"|"link"|…}`) for non-question cards. `create`/`update` pre-flight every positive `card_id` and exit **2** with `{ok:false,errors:[…]}` on a bad ref (non-bypassable). `dashboard get <id>` (or `--full`) hydrates dashcards/tabs; `list` omits them. **The grid is 24 columns wide:** each dashcard's `{col, row, size_x, size_y}` is in grid units — **full-width is `size_x: 24`** (`size_x: 12` is half a row, the usual cause of a card filling only half the width). Keep `col + size_x ≤ 24`, start a full-width stack's `col` at 0, and don't overlap (the server stores collisions as sent — no auto-fix). Layout patterns and per-chart default sizes → the `dashboard` skill; load it before composing any `dashcards` array.
|
|
131
|
-
- **dashboard parameters (filters).** A dashboard's `parameters` array holds its filter widgets; they're part of the dashboard record, so read them with `dashboard get <id> --fields parameters --json` (no separate verb). **Editing replaces the _whole_ array** (like dashcards), so it's a read-modify-write loop
|
|
134
|
+
- **dashboard parameters (filters).** A dashboard's `parameters` array holds its filter widgets; they're part of the dashboard record, so read them with `dashboard get <id> --fields parameters --json` (no separate verb). **Editing replaces the _whole_ array** (like dashcards), so it's a read-modify-write loop and omitting a parameter deletes it. A parameter only filters a card once it is **mapped** onto that dashcard's `parameter_mappings` — an unmapped parameter is an inert widget. `type` is a **closed enum**; an unlisted value is a hard parse error that echoes the full allowed set back to you. `dashboard parameter-values <id> <parameter-id> [--query <substr>]` fetches a widget's selectable values (`{values, has_more_values}`; `--query` is a case-insensitive substring search). Parameter types, ids, mapping targets, and value sources → the `dashboard` skill; load it before authoring a `parameters` array.
|
|
135
|
+
- **alert / subscription are two unrelated systems.** `alert` watches one **card** and fires on a send condition (`/api/notification`: a cron string, `channel/email`-prefixed handlers, typed recipients); `subscription` delivers one **dashboard** on a schedule (`/api/pulse`: structured `schedule_type` + hour/day/frame, bare `email` channels, `{id}|{email}` recipients). The bodies are not interchangeable. Both silently deliver nowhere if the server has no SMTP / Slack app — check `mb setting get 'email-configured?'` (quote it; the `?` is a shell glob) before creating either. Their list-valued fields (`handlers`/`subscriptions`, `channels`/`cards`) **replace wholesale** on update, so adding one recipient is a read-modify-write. `mb card alerts <id>` and `mb dashboard subscriptions <id>` list what's already attached to a card/dashboard; `archive` deactivates rather than deletes. Load the `notification` skill before authoring either body.
|
|
132
136
|
- **snippet `--archived` is a swap, not a union** — list returns _either_ active _or_ archived rows, never both. (Same for `--filter archived` on dashboard/collection.)
|
|
133
137
|
- **segment / measure.** `update` and `archive` require a non-blank `revision_message` (audit-logged); the CLI does not synthesize it on `update`. `archive` defaults to `"Archived via mb CLI"` — override with `--revision-message`. `definition` is a flat MBQL clause (→ `mbql`): segment = a filter, measure = exactly one aggregation.
|
|
134
138
|
- **timeline / timeline-event.** Timelines are collection-scoped event annotations for time-series charts: a timeline's events render only on time-series questions saved in the **same collection** (`collection_id`; null = root) — sub-collections do **not** inherit, and events never draw on dashboard cards, only in the question (and collection) view. To annotate a question's chart, create the timeline in that question's collection, then add events; an event only draws when its `timestamp` falls inside the chart's displayed time range. Event `create` requires `timestamp` (ISO 8601), `timezone` (IANA name), `time_matters` (true = the time of day is significant, false = date-only), and `timeline_id` — the API never auto-creates a default timeline (that's UI-only). There is no `timeline-event list`; enumerate with `timeline events <id>` (`--archived` to include archived). Archiving a timeline cascades `archived` to its events; `delete` is a **hard** delete of the timeline and all its events — prefer `archive`.
|
|
135
|
-
- **collection `<ref>`** accepts four forms only — positive int, `root`, `trash`, or a 21-char entity_id; anything else is a client-side `ConfigError`. `collection items`
|
|
139
|
+
- **collection `<ref>`** accepts four forms only — positive int, `root`, `trash`, or a 21-char entity_id; anything else is a client-side `ConfigError`. `collection items` pages the server endpoint, pulling only as far as the output cap can show — read `has_more`/`next_offset` to continue. `collection tree` is **JSON-only** (`--format text` is rejected). A transform collection needs `collection create --namespace transforms`.
|
|
136
140
|
- **setting set** parses the value as **strict JSON**: a string is `'"value"'` (inner quotes), booleans `true`/`false`, numbers bare. Wrong quoting silently errors — confirm with `setting get <key>` after. `setting get --json` works on every value type (wrapping bare-text responses into `{key, value}`).
|
|
137
141
|
- **search vs. list.** For plain enumeration of cards/dashboards/collections use the dedicated `… list` verbs; reach for `search --models <kind>` only for ranking against a query string or a cross-resource lookup.
|
|
138
142
|
- **transform.** Iterate with `transform update <id>`, never `delete` + `create` (keeps the row, `entity_id`, materialized table, and YAML filename — avoids `_2` suffixes and noisy git history). `transform run` needs `--wait` (or `--sync`, which also waits for the output table to register and returns `target_table_id`) or you get only `{run_id, final:null}`. (→ `transform`.)
|
|
@@ -150,6 +154,7 @@ This file is enough for any single-command task. For anything deeper, load the r
|
|
|
150
154
|
- **`visualization`** — choosing a card's `display` and authoring `visualization_settings`. The presentation counterpart to `mbql`.
|
|
151
155
|
- **`dashboard`** — building interactive dashboards: wiring filters (parameters + mappings), linked/cascading filters, cross-filtering, click behavior, series, and tabs. Load beyond a plain card-layout task.
|
|
152
156
|
- **`metadata`** — setting field/table metadata: semantic types, foreign-key targets, dropdown/scan behavior, and column visibility, and the downstream features each unlocks. Load when editing what a column _means_, not its data.
|
|
157
|
+
- **`notification`** — scheduled delivery: question alerts (`mb alert`) and dashboard subscriptions (`mb subscription`). Choosing between them, the two schedule/recipient contracts, channel prerequisites, testing a send.
|
|
153
158
|
- **`transform`** — transform body JSON, create + run-with-wait, run inspection, tags, jobs.
|
|
154
159
|
- **`document`** — Metabase documents (TipTap body, embedding cards).
|
|
155
160
|
- **`git-sync`** — round-tripping content to/from a git remote.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: dashboard
|
|
3
|
-
description: Build Metabase dashboards via the `mb` CLI — lay out dashcards on the 24-column grid (`{col,row,size_x,size_y}` math, per-chart default sizes) and turn cards into a filterable, cross-linked app. Covers wiring filters to cards (parameters + parameter_mappings), the field-filter vs. raw-variable target grammar, linked/cascading filters and their foreign-key requirement, cross-filtering, click-through, multi-series overlays, and tabs. The
|
|
3
|
+
description: Build Metabase dashboards via the `mb` CLI — lay out dashcards on the 24-column grid (`{col,row,size_x,size_y}` math, per-chart default sizes) and turn cards into a filterable, cross-linked app. Covers wiring filters to cards (parameters + parameter_mappings), the field-filter vs. raw-variable target grammar, linked/cascading filters and their foreign-key requirement, cross-filtering, click-through, multi-series overlays, and tabs. The whole-array replace semantics live in `core`. Triggers — "build a dashboard from these cards", "my dashboard is squished into half the width", "wire a filter to these cards", "make a filter cascade", "click a bar to filter the other charts", "add a dashboard tab", "add a second series", "why isn't my filter showing".
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
|
8
8
|
|
|
9
9
|
A dashboard starts as cards on a grid; it becomes an **app** when filters drive the cards, charts cross-filter each other, and clicks navigate. This skill owns both: the grid layout and the interactive layer.
|
|
10
10
|
|
|
11
|
-
**`core` owns the transport mechanics** — the whole-array replace semantics (editing `dashcards` or `parameters` replaces the entire set; omitted entries are deleted; new cards use negative ids), `update-dashcard` for a single safe patch vs. `update --body` for a full replace,
|
|
11
|
+
**`core` owns the transport mechanics** — the whole-array replace semantics (editing `dashcards` or `parameters` replaces the entire set; omitted entries are deleted; new cards use negative ids), `update-dashcard` for a single safe patch vs. `update --body` for a full replace, and the `parameter-values` verb. Read it first (`mb skills get core`). **`visualization`** owns each card's chart and the full `click_behavior` key catalog.
|
|
12
12
|
|
|
13
13
|
Inspect before you wire: `mb dashboard get <id> --json` hydrates `parameters`, `dashcards`, and `tabs`; `mb dashboard cards <id>` lists just the dashcards.
|
|
14
14
|
|
|
@@ -47,6 +47,10 @@ A dashboard filter is one entry in the dashboard's `parameters` array **plus** a
|
|
|
47
47
|
"target": ["dimension", ["field", 1779, null]] }
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
+
**`id` is a slug-like string you pick** (e.g. `order_status`), unique within the dashboard — Metabase stores any non-blank string verbatim, so reuse the `slug` rather than guessing an opaque value. If you genuinely need an opaque id, mint one with `mb uuid`; never fabricate one.
|
|
51
|
+
|
|
52
|
+
**`type` is a closed enum** — an unlisted value is a hard parse error that echoes the allowed set back: string ops `string/=` `string/!=` `string/contains` `string/does-not-contain` `string/starts-with` `string/ends-with`; number ops `number/=` `number/!=` `number/between` `number/>=` `number/<=`; date `date/single` `date/range` `date/relative` `date/month-year` `date/quarter-year` `date/all-options`; location `location/city` `location/state` `location/zip_code` `location/country`; plus `category`, `id`, `boolean/=`, `temporal-unit`, and bare `number`/`text`/`date`/`boolean`.
|
|
53
|
+
|
|
50
54
|
The `target` grammar depends on what the card is:
|
|
51
55
|
|
|
52
56
|
| Card's query | `target` |
|
|
@@ -20,13 +20,13 @@ mb document update <id> --file patch.json --profile <name> --json # PATCH sema
|
|
|
20
20
|
mb document archive <id> --profile <name> --json # soft-delete (PUT archived:true)
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
- `list` returns the standard envelope (
|
|
23
|
+
- `list` returns the standard list envelope (see `core`). The compact item is `{id, name, collection_id, archived, creator_id, can_write}` and omits the (potentially huge) `document` body — pull the body with `get --full`.
|
|
24
24
|
- `archive` is the only delete, mirroring `card` / `dashboard`. **Unarchive** with `mb document update <id> --body '{"archived":false}'`.
|
|
25
25
|
- `update` is PATCH — send only the keys you want to change: `name`, `document`, `collection_id`, `collection_position`, `archived`, and `cards` (inline card creation works on update too, not just create — see below). Replacing `document` replaces the **whole** body; there is no partial-node patch.
|
|
26
26
|
|
|
27
27
|
## Node ids (`_id`)
|
|
28
28
|
|
|
29
|
-
The editor anchors only these node types with an `_id` (a UUID): `paragraph`, `heading`, `codeBlock`, `orderedList`, `bulletList`, `blockquote`, `cardEmbed`, `supportingText`. **`create`/`update` require a non-empty `_id` on every node of those types** — the CLI validates before sending and rejects a body missing any (`every … node needs a non-empty string _id
|
|
29
|
+
The editor anchors only these node types with an `_id` (a UUID): `paragraph`, `heading`, `codeBlock`, `orderedList`, `bulletList`, `blockquote`, `cardEmbed`, `supportingText`. **`create`/`update` require a non-empty `_id` on every node of those types** — the CLI validates before sending and rejects a body missing any (`every … node needs a non-empty string _id`). Other node types (`doc`, `text`, `listItem`, `resizeNode`, `flexContainer`, …) take no `_id` and are left alone. Without them the editor backfills ids when the document opens, which makes a freshly-saved document show a spurious "unsaved changes" prompt.
|
|
30
30
|
|
|
31
31
|
Mint the ids with `mb uuid --count <n> --json` (→ `["…", …]`), one per id-bearing node, and set each as that node's `attrs._id`.
|
|
32
32
|
|