@metabase/cli 0.3.1-alpha.versioning.9ac5f50 → 0.3.2-alpha.fix-transform-test-ee-path.041c793

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/dist/{add-collection-Dmd-uNeU.mjs → add-collection-73X1DmCM.mjs} +5 -5
  2. package/dist/{alert-D1u2MVZj.mjs → alert-BB38lWSL.mjs} +7 -7
  3. package/dist/{alerts-DcBjcfEE.mjs → alerts-DxyzqLSU.mjs} +6 -6
  4. package/dist/{append-B9Htvmab.mjs → append-CHme1Enm.mjs} +4 -4
  5. package/dist/{archive-BUoYMkxO.mjs → archive-BGiDxu8O.mjs} +3 -3
  6. package/dist/{archive-Bf014rFm.mjs → archive-BMyvyf62.mjs} +3 -3
  7. package/dist/{archive-BmsZFOZY.mjs → archive-C4Y2B58q.mjs} +3 -3
  8. package/dist/{archive-BNivAYGr.mjs → archive-CP5Hlqjw.mjs} +4 -4
  9. package/dist/{archive-CvU2z5192.mjs → archive-Cq3fnc0v2.mjs} +5 -5
  10. package/dist/{archive-B660RguB.mjs → archive-CqKqNdUh.mjs} +5 -5
  11. package/dist/{archive-CgmidYZV.mjs → archive-Czo5T0Lp.mjs} +3 -3
  12. package/dist/{archive-BVmFGFwG.mjs → archive-DBcxZwLd.mjs} +5 -5
  13. package/dist/{archive-DhDQIKR_.mjs → archive-DKFPJ9j3.mjs} +5 -5
  14. package/dist/{archive-CNif6BKy.mjs → archive-DPL1qOuL.mjs} +5 -5
  15. package/dist/{archive-bPdDITuY.mjs → archive-eS-XA74p.mjs} +3 -3
  16. package/dist/{auth-CefYEPP5.mjs → auth-6YyB0HNB.mjs} +5 -5
  17. package/dist/{body-C7m9q4cm.mjs → body-OjAWKVaU.mjs} +3 -3
  18. package/dist/{branches-pz04OjF2.mjs → branches-D5YLVFDK.mjs} +3 -3
  19. package/dist/{cancel-CNLnv19e.mjs → cancel-DeRIq1YJ.mjs} +3 -3
  20. package/dist/{cancel-task-DbnxSh7U.mjs → cancel-task-CqExODVm.mjs} +4 -4
  21. package/dist/card-BMSqofd7.mjs +24 -0
  22. package/dist/{card-zyUkr2nS.mjs → card-CEkp1mcI.mjs} +1 -1
  23. package/dist/{card-DZxRmver.mjs → card-voh1k4hl.mjs} +14 -11
  24. package/dist/{cards-DtYlVoGP.mjs → cards-B813G9I5.mjs} +6 -6
  25. package/dist/cli.mjs +223 -211
  26. package/dist/{client-Bv7Iwdvh.mjs → client-cJ7aw0Gt.mjs} +1788 -72
  27. package/dist/collection-BfNg7tEg.mjs +20 -0
  28. package/dist/{collection-WFdBeyqa.mjs → collection-BxdPxD38.mjs} +1 -1
  29. package/dist/{collection-DALwHnbz.mjs → collection-DYM0p3Xl.mjs} +1 -1
  30. package/dist/{collection-namespace-CvT0TIZA.mjs → collection-namespace-CVzDgJV0.mjs} +2 -2
  31. package/dist/{content-translation-D7POzJJ6.mjs → content-translation-QKWt9l76.mjs} +3 -3
  32. package/dist/{create-JOXq0ULN.mjs → create-4UnoQvsy.mjs} +4 -4
  33. package/dist/{create-CLgalJUe.mjs → create-BJad6MR82.mjs} +7 -7
  34. package/dist/{create-Bh2j733n.mjs → create-BLiB2xqo.mjs} +6 -6
  35. package/dist/{create-DGHILnnk.mjs → create-BWp6L_dW.mjs} +4 -4
  36. package/dist/{create-Di4YvIbK.mjs → create-Bef5eBCA.mjs} +4 -4
  37. package/dist/{create-CGgPnb7L.mjs → create-CMV3qlzJ.mjs} +3 -3
  38. package/dist/{create-Ds-DnSBe.mjs → create-CWGsiFvU.mjs} +3 -3
  39. package/dist/{create-DhDREiiy.mjs → create-CoFg1p6m.mjs} +3 -3
  40. package/dist/{create-CGPle4nE.mjs → create-CvIeb1NU.mjs} +6 -6
  41. package/dist/{create-Bwg-5p08.mjs → create-CvpeAcFc.mjs} +3 -3
  42. package/dist/{create-DYd_o9BD.mjs → create-D50TxVTk.mjs} +4 -4
  43. package/dist/{create-DnqnjGGf.mjs → create-DEBgYRlM.mjs} +5 -5
  44. package/dist/{create-CN24yp_W.mjs → create-DJm0YuLW.mjs} +3 -3
  45. package/dist/{create-CuYGZ4gu2.mjs → create-DmKwDQCY2.mjs} +5 -5
  46. package/dist/{create-branch-DWcxC30N.mjs → create-branch-BN5iH-GM.mjs} +4 -4
  47. package/dist/{create-BEE8uvz2.mjs → create-bvpl6Fn5.mjs} +6 -6
  48. package/dist/create-uanpKsPo.mjs +34 -0
  49. package/dist/{csv-CUQvcCEk.mjs → csv-BhuX9fwh.mjs} +4 -4
  50. package/dist/{current-task-D6P0eL21.mjs → current-task-BMt2NeqV.mjs} +4 -4
  51. package/dist/{dashboard-BudI952R.mjs → dashboard-Ct_ajSYI.mjs} +10 -10
  52. package/dist/{dashboard-CKUR8ZpQ.mjs → dashboard-D0hwTC-f.mjs} +11 -2
  53. package/dist/{dashboard-BlbNszi8.mjs → dashboard-DgK81azj.mjs} +1 -1
  54. package/dist/{database-B19qlLKZ.mjs → database-C3E9PZSx.mjs} +1 -1
  55. package/dist/{database-C8G6ZKG0.mjs → database-JtHTqSpq.mjs} +1 -1
  56. package/dist/{db-C7UTd-6P.mjs → db-B_LW2VE-.mjs} +7 -7
  57. package/dist/{delete-Ud6iliGM.mjs → delete-BOcPK_H9.mjs} +4 -4
  58. package/dist/{delete-_IHffP-A.mjs → delete-CowGO4rh.mjs} +4 -4
  59. package/dist/{delete-Ds-zGh9C.mjs → delete-D0f7VatX.mjs} +4 -4
  60. package/dist/{delete-DbZZKcYj.mjs → delete-D2bUV6uo.mjs} +4 -4
  61. package/dist/delete-DZ_ICQug.mjs +44 -0
  62. package/dist/{delete-DSxqbcFE.mjs → delete-Ur7b11no.mjs} +4 -4
  63. package/dist/{delete-runtime-BjHL1ryM.mjs → delete-runtime-BKEzJn22.mjs} +1 -1
  64. package/dist/{delete-table-DtXH6IN5.mjs → delete-table-Dd8X573t.mjs} +4 -4
  65. package/dist/{dependencies-CR1dlq-A.mjs → dependencies-XDVLBwko.mjs} +6 -6
  66. package/dist/{dirty-CYxnOnh0.mjs → dirty-k-JmGLsS.mjs} +5 -5
  67. package/dist/{document-Cd2mmqCp.mjs → document-BHpLJbKU.mjs} +5 -0
  68. package/dist/document-BW9iow8R.mjs +19 -0
  69. package/dist/{document-D6OybtP2.mjs → document-CA0Q6lqu.mjs} +1 -1
  70. package/dist/{download-DPpmmYQe.mjs → download-CQjPIYDO.mjs} +2 -2
  71. package/dist/{eid-D-BbtWjt.mjs → eid-CNTKDgwj.mjs} +3 -3
  72. package/dist/{events-CJEnn8WE.mjs → events-BshWlkDp.mjs} +4 -4
  73. package/dist/{export-BOgyuIOQ.mjs → export-Dq6ecU8h.mjs} +6 -6
  74. package/dist/{field-CzHBOPER.mjs → field-Bo2ISMO4.mjs} +5 -5
  75. package/dist/{field-Cr2DPUG9.mjs → field-CcN4oZy6.mjs} +16 -1
  76. package/dist/{field-BPsNa-TO.mjs → field-fDtIrY6D.mjs} +1 -1
  77. package/dist/{fields-Bwgkrvus.mjs → fields-CVctqn5G.mjs} +6 -6
  78. package/dist/{get-BLJSCw53.mjs → get-7xTeNGAo.mjs} +5 -5
  79. package/dist/{get-DyyPiiaB.mjs → get-8b5Sh50q.mjs} +5 -5
  80. package/dist/{get-DVi3a2nm.mjs → get-B4RgW-VT.mjs} +5 -5
  81. package/dist/{get-BaPadzdM.mjs → get-BD81MHl_.mjs} +3 -3
  82. package/dist/{get-CvIgxPXV.mjs → get-Bl3OmlBP.mjs} +4 -4
  83. package/dist/get-BtTetWzm.mjs +32 -0
  84. package/dist/{get-BfVCLBqc.mjs → get-BvSA_mmf.mjs} +5 -5
  85. package/dist/{get-DsKmZfM2.mjs → get-BvgEF--n.mjs} +3 -3
  86. package/dist/{get-D8lHwu4-.mjs → get-C5sWciaE.mjs} +5 -5
  87. package/dist/{get-CqQ-pf0q.mjs → get-CO6X4nZH.mjs} +16 -12
  88. package/dist/{get-CWfIiXwL.mjs → get-CTPvdcud.mjs} +5 -5
  89. package/dist/{get-C1ZdOvMm.mjs → get-CrpwxWOV.mjs} +3 -3
  90. package/dist/{get-BOLwso0V.mjs → get-D4oGhZWX.mjs} +3 -3
  91. package/dist/{get-B89DUSvw.mjs → get-Df6cGHCM.mjs} +3 -3
  92. package/dist/{get-BL90QC64.mjs → get-DfMVlz64.mjs} +5 -5
  93. package/dist/{get-CLu4yzMp2.mjs → get-Dr-U321T2.mjs} +5 -5
  94. package/dist/{get-D4OTJblo.mjs → get-Dw7jAno3.mjs} +5 -5
  95. package/dist/{get-DgnYF7LR.mjs → get-PWhOdz1z.mjs} +3 -3
  96. package/dist/{get-COwdtskS.mjs → get-RslzBaXx.mjs} +4 -4
  97. package/dist/{get-run-Iya0Yw9s.mjs → get-run-CZdDqfUj.mjs} +5 -5
  98. package/dist/{get-Eqq13YY-.mjs → get-wjIgUlNl.mjs} +3 -3
  99. package/dist/git-sync-BmoRk0UV.mjs +28 -0
  100. package/dist/{git-sync-BDnxPrqU.mjs → git-sync-BwBRmEhE.mjs} +18 -1
  101. package/dist/{git-sync-DxD_ng48.mjs → git-sync-TjX1r_wF.mjs} +1 -1
  102. package/dist/{group-CmVCLBDz.mjs → group-YQQ5GIcP.mjs} +2 -3
  103. package/dist/{has-remote-changes-DfJUMP8F.mjs → has-remote-changes-i-3MVxat.mjs} +4 -4
  104. package/dist/{import-FEAx-Y5A.mjs → import-DWEKejya.mjs} +6 -6
  105. package/dist/{input-DFZ_qGW_.mjs → input-DEvkIjGr.mjs} +1 -1
  106. package/dist/{is-dirty-BsYjBSXG.mjs → is-dirty-C5ipqd4v.mjs} +2 -2
  107. package/dist/{items-D4rstE12.mjs → items-hKJ2ZDwy.mjs} +6 -6
  108. package/dist/{key-BmWundO3.mjs → key-PYetuQ13.mjs} +1 -1
  109. package/dist/{library-uzyHWBap.mjs → library-B7_04UVK.mjs} +5 -5
  110. package/dist/{library-DXB8sm4r.mjs → library-BPIzb3K_.mjs} +1 -1
  111. package/dist/{library-CmctxHjv.mjs → library-PGCfm0UA.mjs} +1 -1
  112. package/dist/{list-DrS3ePsv.mjs → list-1vdClKSE.mjs} +3 -3
  113. package/dist/{list-xMfCeuZc.mjs → list-6myofqMv.mjs} +6 -6
  114. package/dist/{list-squb_ioH.mjs → list-B-9QOX9Y.mjs} +5 -5
  115. package/dist/{list-ndIl9XqV.mjs → list-Bs7_Rysg.mjs} +6 -6
  116. package/dist/list-CHuhMXet.mjs +35 -0
  117. package/dist/{list-CQy0z7f9.mjs → list-CLZU_EOf.mjs} +3 -3
  118. package/dist/{list-DeNGm9G4.mjs → list-Cen-7uTo.mjs} +4 -4
  119. package/dist/{list-Bjj0z5BS.mjs → list-CgH-H-O6.mjs} +3 -3
  120. package/dist/{list-BmMi_wPD.mjs → list-CjNXskB4.mjs} +6 -6
  121. package/dist/{list-DoTiQc3D.mjs → list-CmFh1GQ_.mjs} +3 -3
  122. package/dist/{list-D_zvX0ms.mjs → list-D6tTvYUP.mjs} +3 -3
  123. package/dist/{list-CC1M_n6Z.mjs → list-DI820W6w.mjs} +5 -5
  124. package/dist/{list-Dgm6TkqR.mjs → list-DKZnQ4Ts.mjs} +6 -6
  125. package/dist/{list-sQcA4g05.mjs → list-DKcC4cm0.mjs} +5 -5
  126. package/dist/{list-BRpPbvyS.mjs → list-DfRqNH1N.mjs} +3 -3
  127. package/dist/{list-bN0RC14-.mjs → list-DjwnsyXM.mjs} +11 -10
  128. package/dist/{list-BXL8HFr_.mjs → list-VNC-_E59.mjs} +5 -5
  129. package/dist/{list-1DkkU82x.mjs → list-eKDT1XXk.mjs} +5 -5
  130. package/dist/{list-B7tqNV8B.mjs → list-oX2SMzxZ.mjs} +3 -3
  131. package/dist/{login-D_1-zE4A.mjs → login-DumZaWXK.mjs} +9 -9
  132. package/dist/{logout-DPi2q1Wu.mjs → logout-BsXPRc-3.mjs} +2 -2
  133. package/dist/{measure-CdA8Nl3Z.mjs → measure-BFxkbAoa.mjs} +6 -6
  134. package/dist/{notification-Fcq1fIPw.mjs → notification-DVrLkjFT.mjs} +1 -1
  135. package/dist/{parameter-DUKR8NXo.mjs → parameter-Celg0wZa.mjs} +1 -1
  136. package/dist/{parameter-values-C6dj6I4g.mjs → parameter-values-CoF9Hx1p.mjs} +4 -4
  137. package/dist/{parse-enum-B1t8S194.mjs → parse-enum-Dc0dMZ3P.mjs} +1 -1
  138. package/dist/{parse-id-DR8aUSdL.mjs → parse-id-DmFJgpY6.mjs} +1 -1
  139. package/dist/{parse-ref-BJ_Q0tNW.mjs → parse-ref-DTDld_LJ.mjs} +1 -1
  140. package/dist/{path-B96DI8u2.mjs → path-BQ4lRDyN.mjs} +4 -4
  141. package/dist/{poll-By46YQ5J.mjs → poll-CZeXepUQ.mjs} +2 -2
  142. package/dist/{preflight-Bl1oitm8.mjs → preflight-BTQe4swo.mjs} +3 -3
  143. package/dist/{process-CcQM4qPv.mjs → process-CTrfxxaC.mjs} +1 -1
  144. package/dist/{publish-BKJYvxif.mjs → publish-CFB2Cc5A.mjs} +4 -4
  145. package/dist/{pulse-BmsDenXm.mjs → pulse-Dz0ocv0l.mjs} +1 -1
  146. package/dist/{pulse-DhG6I9mI.mjs → pulse-x0gFxWfG.mjs} +2 -2
  147. package/dist/{query-qBHjZQc_.mjs → query-BJbUnAHf.mjs} +9 -9
  148. package/dist/query-CV2KCS5O.mjs +114 -0
  149. package/dist/{query-result-DBDwk8TS.mjs → query-result-E4Q-Gra6.mjs} +1 -1
  150. package/dist/{remove-collection-BWFW7Rn6.mjs → remove-collection-D3yvKH3e.mjs} +5 -5
  151. package/dist/{render-DmykmrFB.mjs → render-BJRCs7rA.mjs} +4 -2
  152. package/dist/{replace-BmAqD3zY.mjs → replace-uj4WTqx_.mjs} +4 -4
  153. package/dist/{rescan-values-BrCLrihF.mjs → rescan-values-CzxQU318.mjs} +5 -5
  154. package/dist/{run-q5Y44Fxj.mjs → run-B2f_omHu.mjs} +3 -3
  155. package/dist/run-DlO1J1Sx.mjs +50 -0
  156. package/dist/{run-CtbzjDKY.mjs → run-yX2dtmE5.mjs} +5 -5
  157. package/dist/{runs-JFlbezkQ.mjs → runs-DzUO45wU.mjs} +6 -6
  158. package/dist/{runtime-BQiGgbgZ.mjs → runtime-arKqJqIT.mjs} +225 -68
  159. package/dist/{schema-tables-Bzx2ShyE.mjs → schema-tables-DZCNzuQ6.mjs} +6 -6
  160. package/dist/{schemas-ww5mU2AS.mjs → schemas-2ejqaVsG.mjs} +4 -4
  161. package/dist/{search-DFBwUc6d.mjs → search-BAXg-EJw.mjs} +2 -1
  162. package/dist/{search-J4RwCof-.mjs → search-DcihauDZ.mjs} +5 -5
  163. package/dist/{segment-XXTjU0eG.mjs → segment-BQT2poPG.mjs} +6 -6
  164. package/dist/{selectors-BAAZMi43.mjs → selectors-BzestDld.mjs} +3 -3
  165. package/dist/{send-BmpDlw9O.mjs → send-DMxoLFo7.mjs} +3 -3
  166. package/dist/{set-DUWrSza9.mjs → set-CDmiD0vv.mjs} +4 -4
  167. package/dist/{set-active-BiUlbNI5.mjs → set-active-RrvWR9NY.mjs} +3 -3
  168. package/dist/{setting-B1KBQN3M.mjs → setting-BiBLCcxz.mjs} +4 -4
  169. package/dist/{setup-CVaNVwOd.mjs → setup-DYsTzkWO.mjs} +3 -3
  170. package/dist/{signal-GhGmuHfx.mjs → signal-k7cm5N6h.mjs} +1 -1
  171. package/dist/{skill-list-DTnDhnL5.mjs → skill-list-D9_1Pmt7.mjs} +16 -9
  172. package/dist/{skills-DkDsSH5F.mjs → skills-BPHXUfeL.mjs} +75 -28
  173. package/dist/{skills-BWrAlj9l.mjs → skills-C3bxxC6a.mjs} +3 -3
  174. package/dist/snippet-BtfxE60H.mjs +19 -0
  175. package/dist/{stash-DMm8YF8V.mjs → stash-DdheS0Ad.mjs} +6 -6
  176. package/dist/{status-BzEQjQ_t.mjs → status-BuIzXRX1.mjs} +3 -3
  177. package/dist/{status-ClWsQD6v.mjs → status-CXouQJ31.mjs} +5 -5
  178. package/dist/{subscription-CdFn2hre.mjs → subscription-CJ8Igs1U.mjs} +6 -6
  179. package/dist/{subscriptions-DBda1pE5.mjs → subscriptions-D0NpGvCQ.mjs} +6 -6
  180. package/dist/{summary-B4GPiuqD.mjs → summary-D04S8gGj.mjs} +5 -5
  181. package/dist/{sync-schema-DsIM5g2U.mjs → sync-schema-DrA5zkdl.mjs} +6 -6
  182. package/dist/{sync-task-BACcrs0i.mjs → sync-task-BXeWuARG.mjs} +1 -1
  183. package/dist/{table-CsIJNPFf.mjs → table-C6h4tIRw.mjs} +1 -1
  184. package/dist/{table-CeeTJgQb.mjs → table-DfuY0N8e.mjs} +51 -4
  185. package/dist/{table-D4Alrrwh.mjs → table-Dntbz7Q2.mjs} +5 -5
  186. package/dist/timeline-8jwsldo3.mjs +21 -0
  187. package/dist/{timeline-event-DWIh3Tdt.mjs → timeline-event-BbB1xEdI.mjs} +6 -6
  188. package/dist/{transform-Bk0D0nIs.mjs → transform-CtqB1WYo.mjs} +2 -2
  189. package/dist/{transform-DpuG-ON3.mjs → transform-DiW7bREn.mjs} +43 -1
  190. package/dist/transform-job-B-1YAbvy.mjs +22 -0
  191. package/dist/transform-m6s4kkWU.mjs +28 -0
  192. package/dist/{transform-tag-DJ3_bksm.mjs → transform-tag-PjryheLF.mjs} +5 -5
  193. package/dist/transform-test-BjjCQ2xm.mjs +169 -0
  194. package/dist/transform-test-DSTkKKNC.mjs +16 -0
  195. package/dist/transform-test-gzDcbypy.mjs +25 -0
  196. package/dist/{transforms-Dg2MfB2a.mjs → transforms-CijX3VE7.mjs} +6 -6
  197. package/dist/{tree-BQL0f7YX.mjs → tree-Cmb3O6rH.mjs} +3 -3
  198. package/dist/{unpublish-DfSvb_Rs.mjs → unpublish-DkP_AcK5.mjs} +3 -3
  199. package/dist/{update-DBGaJDsj.mjs → update-8UmD1prT.mjs} +6 -6
  200. package/dist/{update-Izqip6jY.mjs → update-BFyRBc-H.mjs} +7 -7
  201. package/dist/{update-BCgAyfj_.mjs → update-BrXGg3QO.mjs} +7 -7
  202. package/dist/{update-sYLQIUgh.mjs → update-C91m9YAR.mjs} +5 -5
  203. package/dist/{update-D1QdfpKR.mjs → update-COcx61Ur.mjs} +5 -5
  204. package/dist/update-Ci8YL4_2.mjs +41 -0
  205. package/dist/{update-CDo0Orvu.mjs → update-CtLbFCd_.mjs} +4 -4
  206. package/dist/{update-Bhmli02m.mjs → update-D6Zzvc7F.mjs} +6 -6
  207. package/dist/{update-Cr5zHb0D.mjs → update-D8htjzNJ.mjs} +4 -4
  208. package/dist/{update-CtDHMxW8.mjs → update-D9kOTr0n.mjs} +5 -5
  209. package/dist/{update-BxIyFtrX.mjs → update-DPTio6i1.mjs} +6 -6
  210. package/dist/{update-NZhIjTCf.mjs → update-DlWB9s0v.mjs} +4 -4
  211. package/dist/{update-D4qdTlLF.mjs → update-DubrpPbz.mjs} +4 -4
  212. package/dist/{update-CiYxcf8M.mjs → update-Dz47cKBk.mjs} +4 -4
  213. package/dist/{update-B-hRR8gW.mjs → update-FCP5Lop2.mjs} +6 -6
  214. package/dist/{update-CKoBDTL7.mjs → update-KSHnb6vB.mjs} +8 -8
  215. package/dist/{update-dashcard-D5b971AO.mjs → update-dashcard-BlibHa5o.mjs} +6 -6
  216. package/dist/{upgrade-CD1xtsIv.mjs → upgrade-EwL6wPSY.mjs} +4 -4
  217. package/dist/upload-BZshRJIM.mjs +13 -0
  218. package/dist/{upload-akKFxpVA.mjs → upload-D0KaTqUE.mjs} +3 -3
  219. package/dist/{upload-BUd3MG90.mjs → upload-Do2PBSeH.mjs} +2 -2
  220. package/dist/{uuid-oVdJ62eA.mjs → uuid-DjKLDIVE.mjs} +9 -5
  221. package/dist/{validate-query-Boi8-cAP.mjs → validate-query-D6_ad-Gi.mjs} +3 -3
  222. package/dist/{validate-CWd6l6KZ.mjs → validate-xR_MHBNR.mjs} +69 -23
  223. package/dist/{values-DLwZl-P8.mjs → values-Dc9612_L.mjs} +5 -5
  224. package/dist/{verify-CH9Tw8yv.mjs → verify-DVN1eqXZ.mjs} +3 -3
  225. package/dist/{wait-rfTdQWdi.mjs → wait-C-ovOTAZ.mjs} +6 -6
  226. package/dist/{wait-flags-DiQ_kRjZ.mjs → wait-flags-BQNmuvIj.mjs} +2 -2
  227. package/dist/{window-BkvrP0gB.mjs → window-DSb1tqSe.mjs} +1 -1
  228. package/package.json +1 -1
  229. package/skill-data/core/SKILL.md +20 -14
  230. package/skill-data/dashboard/SKILL.md +1 -1
  231. package/skill-data/mbql/SKILL.md +84 -115
  232. package/skill-data/mbql/references/operators.md +81 -240
  233. package/skill-data/native-sql/SKILL.md +8 -9
  234. package/skill-data/native-sql/references/template-tags.md +21 -25
  235. package/skill-data/transform/SKILL.md +64 -2
  236. package/skill-data/transform-test-plan/SKILL.md +171 -0
  237. package/skill-data/transform-test-plan/references/checklist.md +81 -0
  238. package/skill-data/transform-test-plan/references/checks.md +260 -0
  239. package/skill-data/visualization/SKILL.md +2 -3
  240. package/skill-data/visualization/references/settings.md +7 -7
  241. package/skills/metabase-cli/SKILL.md +1 -1
  242. package/dist/card-BRarvKYX.mjs +0 -24
  243. package/dist/collection-CKeO8X7U.mjs +0 -20
  244. package/dist/document-BoILnE_1.mjs +0 -19
  245. package/dist/git-sync-CdN0Maun.mjs +0 -28
  246. package/dist/query-BKSM-pbi.mjs +0 -86
  247. package/dist/snippet-CG75L2DS.mjs +0 -19
  248. package/dist/timeline-DmM0BuX8.mjs +0 -21
  249. package/dist/transform-BcV_XlSX.mjs +0 -28
  250. package/dist/transform-job-CjtwBGoM.mjs +0 -22
  251. package/dist/upload-DzGTlldn.mjs +0 -13
