@metabase/cli 0.1.4 → 0.1.6

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 (218) hide show
  1. package/.claude-plugin/marketplace.json +19 -0
  2. package/README.md +147 -101
  3. package/dist/{add-collection-CffaBB-Y.mjs → add-collection-BU8r3r2M.mjs} +9 -4
  4. package/dist/add-collection-C0w6ACQF.mjs +11 -0
  5. package/dist/{archive-uJrslh9r.mjs → archive-BNinrUak.mjs} +9 -8
  6. package/dist/{archive-GdGm7l2e.mjs → archive-C1enZgKV.mjs} +8 -7
  7. package/dist/archive-CDA0KxL8.mjs +40 -0
  8. package/dist/{archive-BAcEXbT9.mjs → archive-CRhiBpPJ.mjs} +9 -8
  9. package/dist/{archive-B_B3MQp0.mjs → archive-DMPS8Kih.mjs} +9 -8
  10. package/dist/archive-lWgqiFAt.mjs +40 -0
  11. package/dist/auth-CzXb_zB2.mjs +19 -0
  12. package/dist/{body-D6dHGjMT.mjs → body-DjdFxjpg.mjs} +4 -4
  13. package/dist/{branches-Bpe40fEd.mjs → branches-B1WRfG7-.mjs} +11 -7
  14. package/dist/{cancel-BWTY6oYI.mjs → cancel-Dl_Ho056.mjs} +7 -6
  15. package/dist/{cancel-task--BfiAXfS.mjs → cancel-task-CdigdCaO.mjs} +11 -7
  16. package/dist/capabilities-7e9MgquN.mjs +29 -0
  17. package/dist/card-DP4rfoOi.mjs +21 -0
  18. package/dist/{card-CQxvHeyP.mjs → card-DlCAaAPq.mjs} +1 -1
  19. package/dist/{cards-CVlFJxYh.mjs → cards-BGiJS675.mjs} +8 -7
  20. package/dist/cli.mjs +267 -44
  21. package/dist/collection-tY18ezvn.mjs +21 -0
  22. package/dist/{predicates-CGO17Q15.mjs → command-augment-BH9qgQ5u.mjs} +66 -14
  23. package/dist/create-BNiva__H.mjs +52 -0
  24. package/dist/{create-izE3EKCt.mjs → create-BTcpaop_.mjs} +9 -8
  25. package/dist/{create-BykvNpSA.mjs → create-BYlIju0b.mjs} +14 -12
  26. package/dist/{create-Bu-YhIDL.mjs → create-Be_0Vier.mjs} +10 -9
  27. package/dist/{create-DYoc9IXW.mjs → create-CHF313Qg.mjs} +13 -9
  28. package/dist/{create-Cz3_Wxdt.mjs → create-CwGtmwqm.mjs} +14 -12
  29. package/dist/{create-DP8RrLDi.mjs → create-CzzrbL0u.mjs} +10 -9
  30. package/dist/{create-BzElku2l.mjs → create-DGth_uOp.mjs} +14 -12
  31. package/dist/{create-branch-B49UQyCK.mjs → create-branch-DKZkoQ64.mjs} +11 -7
  32. package/dist/{create-DQVdMT2Y.mjs → create-dhxPxfF3.mjs} +16 -14
  33. package/dist/{credentials-xKSoP6eh.mjs → credentials-dzeq7ckm.mjs} +12 -10
  34. package/dist/{current-task-DweHmjlk.mjs → current-task-CCRzm0_7.mjs} +11 -7
  35. package/dist/dashboard-ChM_Tu0l.mjs +22 -0
  36. package/dist/{dashboard-CnMD04PQ.mjs → dashboard-FY5UzJ_Z.mjs} +2 -1
  37. package/dist/{database-BNlvldUL.mjs → database-CIXwHKjK.mjs} +3 -3
  38. package/dist/{database-vvig8k4x.mjs → database-lH-B3G1I.mjs} +1 -1
  39. package/dist/db-DrQn_i3W.mjs +22 -0
  40. package/dist/{remove-B3ZEqBF7.mjs → delete-CM3jnAeQ.mjs} +21 -20
  41. package/dist/{delete-DojHmKeM.mjs → delete-Dimc-2y8.mjs} +9 -8
  42. package/dist/{delete-DIz9Tgz5.mjs → delete-ZjnV35OJ.mjs} +9 -8
  43. package/dist/{delete-runtime-BkAdygbs.mjs → delete-runtime-B6RQo_pw.mjs} +5 -3
  44. package/dist/{delete-table-DjN8E3sd.mjs → delete-table-agZJpivt.mjs} +9 -8
  45. package/dist/{deprovision-_HDcBApz.mjs → deprovision-CwxcIT3k.mjs} +16 -12
  46. package/dist/{dirty-Co8V0SZ3.mjs → dirty-D4d0yHqj.mjs} +11 -7
  47. package/dist/{docker-D9sC_37H.mjs → docker-Oq80q3tu.mjs} +4 -4
  48. package/dist/{translate-CG_Ka0dO.mjs → eid-BXzaQh0o.mjs} +37 -22
  49. package/dist/error-C9S6PN3-.mjs +190 -0
  50. package/dist/{export-CVMFxoo1.mjs → export-DTygoXBP.mjs} +17 -16
  51. package/dist/field-Z6Pcxf4n.mjs +19 -0
  52. package/dist/{fields-Coha7vKv.mjs → fields-CoQi99gv.mjs} +9 -8
  53. package/dist/{get-DXv2FkA7.mjs → get-Bzys7vgp.mjs} +8 -7
  54. package/dist/{get-bNtA7vWe.mjs → get-C2p383Qc.mjs} +8 -7
  55. package/dist/{get-Br6WayZv.mjs → get-C3HdQ91a.mjs} +8 -7
  56. package/dist/{get-BOtKerj8.mjs → get-CP3Z3NiH.mjs} +9 -8
  57. package/dist/{get-BSKoL8ek.mjs → get-C_w1kvN3.mjs} +9 -8
  58. package/dist/{get-Be6EFh94.mjs → get-CzuzeKSe.mjs} +10 -9
  59. package/dist/{get-BVTz9B_H.mjs → get-D3SbEQSE.mjs} +10 -9
  60. package/dist/get-DFxZXaKz.mjs +79 -0
  61. package/dist/{get-DZrV7v9d.mjs → get-DQTZG_NP.mjs} +8 -7
  62. package/dist/{get-CJwzbVjc.mjs → get-DSWFjy7O.mjs} +8 -7
  63. package/dist/{get-BxzCKVC6.mjs → get-Ddr0XLh7.mjs} +8 -7
  64. package/dist/{get-AOvWo48B.mjs → get-Hc93A0Yz.mjs} +8 -7
  65. package/dist/{get-C_6K7MSW.mjs → get-lb7q3JYs.mjs} +7 -6
  66. package/dist/get-run-B7sKdaDU.mjs +38 -0
  67. package/dist/git-sync-CiGAad76.mjs +28 -0
  68. package/dist/{has-remote-changes-D6xgsuUr.mjs → has-remote-changes-BY10-nnE.mjs} +11 -7
  69. package/dist/{import-Dv0ORSNw.mjs → import-CiMz4Wz-.mjs} +17 -16
  70. package/dist/{input-BQ-BZA8h.mjs → input-cMSEqISy.mjs} +7 -4
  71. package/dist/{is-dirty-WNi8a6O9.mjs → is-dirty-BZOaryxT.mjs} +9 -4
  72. package/dist/is-dirty-Ume4oV0j.mjs +10 -0
  73. package/dist/{items-CTcAMknV.mjs → items-BWfvkY-J.mjs} +9 -8
  74. package/dist/key-C2XG394c.mjs +17 -0
  75. package/dist/license-Dxarh-gG.mjs +17 -0
  76. package/dist/{list-FXuSCYpa.mjs → list--OYdUTtu.mjs} +7 -6
  77. package/dist/{list-8oVMvlLV.mjs → list-2j7GsXsl.mjs} +7 -6
  78. package/dist/{list-xQmtQPSl.mjs → list-BI4zr8LW.mjs} +10 -8
  79. package/dist/{list-DhWG5jiW.mjs → list-Brgh-Z2v.mjs} +8 -6
  80. package/dist/{list-DSs0Q78i.mjs → list-C3hfovHv.mjs} +7 -6
  81. package/dist/{list-DvUjMQze.mjs → list-CL7eCOQE.mjs} +7 -6
  82. package/dist/list-Clz5igWg.mjs +44 -0
  83. package/dist/list-D4sFiqX8.mjs +173 -0
  84. package/dist/{list-BxdXvGTK.mjs → list-DXH7TlkU.mjs} +9 -7
  85. package/dist/{list-CocYwmnI.mjs → list-DZ8fNUoQ.mjs} +9 -8
  86. package/dist/{list-DjhZU-FY.mjs → list-SOG0whQ-.mjs} +7 -6
  87. package/dist/{list-DI7K3K6k.mjs → list-d58BprgJ.mjs} +7 -6
  88. package/dist/{list-NiwCL_1X.mjs → list-sD5N3fGk.mjs} +9 -8
  89. package/dist/{list-CbJeP0Z6.mjs → list-zSO0DMw-.mjs} +10 -6
  90. package/dist/{login-SXsSH0I1.mjs → login-Bm2AnCez.mjs} +65 -80
  91. package/dist/{logout-bgOXjxbN.mjs → logout-BlyRJODO.mjs} +8 -7
  92. package/dist/{logs-BnwVbFuD.mjs → logs-CywPikkL.mjs} +9 -8
  93. package/dist/{manifest-CGM7XNLC.mjs → manifest-BBR46KFM.mjs} +15 -15
  94. package/dist/measure-C44EK_xt.mjs +20 -0
  95. package/dist/{measure-BEQfnLdN.mjs → measure-ClESGxIb.mjs} +2 -2
  96. package/dist/{metadata-Bu2HOmuX.mjs → metadata-B8ZSF9LA.mjs} +10 -9
  97. package/dist/{metadata-B0WZT3Yb.mjs → metadata-DqiI2q9q.mjs} +9 -8
  98. package/dist/parse-enum-CrEWOhuY.mjs +11 -0
  99. package/dist/{parse-id-B3B-0hUA.mjs → parse-id-lk_K-CEF.mjs} +1 -1
  100. package/dist/{parse-ref-D1yeDOn8.mjs → parse-ref-BiETXmvm.mjs} +1 -1
  101. package/dist/{parse-schemas-DgtVLikM.mjs → parse-schemas-BqUdWUwq.mjs} +2 -2
  102. package/dist/path-AEtZ3mBq.mjs +58 -0
  103. package/dist/{poll-BCnrcUVf.mjs → poll-DHKDpCiq.mjs} +2 -2
  104. package/dist/{poll-task-0b1V6G-8.mjs → poll-task-Cooi0lQV.mjs} +3 -20
  105. package/dist/{preflight-5ACaYnDp.mjs → preflight-aXV5LyDs.mjs} +4 -4
  106. package/dist/{process-FjsqDwKo.mjs → process-C7V8LJ-j.mjs} +1 -1
  107. package/dist/{prompt-DgDNy_Pc.mjs → prompt-CFKoys7k.mjs} +3 -1
  108. package/dist/{provision-29Zt62Ft.mjs → provision-UWcNDoDe.mjs} +29 -24
  109. package/dist/{ps-BMFiRCi4.mjs → ps-CJU0EbrC.mjs} +5 -3
  110. package/dist/ps-DEroLgbI.mjs +11 -0
  111. package/dist/{query-DxA353Hy.mjs → query-AaKzYnTY.mjs} +9 -8
  112. package/dist/{query-aba8MEe_.mjs → query-BlsVNZpD.mjs} +15 -13
  113. package/dist/{remove-BfgU_CQi.mjs → remove-BFWun0e8.mjs} +9 -8
  114. package/dist/{remove-collection-Brv72xUe.mjs → remove-collection-CoCmrrQs.mjs} +13 -9
  115. package/dist/{render-DuoDUTVL.mjs → render-CfznwleY.mjs} +15 -17
  116. package/dist/render-OQn3iRsI.mjs +32 -0
  117. package/dist/{rescan-values-DIAdjoq7.mjs → rescan-values-C0FDsjT7.mjs} +10 -9
  118. package/dist/{run-CgXRo0hD.mjs → run-B4Wn43zm.mjs} +10 -9
  119. package/dist/{runs-DtLRw6xg.mjs → runs-Bbaszr18.mjs} +9 -8
  120. package/dist/{runtime-Br8L4NPm.mjs → runtime-Dmv5VtUK.mjs} +657 -428
  121. package/dist/{schema-tables-DiKMY6lx.mjs → schema-tables-CaWinbuK.mjs} +9 -8
  122. package/dist/{schemas-Bvr8cOzo.mjs → schemas-DUgGpAyB.mjs} +7 -6
  123. package/dist/{search-BT_TCcTd.mjs → search-BLrBXLUk.mjs} +12 -16
  124. package/dist/segment-B3Uwwcsm.mjs +20 -0
  125. package/dist/{set-DtG0KH6P.mjs → set-B8cUbRLD.mjs} +13 -12
  126. package/dist/{set-CAIkXlPy.mjs → set-DfGsta5O.mjs} +11 -10
  127. package/dist/{setting-BDOi5fk_.mjs → setting-D2p2MA7f.mjs} +3 -3
  128. package/dist/{setup-LjTvvlJy.mjs → setup-C9ikBRw_.mjs} +9 -8
  129. package/dist/skills-CUHIcQS6.mjs +18 -0
  130. package/dist/skills-CiN1OQ8W.mjs +191 -0
  131. package/dist/snippet-B7D0uWlz.mjs +20 -0
  132. package/dist/{start-CXKt0Q7A.mjs → start-3PX3ahjT.mjs} +68 -36
  133. package/dist/{stash-dRw1UEwg.mjs → stash-EIDcSvpF.mjs} +17 -16
  134. package/dist/{status-C2niMfrQ.mjs → status-95ElRAu9.mjs} +12 -8
  135. package/dist/status-B0_MiZEf.mjs +100 -0
  136. package/dist/status-CEplmC44.mjs +34 -0
  137. package/dist/{stop-BdedYfwU.mjs → stop-CQ0XGrN8.mjs} +11 -10
  138. package/dist/{summary-BPDA4K99.mjs → summary-C12LiEuJ.mjs} +8 -7
  139. package/dist/{sync-schema-D95LLRpf.mjs → sync-schema-Ba8M3DiX.mjs} +10 -9
  140. package/dist/{table-B-PYcgGb.mjs → table-C7a5V6Zn.mjs} +1 -1
  141. package/dist/table-e6h8SLVX.mjs +20 -0
  142. package/dist/transform-BMYh1lsC.mjs +25 -0
  143. package/dist/transform-job-Cm7z5TfH.mjs +20 -0
  144. package/dist/{transform-job-Csr86muI.mjs → transform-job-DeTDPMxt.mjs} +1 -1
  145. package/dist/{tree-DazZT7dR.mjs → tree-Des2ZG9d.mjs} +6 -5
  146. package/dist/{update-DE6kjV-f.mjs → update-Bx54nWEI.mjs} +17 -15
  147. package/dist/{update-bW-i6gjZ.mjs → update-CyIZdbIQ.mjs} +11 -10
  148. package/dist/{update-djgvzO3K.mjs → update-DBi5U8zb.mjs} +16 -14
  149. package/dist/{update-CJSDB6S8.mjs → update-DHZubok3.mjs} +18 -14
  150. package/dist/{update-BBfvArCx.mjs → update-DSgceARZ.mjs} +11 -10
  151. package/dist/{update-DSWZSfpw.mjs → update-DzAN4SPj.mjs} +15 -13
  152. package/dist/{update-WyRKlQPh.mjs → update-F6DmZncY.mjs} +11 -10
  153. package/dist/{update-DTIWJxob.mjs → update-_QfgNa53.mjs} +12 -11
  154. package/dist/{update-dashcard-BhD5x__K.mjs → update-dashcard-wpSjv4M7.mjs} +11 -10
  155. package/dist/{update-9kVyE3BJ.mjs → update-mYVnoYNV.mjs} +15 -13
  156. package/dist/{update-659eQR1L.mjs → update-njHe3j-s.mjs} +15 -13
  157. package/dist/{upgrade-D58rvXHM.mjs → upgrade-iAuvhX-W.mjs} +9 -8
  158. package/dist/{url-DKkSu2D8.mjs → url-DWaT6WIZ.mjs} +11 -10
  159. package/dist/{uuid-BF20B59s.mjs → uuid-CMKnS8-z.mjs} +8 -6
  160. package/dist/{validate-CB0bu50i.mjs → validate-dPEOnOf8.mjs} +2 -1
  161. package/dist/{validate-query-CavIA0Q2.mjs → validate-query-Cw6WE5Y8.mjs} +3 -3
  162. package/dist/{values-DyjmpcbT.mjs → values-BfSTAbzc.mjs} +8 -7
  163. package/dist/verify-D5YtTqqp.mjs +79 -0
  164. package/dist/{wait-CeUPCgdc.mjs → wait-8yV9_WIo.mjs} +2 -2
  165. package/dist/{wait-DhkTaV6E.mjs → wait-Bv3Tsnv4.mjs} +12 -8
  166. package/dist/{wait-flags-BR-yqe7y.mjs → wait-flags-Dzq9BGQY.mjs} +20 -9
  167. package/dist/workspace-CKLZrR7l.mjs +26 -0
  168. package/dist/{workspace-credentials-Cctumbru.mjs → workspace-credentials-BXpABsNZ.mjs} +2 -41
  169. package/dist/yaml-YTQiYJ9s.mjs +43 -0
  170. package/package.json +6 -2
  171. package/skill-data/core/SKILL.md +177 -0
  172. package/skill-data/git-sync/SKILL.md +196 -0
  173. package/skill-data/mbql/SKILL.md +156 -0
  174. package/skill-data/mbql/references/operators.md +253 -0
  175. package/skill-data/transform/SKILL.md +197 -0
  176. package/skill-data/viz/SKILL.md +137 -0
  177. package/skill-data/viz/references/settings.md +312 -0
  178. package/skill-data/workspace/SKILL.md +390 -0
  179. package/skills/metabase-cli/SKILL.md +21 -0
  180. package/dist/add-collection-CPL1njYZ.mjs +0 -11
  181. package/dist/api-key-9p1UPnXn.mjs +0 -13
  182. package/dist/auth-N4w5xtwW.mjs +0 -19
  183. package/dist/card-4rZRb5bc.mjs +0 -20
  184. package/dist/collection-Cp_B02I4.mjs +0 -19
  185. package/dist/command-augment-D9pI9Vbh.mjs +0 -11
  186. package/dist/create-doyv3SxU.mjs +0 -50
  187. package/dist/create-ov-De5dO.mjs +0 -125
  188. package/dist/dashboard-BYBiA-IG.mjs +0 -20
  189. package/dist/db-CObVU22j.mjs +0 -22
  190. package/dist/eid-Cr5r-t9B.mjs +0 -13
  191. package/dist/field-CbljasCH.mjs +0 -18
  192. package/dist/flag-pair-Fmcdkrfx.mjs +0 -17
  193. package/dist/get-run-CSrXHDGS.mjs +0 -36
  194. package/dist/git-sync-BGkS8o5b.mjs +0 -28
  195. package/dist/is-dirty-BOZ4xz92.mjs +0 -10
  196. package/dist/key-CCJdVWKc.mjs +0 -12
  197. package/dist/license-DLLTpFvP.mjs +0 -17
  198. package/dist/list-BNzdnE1c.mjs +0 -55
  199. package/dist/measure-B54VtKym.mjs +0 -19
  200. package/dist/package-D-aVYFKM.mjs +0 -80
  201. package/dist/ps-C5FOLwL2.mjs +0 -11
  202. package/dist/segment-C2ui5dSd.mjs +0 -19
  203. package/dist/snippet-BcgVYsoR.mjs +0 -19
  204. package/dist/status-BEONmJWv.mjs +0 -32
  205. package/dist/status-BWep0PFe.mjs +0 -56
  206. package/dist/table-lCNGbvej.mjs +0 -19
  207. package/dist/transform-BGAm1s4f.mjs +0 -24
  208. package/dist/transform-job-cNTJ30pm.mjs +0 -19
  209. package/dist/workspace-DtcBldk0.mjs +0 -24
  210. /package/dist/{body-flags-BK7J6Daz.mjs → body-flags-D7q87Btw.mjs} +0 -0
  211. /package/dist/{field-B3gvaqpK.mjs → field-yomXlkvl.mjs} +0 -0
  212. /package/dist/{paginate-CTSfuYiF.mjs → paginate-Dfm9eO9A.mjs} +0 -0
  213. /package/dist/{revision-message-flag-oyq2xrDU.mjs → revision-message-flag-WmsIzUOM.mjs} +0 -0
  214. /package/dist/{segment-BMrUBz94.mjs → segment-Be2v4ilr.mjs} +0 -0
  215. /package/dist/{setting-CTaAeMci.mjs → setting-oL97SNeO.mjs} +0 -0
  216. /package/dist/{snippet-Dw0Sjzkr.mjs → snippet-COggaWxx.mjs} +0 -0
  217. /package/dist/{transform-IEX4Mx3X.mjs → transform-GTW3G-01.mjs} +0 -0
  218. /package/dist/{workspace-C5q4nbpY.mjs → workspace-BBXJczJK.mjs} +0 -0
