@metabase/cli 0.3.0 → 0.3.1-alpha.versioning.9ac5f50
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/dist/{add-collection-B3Ty8SzB.mjs → add-collection-Dmd-uNeU.mjs} +4 -7
- package/dist/{alert-DT-ee7yf.mjs → alert-D1u2MVZj.mjs} +7 -7
- package/dist/{alerts-Bf2RH_p_.mjs → alerts-DcBjcfEE.mjs} +5 -5
- package/dist/{append-DFzQRPMd.mjs → append-B9Htvmab.mjs} +6 -5
- package/dist/{archive-lQqs13Uz.mjs → archive-B660RguB.mjs} +4 -4
- package/dist/{archive-ByvA49Kz.mjs → archive-BNivAYGr.mjs} +4 -4
- package/dist/{archive-4tmm946K.mjs → archive-BUoYMkxO.mjs} +4 -4
- package/dist/{archive-C7w49Grr.mjs → archive-BVmFGFwG.mjs} +4 -4
- package/dist/{archive-ChORH5JH.mjs → archive-Bf014rFm.mjs} +4 -4
- package/dist/{archive-gid9Y09v.mjs → archive-BmsZFOZY.mjs} +4 -4
- package/dist/{archive-BxNPHxOY.mjs → archive-CNif6BKy.mjs} +6 -6
- package/dist/{archive-Cd29QC0c.mjs → archive-CgmidYZV.mjs} +4 -4
- package/dist/{archive-CwAdlv63.mjs → archive-CvU2z5192.mjs} +4 -4
- package/dist/{archive-Dr9Xnx_Z.mjs → archive-DhDQIKR_.mjs} +6 -6
- package/dist/{archive-B6eXiyER.mjs → archive-bPdDITuY.mjs} +4 -4
- package/dist/{auth-Dltxua89.mjs → auth-CefYEPP5.mjs} +5 -5
- package/dist/{body-Cur4NJt9.mjs → body-C7m9q4cm.mjs} +3 -3
- package/dist/{branches-DchlyU0i.mjs → branches-pz04OjF2.mjs} +3 -6
- package/dist/{cancel-BMQa5R1Z.mjs → cancel-CNLnv19e.mjs} +4 -4
- package/dist/{cancel-task-C5CU1pxU.mjs → cancel-task-DbnxSh7U.mjs} +3 -6
- package/dist/card-BRarvKYX.mjs +24 -0
- package/dist/{cards-SccWvRQD.mjs → cards-DtYlVoGP.mjs} +6 -6
- package/dist/cli.mjs +554 -62
- package/dist/{client-BqhzKdLM.mjs → client-Bv7Iwdvh.mjs} +258 -76
- package/dist/collection-CKeO8X7U.mjs +20 -0
- package/dist/{collection-CGoVLvcD.mjs → collection-DALwHnbz.mjs} +1 -1
- package/dist/{collection-CfulNRBG.mjs → collection-WFdBeyqa.mjs} +1 -1
- package/dist/{collection-namespace-GwydWBF3.mjs → collection-namespace-CvT0TIZA.mjs} +2 -2
- package/dist/content-translation-BrHOrmj9.mjs +5 -0
- package/dist/content-translation-D7POzJJ6.mjs +12 -0
- package/dist/{create-CD008jdE.mjs → create-BEE8uvz2.mjs} +12 -8
- package/dist/{create-CAQV2g6V.mjs → create-Bh2j733n.mjs} +7 -7
- package/dist/{create-BNQ_DytP.mjs → create-Bwg-5p08.mjs} +4 -4
- package/dist/{create-C79vErX0.mjs → create-CGPle4nE.mjs} +5 -5
- package/dist/{create-i14Wv3Tj.mjs → create-CGgPnb7L.mjs} +4 -4
- package/dist/{create-DJmXXQoq.mjs → create-CLgalJUe.mjs} +8 -8
- package/dist/{create-Beh-2uoN.mjs → create-CN24yp_W.mjs} +6 -6
- package/dist/{create-DF4QtgDL.mjs → create-CuYGZ4gu2.mjs} +4 -4
- package/dist/{create-CAWytBE5.mjs → create-DGHILnnk.mjs} +5 -5
- package/dist/{create-zeveFdnd.mjs → create-DYd_o9BD.mjs} +5 -8
- package/dist/{create-DV-Ln5Mo.mjs → create-DhDREiiy.mjs} +4 -4
- package/dist/{create-CHQx7jq4.mjs → create-Di4YvIbK.mjs} +4 -4
- package/dist/{create-tQbnuz-I.mjs → create-DnqnjGGf.mjs} +4 -4
- package/dist/{create-CCh_LyW9.mjs → create-Ds-DnSBe.mjs} +4 -4
- package/dist/{create-BOLwWt8Q.mjs → create-JOXq0ULN.mjs} +5 -5
- package/dist/{create-branch-CYo6jZth.mjs → create-branch-DWcxC30N.mjs} +3 -7
- package/dist/{csv-B2Jgb1GM.mjs → csv-CUQvcCEk.mjs} +6 -5
- package/dist/{current-task-MpBFGttd.mjs → current-task-D6P0eL21.mjs} +3 -6
- package/dist/{dashboard-CsIFFpzK.mjs → dashboard-BlbNszi8.mjs} +1 -1
- package/dist/{dashboard-BHJBoaG7.mjs → dashboard-BudI952R.mjs} +10 -10
- package/dist/{dashboard-BCpSq_G-.mjs → dashboard-CKUR8ZpQ.mjs} +1 -0
- package/dist/{db-DsfojyeH.mjs → db-C7UTd-6P.mjs} +7 -7
- package/dist/{delete-DFmX7jTp.mjs → delete-DSxqbcFE.mjs} +5 -5
- package/dist/{delete-Ck0q4Dzp.mjs → delete-DbZZKcYj.mjs} +5 -5
- package/dist/{delete-Ob06PPie.mjs → delete-Ds-zGh9C.mjs} +5 -5
- package/dist/{delete-B8e01xAG.mjs → delete-Ud6iliGM.mjs} +5 -5
- package/dist/{delete-BApOjQvl.mjs → delete-_IHffP-A.mjs} +5 -5
- package/dist/{delete-runtime-D74s6vhu.mjs → delete-runtime-BjHL1ryM.mjs} +1 -2
- package/dist/{delete-table-DuyhGrvA.mjs → delete-table-DtXH6IN5.mjs} +5 -5
- package/dist/{dependencies-Bj3QrGIm.mjs → dependencies-CR1dlq-A.mjs} +6 -6
- package/dist/{dirty-DNYoM6Bp.mjs → dirty-CYxnOnh0.mjs} +3 -6
- package/dist/document-BoILnE_1.mjs +19 -0
- package/dist/download-DPpmmYQe.mjs +25 -0
- package/dist/{eid-WTZmDdsr.mjs → eid-D-BbtWjt.mjs} +4 -5
- package/dist/{events-Bn7jh5lP.mjs → events-CJEnn8WE.mjs} +4 -4
- package/dist/{export-BjfoZRDJ.mjs → export-BOgyuIOQ.mjs} +4 -7
- package/dist/{field-Zau6Hc6X.mjs → field-CzHBOPER.mjs} +5 -5
- package/dist/{fields-CBBa-Prp.mjs → fields-Bwgkrvus.mjs} +4 -4
- package/dist/{get-C2-Q3iQ5.mjs → get-B89DUSvw.mjs} +4 -4
- package/dist/{get-DkWO0EI0.mjs → get-BL90QC64.mjs} +6 -6
- package/dist/{get-ByBOq30r.mjs → get-BLJSCw53.mjs} +6 -6
- package/dist/{get-DRvsATp-.mjs → get-BOLwso0V.mjs} +6 -6
- package/dist/{get-B7sMgsFs.mjs → get-BaPadzdM.mjs} +4 -4
- package/dist/{get-00lyLv6R.mjs → get-BfVCLBqc.mjs} +4 -4
- package/dist/{get-DdsoHaKH.mjs → get-C1ZdOvMm.mjs} +4 -4
- package/dist/{get-DmpB6J9g.mjs → get-CLu4yzMp2.mjs} +4 -4
- package/dist/{get-DY03Azx9.mjs → get-COwdtskS.mjs} +5 -8
- package/dist/{get-D_h-G9bn.mjs → get-CWfIiXwL.mjs} +4 -4
- package/dist/get-CqQ-pf0q.mjs +89 -0
- package/dist/{get-DYO1kywc.mjs → get-CvIgxPXV.mjs} +4 -4
- package/dist/{get-Bz99dAxK.mjs → get-D4OTJblo.mjs} +6 -6
- package/dist/{get-Dn9ZiSZr.mjs → get-D8lHwu4-.mjs} +4 -4
- package/dist/{get-B_xdF1kq.mjs → get-DVi3a2nm.mjs} +4 -4
- package/dist/{get-CDJFVvhj.mjs → get-DgnYF7LR.mjs} +4 -4
- package/dist/{get-CDMGbgrh.mjs → get-DsKmZfM2.mjs} +4 -4
- package/dist/{get-Dmj9Ygz1.mjs → get-DyyPiiaB.mjs} +4 -4
- package/dist/{get-CnbUCzDM.mjs → get-Eqq13YY-.mjs} +4 -4
- package/dist/{get-run-Cnux9ln0.mjs → get-run-Iya0Yw9s.mjs} +6 -6
- package/dist/git-sync-CdN0Maun.mjs +28 -0
- package/dist/{group-DBM87IgC.mjs → group-CmVCLBDz.mjs} +2 -1
- package/dist/{has-remote-changes-C684Redh.mjs → has-remote-changes-DfJUMP8F.mjs} +3 -6
- package/dist/{import-Rmmttboo.mjs → import-FEAx-Y5A.mjs} +4 -7
- package/dist/{input-DH9i67x_.mjs → input-DFZ_qGW_.mjs} +1 -1
- package/dist/{is-dirty-DYeJYhBz.mjs → is-dirty-BsYjBSXG.mjs} +3 -6
- package/dist/{items-CQlPXBXE.mjs → items-D4rstE12.mjs} +6 -6
- package/dist/{key-BEhqIzIQ.mjs → key-BmWundO3.mjs} +1 -1
- package/dist/{library-DfYAT2Ep.mjs → library-CmctxHjv.mjs} +1 -1
- package/dist/library-DXB8sm4r.mjs +81 -0
- package/dist/{library-Bsm5KsFF.mjs → library-uzyHWBap.mjs} +5 -5
- package/dist/{list-DF2rvoO1.mjs → list-1DkkU82x.mjs} +13 -12
- package/dist/{list-BpFp9Wre.mjs → list-B7tqNV8B.mjs} +3 -3
- package/dist/{list-DE9FM957.mjs → list-BRpPbvyS.mjs} +3 -3
- package/dist/{list-CQwOgIlj.mjs → list-BXL8HFr_.mjs} +3 -3
- package/dist/{list-BzVTHOoH.mjs → list-Bjj0z5BS.mjs} +5 -5
- package/dist/{list-CQDprvW0.mjs → list-BmMi_wPD.mjs} +6 -6
- package/dist/{list-C5Zs8nrb.mjs → list-CC1M_n6Z.mjs} +5 -5
- package/dist/{list-CKK-s3Ty.mjs → list-CQy0z7f9.mjs} +3 -3
- package/dist/{list-BtmsNOEn.mjs → list-D_zvX0ms.mjs} +3 -3
- package/dist/{list-CMpoc2TN.mjs → list-DeNGm9G4.mjs} +3 -3
- package/dist/{list-DMKDsBRd.mjs → list-Dgm6TkqR.mjs} +6 -6
- package/dist/{list-BOET6zhP.mjs → list-DoTiQc3D.mjs} +3 -3
- package/dist/{list-BP3MPq-M.mjs → list-DrS3ePsv.mjs} +3 -3
- package/dist/list-bN0RC14-.mjs +59 -0
- package/dist/{list-B4hJuMhA.mjs → list-ndIl9XqV.mjs} +4 -4
- package/dist/{list-B8nAGwP4.mjs → list-sQcA4g05.mjs} +3 -3
- package/dist/{list-CNUiF8Z7.mjs → list-squb_ioH.mjs} +3 -3
- package/dist/{list-BtkWNtvY.mjs → list-xMfCeuZc.mjs} +4 -4
- package/dist/{login-CGHeSjlP.mjs → login-D_1-zE4A.mjs} +15 -12
- package/dist/{logout-DAxOlbv4.mjs → logout-DPi2q1Wu.mjs} +3 -4
- package/dist/{measure-BsYv0p26.mjs → measure-CdA8Nl3Z.mjs} +6 -6
- package/dist/{parameter-values-CJTdqd8c.mjs → parameter-values-C6dj6I4g.mjs} +4 -5
- package/dist/{parse-enum-D0Jfm_Bz.mjs → parse-enum-B1t8S194.mjs} +1 -1
- package/dist/{parse-id-C_jmKFaa.mjs → parse-id-DR8aUSdL.mjs} +1 -1
- package/dist/{parse-ref-ibKVB0J4.mjs → parse-ref-BJ_Q0tNW.mjs} +1 -1
- package/dist/{path-B5gHvrYL.mjs → path-B96DI8u2.mjs} +4 -4
- package/dist/{poll-75SvT7Zv.mjs → poll-By46YQ5J.mjs} +2 -2
- package/dist/{preflight-YpPQo-sa.mjs → preflight-Bl1oitm8.mjs} +3 -4
- package/dist/{process-DBOOrmET.mjs → process-CcQM4qPv.mjs} +1 -1
- package/dist/{publish-DijrxaCW.mjs → publish-BKJYvxif.mjs} +9 -9
- package/dist/{query-Dc__-KJH.mjs → query-BKSM-pbi.mjs} +6 -7
- package/dist/{query-BbqECzmF.mjs → query-qBHjZQc_.mjs} +5 -12
- package/dist/{remove-collection-BOnxYvhj.mjs → remove-collection-BWFW7Rn6.mjs} +4 -7
- package/dist/{render-CI93iP0I.mjs → render-DmykmrFB.mjs} +11 -2
- package/dist/{replace-Cq4CxVa-.mjs → replace-BmAqD3zY.mjs} +6 -5
- package/dist/{rescan-values-Dr_j416g.mjs → rescan-values-BrCLrihF.mjs} +4 -4
- package/dist/{run-C3DkS6NP.mjs → run-CtbzjDKY.mjs} +6 -6
- package/dist/{run-DdGJ544X.mjs → run-q5Y44Fxj.mjs} +26 -14
- package/dist/{runs-CUNWiidL.mjs → runs-JFlbezkQ.mjs} +6 -6
- package/dist/{runtime-DiKyBxOw.mjs → runtime-BQiGgbgZ.mjs} +850 -265
- package/dist/{schema-tables-CV386fnC.mjs → schema-tables-Bzx2ShyE.mjs} +4 -4
- package/dist/{schemas-DM-UqZBQ.mjs → schemas-ww5mU2AS.mjs} +4 -4
- package/dist/{search-DmGScXs8.mjs → search-J4RwCof-.mjs} +4 -4
- package/dist/{segment-BzUGM2Fr.mjs → segment-XXTjU0eG.mjs} +6 -6
- package/dist/{selectors-DGDn0Hto.mjs → selectors-BAAZMi43.mjs} +3 -3
- package/dist/{send-CVxxEpDB.mjs → send-BmpDlw9O.mjs} +4 -4
- package/dist/{set-DFolTjbd.mjs → set-DUWrSza9.mjs} +5 -5
- package/dist/{set-active-BD8L1lPX.mjs → set-active-BiUlbNI5.mjs} +5 -5
- package/dist/{setting-DyhaeICs.mjs → setting-B1KBQN3M.mjs} +4 -4
- package/dist/{setup-BbDQN8fe.mjs → setup-CVaNVwOd.mjs} +4 -4
- package/dist/{signal-CMd0EFUa.mjs → signal-GhGmuHfx.mjs} +11 -2
- package/dist/{list-UhpKG6_m.mjs → skill-list-DTnDhnL5.mjs} +17 -46
- package/dist/{skills--vK6J-e4.mjs → skills-BWrAlj9l.mjs} +3 -3
- package/dist/{skills-DTCrMcix.mjs → skills-DkDsSH5F.mjs} +102 -14
- package/dist/snippet-CG75L2DS.mjs +19 -0
- package/dist/{stash-D0S4JmAz.mjs → stash-DMm8YF8V.mjs} +4 -8
- package/dist/{status-hL1am-HV.mjs → status-BzEQjQ_t.mjs} +12 -11
- package/dist/{status-BhswxJL1.mjs → status-ClWsQD6v.mjs} +9 -7
- package/dist/stream-McixcoUl.mjs +7 -0
- package/dist/{subscription-_d5fB45F.mjs → subscription-CdFn2hre.mjs} +6 -6
- package/dist/{subscriptions-s4TF6Ax3.mjs → subscriptions-DBda1pE5.mjs} +5 -5
- package/dist/{summary-CsPvcUwW.mjs → summary-B4GPiuqD.mjs} +4 -4
- package/dist/{sync-schema-DaZ_MV-u.mjs → sync-schema-DsIM5g2U.mjs} +5 -5
- package/dist/{table-DYoC1kPn.mjs → table-D4Alrrwh.mjs} +5 -5
- package/dist/timeline-DmM0BuX8.mjs +21 -0
- package/dist/{timeline-event-CNQdCTDg.mjs → timeline-event-DWIh3Tdt.mjs} +6 -6
- package/dist/transform-BcV_XlSX.mjs +28 -0
- package/dist/{transform-DoTyyXAu.mjs → transform-Bk0D0nIs.mjs} +1 -1
- package/dist/{transform-D3QX0jxA.mjs → transform-DpuG-ON3.mjs} +26 -5
- package/dist/{transform-job-50GZHhKH.mjs → transform-job-AaMZRxAq.mjs} +1 -1
- package/dist/{transform-job-DRrK28IH.mjs → transform-job-CCguL6LP.mjs} +41 -4
- package/dist/transform-job-CjtwBGoM.mjs +22 -0
- package/dist/{transform-tag-_tgwlsdB.mjs → transform-tag-DJ3_bksm.mjs} +5 -5
- package/dist/{transforms-oU4zizbO.mjs → transforms-Dg2MfB2a.mjs} +6 -6
- package/dist/{tree-CH-f3bjP.mjs → tree-BQL0f7YX.mjs} +4 -5
- package/dist/{unpublish-BUl9RU5C.mjs → unpublish-DfSvb_Rs.mjs} +4 -7
- package/dist/{update-D-NE60AV.mjs → update-B-hRR8gW.mjs} +5 -5
- package/dist/{update-CO4m4wH3.mjs → update-BCgAyfj_.mjs} +6 -6
- package/dist/{update-BzMDeZiU.mjs → update-Bhmli02m.mjs} +5 -5
- package/dist/{update-CvOO8TED.mjs → update-BxIyFtrX.mjs} +5 -5
- package/dist/{update-BiFDBcEH.mjs → update-CDo0Orvu.mjs} +5 -5
- package/dist/{update-BCS5FxKr.mjs → update-CKoBDTL7.mjs} +9 -9
- package/dist/{update-CmDTljK-.mjs → update-CiYxcf8M.mjs} +7 -7
- package/dist/{update-CHNSUHK4.mjs → update-Cr5zHb0D.mjs} +5 -5
- package/dist/{update-Nfi44RrE.mjs → update-CtDHMxW8.mjs} +6 -6
- package/dist/{update-bD_Jh5-s.mjs → update-D1QdfpKR.mjs} +5 -5
- package/dist/{update-BZPllQoR.mjs → update-D4qdTlLF.mjs} +5 -5
- package/dist/{update-C4YJQFDS.mjs → update-DBGaJDsj.mjs} +5 -5
- package/dist/{update-tX9mKBN_.mjs → update-Izqip6jY.mjs} +9 -9
- package/dist/{update-cYkvbqK8.mjs → update-NZhIjTCf.mjs} +5 -5
- package/dist/{update-dashcard-C3TuYO_k.mjs → update-dashcard-D5b971AO.mjs} +7 -7
- package/dist/{update-CVPAwJaH.mjs → update-sYLQIUgh.mjs} +6 -6
- package/dist/{upgrade-DXMV4AyP.mjs → upgrade-CD1xtsIv.mjs} +6 -8
- package/dist/upload-BUd3MG90.mjs +23 -0
- package/dist/upload-C3z5ZaXA.mjs +24 -0
- package/dist/upload-DzGTlldn.mjs +13 -0
- package/dist/upload-akKFxpVA.mjs +39 -0
- package/dist/{uuid-BJkDWj9p.mjs → uuid-oVdJ62eA.mjs} +3 -4
- package/dist/{validate-BWchyW0V.mjs → validate-CWd6l6KZ.mjs} +1 -1
- package/dist/{validate-query-DaGYSmpQ.mjs → validate-query-Boi8-cAP.mjs} +2 -3
- package/dist/{values-Dxf1JEoA.mjs → values-DLwZl-P8.mjs} +4 -4
- package/dist/{verify-K96rItG5.mjs → verify-CH9Tw8yv.mjs} +3 -18
- package/dist/{wait-flags-DWEF9tX4.mjs → wait-flags-DiQ_kRjZ.mjs} +2 -2
- package/dist/{wait-DoMDH226.mjs → wait-rfTdQWdi.mjs} +5 -8
- package/package.json +1 -1
- package/skill-data/core/SKILL.md +16 -5
- package/skill-data/dashboard/SKILL.md +2 -2
- package/skill-data/data-workflow/references/building-clean-tables.md +6 -2
- package/skill-data/data-workflow/references/reusable-definitions.md +11 -3
- package/skill-data/document/SKILL.md +4 -1
- package/skill-data/git-sync/SKILL.md +5 -0
- package/skill-data/mbql/SKILL.md +1 -1
- package/skill-data/mbql/references/operators.md +20 -15
- package/skill-data/metadata/SKILL.md +1 -1
- package/skill-data/metadata/references/semantic-types.md +7 -1
- package/skill-data/native-sql/references/template-tags.md +6 -2
- package/skill-data/notification/SKILL.md +7 -1
- package/skill-data/transform/SKILL.md +12 -2
- package/skill-data/visualization/SKILL.md +11 -3
- package/skill-data/visualization/references/settings.md +6 -4
- package/skills/metabase-cli/SKILL.md +1 -1
- package/dist/card-CHI2bmds.mjs +0 -24
- package/dist/collection-CY0AB99E.mjs +0 -20
- package/dist/document-BbskZPTT.mjs +0 -19
- package/dist/get-CvI--9S_.mjs +0 -80
- package/dist/git-sync-MQQYRYLg.mjs +0 -28
- package/dist/library-ClLgrAXy.mjs +0 -19
- package/dist/network-error-CEb9ymDW.mjs +0 -423
- package/dist/predicates-Bkm2IoeX.mjs +0 -170
- package/dist/snippet-DRwKb2x7.mjs +0 -19
- package/dist/timeline-xlDbEKWg.mjs +0 -21
- package/dist/transform-Bs0EWijQ.mjs +0 -28
- package/dist/transform-job-BcLChRup.mjs +0 -22
- package/dist/upload-CH632qW6.mjs +0 -46
- package/dist/upload-Dey_8rLf.mjs +0 -13
|
@@ -131,7 +131,7 @@ Then make the links real, not just implied:
|
|
|
131
131
|
- **Wire foreign keys between your tables.** Mark each linking id as a foreign key pointing at the id it references — set the column's type to foreign-key and its target so Metabase itself knows the tables connect and can traverse them.
|
|
132
132
|
- **Graft onto existing clean data** the user approved (step 3 / Phase 1): point the linking id at the existing table's id the same way. Link, don't duplicate.
|
|
133
133
|
|
|
134
|
-
**Set the metadata — a transform's output starts blank, and these tables are
|
|
134
|
+
**Set the metadata — a transform's output starts blank, and these tables are the ones people will start from.** A fresh transform table has no descriptions, raw column names, and untyped columns. You worked it out while investigating; don't leave that knowledge stranded in this chat. Set it on the table so the data explains itself inside Metabase (search, the Question editor, Metabot) and is fit to publish. The mechanics — `mb field update` for semantic types / FK targets / display names, `mb table update` for table descriptions, and the feature each edit unlocks — are in the `metadata` skill; the calls about _what_ to set:
|
|
135
135
|
|
|
136
136
|
- **Semantic types — the highest-value piece.** A column's semantic type is what makes Metabase treat it right: `type/Email`, `type/Currency`/`type/Price`, `type/Category` (turns into a filter dropdown), `type/City`/`type/State`/`type/Country`, `type/CreationTimestamp`, `type/Description`. Set it on every column whose meaning you decoded. A typed column shows money as money, offers a filter dropdown, and lands on the right chart axis for everyone downstream; an untyped one is a guess.
|
|
137
137
|
- **Descriptions.** A one-line description on each table and every non-obvious column.
|
|
@@ -165,7 +165,11 @@ Then report plainly:
|
|
|
165
165
|
|
|
166
166
|
End on that connection map: it's what the user reads to trust the result, and what lets whatever they build next join on the right ids instead of guessing.
|
|
167
167
|
|
|
168
|
-
|
|
168
|
+
<!-- requires: library -->
|
|
169
|
+
|
|
170
|
+
These clean tables are exactly what belongs in the **Library** — published tables appear first when anyone picks a data source, so people start from your curated set, not the raw source. If the user wants that, publish the polished tables to the Library (`mb library publish` / `mb library create` mechanics and permissions are in `core`). Defining reusable segments / measures / metrics on top is the **reusable-definitions** stage (`references/reusable-definitions.md` in this skill).
|
|
171
|
+
|
|
172
|
+
<!-- /requires -->
|
|
169
173
|
|
|
170
174
|
---
|
|
171
175
|
|
|
@@ -50,7 +50,9 @@ Two things never bend in any mode: when genuinely unsure, **ask** (the Shared Co
|
|
|
50
50
|
- "Let me add up revenue the same way everywhere, on this table" → a **measure** on the table.
|
|
51
51
|
- "Revenue is an _official company number_ people pull onto dashboards" → a **metric** in a collection, with a default month-by-month view so it charts cleanly. Lean: make it a metric when it's a headline figure the org reuses across many questions/dashboards; keep it a measure when it's a table-local convenience.
|
|
52
52
|
- **Where the metric lives.** Metrics sit in a collection (folder). Lean: put the org's blessed ones in the shared **Library** so they surface prominently; keep experimental ones in a working collection until trusted.
|
|
53
|
-
|
|
53
|
+
<!-- requires: library -->
|
|
54
|
+
- **Publish the official tables to the Library.** The clean, analysis-ready tables your definitions sit on are the org's official starting points — the **Library** is how you mark them as such. Tables published to the Library's **Data** section appear _first_ when anyone picks a data source, nudging people toward your curated tables instead of raw warehouse ones. Lean: publish the wide clean tables you built the semantic layer on; hold back raw or half-built ones. Surface which tables you'd publish and confirm. (Only admins and data analysts can publish — mechanics in `core`.)
|
|
55
|
+
<!-- /requires -->
|
|
54
56
|
- **Default time dimension for a metric.** A monthly default makes it chart nicely on a dashboard, but doesn't lock anyone out of other groupings. Lean: set a sensible default (usually month) for anything headline; leave it off for raw counts that aren't inherently time-series.
|
|
55
57
|
- **How strict a segment is.** "Active" = last 30 vs 90 days is a real business call with no right answer from the data alone. Lean: surface the few reasonable thresholds with how many rows each catches, let the user pick.
|
|
56
58
|
|
|
@@ -101,7 +103,9 @@ Build each agreed definition. The verb mechanics (create/update flags, the `revi
|
|
|
101
103
|
- **Segment** → `mb segment create`. A flat MBQL filter clause on a table.
|
|
102
104
|
- **Measure** → `mb measure create`. **Exactly one** aggregation on a table.
|
|
103
105
|
- **Metric** → `mb card create` with the metric shape (`type: "metric"`) — it lives in a **collection**, carries the aggregation plus an optional default time dimension. Put org-blessed ones in the Library collection.
|
|
106
|
+
<!-- requires: library -->
|
|
104
107
|
- **Publish the official tables** → `mb library create` then `mb library publish` (mechanics in `core`) to move the clean tables your definitions sit on into the Library's **Data** section, so people start from your curated set, not raw warehouse tables.
|
|
108
|
+
<!-- /requires -->
|
|
105
109
|
|
|
106
110
|
Then **verify what the user can't see**, before you hand back:
|
|
107
111
|
|
|
@@ -122,10 +126,14 @@ Then **stop. Hard gate — every mode, no exceptions.** Recap in plain language
|
|
|
122
126
|
>
|
|
123
127
|
> **Metric** (in your **Library**, charts by month):
|
|
124
128
|
> • **Monthly recurring revenue**
|
|
125
|
-
|
|
129
|
+
|
|
130
|
+
<!-- requires: library -->
|
|
131
|
+
|
|
126
132
|
> **Published to the Library** (these now show up first when anyone picks a data source):
|
|
127
133
|
> • **Customers**, **Orders**
|
|
128
|
-
|
|
134
|
+
|
|
135
|
+
<!-- /requires -->
|
|
136
|
+
|
|
129
137
|
> Open any of those tables' Filter or Summarize block in Metabase to see them in place and try one — give it a look before you start building dashboards on top.
|
|
130
138
|
|
|
131
139
|
End on that plain-language map. It's what the user reads to trust the result — and it's what stops a wrong definition from quietly propagating into everything built next.
|
|
@@ -81,7 +81,10 @@ Every node is `{ "type": string, "attrs"?: object, "content"?: [nodes], "text"?:
|
|
|
81
81
|
- **`resizeNode`** — wraps a single `cardEmbed` or `flexContainer` to make it resizable (no `_id`). `attrs: { "height": <px>, "minHeight": <px> }`, `content` is exactly one `cardEmbed`/`flexContainer`.
|
|
82
82
|
- **`flexContainer`** — a horizontal row of 1–3 `cardEmbed` / `supportingText` cells side by side (no `_id`). `attrs.columnWidths` is an array of width percentages.
|
|
83
83
|
- **`supportingText`** — a text column that sits next to a card inside a `flexContainer` (id-bearing); `content` is the usual block nodes (`paragraph`, `heading`, lists, …).
|
|
84
|
-
- **`smartLink`** — an inline reference to a Metabase entity (renders as a live chip). Inline, atomic, no `_id`. `attrs: { "entityId": <id>, "model": <model>, "label": <string|null>, "href": <relative-path> }`. `model` ∈ `card`, `dataset`, `metric`, `dashboard`, `collection`, `table`, `database`, `document`, `transform`, `segment`, `user`, `action`, `indexed-entity
|
|
84
|
+
- **`smartLink`** — an inline reference to a Metabase entity (renders as a live chip). Inline, atomic, no `_id`. `attrs: { "entityId": <id>, "model": <model>, "label": <string|null>, "href": <relative-path> }`. `model` ∈ `card`, `dataset`, `metric`, `dashboard`, `collection`, `table`, `database`, `document`, `transform`, `segment`, `user`, `action`, `indexed-entity`.
|
|
85
|
+
<!-- requires: smartLinkMeasureModel -->
|
|
86
|
+
- `measure` is a valid `model` too.
|
|
87
|
+
<!-- /requires -->
|
|
85
88
|
- **`metabot`** — an inline Metabot prompt block.
|
|
86
89
|
|
|
87
90
|
## Embedding an existing card
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
name: git-sync
|
|
3
3
|
description: Round-trip Metabase content (cards, dashboards, transforms, snippets, collections, Library-published table/field metadata) between an instance and a git remote via `mb git-sync …` — status, dirty / has-remote-changes checks, import, export (with branch guard), branches, stash, add/remove a collection from sync. Load when the user wants to "import the latest changes", "export to git", "push my changes to the repo", "open a PR with my Metabase changes", "git sync", "dirty check", "stash before pulling", "add a collection to sync", or anything `mb git-sync …`.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
5
|
+
requires: [remoteSync]
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
# git-sync (representations ↔ instance)
|
|
@@ -130,6 +131,8 @@ mb setting set remote-sync-type '"read-write"' --profile <n>
|
|
|
130
131
|
|
|
131
132
|
**Verifying the result.** `mb git-sync status --profile <n> --json` lists the flagged collections under `synced_collections`, and `mb collection get <id> --json` shows the per-collection `is_remote_synced` flag.
|
|
132
133
|
|
|
134
|
+
<!-- requires: library -->
|
|
135
|
+
|
|
133
136
|
## Published table metadata (Library) and sync scope
|
|
134
137
|
|
|
135
138
|
Table and field metadata — table/field descriptions, semantic types (`type/PK`, `type/FK`), FK targets, plus segments and measures on the table — serializes for **Library-published tables only**, under `databases/<db>/schemas/<schema>/tables/<table>/…` in the repo. Eligibility is two-gated: the table must be published (`mb library publish`), **and** the Library collection holding it must itself carry `is_remote_synced: true`. An ordinary warehouse table, or a transform's target table that isn't published, never serializes — a transform's YAML carries only the transform definition (query, target, description), not the output table's field metadata.
|
|
@@ -144,6 +147,8 @@ mb git-sync stash --new-branch <branch> -m "..." --profile <n> # or create-b
|
|
|
144
147
|
|
|
145
148
|
Flagging the collection records it for the next export, which serializes its current content — including already-published tables and their field metadata. `mb library publish` prints a reminder when the target collection is outside the sync scope on an instance with a configured remote.
|
|
146
149
|
|
|
150
|
+
<!-- /requires -->
|
|
151
|
+
|
|
147
152
|
## Don't (git-sync-specific)
|
|
148
153
|
|
|
149
154
|
- Don't turn instance-side changes into hand-written repo files. When the changes were made against the instance, export them (`stash` / `create-branch` + `export`) and PR the exported branch; reconstructing them as YAML by hand — or pushing files in paths/formats the serializer doesn't own — produces content that never applies on import, and pushing behind Metabase's back races its own sync tasks. Hand-editing YAML belongs to the repo-first workflow, in the serialized layout the repo already uses.
|
package/skill-data/mbql/SKILL.md
CHANGED
|
@@ -122,7 +122,7 @@ No `type:"query"` wrapper, no `query:` nesting. If you wrap the query inside a l
|
|
|
122
122
|
|
|
123
123
|
## Legacy formats you may encounter
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
Queries created long ago may carry a different envelope (sometimes called MBQL 4 / "legacy MBQL"); the `mbql/query` shape above is what the server stores and returns. You won't author the legacy shapes, but you may see them in old content. Anything not `lib/type: "mbql/query"` is sent as-is and normalized server-side — you lose validation, so don't author these:
|
|
126
126
|
|
|
127
127
|
- **Legacy structured** — `{ "type": "query", "database": N, "query": { "source-table": T, … } }`
|
|
128
128
|
- **Flat native** — `{ "type": "native", "database": N, "native": { "query": "SELECT …" } }` — the server accepts it, but author the native stage instead (`native-sql`).
|
|
@@ -106,21 +106,26 @@ Units (truncation only): `millisecond`, `second`, `minute`, `hour`, `day`, `week
|
|
|
106
106
|
|
|
107
107
|
A stage's `aggregation` is a list of aggregation clauses.
|
|
108
108
|
|
|
109
|
-
| Op | Args | Notes
|
|
110
|
-
| ----------------------- | -------------------------- |
|
|
111
|
-
| `count` | none, or 1 expression | with arg: count non-NULL
|
|
112
|
-
| `sum` `avg` `min` `max` | 1 numeric/orderable |
|
|
113
|
-
| `distinct` | 1 expression | count of distinct values
|
|
114
|
-
| `cum-count` | none or 1 expression | running count
|
|
115
|
-
| `cum-sum` | 1 numeric | running sum
|
|
116
|
-
| `stddev` `var` `median` | 1 numeric |
|
|
117
|
-
| `percentile` | numeric, p (0.0–1.0) |
|
|
118
|
-
| `count-where` | 1 boolean clause |
|
|
119
|
-
| `sum-where` | numeric, boolean clause |
|
|
120
|
-
| `distinct-where` | expression, boolean clause |
|
|
121
|
-
| `share` | 1 boolean clause | proportion 0–1
|
|
122
|
-
| `metric` | metric id | reference a saved metric card
|
|
123
|
-
|
|
109
|
+
| Op | Args | Notes |
|
|
110
|
+
| ----------------------- | -------------------------- | ----------------------------- |
|
|
111
|
+
| `count` | none, or 1 expression | with arg: count non-NULL |
|
|
112
|
+
| `sum` `avg` `min` `max` | 1 numeric/orderable | |
|
|
113
|
+
| `distinct` | 1 expression | count of distinct values |
|
|
114
|
+
| `cum-count` | none or 1 expression | running count |
|
|
115
|
+
| `cum-sum` | 1 numeric | running sum |
|
|
116
|
+
| `stddev` `var` `median` | 1 numeric | |
|
|
117
|
+
| `percentile` | numeric, p (0.0–1.0) | |
|
|
118
|
+
| `count-where` | 1 boolean clause | |
|
|
119
|
+
| `sum-where` | numeric, boolean clause | |
|
|
120
|
+
| `distinct-where` | expression, boolean clause | |
|
|
121
|
+
| `share` | 1 boolean clause | proportion 0–1 |
|
|
122
|
+
| `metric` | metric id | reference a saved metric card |
|
|
123
|
+
|
|
124
|
+
<!-- requires: measures -->
|
|
125
|
+
|
|
126
|
+
`measure` takes a measure id and references a saved measure.
|
|
127
|
+
|
|
128
|
+
<!-- /requires -->
|
|
124
129
|
|
|
125
130
|
```json
|
|
126
131
|
["count", {…}]
|
|
@@ -43,7 +43,7 @@ mb field update 1711 --body '{"semantic_type":"type/FK","fk_target_field_id":168
|
|
|
43
43
|
- Queries can pull columns from the related table with no explicit join — `["field", {"source-field": 1711}, 1682]` in MBQL (see `mbql`).
|
|
44
44
|
- Dashboard **linked filters** become possible (a State filter narrowing a City filter). **Linked filters read only these table-metadata FKs** — never a join you wrote inside a saved question — which is why a linked filter that "shows values it shouldn't" almost always means the FK isn't set in metadata. (See `dashboard`.)
|
|
45
45
|
|
|
46
|
-
Removing the `type/FK` semantic type auto-clears `fk_target_field_id`. Point a FK only at a field in the **same database** —
|
|
46
|
+
Removing the `type/FK` semantic type auto-clears `fk_target_field_id`. Point a FK only at a field in the **same database** — a cross-database target is invalid and never resolves to a relationship.
|
|
47
47
|
|
|
48
48
|
## Semantic types are labels, not casts
|
|
49
49
|
|
|
@@ -71,7 +71,13 @@ Everything else on a field/table (physical `name`, `base_type`, `effective_type`
|
|
|
71
71
|
`display_name` · `description` · `caveats` · `points_of_interest` · `semantic_type` · `coercion_strategy` · `fk_target_field_id` · `visibility_type` · `has_field_values` · `settings` · `nfc_path` · `json_unfolding`
|
|
72
72
|
|
|
73
73
|
**`PUT /api/table/:id` (`mb table update`)**
|
|
74
|
-
`display_name` · `description` · `visibility_type` · `field_order` (`database` / `alphabetical` / `custom` / `smart`) · `entity_type` · `caveats` · `points_of_interest` · `show_in_getting_started` · `owner_user_id` / `owner_email` (ownership) · `data_layer` / `data_authority` / `data_source` (data-governance tiers)
|
|
74
|
+
`display_name` · `description` · `visibility_type` · `field_order` (`database` / `alphabetical` / `custom` / `smart`) · `entity_type` · `caveats` · `points_of_interest` · `show_in_getting_started` · `owner_user_id` / `owner_email` (ownership) · `data_layer` / `data_authority` / `data_source` (data-governance tiers)
|
|
75
|
+
|
|
76
|
+
<!-- requires: library -->
|
|
77
|
+
|
|
78
|
+
· `collection_id` — the Library **Data** collection a published table sits in (`mb library publish` sets it; see `core`)
|
|
79
|
+
|
|
80
|
+
<!-- /requires -->
|
|
75
81
|
|
|
76
82
|
## Coercion strategies (common)
|
|
77
83
|
|
|
@@ -86,9 +86,13 @@ SQL: `{{snippet: Active Rows}}`. Create/manage the fragment with `mb snippet` (`
|
|
|
86
86
|
|
|
87
87
|
SQL: `{{#42}}` or `{{#42-slug}}`, used where a table/subquery goes (`FROM {{#42}}`, `WITH x AS {{#42}}`). Runs with the referenced card's own defaults; no user value.
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
<!-- requires: nativeTableTemplateTag -->
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
### Source table — `table`
|
|
92
|
+
|
|
93
|
+
A niche type that references a warehouse table by id (`{type: "table", table-id: <id>}`, optional `source-filters`) where a table/subquery goes — analogous to a card reference but pointing at a raw table. Reach for a card reference (`card`) unless you specifically need a bare-table source tag.
|
|
94
|
+
|
|
95
|
+
<!-- /requires -->
|
|
92
96
|
|
|
93
97
|
### Temporal unit — `temporal-unit`
|
|
94
98
|
|
|
@@ -110,7 +110,13 @@ An alert body has exactly three parts:
|
|
|
110
110
|
|
|
111
111
|
Recipients are `{"email": "a@b.com"}` for an external address or `{"id": <user-id>}` for a Metabase user. A Slack channel is **not** a recipient — it goes in `details`: `{"channel_type": "slack", "details": {"channel": "#general"}, …}`.
|
|
112
112
|
|
|
113
|
-
**`skip_if_empty: true`** suppresses the send when the dashboard's questions return no rows — the way to build a "only tell me when something happened" dashboard report.
|
|
113
|
+
**`skip_if_empty: true`** suppresses the send when the dashboard's questions return no rows — the way to build a "only tell me when something happened" dashboard report.
|
|
114
|
+
|
|
115
|
+
<!-- requires: dashboardSubscriptionFilters -->
|
|
116
|
+
|
|
117
|
+
**`parameters`** sets filter values for this subscription only, so one dashboard can feed several audiences a different slice. Its entries are dashboard parameter values — the parameter `id`s come from `mb dashboard get <id> --fields parameters --json` (see the `dashboard` skill).
|
|
118
|
+
|
|
119
|
+
<!-- /requires -->
|
|
114
120
|
|
|
115
121
|
`mb subscription list --archived` is a **swap, not a union** — it returns archived subscriptions _instead of_ active ones, never both. `mb dashboard subscriptions <id>` is the list scoped to one dashboard. `mb subscription archive <id>` also disables every channel on it, so restoring takes two steps: `update --body '{"archived":false}'`, then re-send the `channels` array with `enabled: true`.
|
|
116
122
|
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
name: transform
|
|
3
3
|
description: Author and run Metabase transforms via `mb` — body shape (native SQL or structured MBQL), create + run-with-wait, run inspection, dependencies, cancel, the `update`-vs-recreate iteration rule, the writable-keys-only PATCH contract, plus transform tags and tag-driven transform-job schedules. Load when the user touches transforms — "create a transform", "run a transform", "fix a failing transform", "list transform runs", "cancel a running transform", "manage transform tags", "run a transform job", or anything `mb transform …` / `mb transform-job …` / `mb transform-tag …`.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
5
|
+
requires: [transforms]
|
|
5
6
|
---
|
|
6
7
|
|
|
7
8
|
# Transforms
|
|
@@ -67,7 +68,7 @@ TABLE_ID=$(mb transform run <id> --sync --profile <name> --json | jq -r '.target
|
|
|
67
68
|
mb table get "$TABLE_ID" --include fields --profile <name> --json # field ids for MBQL
|
|
68
69
|
```
|
|
69
70
|
|
|
70
|
-
On `target_table_id: null` (still syncing when the poll timed out; exit 0) re-poll `mb transform get <id> --
|
|
71
|
+
On `target_table_id: null` (still syncing when the poll timed out; exit 0) re-poll `mb transform get <id> --json` until `target_table_id` is a number.
|
|
71
72
|
|
|
72
73
|
Columns and types are inferred from the result set; change the SELECT shape and the next run fails on a column mismatch — drop the table first (`transform delete-table <id>`). A changed shape also needs a re-run with `--sync` before MBQL sees the new/renamed columns.
|
|
73
74
|
|
|
@@ -198,7 +199,16 @@ Key verbs (`mb transform-job --help` for the full list):
|
|
|
198
199
|
mb transform-job transforms <id> --profile <name> --json # preview which transforms this job resolves to (by tag)
|
|
199
200
|
mb transform-job run <id> --profile <name> --json # trigger a job now; runs all its tagged transforms
|
|
200
201
|
mb transform-job run <id> --force-refresh --profile <name> --json # also re-run dependencies that are already fresh
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
<!-- requires: transformJobActivation -->
|
|
205
|
+
|
|
206
|
+
```bash
|
|
201
207
|
mb transform-job set-active false --profile <name> --json # disable every job at once (true re-enables); admin only
|
|
202
208
|
```
|
|
203
209
|
|
|
204
|
-
|
|
210
|
+
<!-- /requires -->
|
|
211
|
+
|
|
212
|
+
Every job row carries `active`; it is `null` on a server that cannot switch jobs off, where every job runs on schedule.
|
|
213
|
+
|
|
214
|
+
`transform-job run` is fire-and-forget — it returns `{message, started, run_id}` immediately (both `null` when the server does not number job runs: the request was accepted and whether a run started is unsaid), with no per-job-run polling (no `--wait`). Most ad-hoc agent work is one-off `transform run`, not job authoring.
|
|
@@ -27,7 +27,10 @@ Decide which relationship in the data matters most, then pick the chart. The sha
|
|
|
27
27
|
- **Compare a measure across categories** → `bar` (vertical). Use `row` (horizontal bar) when labels are long or there are many categories. Sort by value unless the dimension has a natural order.
|
|
28
28
|
- **Change over time / trend** → `line` for a continuous series; `bar`/`area` for a few discrete periods. Two measures on unlike scales → `combo` (line + bar, dual-axis) — only when the metrics are genuinely related.
|
|
29
29
|
- **Part-to-whole, one snapshot** → `pie`, but only for a meaningful whole with **≤5 slices**; beyond that use a sorted `bar`/`row`. Composition over time → stacked `area`/`bar`.
|
|
30
|
-
- **Distribution / spread / outliers** → a `bar` histogram (bin the measure — see `mbql` binning)
|
|
30
|
+
- **Distribution / spread / outliers** → a `bar` histogram (bin the measure — see `mbql` binning).
|
|
31
|
+
<!-- requires: boxplotDisplay -->
|
|
32
|
+
- **Spread across several groups** → `boxplot` compares the groups' distributions directly.
|
|
33
|
+
<!-- /requires -->
|
|
31
34
|
- **Correlation between two measures** → `scatter` (a third measure → bubble size).
|
|
32
35
|
- **Sequential additive contributions** (start → +/− steps → total) → `waterfall`.
|
|
33
36
|
- **Stage drop-off in an ordered, cumulative funnel** → `funnel`.
|
|
@@ -35,7 +38,7 @@ Decide which relationship in the data matters most, then pick the chart. The sha
|
|
|
35
38
|
- **Geographic** → `map`: region/choropleth (a region dimension + a measure), pin (lat + long), or grid/heat (coordinates + measure).
|
|
36
39
|
- **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
40
|
|
|
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`. The API types `display` as a plain string and accepts any value — it renders an unknown one as nothing. (`
|
|
41
|
+
Valid `display` values — the registered visualizations: `table`, `bar`, `line`, `area`, `row`, `pie`, `scalar`, `smartscalar`, `combo`, `pivot`, `funnel`, `map`, `scatter`, `waterfall`, `progress`, `gauge`, `object`, `sankey`. 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
42
|
|
|
40
43
|
## Step 2 — bind data columns and set options
|
|
41
44
|
|
|
@@ -53,7 +56,6 @@ Valid `display` values — the registered visualizations: `table`, `bar`, `line`
|
|
|
53
56
|
| `row` | as bar; prefer for long/many category labels | `graph.dimensions`, `graph.metrics` |
|
|
54
57
|
| `scatter` | two numeric measures (correlation) | `graph.dimensions`, `graph.metrics` (`scatter.bubble` opt) |
|
|
55
58
|
| `waterfall` | exactly 1 dimension + ≥1 measure; sequential | `graph.dimensions` (1), `graph.metrics` (1) |
|
|
56
|
-
| `boxplot` _(v59+)_ | ≥3 cols, ≥2 dimensions, ≥1 measure | `graph.dimensions`, `graph.metrics` |
|
|
57
59
|
| `pie` | ≥2 rows, ≥2 cols, ≥1 dimension + ≥1 measure; ≤~5 slices | `pie.dimension`, `pie.metric` |
|
|
58
60
|
| `funnel` | 2 columns (stage + value); ordered stages | `funnel.dimension`, `funnel.metric` |
|
|
59
61
|
| `map` (region) | a string/region dimension + a measure | `map.region`, `map.dimension`, `map.metric` |
|
|
@@ -62,6 +64,12 @@ Valid `display` values — the registered visualizations: `table`, `bar`, `line`
|
|
|
62
64
|
| `pivot` | ≥2 cols, all aggregated/breakout | — (`pivot_table.column_split` auto) |
|
|
63
65
|
| `table` `object` | anything (table is the universal fallback) | — (always renders) |
|
|
64
66
|
|
|
67
|
+
<!-- requires: boxplotDisplay -->
|
|
68
|
+
|
|
69
|
+
`boxplot` is registered too: ≥3 cols, ≥2 dimensions, ≥1 measure, on **unaggregated** rows; required keys `graph.dimensions`, `graph.metrics`.
|
|
70
|
+
|
|
71
|
+
<!-- /requires -->
|
|
72
|
+
|
|
65
73
|
### The rule that trips everyone: settings name **output columns**, by name
|
|
66
74
|
|
|
67
75
|
`graph.dimensions`, `graph.metrics`, `pie.dimension`, `pie.metric`, `scalar.field`, `funnel.metric`, `map.latitude_column`, `sankey.source`, … all take **output column-name strings** — the names the query _produces_, not field ids. A `count` aggregation outputs the column `count`; a breakout on a field outputs that field's name; a named aggregation outputs its `name`. These strings are **identical in the API form and the portable (git-sync) form** — no numeric-vs-name footgun here.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Contents
|
|
4
4
|
|
|
5
|
-
- [Cartesian — `bar`, `line`, `area`, `combo`, `scatter`, `waterfall`, `row
|
|
5
|
+
- [Cartesian — `bar`, `line`, `area`, `combo`, `scatter`, `waterfall`, `row`](#cartesian--bar-line-area-combo-scatter-waterfall-row) — shared keys (binding, stacking, goal/trend, data labels, axes, tooltip) plus `scatter`, `waterfall`, `row` extras
|
|
6
6
|
- [Part-to-whole & single value — `pie`, `funnel`, `gauge`, `progress`, `scalar`, `smartscalar`](#part-to-whole--single-value--pie-funnel-gauge-progress-scalar-smartscalar)
|
|
7
7
|
- [Tabular, geographic & flow — `table`, `pivot`, `object`, `map`, `sankey`](#tabular-geographic--flow--table-pivot-object-map-sankey) — includes `table.column_formatting` conditional formatting
|
|
8
8
|
- [`column_settings` — per-column formatting](#column_settings--per-column-formatting) — number/date/currency, `view_as`, alignment, mini bars
|
|
@@ -18,7 +18,7 @@ All column-naming keys (`graph.dimensions`, `pie.dimension`, `table.columns[].na
|
|
|
18
18
|
|
|
19
19
|
---
|
|
20
20
|
|
|
21
|
-
# Cartesian — `bar`, `line`, `area`, `combo`, `scatter`, `waterfall`, `row
|
|
21
|
+
# Cartesian — `bar`, `line`, `area`, `combo`, `scatter`, `waterfall`, `row`
|
|
22
22
|
|
|
23
23
|
`bar`/`line`/`area`/`combo` share an identical key set (combo just defaults the first series to a line, the rest to bars). `scatter`/`waterfall`/`row`/`boxplot` use a subset plus their own extras. Most allow up to 2 dimensions and unlimited metrics; **waterfall is 1 dimension + 1 metric**, boxplot allows 2 dimensions.
|
|
24
24
|
|
|
@@ -102,9 +102,9 @@ Use for sequential additive contributions (start → +/− steps → total). **U
|
|
|
102
102
|
|
|
103
103
|
Horizontal bars — use when category labels are long or numerous. Here `graph.dimensions` is the y-axis (categories) and `graph.metrics` the x-axis (values). X-scale is `"ordinal"` only; no trend line, tooltip columns, or split panels. **Required:** `graph.dimensions`, `graph.metrics`.
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
<!-- requires: boxplotDisplay -->
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
## boxplot
|
|
108
108
|
|
|
109
109
|
Use for distribution/spread/outliers, especially across several groups. Needs **unaggregated** rows. **Use for:** ≥3 columns, ≥2 dimensions, ≥1 measure. **Required:** `graph.dimensions`, `graph.metrics`. X-scale is `"ordinal"`.
|
|
110
110
|
|
|
@@ -115,6 +115,8 @@ Use for distribution/spread/outliers, especially across several groups. Needs **
|
|
|
115
115
|
| `boxplot.show_mean` | boolean | | `true` |
|
|
116
116
|
| `boxplot.show_values_mode` | string | `"median"`, `"all"` (when `graph.show_values`) | `"median"` |
|
|
117
117
|
|
|
118
|
+
<!-- /requires -->
|
|
119
|
+
|
|
118
120
|
---
|
|
119
121
|
|
|
120
122
|
# Part-to-whole & single value — `pie`, `funnel`, `gauge`, `progress`, `scalar`, `smartscalar`
|
|
@@ -17,7 +17,7 @@ Before running any `mb` command, load the workflow content from the CLI:
|
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
19
|
mb skills get core # auth, flag conventions, every command group
|
|
20
|
-
mb skills list #
|
|
20
|
+
mb skills list # every bundled skill the profile's server can use (--all for all of them)
|
|
21
21
|
```
|
|
22
22
|
|
|
23
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:
|
package/dist/card-CHI2bmds.mjs
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { t as defineCommandGroup } from "./group-DBM87IgC.mjs";
|
|
2
|
-
//#region src/commands/card/index.ts
|
|
3
|
-
var card_default = defineCommandGroup({
|
|
4
|
-
name: "card",
|
|
5
|
-
description: "Manage Metabase cards (questions, models, metrics)",
|
|
6
|
-
skills: [{
|
|
7
|
-
skill: "mbql",
|
|
8
|
-
purpose: "author the dataset_query"
|
|
9
|
-
}, {
|
|
10
|
-
skill: "visualization",
|
|
11
|
-
purpose: "choose display and visualization_settings"
|
|
12
|
-
}],
|
|
13
|
-
subCommands: {
|
|
14
|
-
list: () => import("./list-B4hJuMhA.mjs").then((mod) => mod.default),
|
|
15
|
-
get: () => import("./get-B_xdF1kq.mjs").then((mod) => mod.default),
|
|
16
|
-
query: () => import("./query-BbqECzmF.mjs").then((mod) => mod.default),
|
|
17
|
-
alerts: () => import("./alerts-Bf2RH_p_.mjs").then((mod) => mod.default),
|
|
18
|
-
create: () => import("./create-C79vErX0.mjs").then((mod) => mod.default),
|
|
19
|
-
update: () => import("./update-CO4m4wH3.mjs").then((mod) => mod.default),
|
|
20
|
-
archive: () => import("./archive-C7w49Grr.mjs").then((mod) => mod.default)
|
|
21
|
-
}
|
|
22
|
-
});
|
|
23
|
-
//#endregion
|
|
24
|
-
export { card_default as default };
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { t as defineCommandGroup } from "./group-DBM87IgC.mjs";
|
|
2
|
-
//#region src/commands/collection/index.ts
|
|
3
|
-
var collection_default = defineCommandGroup({
|
|
4
|
-
name: "collection",
|
|
5
|
-
description: "Manage Metabase collections",
|
|
6
|
-
skills: [{
|
|
7
|
-
skill: "core",
|
|
8
|
-
purpose: "collection ref forms and the transforms namespace"
|
|
9
|
-
}],
|
|
10
|
-
subCommands: {
|
|
11
|
-
list: () => import("./list-DMKDsBRd.mjs").then((mod) => mod.default),
|
|
12
|
-
get: () => import("./get-DkWO0EI0.mjs").then((mod) => mod.default),
|
|
13
|
-
items: () => import("./items-CQlPXBXE.mjs").then((mod) => mod.default),
|
|
14
|
-
tree: () => import("./tree-CH-f3bjP.mjs").then((mod) => mod.default),
|
|
15
|
-
create: () => import("./create-CAQV2g6V.mjs").then((mod) => mod.default),
|
|
16
|
-
archive: () => import("./archive-BxNPHxOY.mjs").then((mod) => mod.default)
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
//#endregion
|
|
20
|
-
export { collection_default as default };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { t as defineCommandGroup } from "./group-DBM87IgC.mjs";
|
|
2
|
-
//#region src/commands/document/index.ts
|
|
3
|
-
var document_default = defineCommandGroup({
|
|
4
|
-
name: "document",
|
|
5
|
-
description: "Manage Metabase documents",
|
|
6
|
-
skills: [{
|
|
7
|
-
skill: "document",
|
|
8
|
-
purpose: "author the ProseMirror document body"
|
|
9
|
-
}],
|
|
10
|
-
subCommands: {
|
|
11
|
-
list: () => import("./list-CNUiF8Z7.mjs").then((mod) => mod.default),
|
|
12
|
-
get: () => import("./get-D_h-G9bn.mjs").then((mod) => mod.default),
|
|
13
|
-
create: () => import("./create-tQbnuz-I.mjs").then((mod) => mod.default),
|
|
14
|
-
update: () => import("./update-D-NE60AV.mjs").then((mod) => mod.default),
|
|
15
|
-
archive: () => import("./archive-lQqs13Uz.mjs").then((mod) => mod.default)
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
//#endregion
|
|
19
|
-
export { document_default as default };
|
package/dist/get-CvI--9S_.mjs
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { i as ConfigError } from "./predicates-Bkm2IoeX.mjs";
|
|
2
|
-
import { F as outputFlags, N as listFlags, R as listEnvelopeSchema, s as renderList, u as writeText } from "./cli.mjs";
|
|
3
|
-
import { n as parseCsv, t as defineMetabaseCommand } from "./runtime-DiKyBxOw.mjs";
|
|
4
|
-
import { n as windowList } from "./window-BkvrP0gB.mjs";
|
|
5
|
-
import { a as readSkillContent, i as loadVisibleSkills, o as selectSkillsByNames, r as loadAllSkills, t as SkillContent } from "./skills-DTCrMcix.mjs";
|
|
6
|
-
//#region src/commands/skills/get.ts
|
|
7
|
-
const SkillGetEnvelope = listEnvelopeSchema(SkillContent);
|
|
8
|
-
const SKILL_OVERSIZE_HINT = "a skill body is indivisible — pass --max-bytes 0 to print it whole, or `mb skills path <name>` to read it from disk";
|
|
9
|
-
const skillContentView = {
|
|
10
|
-
compactPick: SkillContent,
|
|
11
|
-
tableColumns: [{
|
|
12
|
-
key: "name",
|
|
13
|
-
label: "Name"
|
|
14
|
-
}, {
|
|
15
|
-
key: "description",
|
|
16
|
-
label: "Description"
|
|
17
|
-
}]
|
|
18
|
-
};
|
|
19
|
-
var get_default = defineMetabaseCommand({
|
|
20
|
-
meta: {
|
|
21
|
-
name: "get",
|
|
22
|
-
description: "Print one or more skills' SKILL.md content. Pass comma-separated names, or --all for every non-hidden skill. --full includes references and templates."
|
|
23
|
-
},
|
|
24
|
-
capabilities: null,
|
|
25
|
-
args: {
|
|
26
|
-
...outputFlags,
|
|
27
|
-
...listFlags,
|
|
28
|
-
names: {
|
|
29
|
-
type: "positional",
|
|
30
|
-
description: "Skill name (or comma-separated list). Omit when using --all.",
|
|
31
|
-
required: false
|
|
32
|
-
},
|
|
33
|
-
all: {
|
|
34
|
-
type: "boolean",
|
|
35
|
-
description: "Fetch every non-hidden skill"
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
outputSchema: SkillGetEnvelope,
|
|
39
|
-
examples: [
|
|
40
|
-
"mb skills get core",
|
|
41
|
-
"mb skills get core --full",
|
|
42
|
-
"mb skills get git-sync,transform --json",
|
|
43
|
-
"mb skills get --all --json"
|
|
44
|
-
],
|
|
45
|
-
run({ args, ctx }) {
|
|
46
|
-
const envelope = windowList(pickSkills({
|
|
47
|
-
names: args.names,
|
|
48
|
-
all: args.all === true
|
|
49
|
-
}).map((info) => readSkillContent(info, { includeExtras: ctx.full })), ctx.range);
|
|
50
|
-
if (ctx.format === "json") {
|
|
51
|
-
renderList(envelope, skillContentView, {
|
|
52
|
-
...ctx,
|
|
53
|
-
oversizeHint: SKILL_OVERSIZE_HINT
|
|
54
|
-
});
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
writeText(renderText(envelope.data, ctx.full));
|
|
58
|
-
}
|
|
59
|
-
});
|
|
60
|
-
function pickSkills({ names, all }) {
|
|
61
|
-
if (all && names !== void 0) throw new ConfigError("--all conflicts with a positional skill name");
|
|
62
|
-
if (all) return loadVisibleSkills();
|
|
63
|
-
if (names === void 0) throw new ConfigError("provide a skill name (comma-separated for multiple) or --all");
|
|
64
|
-
return selectSkillsByNames(loadAllSkills(), parseCsv(names));
|
|
65
|
-
}
|
|
66
|
-
function renderText(payloads, includeExtras) {
|
|
67
|
-
return payloads.map((payload) => renderTextSection(payload, includeExtras)).join("\n\n");
|
|
68
|
-
}
|
|
69
|
-
function renderTextSection(payload, includeExtras) {
|
|
70
|
-
const parts = [payload.body.trimEnd()];
|
|
71
|
-
if (!includeExtras) return parts.join("\n\n");
|
|
72
|
-
for (const ref of payload.references) parts.push(extraFileHeader(payload.name, ref.path), ref.content.trimEnd());
|
|
73
|
-
for (const tpl of payload.templates) parts.push(extraFileHeader(payload.name, tpl.path), tpl.content.trimEnd());
|
|
74
|
-
return parts.join("\n\n");
|
|
75
|
-
}
|
|
76
|
-
function extraFileHeader(skillName, relPath) {
|
|
77
|
-
return `=== ${skillName}/${relPath} ===`;
|
|
78
|
-
}
|
|
79
|
-
//#endregion
|
|
80
|
-
export { get_default as default };
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { t as defineCommandGroup } from "./group-DBM87IgC.mjs";
|
|
2
|
-
//#region src/commands/git-sync/index.ts
|
|
3
|
-
var git_sync_default = defineCommandGroup({
|
|
4
|
-
name: "git-sync",
|
|
5
|
-
description: "Sync Metabase content with a git remote",
|
|
6
|
-
skills: [{
|
|
7
|
-
skill: "git-sync",
|
|
8
|
-
purpose: "import/export round-trip and dirty checks"
|
|
9
|
-
}],
|
|
10
|
-
subCommands: {
|
|
11
|
-
status: () => import("./status-BhswxJL1.mjs").then((mod) => mod.default),
|
|
12
|
-
"is-dirty": () => import("./is-dirty-DYeJYhBz.mjs").then((mod) => mod.default),
|
|
13
|
-
"has-remote-changes": () => import("./has-remote-changes-C684Redh.mjs").then((mod) => mod.default),
|
|
14
|
-
dirty: () => import("./dirty-DNYoM6Bp.mjs").then((mod) => mod.default),
|
|
15
|
-
"current-task": () => import("./current-task-MpBFGttd.mjs").then((mod) => mod.default),
|
|
16
|
-
"cancel-task": () => import("./cancel-task-C5CU1pxU.mjs").then((mod) => mod.default),
|
|
17
|
-
wait: () => import("./wait-DoMDH226.mjs").then((mod) => mod.default),
|
|
18
|
-
import: () => import("./import-Rmmttboo.mjs").then((mod) => mod.default),
|
|
19
|
-
export: () => import("./export-BjfoZRDJ.mjs").then((mod) => mod.default),
|
|
20
|
-
stash: () => import("./stash-D0S4JmAz.mjs").then((mod) => mod.default),
|
|
21
|
-
branches: () => import("./branches-DchlyU0i.mjs").then((mod) => mod.default),
|
|
22
|
-
"create-branch": () => import("./create-branch-CYo6jZth.mjs").then((mod) => mod.default),
|
|
23
|
-
"add-collection": () => import("./add-collection-B3Ty8SzB.mjs").then((mod) => mod.default),
|
|
24
|
-
"remove-collection": () => import("./remove-collection-BOnxYvhj.mjs").then((mod) => mod.default)
|
|
25
|
-
}
|
|
26
|
-
});
|
|
27
|
-
//#endregion
|
|
28
|
-
export { git_sync_default as default };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { r as Collection } from "./collection-CfulNRBG.mjs";
|
|
2
|
-
import { z } from "zod";
|
|
3
|
-
//#region ../client/src/domain/library.ts
|
|
4
|
-
const LibraryChild = Collection.pick({
|
|
5
|
-
id: true,
|
|
6
|
-
name: true,
|
|
7
|
-
type: true,
|
|
8
|
-
description: true,
|
|
9
|
-
is_remote_synced: true
|
|
10
|
-
}).strip();
|
|
11
|
-
const Library = Collection.extend({ effective_children: z.array(LibraryChild) }).loose();
|
|
12
|
-
const LibraryCompact = Library.pick({
|
|
13
|
-
id: true,
|
|
14
|
-
name: true,
|
|
15
|
-
type: true,
|
|
16
|
-
effective_children: true
|
|
17
|
-
}).strip();
|
|
18
|
-
//#endregion
|
|
19
|
-
export { LibraryCompact as n, Library as t };
|