@@ -1,7 +1,7 @@
1
- import { I as outputFlags, M as version, Q as UnknownError, W as AbortError, Y as NetworkError, Z as TimeoutError, a as renderItem, et as errorMessage, g as promptConfirm, j as name, t as interruptSignal, u as writeText } from "./cli.mjs";
2
- import { L as HttpError, O as USER_AGENT, V as parseJson, t as defineMetabaseCommand } from "./runtime-BQiGgbgZ.mjs";
3
- import { n as throwIfAborted, t as combineAborts } from "./signal-GhGmuHfx.mjs";
4
- import { n as streamProcess } from "./process-CcQM4qPv.mjs";
1
+ import { H as outputFlags, L as name, R as version, X as AbortError, h as writeText, it as UnknownError, ot as errorMessage, rt as TimeoutError, t as interruptSignal, tt as NetworkError, u as renderItem, x as promptConfirm } from "./cli.mjs";
2
+ import { L as HttpError, O as USER_AGENT, V as parseJson, t as defineMetabaseCommand } from "./runtime-arKqJqIT.mjs";
3
+ import { n as throwIfAborted, t as combineAborts } from "./signal-k7cm5N6h.mjs";
4
+ import { n as streamProcess } from "./process-CTrfxxaC.mjs";
5
5
  import { z } from "zod";