@@ -0,0 +1,390 @@
1
+ ---
2
+ name: workspace
3
+ description: Enterprise workspace lifecycle for `mb` — create, provision databases, start (with Remote Sync wiring + branch guard), save child credentials as a profile, diagnose. Load when the user touches `mb workspace …` — "spin up a workspace", "provision a database", "start a local Metabase against my prod", "save the child's API key", "diagnose a workspace that won't start", or anything Enterprise workspaces.
4
+ allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
5
+ ---
6
+
7
+ # Workspaces (Enterprise)
8
+
9
+ A **workspace** is a child Metabase instance bound to a parent's databases. Local lifecycle is `mb workspace <verb>`; the parent is reached via a profile (the parent's profile — typically `prod` / `staging`). Each provisioned database gets a per-workspace isolation schema on the warehouse, and the QP rewrites references from canonical names (`public.foo`) to that isolation schema (`mb__isolation_<hash>_<ws-id>.foo`) on the fly. Cards, transforms, and queries authored in the workspace target canonical names; the rewrite is invisible to the author.
10
+
11
+ This skill covers the full lifecycle. The general flag conventions, auth setup, and output flags live in the `core` skill; load that first (`mb skills get core`).
12
+
13
+ ## Always ask about Remote Sync before starting
14
+
15
+ Before running `mb workspace start`, **ask the user how they want Remote Sync wired**. The bind mount is set at container-create time — you cannot add it later without a recreate, so this decision belongs at start time. Use `AskUserQuestion` with three options:
16
+
17
+ > "How should I wire Remote Sync for this workspace?"
18
+ >
19
+ > 1. **Current directory** — bind-mount the directory you're running Claude from (`pwd`) as `file:///mnt/repo` and set the workspace to remote-sync against it (read-write). Pick this when the conversation is happening inside the sync repo.
20
+ > 2. **Custom path** — you specify a different host directory; same wiring as option 1.
21
+ > 3. **No sync** — start the workspace without a repo bind mount; you can configure remote-sync against a remote URL later via `setting set`.
22
+
23
+ Default-suggest option 1 if the current working directory looks like a git repo (a `.git/` is present). Otherwise default-suggest option 3 and let the user volunteer a path.
24
+
25
+ Map the answer to flags on `workspace start`:
26
+
27
+ | Choice | Flags to add to `workspace start` |
28
+ | ----------------- | ----------------------------------------------------------------- |
29
+ | Current directory | `--repo "$(pwd)"` |
30
+ | Custom path | `--repo <path>` |
31
+ | No sync | (omit `--repo` — no bind mount, no remote-sync settings injected) |
32
+
33
+ The `--repo` flag (a) bind-mounts the host path into the container at `/mnt/repo`, and (b) injects three settings into the workspace's config.yml at boot: `remote-sync-url=file:///mnt/repo`, `remote-sync-branch=<HEAD>`, `remote-sync-type=read-write`. The branch defaults to the current branch of the host repo (read via `git -C <path> symbolic-ref --short HEAD`); override with `--repo-branch <name>`. Switch to read-only with `--repo-mode read-only` (also makes the bind mount read-only).
34
+
35
+ Do not skip this question — silently picking "no sync" loses the user's repo context, and silently picking "current directory" pushes work into a repo they didn't intend.
36
+
37
+ ## Branch guard before `--repo`
38
+
39
+ When the user picks a `--repo` option (current dir or custom path), check the host's branch before `workspace start`. `--repo` reads `git -C <path> symbolic-ref --short HEAD` and injects it as the workspace's `remote-sync-branch` setting; that branch then becomes the default target for every subsequent `git-sync import` and `git-sync export`. If the host is on `main` (or `master`), every export commits straight to it — usually not what the user wants for ephemeral workspace work.
40
+
41
+ ```bash
42
+ HOST_BRANCH=$(git -C <repo-path> symbolic-ref --short HEAD)
43
+ ```
44
+
45
+ If `HOST_BRANCH` is `main` or `master`, ask the user via `AskUserQuestion`:
46
+
47
+ > "The host repo is on `<branch>` — the workspace will track and export to that branch by default. Switch to a feature branch first?"
48
+ >
49
+ > 1. **Create + checkout a feature branch on the host** — agent suggests a name (e.g., `agent/<task>`); run `git -C <repo-path> checkout -b <name>` then proceed with `workspace start --repo …` so the workspace tracks `<name>`.
50
+ > 2. **Pin the workspace to a specific branch** — pass `--repo-branch <name>` on `workspace start` to override host HEAD. The branch must exist **locally** in the bind-mounted host repo before `workspace start` (create it first with `git -C <repo-path> branch <name>` or `git -C <repo-path> checkout -b <name>`); it does **not** need to exist on `origin`. Local-only branches are fine — the workspace never pushes, and the remote side gets created on the user's first `git push` later.
51
+ > 3. **Proceed on `main`/`master`** — explicitly accepted; downstream `git-sync export` will commit to that branch unless overridden per-call.
52
+
53
+ Skip this question only when the user's instructions already named the branch (e.g., they explicitly asked to work against `main`). The same guard applies later at `git-sync export` time — see the `git-sync` skill, "Branch guard".
54
+
55
+ ## Quick start (copy-pasteable, end-to-end)
56
+
57
+ When a parent profile + license are in place, this whole sequence runs in one go. Replace the four shell vars; pick whether to bind-mount a sync repo with `REPO_FLAGS` per the question above.
58
+
59
+ ```bash
60
+ PARENT=<parent> # e.g. prod — the parent profile name
61
+ WS_NAME=<ws-name> # e.g. my_nice_ws — also reused as the child profile name
62
+ DB_ID=<db-id> # parent database id from `mb database list --profile $PARENT --json`
63
+ SCHEMAS=<schema1,schema2> # comma-separated; no "all" wildcard
64
+ REPO_FLAGS=(--repo "$(pwd)") # OR (--repo /path/to/sync-repo) OR () for no sync
65
+
66
+ # 0. Branch guard (only when REPO_FLAGS is non-empty). If the host repo is on
67
+ # main/master, ask the user before continuing — see "Branch guard before --repo"
68
+ # above. Skip when REPO_FLAGS is () (no sync = no branch).
69
+ if [ ${#REPO_FLAGS[@]} -gt 0 ]; then
70
+ HOST_BRANCH=$(git -C "$(pwd)" symbolic-ref --short HEAD)
71
+ case "$HOST_BRANCH" in main|master) ;; # ask user; not auto-resolvable
72
+ esac
73
+ fi
74
+
75
+ # 1. Create empty workspace, capture id
76
+ WS_ID=$(mb workspace create --name "$WS_NAME" --profile "$PARENT" --json | jq -r '.id')
77
+
78
+ # 2. Provision a database into it (blocks on :provisioned)
79
+ mb workspace database provision "$WS_ID" "$DB_ID" \
80
+ --schemas "$SCHEMAS" \
81
+ --wait \
82
+ --profile "$PARENT"
83
+
84
+ # 3. Start the child container, block on state=running.
85
+ # With REPO_FLAGS set, the child boots already wired to the local repo:
86
+ # bind-mounted at /mnt/repo, remote-sync-url=file:///mnt/repo, branch from HEAD.
87
+ mb workspace start "$WS_ID" --wait --profile "$PARENT" "${REPO_FLAGS[@]}"
88
+
89
+ # 4. Save the child's API key as its own profile (use the workspace name as profile name).
90
+ # This is the documented exception to "the agent doesn't run auth login" — the child
91
+ # key was minted by the parent the human authorized, and reading it via
92
+ # `workspace credentials` is the supported path.
93
+ WS_URL=$(mb workspace url "$WS_ID" --json | jq -r '.url')
94
+ WS_API_KEY=$(mb workspace credentials "$WS_ID" --json | jq -r '.api_key')
95
+ printf '%s' "$WS_API_KEY" | mb auth login \
96
+ --url "$WS_URL" \
97
+ --profile "$WS_NAME" \
98
+ --json
99
+
100
+ # 5. Smoke test: list child databases
101
+ mb database list --profile "$WS_NAME" --json
102
+
103
+ # 6. (If REPO_FLAGS was set) Verify sync is wired:
104
+ mb setting get remote-sync-url --profile "$WS_NAME" --json # → "file:///mnt/repo"
105
+ mb git-sync status --profile "$WS_NAME" --json # → branch, dirty, current task
106
+
107
+ # 7. (If REPO_FLAGS was set) Apply the repo to the fresh workspace. The container's
108
+ # boot-time auto-import usually handles this — the step-6 `git-sync status` shows
109
+ # whether it landed. If `current_task` is not a successful `import` for the host
110
+ # branch, run an explicit import. The status-check + retry-then-force guard lives
111
+ # in the git-sync skill, "First import on a fresh workspace". Skipping the import is
112
+ # *not* safe — without it the instance has none of the repo content and edits diverge.
113
+ ```
114
+
115
+ After step 5, drive the child via `mb <verb> --profile $WS_NAME` for everything (cards, transforms, queries, …). To author a transform on the workspace, load the `transform` skill (`mb skills get transform`). To use the sync flow (import host commits, export instance changes), load the `git-sync` skill (`mb skills get git-sync`).
116
+
117
+ ## Setup (steps in order)
118
+
119
+ ### 1. Parent profile
120
+
121
+ ```bash
122
+ mb auth status --profile <parent> --json
123
+ ```
124
+
125
+ If a profile is missing or expired, **stop and ask the operator** to run, themselves:
126
+
127
+ > Please run `mb auth login --url <parent-base-url> --profile <parent>` from your terminal and tell me the profile name when you're done.
128
+
129
+ Don't run `auth login` for them and don't suggest a URL — they pick. Verify with `mb auth status --profile <parent> --json` once they confirm. If multiple parent profiles exist and the user hasn't named one, use `AskUserQuestion` to disambiguate.
130
+
131
+ ### 2. License
132
+
133
+ ```bash
134
+ mb workspace license status --json
135
+ ```
136
+
137
+ If `present: false`, ask the operator to run, themselves:
138
+
139
+ ```bash
140
+ echo "<your-token>" | mb workspace license set
141
+ ```
142
+
143
+ A workspace child cannot start without a parent license — it inherits feature gates from the parent.
144
+
145
+ ### 3. Find or create a workspace
146
+
147
+ ```bash
148
+ mb workspace list --profile <parent> --json
149
+ ```
150
+
151
+ - Empty → create one (below).
152
+ - One workspace → use its `id`. Surface name + id to the user.
153
+ - Multiple → `AskUserQuestion`.
154
+
155
+ Create:
156
+
157
+ ```bash
158
+ mb workspace create --name "<descriptive-name>" --profile <parent> --json
159
+ ```
160
+
161
+ Note the returned `id`. The workspace is empty; you must provision at least one database before `start` will succeed.
162
+
163
+ ### 4. Provision databases
164
+
165
+ A workspace needs at least one provisioned database. Source databases come from the parent.
166
+
167
+ ```bash
168
+ mb database list --profile <parent> --json
169
+ ```
170
+
171
+ For each source database, decide which schemas to expose. Enumerate the schemas the parent already syncs for that database:
172
+
173
+ ```bash
174
+ mb table list --db-id <db-id> --profile <parent> --json \
175
+ | jq -r '[.data[].schema] | unique | .[]'
176
+ ```
177
+
178
+ Provision (one db per call; `--schemas` is required, no "all" wildcard):
179
+
180
+ ```bash
181
+ mb workspace database provision <ws-id> <db-id> \
182
+ --schemas <schema1>,<schema2> \
183
+ --wait \
184
+ --profile <parent>
185
+ ```
186
+
187
+ `--wait` blocks until status is `provisioned`. Repeat per source database.
188
+
189
+ Verify all are ready:
190
+
191
+ ```bash
192
+ mb workspace list --profile <parent> --full --json \
193
+ | jq '.data[] | select(.id==<ws-id>) | .databases'
194
+ ```
195
+
196
+ Every entry's `status` must be `provisioned`.
197
+
198
+ ## Start
199
+
200
+ Before running `start`, ask the user about Remote Sync (see "Always ask about Remote Sync before starting" at the top of this file). The bind mount is decided at container-create time and cannot be added later without recreate.
201
+
202
+ ### Pick a free port up front
203
+
204
+ Despite the `--port` flag's "auto-shifts up if taken" hint, in practice `workspace start` fails with `docker start failed for metabase-workspace-<id>` when the host port is occupied — typically by a stale workspace container from a prior session. **List local containers first** and pass an explicit free `--port`:
205
+
206
+ ```bash
207
+ mb workspace ps # → currently-running workspace containers + their host ports
208
+ docker ps --filter "name=metabase-workspace" \
209
+ --format "{{.Names}}\t{{.Ports}}\t{{.Status}}" # also surfaces stopped containers
210
+ ```
211
+
212
+ If 3000 is taken, pass e.g. `--port 3322`. The child's URL in `workspace credentials` and `workspace url` reflects the chosen port automatically.
213
+
214
+ ```bash
215
+ # No sync:
216
+ mb workspace start <ws-id> --wait --profile <parent>
217
+
218
+ # With sync against the current directory:
219
+ mb workspace start <ws-id> --repo "$(pwd)" --wait --profile <parent>
220
+
221
+ # With sync against a custom path, branch override, read-only:
222
+ mb workspace start <ws-id> --repo /path/to/repo --repo-branch dev --repo-mode read-only --wait --profile <parent>
223
+ ```
224
+
225
+ `--wait` blocks until `state: "running"`. Don't omit it for interactive bring-up — without it the next step (saving credentials as a child profile) races the container's HTTP listener and you'll get spurious connection errors.
226
+
227
+ - `--port <n>` — host port (default 3000; **does not** auto-shift reliably — pass an explicit free port if 3000 might be taken).
228
+ - `--wait` — block until `/api/health` reports ready before returning.
229
+ - `--no-pull` — skip `docker pull` (image already present).
230
+ - `--no-metadata` — skip the warehouse metadata export.
231
+ - `--force` — recreate even if a container for this workspace exists. Preserves the app db.
232
+ - `--timeout <ms>` — per-phase readiness deadline (default 240000). Covers the post-create config-consumption wait, (with `--wait`) the `/api/health` probe, and (with `--metadata`) the metadata-import status poll on the child. Bump if the first cold boot exceeds the default — image pull + JVM startup can stretch on slow disks/networks.
233
+ - `--repo <host-path>` — bind-mount a host directory at `/mnt/repo` and inject `remote-sync-url=file:///mnt/repo` into config.yml.
234
+ - `--repo-branch <name>` — `remote-sync-branch` value. Default: current branch of the host repo (`git symbolic-ref --short HEAD`).
235
+ - `--repo-mode <mode>` — `read-write` (default) or `read-only`. Also flips the bind mount's mount mode.
236
+
237
+ **Notes on `--repo`:**
238
+
239
+ - `--repo` is honored only on container create. To change the mount on an existing container you must `start --force` (which recreates), passing `--repo` again. The app db volume persists, so users/sessions/saved questions survive.
240
+ - The host path must be a directory and must already exist. The CLI does not create or initialize a git repo for you.
241
+ - For `--repo-branch` auto-detection, the path needs to be a git repo (a `.git/` ancestor); otherwise pass `--repo-branch` explicitly.
242
+ - The `--repo-branch` value must name a branch that already exists **locally** in the host repo. Local-only branches (never pushed to `origin`) are fine — the workspace operates against the bind-mounted working tree, never pushes anywhere itself, and the remote side is created on the user's first `git push` later. If the branch doesn't exist locally yet, create it before `workspace start`: `git -C <repo-path> branch <name>` (or `checkout -b <name>` if you also want to switch HEAD).
243
+ - File-permission gotcha (Linux only): the Metabase container runs as uid 2000 by default; the host directory must be writable by that uid for `git-sync export` to succeed. macOS Docker Desktop / OrbStack / Colima handle this via their file-sharing layer.
244
+
245
+ ## Interact with a running workspace
246
+
247
+ `url` and `credentials` both return JSON envelopes. Extract fields with `jq`:
248
+
249
+ ```bash
250
+ mb workspace url <ws-id> --json
251
+ # → {"workspace_id": ..., "url": "http://localhost:3000"}
252
+
253
+ mb workspace credentials <ws-id> --json
254
+ # → {"email": ..., "password": ..., "api_key": ...}
255
+ ```
256
+
257
+ Save the child's API key as its own named profile. **Always pipe the key on stdin** (the CLI rejects `--api-key "$VAR"`).
258
+
259
+ ```bash
260
+ WS_URL=$(mb workspace url <ws-id> --json | jq -r '.url')
261
+ WS_API_KEY=$(mb workspace credentials <ws-id> --json | jq -r '.api_key')
262
+ printf '%s' "$WS_API_KEY" | mb auth login \
263
+ --url "$WS_URL" \
264
+ --profile <ws-name> \
265
+ --json
266
+ ```
267
+
268
+ Convention: use the workspace name as the profile name (`my_nice_ws` workspace → `my_nice_ws` profile). Then drive the child with the same CLI verbs:
269
+
270
+ ```bash
271
+ mb database list --profile <ws-name> --json
272
+ mb card list --profile <ws-name> --json
273
+ mb transform list --profile <ws-name> --json
274
+ ```
275
+
276
+ To create and run a transform in the workspace, load the `transform` skill. The `<db-id-in-child>` referenced there comes from `mb database list --profile <ws-name> --json` — the child re-numbers databases independently of the parent.
277
+
278
+ ## Open the UI
279
+
280
+ ```
281
+ http://localhost:<port> # default 3000; honors `--port` from `workspace start`
282
+ http://localhost:<port>/admin/transforms/<transform-id>
283
+ ```
284
+
285
+ Log in with the **admin email + password** from `workspace credentials` (the API key authenticates as a synthetic api-key user, not as the admin — many UI screens hide content from the api-key user).
286
+
287
+ **Don't open the URL before `state: "running"`** — the Metabase setup wizard will hijack it and create a fresh app db, bypassing the workspace bring-up.
288
+
289
+ ## Lifecycle
290
+
291
+ | User intent | Command |
292
+ | --------------------------------- | -------------------------------------------------------------- |
293
+ | List local workspace containers | `mb workspace ps` |
294
+ | Tail logs | `mb workspace logs <ws-id> --tail 200` |
295
+ | Follow logs | `mb workspace logs <ws-id> --follow` |
296
+ | Read admin email/password/API key | `mb workspace credentials <ws-id> --json` |
297
+ | Stop (preserves app db) | `mb workspace stop <ws-id>` |
298
+ | Restart | `mb workspace start <ws-id> --force --wait --profile <parent>` |
299
+ | Remove container + app db | `mb workspace delete <ws-id> --yes` |
300
+ | Remove container, keep app db | `mb workspace delete <ws-id> --keep-volume --yes` |
301
+
302
+ The supported restart path is `stop` + `start --force` (or `start --force` directly). The app db volume persists across `stop`/`start` cycles, so users/sessions/saved questions survive. `delete`, `start --force`, and `stop` are destructive enough to confirm before running unless the user explicitly asked for them.
303
+
304
+ ## Diagnose
305
+
306
+ Pick the symptom.
307
+
308
+ ### `start` succeeds but the database isn't visible in the UI
309
+
310
+ ```bash
311
+ mb workspace logs <ws-id> --tail 300 | grep -iE "advanced-config|workspace|error"
312
+ ```
313
+
314
+ | Log signal | Cause | Fix |
315
+ | ---------------------------------------------------------------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
316
+ | `Spec assertion failed ... :input ... :output` | Parent emits keys the child's spec doesn't accept (server-side). | File against the parent. Not a CLI issue. |
317
+ | `Connection refused` / `unknown host` against the warehouse host | Container can't reach the source DB. | Source DB credentials configured on the parent use a host that doesn't resolve from inside docker. Use a routable hostname. |
318
+ | `Invalid token` / `License expired` | EE license bad or unset on the parent (forwarded into the child). | Re-set on the parent: `mb workspace license set` (operator pastes). |
319
+
320
+ ### `workspace credentials` returns values that don't authenticate
321
+
322
+ Symptom: right after `workspace start`, the API key returned by `mb workspace credentials <ws-id>` is rejected by the child (`Unauthenticated` on `/api/user/current`, or `Invalid or unauthorized API key` from `mb auth login --skip-verify` followed by any verb). The admin password from the same response also fails (`did not match stored password`). The values inside the container's `/mw-config/credentials.json` match what the parent reports, but the child's app db has different state.
323
+
324
+ This is a parent↔child credential drift bug — the parent's record for the workspace can desync from the child's app db, especially after a rapid `start` → `start --force` sequence on the same port. **`start --force` alone does not fix it** (the volume persists across the recreate; the api-key already exists from the prior init and the new credentials.json is ignored).
325
+
326
+ Recovery (works reliably):
327
+
328
+ ```bash
329
+ mb workspace delete <ws-id> --yes # destroys container + volume; keeps parent record + provisioned dbs
330
+ mb workspace start <ws-id> --port <fresh-port> --wait --profile <parent> # different port from the bad attempt
331
+ mb workspace credentials <ws-id> --json | jq -r '.api_key' \
332
+ | xargs -I{} curl -s -H "x-api-key: {}" http://localhost:<fresh-port>/api/user/current # smoke check
333
+ ```
334
+
335
+ Why "different port": empirically, restarting on the same port after the drifted attempt can cling to the same broken state; switching ports forces a clean parent-side handoff. If you must reuse the original port, `workspace delete --yes` plus a brief pause (a few seconds) before `start` increases the success rate.
336
+
337
+ `workspace delete --yes` is destructive — it drops the container _and_ the app db volume — but in the bring-up window (before any user content has been imported) there's nothing to lose. The provisioned-database records on the parent survive the delete and don't need to be re-created.
338
+
339
+ ### Container exited shortly after `start`
340
+
341
+ ```bash
342
+ mb workspace ps
343
+ ```
344
+
345
+ `Exited (137)` → OOM. Bump Docker host memory to ≥ 6 GB.
346
+
347
+ - Colima: `colima stop && colima start --memory 6 --cpu 2`
348
+ - Docker Desktop: Settings → Resources → Memory.
349
+
350
+ Then `mb workspace start <ws-id> --force --wait --profile <parent>`.
351
+
352
+ ### `Endpoint not found — is this a Metabase instance?`
353
+
354
+ The parent doesn't expose `/api/ee/workspace-manager/*`. Either:
355
+
356
+ - Parent is OSS (no EE).
357
+ - Parent has no license, or license lacks the workspace feature.
358
+ - Parent is on a Metabase version that predates workspaces.
359
+
360
+ Confirm the URL points at the right instance with `mb auth status --profile <parent> --json`. If the URL is correct, the parent simply lacks the workspace feature — pick a different instance.
361
+
362
+ ### `workspace has no databases — provision at least one before starting`
363
+
364
+ `mb workspace list --profile <parent> --full --json` will show the workspace with `databases: []`. Run a `provision` (step 4) and retry.
365
+
366
+ ### `workspace ... is not ready: database X=provisioning`
367
+
368
+ Provisioning is async on the parent. Re-run the original `provision` with `--wait`, or poll:
369
+
370
+ ```bash
371
+ mb workspace list --profile <parent> --full --json \
372
+ | jq '.data[] | select(.id==<ws-id>) | .databases[] | {database_id, status}'
373
+ ```
374
+
375
+ ### Workspace UI demands the setup wizard
376
+
377
+ You opened the URL before health passed and walked through the wizard, which created a fresh app db and bypassed the workspace bring-up. `mb workspace delete <ws-id> --yes` then `start --wait` again. Don't open the URL before `state: "running"`.
378
+
379
+ ### `git status` on the host shows confusing "staged changes" after `git-sync export`
380
+
381
+ The in-container exporter writes the new commit object directly into the bind-mounted `.git/` and advances HEAD, but does not update the host's working tree or index. The host then shows the export's content as "Changes to be committed" reverting to the prior commit — display artifact, not a real revert. The non-destructive realignment is `git -C <repo> restore --staged --worktree .` (only touches paths that disagree with HEAD; refuses on unmerged paths; does not move HEAD). See the `git-sync` skill, "Working-tree drift on `--repo` bind-mount workspaces" for the full decision tree (when to stash first, when `reset --hard` is acceptable).
382
+
383
+ ## Don't (workspace-specific)
384
+
385
+ - Don't run raw `docker` commands against the workspace container — use the `mb workspace` subcommands. They wrap the right labels, volumes, network, and lifecycle hooks.
386
+ - Don't open the workspace URL before `state: "running"` — the setup wizard will hijack it.
387
+ - Don't try to share an API key across workspaces — each child mints its own. Save credentials per-workspace under a profile named after the workspace.
388
+ - Don't write the workspace's isolation schema (`mb__isolation_<hash>_<ws-id>`) into transform/card SQL or `target.schema`. Author against the **canonical** schema (e.g. `public`); the QP rewrites at execution time. Hard-coding the isolation prefix breaks portability across workspaces and bypasses the rewrite contract.
389
+ - Don't run `workspace start` without first asking the user about Remote Sync (current dir / custom path / no sync). The bind mount is set at create time; "I'll add it after start" is not supported.
390
+ - Don't run `workspace start --repo <path>` when the host repo is on `main`/`master` without first asking the user (see "Branch guard before `--repo`"). The host's HEAD becomes the workspace's `remote-sync-branch`, so every subsequent export targets `main` by default.
@@ -0,0 +1,21 @@
1
+ ---
2
+ name: metabase-cli
3
+ description: Drive a Metabase instance from the terminal via the `mb` CLI — auth, databases, cards, dashboards, transforms, queries, search, git-sync, Enterprise workspaces. Discovery entry; load the full guide with `mb skills get core`.
4
+ allowed-tools: Bash, Read, Write, Edit, AskUserQuestion
5
+ hidden: true
6
+ ---
7
+
8
+ # metabase-cli
9
+
10
+ The official Metabase CLI (`mb`) drives a Metabase instance over its REST API.
11
+
12
+ Install: `npm i -g @metabase/cli`
13
+
14
+ ## Start here
15
+
16
+ Before running any `mb` command, load the workflow content from the CLI:
17
+
18
+ ```bash
19
+ mb skills get core # auth, flag conventions, every command group
20
+ mb skills list # everything available on the installed version
21
+ ```
@@ -1,11 +0,0 @@
1
- import "./package-D-aVYFKM.mjs";
2
- import "./command-augment-D9pI9Vbh.mjs";
3
- import "./render-DuoDUTVL.mjs";
4
- import "./predicates-CGO17Q15.mjs";
5
- import "./runtime-Br8L4NPm.mjs";
6
- import "./parse-id-B3B-0hUA.mjs";
7
- import "./poll-task-0b1V6G-8.mjs";
8
- import "./poll-BCnrcUVf.mjs";
9
- import { SyncSettingsUpdateResult, add_collection_default, setCollectionRemoteSynced, syncSettingsUpdateView } from "./add-collection-CffaBB-Y.mjs";
10
-
11
- export { add_collection_default as default };
@@ -1,13 +0,0 @@
1
- import { defineCommand } from "citty";
2
-
3
- //#region src/commands/api-key/index.ts
4
- var api_key_default = defineCommand({
5
- meta: {
6
- name: "api-key",
7
- description: "Manage Metabase API keys"
8
- },
9
- subCommands: { create: () => import("./create-ov-De5dO.mjs").then((mod) => mod.default) }
10
- });
11
-
12
- //#endregion
13
- export { api_key_default as default };
@@ -1,19 +0,0 @@
1
- import { defineCommand } from "citty";
2
-
3
- //#region src/commands/auth/index.ts
4
- var auth_default = defineCommand({
5
- meta: {
6
- name: "auth",
7
- description: "Authenticate against a Metabase instance"
8
- },
9
- default: "login",
10
- subCommands: {
11
- login: () => import("./login-SXsSH0I1.mjs").then((m) => m.default),
12
- status: () => import("./status-BWep0PFe.mjs").then((m) => m.default),
13
- list: () => import("./list-BNzdnE1c.mjs").then((m) => m.default),
14
- logout: () => import("./logout-bgOXjxbN.mjs").then((m) => m.default)
15
- }
16
- });
17
-
18
- //#endregion
19
- export { auth_default as default };
@@ -1,20 +0,0 @@
1
- import { defineCommand } from "citty";
2
-
3
- //#region src/commands/card/index.ts
4
- var card_default = defineCommand({
5
- meta: {
6
- name: "card",
7
- description: "Manage Metabase cards (questions, models, metrics)"
8
- },
9
- subCommands: {
10
- list: () => import("./list-xQmtQPSl.mjs").then((mod) => mod.default),
11
- get: () => import("./get-BOtKerj8.mjs").then((mod) => mod.default),
12
- query: () => import("./query-DxA353Hy.mjs").then((mod) => mod.default),
13
- create: () => import("./create-doyv3SxU.mjs").then((mod) => mod.default),
14
- update: () => import("./update-djgvzO3K.mjs").then((mod) => mod.default),
15
- archive: () => import("./archive-uJrslh9r.mjs").then((mod) => mod.default)
16
- }
17
- });
18
-
19
- //#endregion
20
- export { card_default as default };
@@ -1,19 +0,0 @@
1
- import { defineCommand } from "citty";
2
-
3
- //#region src/commands/collection/index.ts
4
- var collection_default = defineCommand({
5
- meta: {
6
- name: "collection",
7
- description: "Browse Metabase collections"
8
- },
9
- subCommands: {
10
- list: () => import("./list-DhWG5jiW.mjs").then((mod) => mod.default),
11
- get: () => import("./get-C_6K7MSW.mjs").then((mod) => mod.default),
12
- items: () => import("./items-CTcAMknV.mjs").then((mod) => mod.default),
13
- tree: () => import("./tree-DazZT7dR.mjs").then((mod) => mod.default),
14
- create: () => import("./create-izE3EKCt.mjs").then((mod) => mod.default)
15
- }
16
- });
17
-
18
- //#endregion
19
- export { collection_default as default };
@@ -1,11 +0,0 @@
1
- //#region src/runtime/command-augment.ts
2
- const augments = new WeakMap();
3
- function setMetabaseAugment(cmd, augment) {
4
- augments.set(cmd, augment);
5
- }
6
- function getMetabaseAugment(cmd) {
7
- return augments.get(cmd) ?? null;
8
- }
9
-
10
- //#endregion
11
- export { getMetabaseAugment, setMetabaseAugment };
@@ -1,50 +0,0 @@
1
- import "./package-D-aVYFKM.mjs";
2
- import "./command-augment-D9pI9Vbh.mjs";
3
- import { renderItem } from "./render-DuoDUTVL.mjs";
4
- import "./predicates-CGO17Q15.mjs";
5
- import "./input-BQ-BZA8h.mjs";
6
- import { connectionFlags, defineMetabaseCommand, outputFlags, profileFlag } from "./runtime-Br8L4NPm.mjs";
7
- import { readBody } from "./body-D6dHGjMT.mjs";
8
- import { bodyInputFlags } from "./body-flags-BK7J6Daz.mjs";
9
- import "./field-B3gvaqpK.mjs";
10
- import { Card, CardCreateInput, cardView } from "./card-CQxvHeyP.mjs";
11
- import "./validate-CB0bu50i.mjs";
12
- import { CARD_DATASET_QUERY_LABELS, preflightMbql5Query, skipValidateFlag } from "./validate-query-CavIA0Q2.mjs";
13
-
14
- //#region src/commands/card/create.ts
15
- var create_default = defineMetabaseCommand({
16
- meta: {
17
- name: "create",
18
- description: "Create a card from a JSON spec; if dataset_query is MBQL 5 (lib/type: mbql/query) it is pre-flight-validated against the same schema as `mb query` (see `mb query --print-schema`)"
19
- },
20
- args: {
21
- ...outputFlags,
22
- ...profileFlag,
23
- ...connectionFlags,
24
- ...bodyInputFlags,
25
- ...skipValidateFlag
26
- },
27
- outputSchema: Card,
28
- examples: [
29
- "cat card.json | mb card create",
30
- "mb card create --file card.json",
31
- "mb card create --body '{\"name\":\"x\",\"display\":\"table\",\"dataset_query\":{...},\"visualization_settings\":{}}'",
32
- "mb card create --file card.json --skip-validate"
33
- ],
34
- async run({ args, ctx, getClient }) {
35
- const body = await readBody({
36
- flag: args.body,
37
- file: args.file
38
- }, CardCreateInput);
39
- preflightMbql5Query(body.dataset_query, CARD_DATASET_QUERY_LABELS, { skip: args["skip-validate"] === true });
40
- const client = await getClient();
41
- const created = await client.requestParsed(Card, "/api/card", {
42
- method: "POST",
43
- body
44
- });
45
- renderItem(created, cardView, ctx);
46
- }
47
- });
48
-
49
- //#endregion
50
- export { create_default as default };