6
6
  import { realpathSync } from "node:fs";
7
7
  import { compare, valid } from "semver";
@@ -0,0 +1,13 @@
1
+ import { t as defineCommandGroup } from "./group-YQQ5GIcP.mjs";
2
+ //#region src/commands/upload/index.ts
3
+ var upload_default = defineCommandGroup({
4
+ name: "upload",
5
+ description: "Upload CSV files into Metabase",
6
+ subCommands: {
7
+ csv: () => import("./csv-BhuX9fwh.mjs").then((m) => m.default),
8
+ append: () => import("./append-CHme1Enm.mjs").then((m) => m.default),
9
+ replace: () => import("./replace-uj4WTqx_.mjs").then((m) => m.default)
10
+ }
11
+ });
12
+ //#endregion
13
+ export { upload_default as default };
@@ -1,7 +1,7 @@
1
- import { I as outputFlags, L as profileFlag, N as connectionFlags, c as renderSummary } from "./cli.mjs";
2
- import { t as defineMetabaseCommand } from "./runtime-BQiGgbgZ.mjs";
1
+ import { H as outputFlags, U as profileFlag, p as renderSummary, z as connectionFlags } from "./cli.mjs";
2
+ import { t as defineMetabaseCommand } from "./runtime-arKqJqIT.mjs";
3
3
  import { t as ContentTranslationUploadResult } from "./content-translation-BrHOrmj9.mjs";
4
- import { n as requireUploadFilePath, t as readCsvFile } from "./upload-BUd3MG90.mjs";
4
+ import { n as requireUploadFilePath, t as readCsvFile } from "./upload-Do2PBSeH.mjs";
5
5
  //#region src/output/views/content-translation.ts
6
6
  const contentTranslationUploadView = {
7
7
  compactPick: ContentTranslationUploadResult,
@@ -1,5 +1,5 @@
1
- import { K as ConfigError, tt as isFileNotFoundError } from "./cli.mjs";
2
- import { n as fileNotFoundError } from "./input-DFZ_qGW_.mjs";
1
+ import { Q as ConfigError, st as isFileNotFoundError } from "./cli.mjs";
2
+ import { n as fileNotFoundError } from "./input-DEvkIjGr.mjs";
3
3
  import { basename } from "node:path";
4
4
  import { readFile } from "node:fs/promises";
5
5
  //#region src/runtime/upload.ts
@@ -1,5 +1,5 @@
1
- import { I as outputFlags, K as ConfigError, l as writeJson, u as writeText } from "./cli.mjs";
2
- import { nt as parseInteger, t as defineMetabaseCommand } from "./runtime-BQiGgbgZ.mjs";
1
+ import { H as outputFlags, Q as ConfigError, h as writeText, m as writeJson } from "./cli.mjs";
2
+ import { rt as parseInteger, t as defineMetabaseCommand } from "./runtime-arKqJqIT.mjs";
3
3
  import { z } from "zod";
4
4
  import { randomUUID } from "node:crypto";
5
5
  //#region src/commands/uuid.ts
@@ -10,10 +10,13 @@ var uuid_default = defineMetabaseCommand({
10
10
  name: "uuid",
11
11
  description: "Mint random UUID v4 strings"
12
12
  },
13
- details: "For MBQL `lib/uuid` slots, native template-tag ids, and other UUID fields. Mint fresh values here rather than authoring them by hand — the MBQL 5 schema rejects placeholder strings.",
13
+ details: "For the values that must be a UUID: the `lib/uuid` of an aggregation an MBQL aggregation ref points at, and a document node's `_id`.",
14
14
  skills: [{
15
15
  skill: "mbql",
16
- purpose: "where lib/uuid values are used"
16
+ purpose: "aggregation refs"
17
+ }, {
18
+ skill: "document",
19
+ purpose: "document node ids"
17
20
  }],
18
21
  requires: null,
19
22
  args: {
@@ -28,7 +31,8 @@ var uuid_default = defineMetabaseCommand({
28
31
  examples: [
29
32
  "mb uuid",
30
33
  "mb uuid --count 5",
31
- "mb uuid --count 5 --json"
34
+ "mb uuid --count 5 --json",
35
+ "U=$(mb uuid --format text)"
32
36
  ],
33
37
  run({ args, ctx }) {
34
38
  const count = parseInteger(args.count, {
@@ -1,5 +1,5 @@
1
- import { K as ConfigError, l as writeJson } from "./cli.mjs";
2
- import { i as validateQuery, r as isMbql5Query, t as assertNotLegacyEnvelopeWrappingMbql5 } from "./validate-CWd6l6KZ.mjs";
1
+ import { Q as ConfigError, m as writeJson } from "./cli.mjs";
2
+ import { a as validateQuery, i as isMbql5Query, n as assertNotLegacyEnvelopeWrappingMbql5 } from "./validate-xR_MHBNR.mjs";
3
3
  //#region src/commands/validate-query.ts
4
4
  const skipValidateFlag = { "skip-validate": {
5
5
  type: "boolean",
@@ -28,7 +28,7 @@ function preflightMbql5Query(query, labels, options) {
28
28
  const outcome = validateQuery(query);
29
29
  if (outcome.ok) return;
30
30
  writeJson(outcome);
31
- throw new ConfigError(`${labels.contextLabel}: ${outcome.errors.length} error(s) — pass valid MBQL 5 or use the legacy format`);
31
+ throw new ConfigError(`${labels.contextLabel}: ${outcome.errors.length} error(s) — fix them, or pass --skip-validate to send anyway`);
32
32
  }
33
33
  //#endregion
34
34
  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,4 +1,4 @@
1
- import { K as ConfigError, gt as escapeJsonPointerSegment, h as isPlainObject } from "./cli.mjs";
1
+ import { Q as ConfigError, b as isPlainObject, lt as escapeJsonPointerSegment } from "./cli.mjs";
2
2
  import { z } from "zod";
3
3
  import Ajv2020 from "ajv/dist/2020.js";
4
4
  import addFormats from "ajv-formats";
@@ -1308,7 +1308,7 @@ const ValidationIssue = z.object({
1308
1308
  path: z.string(),
1309
1309
  message: z.string()
1310
1310
  });
1311
- z.object({
1311
+ const ValidationOutcome = z.object({
1312
1312
  ok: z.boolean(),
1313
1313
  errors: z.array(ValidationIssue)
1314
1314
  });
@@ -1327,6 +1327,58 @@ const idSchema = {
1327
1327
  field_id: POSITIVE_INTEGER
1328
1328
  }
1329
1329
  };
1330
+ function definitionRef(tag) {
1331
+ return {
1332
+ description: `[${tag}, options, id]`,
1333
+ type: "array",
1334
+ prefixItems: [
1335
+ { const: tag },
1336
+ { $ref: "query.yaml#/$defs/options" },
1337
+ POSITIVE_INTEGER
1338
+ ],
1339
+ minItems: 3,
1340
+ maxItems: 3
1341
+ };
1342
+ }
1343
+ const refSchemaWithIds = {
1344
+ ...ref_default,
1345
+ $defs: {
1346
+ ...ref_default.$defs,
1347
+ metric_ref: definitionRef("metric"),
1348
+ measure_ref: definitionRef("measure"),
1349
+ segment_ref: definitionRef("segment")
1350
+ }
1351
+ };
1352
+ const templateTag = query_default.$defs.template_tag;
1353
+ const nativeStage = query_default.$defs.native_stage;
1354
+ const TEMPLATE_TAG_REF = { $ref: "#/$defs/template_tag" };
1355
+ const querySchemaForApi = {
1356
+ ...query_default,
1357
+ $defs: {
1358
+ ...query_default.$defs,
1359
+ native_stage: {
1360
+ ...nativeStage,
1361
+ properties: {
1362
+ ...nativeStage.properties,
1363
+ "template-tags": {
1364
+ type: ["object", "array"],
1365
+ additionalProperties: TEMPLATE_TAG_REF,
1366
+ items: TEMPLATE_TAG_REF
1367
+ }
1368
+ }
1369
+ },
1370
+ template_tag: {
1371
+ ...templateTag,
1372
+ properties: {
1373
+ ...templateTag.properties,
1374
+ id: {
1375
+ type: "string",
1376
+ minLength: 1
1377
+ }
1378
+ }
1379
+ }
1380
+ }
1381
+ };
1330
1382
  let validator = null;
1331
1383
  function getValidator() {
1332
1384
  if (validator !== null) return validator;
@@ -1338,18 +1390,18 @@ function getValidator() {
1338
1390
  addFormats(ajv);
1339
1391
  ajv.addSchema(idSchema, "id.yaml");
1340
1392
  ajv.addSchema(parameter_default, "parameter.yaml");
1341
- ajv.addSchema(ref_default, "ref.yaml");
1393
+ ajv.addSchema(refSchemaWithIds, "ref.yaml");
1342
1394
  ajv.addSchema(temporal_bucketing_default, "temporal_bucketing.yaml");
1343
- ajv.addSchema(query_default, "query.yaml");
1395
+ ajv.addSchema(querySchemaForApi, "query.yaml");
1344
1396
  const compiled = ajv.getSchema("query.yaml");
1345
1397
  if (compiled === void 0) throw new Error("internal: query.yaml validator not registered");
1346
1398
  validator = compiled;
1347
1399
  return validator;
1348
1400
  }
1349
- const UUID_HINT_MESSAGE = "must be a UUID v4 (RFC 4122) — run `mb uuid` (or `mb uuid --count N`) to mint one. The MBQL 5 schema rejects placeholder strings (`a1`, `uuid-1`, etc.); agents must call the CLI for UUIDs rather than authoring them.";
1350
- const FIELD_SLOT1_HINT_MESSAGE = "must be the field options object — MBQL 5 field refs are [\"field\", {options}, fieldId]; the legacy MBQL 4 shape [\"field\", id, opts] is not accepted here. (Tip: `mb uuid` mints `lib/uuid` strings if you need them.)";
1351
- function clauseSlot1HintMessage(operator, slot1) {
1352
- return `must be the clause options object — every MBQL 5 clause is ["${operator}", {options}, ...args]; got ${describeJsonValue(slot1)} at index 1`;
1401
+ const UUID_HINT_MESSAGE = "must be a UUID from `mb uuid`";
1402
+ const FIELD_SLOT1_HINT_MESSAGE = "must be the options object: [\"field\", {}, <field id>]";
1403
+ function clauseSlot1HintMessage(operator) {
1404
+ return `must be the options object: ["${operator}", {}, ...args]`;
1353
1405
  }
1354
1406
  const FormatErrorParams = z.object({ format: z.string() });
1355
1407
  function isUuidFormatIssue(issue) {
@@ -1365,7 +1417,7 @@ function runValidator(validatorFn, value) {
1365
1417
  const overrides = collectMessageOverrides(value);
1366
1418
  return {
1367
1419
  ok: false,
1368
- errors: (validatorFn.errors ?? []).map((issue) => {
1420
+ errors: (validatorFn.errors ?? []).filter((issue) => issue.keyword !== IF_KEYWORD).map((issue) => {
1369
1421
  if (issue.message === void 0) throw new Error(`Ajv issue at ${issue.instancePath} has no message`);
1370
1422
  const path = issue.instancePath === "" ? "/" : issue.instancePath;
1371
1423
  if (isUuidFormatIssue(issue)) return {
@@ -1379,6 +1431,7 @@ function runValidator(validatorFn, value) {
1379
1431
  })
1380
1432
  };
1381
1433
  }
1434
+ const IF_KEYWORD = "if";
1382
1435
  function collectMessageOverrides(root) {
1383
1436
  const overrides = /* @__PURE__ */ new Map();
1384
1437
  visit(root, "");
@@ -1403,7 +1456,7 @@ function clauseSlot1Message(clause) {
1403
1456
  const slot1 = clause[1];
1404
1457
  if (isPlainObject(slot1)) return null;
1405
1458
  if (operator === "field") return FIELD_SLOT1_HINT_MESSAGE;
1406
- return clauseSlot1HintMessage(operator, slot1);
1459
+ return clauseSlot1HintMessage(operator);
1407
1460
  }
1408
1461
  function refSlot2Message(clause) {
1409
1462
  if (clause.length !== 3) return null;
@@ -1414,18 +1467,11 @@ function refSlot2Message(clause) {
1414
1467
  }
1415
1468
  function refHintForKind(kind) {
1416
1469
  switch (kind) {
1417
- case "aggregation": return "must be the target aggregation's lib/uuid (string), not a numeric position";
1418
- case "expression": return "must be the target expression's name (string), not a numeric position";
1470
+ case "aggregation": return "must be the lib/uuid of an aggregation in this stage";
1471
+ case "expression": return "must be the name of an expression in this stage";
1419
1472
  default: return null;
1420
1473
  }
1421
1474
  }
1422
- function describeJsonValue(value) {
1423
- if (value === null) return "null";
1424
- if (Array.isArray(value)) return "array";
1425
- if (typeof value === "string") return `string ${JSON.stringify(value)}`;
1426
- if (typeof value === "number" || typeof value === "boolean") return `${typeof value} ${String(value)}`;
1427
- return typeof value;
1428
- }
1429
1475
  function validateQuery(value) {
1430
1476
  return runValidator(getValidator(), value);
1431
1477
  }
@@ -1443,7 +1489,7 @@ function isLegacyEnvelopeWrappingMbql5(value) {
1443
1489
  }
1444
1490
  function assertNotLegacyEnvelopeWrappingMbql5(value, options) {
1445
1491
  if (!isLegacyEnvelopeWrappingMbql5(value)) return;
1446
- throw new ConfigError(`${options.contextLabel}: MBQL 5 query nested inside a legacy {type:"query", query:…} envelope. For MBQL 5, ${options.bodyNoun} is the mbql/query value itself: {"lib/type":"mbql/query", database:N, stages:[…]}.`);
1492
+ throw new ConfigError(`${options.contextLabel}: ${options.bodyNoun} is the query itself: {"lib/type": "mbql/query", "database": N, "stages": […]}.`);
1447
1493
  }
1448
1494
  z.object({
1449
1495
  schema: z.unknown(),
@@ -1456,14 +1502,14 @@ z.object({
1456
1502
  });
1457
1503
  function getQuerySchemaBundle() {
1458
1504
  return {
1459
- schema: query_default,
1505
+ schema: querySchemaForApi,
1460
1506
  defs: {
1461
1507
  "id.yaml": idSchema,
1462
1508
  "parameter.yaml": parameter_default,
1463
- "ref.yaml": ref_default,
1509
+ "ref.yaml": refSchemaWithIds,
1464
1510
  "temporal_bucketing.yaml": temporal_bucketing_default
1465
1511
  }
1466
1512
  };
1467
1513
  }
1468
1514
  //#endregion
1469
- export { validateQuery as i, getQuerySchemaBundle as n, isMbql5Query as r, assertNotLegacyEnvelopeWrappingMbql5 as t };
1515
+ export { validateQuery as a, isMbql5Query as i, assertNotLegacyEnvelopeWrappingMbql5 as n, getQuerySchemaBundle as r, ValidationOutcome as t };
@@ -1,8 +1,8 @@
1
- import { I as outputFlags, L as profileFlag, N as connectionFlags, c as renderSummary, f as formatScalar } from "./cli.mjs";
2
- import { t as defineMetabaseCommand } from "./runtime-BQiGgbgZ.mjs";
3
- import { t as parseId } from "./parse-id-DR8aUSdL.mjs";
4
- import { s as FieldValues } from "./field-Cr2DPUG9.mjs";
5
- import { n as fieldValuesView } from "./field-BPsNa-TO.mjs";
1
+ import { H as outputFlags, U as profileFlag, _ as formatScalar, p as renderSummary, z as connectionFlags } from "./cli.mjs";
2
+ import { t as defineMetabaseCommand } from "./runtime-arKqJqIT.mjs";
3
+ import { t as parseId } from "./parse-id-DmFJgpY6.mjs";
4
+ import { l as FieldValues } from "./field-CcN4oZy6.mjs";
5
+ import { n as fieldValuesView } from "./field-fDtIrY6D.mjs";
6
6
  //#region src/commands/field/values.ts
7
7
  var values_default = defineMetabaseCommand({
8
8
  meta: {
@@ -1,6 +1,6 @@
1
- import { n as createClient } from "./client-Bv7Iwdvh.mjs";
2
- import { J as MetabaseError, Y as NetworkError, Z as TimeoutError, et as errorMessage } from "./cli.mjs";
3
- import { $ as probeServer, L as HttpError, O as USER_AGENT } from "./runtime-BQiGgbgZ.mjs";
1
+ import { n as createClient } from "./client-cJ7aw0Gt.mjs";
2
+ import { et as MetabaseError, ot as errorMessage, rt as TimeoutError, tt as NetworkError } from "./cli.mjs";
3
+ import { L as HttpError, O as USER_AGENT, et as probeServer } from "./runtime-arKqJqIT.mjs";
4
4
  //#region src/core/auth/verify.ts
5
5
  const VERIFY_TIMEOUT_MS = 15e3;
6
6
  async function verifyAndProbe(url, credential, options = {}) {
@@ -1,9 +1,9 @@
1
- import { I as outputFlags, L as profileFlag, N as connectionFlags, c as renderSummary } from "./cli.mjs";
2
- import { t as defineMetabaseCommand } from "./runtime-BQiGgbgZ.mjs";
3
- import { n as DEFAULT_TIMEOUT_MS, t as DEFAULT_INTERVAL_MS } from "./poll-By46YQ5J.mjs";
4
- import { r as parseWaitSchedule } from "./wait-flags-DiQ_kRjZ.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";
1
+ import { H as outputFlags, U as profileFlag, p as renderSummary, z as connectionFlags } from "./cli.mjs";
2
+ import { t as defineMetabaseCommand } from "./runtime-arKqJqIT.mjs";
3
+ import { n as DEFAULT_TIMEOUT_MS, t as DEFAULT_INTERVAL_MS } from "./poll-CZeXepUQ.mjs";
4
+ import { r as parseWaitSchedule } from "./wait-flags-BQNmuvIj.mjs";
5
+ import { c as syncTaskView } from "./git-sync-TjX1r_wF.mjs";
6
+ import { a as throwIfFailedTask, i as taskPollOptions, n as formatSyncTask, r as syncTaskIdleView, t as SyncTaskOrIdle } from "./sync-task-BXeWuARG.mjs";
7
7
  //#region src/commands/git-sync/wait.ts
8
8
  const WaitResult = SyncTaskOrIdle;
9
9
  var wait_default = defineMetabaseCommand({
@@ -1,6 +1,6 @@
1
1
  import { t as interruptSignal } from "./cli.mjs";
2
- import { t as parseId } from "./parse-id-DR8aUSdL.mjs";
3
- import { n as DEFAULT_TIMEOUT_MS, t as DEFAULT_INTERVAL_MS } from "./poll-By46YQ5J.mjs";
2
+ import { t as parseId } from "./parse-id-DmFJgpY6.mjs";
3
+ import { n as DEFAULT_TIMEOUT_MS, t as DEFAULT_INTERVAL_MS } from "./poll-CZeXepUQ.mjs";
4
4
  //#region src/commands/wait-flags.ts
5
5
  const waitScheduleFlags = {
6
6
  timeout: {
@@ -1,4 +1,4 @@
1
- import { m as projectForList } from "./cli.mjs";
1
+ import { y as projectForList } from "./cli.mjs";
2
2
  //#region src/output/window.ts
3
3
  const MAX_REQUEST_PAGE_SIZE = 200;
4
4
  function windowList(items, range, serverTotal) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@metabase/cli",
3
- "version": "0.3.1-alpha.versioning.9ac5f50",
3
+ "version": "0.3.2-alpha.fix-transform-test-ee-path.041c793",
4
4
  "description": "Metabase CLI",
5
5
  "license": "AGPL-3.0",
6
6
  "repository": {
@@ -6,17 +6,17 @@ allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
6
6
 
7
7
  # metabase-cli (core)
8
8
 
9
- The official Metabase CLI (`mb`) drives a Metabase instance over its REST API: auth, list/get/create/update/delete on every resource, query and transform execution, content search, git-sync (representations ↔ instance), and entity-id translation.
9
+ `mb` drives a Metabase instance over its REST API: CRUD on every resource, query and transform execution, search, git-sync (representations ↔ instance), and entity-id translation.
10
10
 
11
11
  Top-level command groups (run `mb <group> --help` to discover verbs):
12
12
 
13
13
  ```
14
14
  auth | db | table | field | upload | content-translation | query | card | dashboard | snippet | segment | measure | collection | library
15
- document | timeline | timeline-event | transform | transform-job | transform-tag | alert | subscription | setting
15
+ document | timeline | timeline-event | transform | transform-job | transform-tag | transform-test | alert | subscription | setting
16
16
  search | git-sync | setup | eid | uuid | upgrade | skills
17
17
  ```
18
18
 
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.
19
+ The conventions below — auth, flags, output, body input — hold across **every** group. 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.
20
20
 
21
21
  ## Auth & profiles
22
22
 
@@ -28,7 +28,7 @@ mb auth status --json # → {profile, present, url} for the d
28
28
  mb auth status --profile <name> --json # health probe for one profile
29
29
  ```
30
30
 
31
- `auth list` is the primary enumeration path — one call returns every profile with sanitized URL, an `authenticated` flag, and a probe `status` (`ok` / `auth-failed` / `network-error` / `server-error` / `not-probed`). Use it before asking which profile to pick.
31
+ `auth list` is the primary enumeration path — one call returns every profile with sanitized URL, an `authenticated` flag, and a probe `status` (`ok` / `auth-failed` / `network-error` / `server-error` / `not-probed`).
32
32
 
33
33
  - One profile and intent doesn't disambiguate → use it.
34
34
  - Several → ask via `AskUserQuestion`, presenting the names from `auth list`.
@@ -60,7 +60,7 @@ 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 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.
63
+ - `--max-bytes <n>` — cap output size. Default 24576; `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
66
  ## List windows and resumption
@@ -69,10 +69,10 @@ Every list verb takes `--limit <n>` (items this call returns) and `--offset <n>`
69
69
 
70
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
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; …".
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` — 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
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.
74
74
 
75
- The whole walk, literally:
75
+ The whole walk:
76
76
 
77
77
  ```bash
78
78
  offset=0
@@ -104,7 +104,7 @@ mb <noun> create --file ./.scratch/body.json --profile <n> --json
104
104
 
105
105
  Single-quoted `'EOF'` stops the shell interpolating `$vars` inside the JSON.
106
106
 
107
- Write working files to **`./.scratch`** in the current directory (`mkdir -p ./.scratch` first), never `/tmp` — better permissions, they persist across the session, and the user can review them.
107
+ Write working files to **`./.scratch`** in the current directory (`mkdir -p ./.scratch` first), never `/tmp` — they persist across the session and the user can review them.
108
108
 
109
109
  ## Discovering commands and schemas
110
110
 
@@ -123,7 +123,7 @@ mb transform --help --json | jq -r '.commands[].command' # verbs under "transfo
123
123
 
124
124
  ## Resource quirks worth memorizing
125
125
 
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.
126
+ Only what `--help` does _not_ tell you: footguns and non-obvious behaviors.
127
127
 
128
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`.
129
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.
@@ -132,8 +132,8 @@ Routine verb shapes (list / get / create / update), every flag, and output schem
132
132
  <!-- requires: contentTranslation -->
133
133
  - **content-translation.** Admin-only, and separate from Remote Sync. `content-translation download > translations.csv` streams the complete active dictionary; `content-translation upload --file translations.csv` replaces every active translation with the file's contents. Always upload the canonical complete CSV, never a partial patch. An empty dictionary downloads as Metabase's four-row sample dictionary — don't re-upload it as real translations. Metabase limits dictionaries to 1.5 MiB.
134
134
  <!-- /requires -->
135
- - **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`.
136
- - **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). Every dashcard must include `card_id`, including existing rows; use `card_id:null` plus a `visualization_settings.virtual_card` block (`{display:"text"|"heading"|"link"|…}`) for non-question cards. `create` accepts the **same** `dashcards` array in its initial body, so lay out the whole dashboard in one call. `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.
135
+ - **card.** `dataset_query` is the `mbql/query` object itself (→ `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`.
136
+ - **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). Every dashcard must include `card_id`, including existing rows; use `card_id:null` plus a `visualization_settings.virtual_card` block (`{display:"text"|"heading"|"link"|…}`) for non-question cards. `create` accepts the **same** `dashcards` array in its initial body, so lay out the whole dashboard in one call. `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`**. 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.
137
137
  - **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.
138
138
  - **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.
139
139
  - **snippet `--archived` is a swap, not a union** — list returns _either_ active _or_ archived rows, never both. (Same for `--filter archived` on dashboard/collection.)
@@ -144,13 +144,16 @@ Routine verb shapes (list / get / create / update), every flag, and output schem
144
144
  - **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.
145
145
  <!-- requires: transforms -->
146
146
  - **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`.)
147
+ <!-- /requires -->
148
+ <!-- requires: transformTests -->
149
+ - **transform-test.** `transform-test run <id>` checks a transform against fixtures in temp tables — no real table is read — and exits non-zero unless it passes. (→ `transform`.)
147
150
  <!-- /requires -->
148
151
  - **setup is one-shot.** `mb setup` walks `/api/setup` for a **fresh** instance only — errors against an already-configured one. Mostly for bootstrapping local / e2e instances.
149
152
  - **eid** translates a string entity id → numeric id: `mb eid --model <model> <eid1,eid2> --json`. Entity ids are NanoIDs that can start with `-`, which the positional form misreads as a flag (shell quotes don't help) — for those, use `--body '{"entity_ids":{"card":["-…"]}}'` (the id is a JSON string value, immune to flag parsing).
150
153
  <!-- requires: library -->
151
- - **library.** The Library is a curated subtree (`library-data` "Data" + `library-metrics` "Metrics" under a `library` root): tables published to **Data** appear first in data pickers and rank up in search; metrics saved to **Metrics** are prioritized in nav, search, and the query builder — it's how you tell people (and agents) "start from these, they're trusted." `library get` shows the Library and its Data/Metrics collection ids; `library create` provisions it (idempotent). `library publish --table-ids/--db-ids/--schemas` publishes tables into Data — it **resolves the Data collection itself and creates the Library if absent** (no collection id to find); each `--schemas` entry is `<db-id>:<schema>` (e.g. `1:public`), not a bare name. `publish` cascades to upstream FK dependencies, `unpublish` to downstream dependents; both need **admin or data-analyst** (Curate alone won't publish) and exit **403** without write **and** query permission on every affected table. Publish status shows on the table: `table get`/`table list` carry `is_published` (`collection_id` under `--full`). Good candidates are finished, analysis-ready tables — clean/combine via transforms first, then publish the polished result. Publishing does not put the Data collection in the git-sync scope: on a remote-sync instance, `mb git-sync add-collection <data-collection-id>` is what makes exports carry the published tables' metadata (see the `git-sync` skill).
154
+ - **library.** The Library is a curated subtree (`library-data` "Data" + `library-metrics` "Metrics" under a `library` root): tables published to **Data** appear first in data pickers and rank up in search; metrics saved to **Metrics** are prioritized in nav, search, and the query builder. `library get` shows the Library and its Data/Metrics collection ids; `library create` provisions it (idempotent). `library publish --table-ids/--db-ids/--schemas` publishes tables into Data — it **resolves the Data collection itself and creates the Library if absent**; each `--schemas` entry is `<db-id>:<schema>` (e.g. `1:public`), not a bare name. `publish` cascades to upstream FK dependencies, `unpublish` to downstream dependents; both need **admin or data-analyst** (Curate alone won't publish) and exit **403** without write **and** query permission on every affected table. Publish status shows on the table: `table get`/`table list` carry `is_published` (`collection_id` under `--full`). Publishing does not put the Data collection in the git-sync scope: on a remote-sync instance, `mb git-sync add-collection <data-collection-id>` is what makes exports carry the published tables' metadata (see the `git-sync` skill).
152
155
  <!-- /requires -->
153
- - **query / uuid.** `mb query` is the ad-hoc MBQL surface (`--print-schema` → `--dry-run` → run); `mb uuid --count <n>` mints the `lib/uuid` values MBQL clauses need. Both live in `mbql`.
156
+ - **query / uuid.** `mb query` runs MBQL (`--dry-run` → run; `mbql`). `mb uuid --count <n>` mints an aggregation's `lib/uuid` (`mbql`) and document node `_id`s (`document`).
154
157
 
155
158
  ## Specialized skills (load on demand)
156
159
 
@@ -164,6 +167,9 @@ This file is enough for any single-command task. For anything deeper, load the r
164
167
  - **`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.
165
168
  <!-- requires: transforms -->
166
169
  - **`transform`** — transform body JSON, create + run-with-wait, run inspection, tags, jobs.
170
+ <!-- /requires -->
171
+ <!-- requires: transformTests -->
172
+ - **`transform-test-plan`** — deciding _what_ to test in a transform: the fixture cast, the expectations, the coverage matrix. (`transform` has the `mb transform-test` shapes.)
167
173
  <!-- /requires -->
168
174
  - **`document`** — Metabase documents (TipTap body, embedding cards).
169
175
  <!-- requires: remoteSync -->
@@ -171,7 +177,7 @@ This file is enough for any single-command task. For anything deeper, load the r
171
177
  <!-- /requires -->
172
178
  - **`data-workflow`** — the guided, end-to-end data workflow: investigate raw data, build clean analysis-ready tables, define reusable segments/measures/metrics, answer questions, build dashboards. **Start here when the user states a goal rather than a single verb** — "make sense of my data", "build a data model", "go from raw data to a dashboard", "be my data analyst", "set up analytics for X". It detects where the data is and routes to the right stage.
173
179
 
174
- If a task spans more than one, load each. `mb skills list` enumerates the skills the profile's server can use, and `mb skills get` prints a skill with the sections that server cannot use left out; `--all` shows everything.
180
+ If a task spans more than one, load each. `mb skills list` enumerates the skills the profile's server can use, and `mb skills get` prints a skill with the sections that server cannot use left out; `--unfiltered` shows everything.
175
181
 
176
182
  ## Don't
177
183
 
@@ -47,7 +47,7 @@ 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.
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.
51
51
 
52
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
53