@metabase/cli 0.1.15 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -32
- package/dist/add-collection-BqfYL4FU.mjs +10 -0
- package/dist/{add-collection-CXhrMjXU.mjs → add-collection-H4LcP-9B.mjs} +4 -4
- package/dist/{archive-Drt-rWvU.mjs → archive-B3cjzOIK.mjs} +5 -5
- package/dist/{archive-BUwiCFnd.mjs → archive-BCXoM1nX.mjs} +3 -3
- package/dist/{archive-BxGSR7El.mjs → archive-C6MDtV1F.mjs} +3 -3
- package/dist/{archive-D-Ovk0-E.mjs → archive-CQQWkC5S.mjs} +4 -4
- package/dist/{archive-yTvDRQUZ.mjs → archive-CdUS-OG9.mjs} +3 -3
- package/dist/{archive-Blc1dz8Z.mjs → archive-D1mfiftv.mjs} +5 -5
- package/dist/{archive-CQiaCBSj.mjs → archive-hN8PfvhX.mjs} +3 -3
- package/dist/auth-BaCMFLTA.mjs +19 -0
- package/dist/{body-B9XTTDEu.mjs → body-DB2upz6a.mjs} +1 -1
- package/dist/{branches-Ct3PK5U3.mjs → branches-B6R60Vr1.mjs} +4 -4
- package/dist/{cancel-tST8Bh0w.mjs → cancel-oPsWomYc.mjs} +3 -3
- package/dist/{cancel-task-BHnzRQKL.mjs → cancel-task-CleJVDNI.mjs} +4 -4
- package/dist/card-DzH3aK0a.mjs +20 -0
- package/dist/{cards-BySIFsLG.mjs → cards-Bw37jizL.mjs} +3 -3
- package/dist/cli.mjs +26 -25
- package/dist/collection-Wagz-ira.mjs +20 -0
- package/dist/{collection-namespace-D8ohM5gD.mjs → collection-namespace-CUDPh2rF.mjs} +1 -1
- package/dist/{create-4mAGsBd0.mjs → create-B-mvVFIl.mjs} +3 -3
- package/dist/{create-DxDD6n1d.mjs → create-B87ZQjNM.mjs} +5 -5
- package/dist/{create-D3cVDtxM.mjs → create-BEkuqChu.mjs} +4 -4
- package/dist/{create-HZ-9GMLx.mjs → create-Bj6PuaAW.mjs} +4 -4
- package/dist/{create-C7FPeJqF.mjs → create-CF2Zn4pT.mjs} +3 -3
- package/dist/create-CZ0_s5ap.mjs +34 -0
- package/dist/{create-fIDFkdox.mjs → create-CfLaBO0V.mjs} +4 -4
- package/dist/{create-DGxZmbxh.mjs → create-Cy2TNnJB.mjs} +4 -4
- package/dist/{create-DnT1Sayk.mjs → create-D-qE3Oq8.mjs} +3 -3
- package/dist/{create-C43RQYgj.mjs → create-DSWjS09p.mjs} +4 -4
- package/dist/{create-BDWthCYq.mjs → create-DwoqFYb9.mjs} +4 -4
- package/dist/{create-branch-jPE7nW-E.mjs → create-branch-BaZ00MIc.mjs} +4 -4
- package/dist/{current-task-rW54KJax.mjs → current-task-Dr5dOD4V.mjs} +4 -4
- package/dist/dashboard-OUgS1Gi-.mjs +21 -0
- package/dist/{database-BmsxuRmO.mjs → database-BJxGUXhA.mjs} +1 -1
- package/dist/db-Btfl5JMZ.mjs +22 -0
- package/dist/{delete-BWO6uB4P.mjs → delete-DHrFA1SZ.mjs} +4 -4
- package/dist/{delete-CBwztF6P.mjs → delete-DJti0TOA.mjs} +4 -4
- package/dist/{delete-CeigtfRI.mjs → delete-evwMw6Hk.mjs} +4 -4
- package/dist/{delete-table-BXzvDEPG.mjs → delete-table-DvuuwVqu.mjs} +4 -4
- package/dist/{dependencies-D2N9eqm1.mjs → dependencies-DrV31Rj5.mjs} +4 -4
- package/dist/{dirty-DoEZRSGB.mjs → dirty-C-rkrnVM.mjs} +4 -4
- package/dist/document-CU28GfFw.mjs +19 -0
- package/dist/{eid-1mROiwJr.mjs → eid-BeXI-eII.mjs} +3 -3
- package/dist/{error-D5bZ5BUX.mjs → error-CIObEXLY.mjs} +1 -1
- package/dist/{export-Bgv5B4_F.mjs → export-CGa-SgEV.mjs} +6 -6
- package/dist/field-BTbzlcyC.mjs +18 -0
- package/dist/{fields-VA7tXHJz.mjs → fields-Recymu7n.mjs} +4 -4
- package/dist/{get-C-UeGtgW.mjs → get-7fWSU6ow.mjs} +3 -3
- package/dist/{get-DvQoDU2m.mjs → get-BAH_M5vj.mjs} +4 -4
- package/dist/{get-BtAD26gc.mjs → get-BD_P_Ejc.mjs} +3 -3
- package/dist/{get-CqnCaosn.mjs → get-BM-d3-zk.mjs} +4 -4
- package/dist/{get-B8etVxWD.mjs → get-BQxLtFE-.mjs} +4 -4
- package/dist/{get-DLRBq8kR.mjs → get-C6g2C4dM.mjs} +4 -4
- package/dist/{get-D9o38nK5.mjs → get-CARdLkmp.mjs} +4 -4
- package/dist/{get-CGkhSY5L.mjs → get-CHi8tU_1.mjs} +5 -5
- package/dist/{get-Wj88mnhn.mjs → get-CXMv-r1p.mjs} +3 -3
- package/dist/{get-RQFSmnpY.mjs → get-CYh2DBsq.mjs} +3 -3
- package/dist/{get-BgIE_YEg.mjs → get-DaixPDU9.mjs} +4 -4
- package/dist/{get-qnGGGRTa.mjs → get-Nc5GOs6-.mjs} +3 -3
- package/dist/{get-eUYDNALt.mjs → get-Q2WZ79q_.mjs} +4 -4
- package/dist/get-b4xbfFbA.mjs +35 -0
- package/dist/{get-DAsaor0n.mjs → get-rFcAVIch.mjs} +2 -2
- package/dist/{get-run-CATz-XMS.mjs → get-run-CfQR6ZNa.mjs} +4 -4
- package/dist/git-sync-CBxS2urR.mjs +28 -0
- package/dist/{has-remote-changes-B6YEMC90.mjs → has-remote-changes-Bvyv4FLP.mjs} +4 -4
- package/dist/{import-Bl2Wj9Xf.mjs → import-c3o3OAx0.mjs} +6 -6
- package/dist/{is-dirty-D9MoFj0T.mjs → is-dirty-BE53XwOC.mjs} +3 -3
- package/dist/is-dirty-Z-pqyVyB.mjs +9 -0
- package/dist/{items-LjtICjvX.mjs → items-1KkBMiO4.mjs} +3 -3
- package/dist/library-BlbH0xyK.mjs +18 -0
- package/dist/{list-DMik04Dh.mjs → list-7rwzxX6t.mjs} +3 -3
- package/dist/{list-B5Q7E2Km.mjs → list-BC2B02IR.mjs} +3 -3
- package/dist/{list-DcjenlTM.mjs → list-BqgbrpQQ.mjs} +3 -3
- package/dist/list-BwdO1_gX.mjs +99 -0
- package/dist/{list-ChK06rJh.mjs → list-C4KnM3Rq.mjs} +2 -2
- package/dist/{list-Dq86BAMG.mjs → list-CO5J3SZU.mjs} +4 -4
- package/dist/{list-cnqPlJgC.mjs → list-CSjFJDls.mjs} +3 -3
- package/dist/{list-C410Ptw_.mjs → list-D52_BozQ.mjs} +2 -2
- package/dist/{list-DfoNv0gb.mjs → list-DHb4vQUM.mjs} +3 -3
- package/dist/{list-DtrfE0sF.mjs → list-DIvOPW1g.mjs} +4 -4
- package/dist/{list-DaJk60dd.mjs → list-DPcPTqFU.mjs} +3 -3
- package/dist/{list-Bjp9nd0o.mjs → list-DUEYX3bX.mjs} +2 -2
- package/dist/{list-CoRX8Ruc.mjs → list-Drr4JiWg.mjs} +3 -3
- package/dist/{list-CfWblVHJ.mjs → list-F0vkE22V.mjs} +2 -2
- package/dist/{list-C6U3Ftg8.mjs → list-FR8Q1SzV.mjs} +3 -3
- package/dist/{login-Cn2UtFUt.mjs → login-C0Rf2hg0.mjs} +3 -3
- package/dist/{logout-_HXgEmqA.mjs → logout-C7_UON-s.mjs} +2 -2
- package/dist/measure-BUedPu4K.mjs +19 -0
- package/dist/{metadata-8yqT8OZI.mjs → metadata-Db3Kpo-z.mjs} +5 -5
- package/dist/{metadata-DHODjg1d.mjs → metadata-FltZq5Ek.mjs} +4 -4
- package/dist/{parse-id-DNPeV0Iu.mjs → parse-id-B5adfBlS.mjs} +1 -1
- package/dist/{path-BflajM08.mjs → path-BojuJkE4.mjs} +3 -3
- package/dist/{poll-CYkX02Bm.mjs → poll-AduuU55-.mjs} +1 -1
- package/dist/{poll-task-oXpl3wzp.mjs → poll-task-B00Qwd87.mjs} +2 -2
- package/dist/{preflight-BdJr2amA.mjs → preflight-QVPvG_Xg.mjs} +1 -1
- package/dist/publish-h5RJh6im.mjs +66 -0
- package/dist/{query-DWQaN7hO.mjs → query-BUkuB4bZ.mjs} +3 -3
- package/dist/{query-CxTjguwp.mjs → query-Dvi-Rksy.mjs} +3 -3
- package/dist/{remove-collection-BwcFi8Fs.mjs → remove-collection-D8ZfB2RN.mjs} +6 -6
- package/dist/{rescan-values-B9Qtsd32.mjs → rescan-values-DOsDLrRG.mjs} +5 -5
- package/dist/resolve-BQ9vjlNJ.mjs +84 -0
- package/dist/{run-C-vftXCu.mjs → run-CeG0KH5W.mjs} +3 -3
- package/dist/{run-3eFtdI2Z.mjs → run-CjhD-Zbr.mjs} +6 -6
- package/dist/{runs-CpRTkn1W.mjs → runs-6k8C6kXF.mjs} +4 -4
- package/dist/{runtime-C1QgWHM7.mjs → runtime-CmAIahm5.mjs} +1 -1
- package/dist/{schema-tables-rdeupgsu.mjs → schema-tables-C45QegaY.mjs} +4 -4
- package/dist/{schemas-Cr7RjYqV.mjs → schemas-EVwEFuTj.mjs} +3 -3
- package/dist/{search-D7Yq2MDu.mjs → search-C_uw_D1U.mjs} +3 -3
- package/dist/segment-CkZUZcWz.mjs +19 -0
- package/dist/{selectors-DPc2ZDdd.mjs → selectors-AktxTEMK.mjs} +3 -3
- package/dist/{set-X2N6x7pe.mjs → set-C3EAuyb8.mjs} +5 -5
- package/dist/{set-active-BoBa3pOw.mjs → set-active-BW6LN6y0.mjs} +2 -2
- package/dist/{setting-zZjcOPyE.mjs → setting-C50HEiGG.mjs} +3 -3
- package/dist/{setup-C47WUieB.mjs → setup-CYrbNrlG.mjs} +3 -3
- package/dist/{skills-Po0YPVU5.mjs → skills-D6xQkmhu.mjs} +3 -3
- package/dist/snippet-BjaWAxCu.mjs +19 -0
- package/dist/{stash-BV4sEp73.mjs → stash-C1V2FvJR.mjs} +6 -6
- package/dist/{status-BKF9rRnk.mjs → status-CxYw6zQM.mjs} +5 -5
- package/dist/{status-Cf8c0NON.mjs → status-DY92F9mn.mjs} +2 -2
- package/dist/{summary-RgLcBcEh.mjs → summary-DOxgqJoA.mjs} +3 -3
- package/dist/{sync-schema-DKEel2Sv.mjs → sync-schema-CQPfffjU.mjs} +7 -7
- package/dist/table-B35ovbcd.mjs +19 -0
- package/dist/{table-qDD2kApF.mjs → table-CDMG0Zi5.mjs} +8 -1
- package/dist/transform-DF79sJ0_.mjs +25 -0
- package/dist/transform-job-PmA_D8gz.mjs +22 -0
- package/dist/transform-tag-CE3cuO1K.mjs +18 -0
- package/dist/{transforms-BOQ9CG0l.mjs → transforms-DzBJDydn.mjs} +4 -4
- package/dist/{tree-CF8mscd9.mjs → tree-B3f5F_dP.mjs} +2 -2
- package/dist/{unpublish-CmaRNjK3.mjs → unpublish-B5RDeN-V.mjs} +17 -16
- package/dist/{update-DR4WkAET.mjs → update-BIZ9XhjS.mjs} +5 -5
- package/dist/{update-nwXgVNQa.mjs → update-C0pFSc1B.mjs} +6 -6
- package/dist/{update-DoQpy9SA.mjs → update-CcvDVqNd.mjs} +4 -4
- package/dist/{update-BuypOaXq.mjs → update-CiWPEqQ-.mjs} +5 -5
- package/dist/{update-CgQOSuZt.mjs → update-D5gioyBa.mjs} +4 -4
- package/dist/{update-B59h7KmS.mjs → update-D698CaeV.mjs} +5 -5
- package/dist/{update-DERsb0eO.mjs → update-DOfL_KPx.mjs} +5 -5
- package/dist/{update-Kz4kyqY_.mjs → update-DSueNZRw.mjs} +5 -5
- package/dist/{update-DQPg0_-d.mjs → update-DudyZ-FP.mjs} +5 -5
- package/dist/{update-rhfPHALN.mjs → update-I3TA2Tem.mjs} +4 -4
- package/dist/{update-BXZBEeUp.mjs → update-PZPNx0Xd.mjs} +5 -5
- package/dist/{update-dashcard-BJVeSGvO.mjs → update-dashcard-BXZ4vS15.mjs} +4 -4
- package/dist/{upgrade-CNrkJF6s.mjs → upgrade-4cWfLu90.mjs} +2 -2
- package/dist/{uuid-Dpl3ALKq.mjs → uuid---pAboNQ.mjs} +2 -2
- package/dist/{values-DMYpkoEH.mjs → values-I503dI7K.mjs} +3 -3
- package/dist/{verify-By9ZYzx4.mjs → verify-BMhTWW9s.mjs} +1 -1
- package/dist/{wait-flags-DQrxnlwv.mjs → wait-flags-HtCL2l1r.mjs} +2 -2
- package/dist/{wait-BzIAj8lJ.mjs → wait-oMSs_IdS.mjs} +5 -5
- package/package.json +1 -1
- package/skill-data/core/SKILL.md +2 -2
- package/skill-data/data-transformation/SKILL.md +35 -28
- package/skill-data/semantic-layer/SKILL.md +5 -0
- package/dist/add-collection-Bnuh0d4j.mjs +0 -10
- package/dist/auth-Bkue4Psy.mjs +0 -19
- package/dist/card-faWo9ZWU.mjs +0 -20
- package/dist/collection-DcRz7fmf.mjs +0 -20
- package/dist/dashboard-pXAxJTTx.mjs +0 -21
- package/dist/db-CmHHj5eI.mjs +0 -22
- package/dist/document-DQIhL75C.mjs +0 -19
- package/dist/field-B-UcqFzm.mjs +0 -18
- package/dist/git-sync-CwOvcUI2.mjs +0 -28
- package/dist/is-dirty-MT0BT4CS.mjs +0 -9
- package/dist/list-Cx8JxS2C.mjs +0 -42
- package/dist/measure-BIAoqgcS.mjs +0 -19
- package/dist/publish-CGUkIqSm.mjs +0 -70
- package/dist/segment-BN8sFunv.mjs +0 -19
- package/dist/snippet-DK0ZA8m5.mjs +0 -19
- package/dist/table-COAKXNuj.mjs +0 -21
- package/dist/transform-Bto4U82j.mjs +0 -25
- package/dist/transform-job-_fW1y2tg.mjs +0 -22
- package/dist/transform-tag-C8n1oTr1.mjs +0 -18
- /package/dist/{delete-runtime-PzLFavb0.mjs → delete-runtime-CZMw_AGX.mjs} +0 -0
- /package/dist/{key-C8q5oIr5.mjs → key-DwiMOWRQ.mjs} +0 -0
- /package/dist/{manifest-DYeLri80.mjs → manifest-B2F8iL7X.mjs} +0 -0
- /package/dist/{measure-JJAdFoqK.mjs → measure-BCv5wDDN.mjs} +0 -0
- /package/dist/{revision-message-flag-C7zBeWEt.mjs → revision-message-flag-CP5NFrWQ.mjs} +0 -0
- /package/dist/{segment-B9SEv9V_.mjs → segment-BAUuELKs.mjs} +0 -0
- /package/dist/{setting-i0pugNHl.mjs → setting-DhMk0TNo.mjs} +0 -0
- /package/dist/{skills-CJ8g8fhQ.mjs → skills-DJsuBguh.mjs} +0 -0
- /package/dist/{snippet-NNzqlksR.mjs → snippet-D4SyVLKB.mjs} +0 -0
- /package/dist/{transform-n376akp8.mjs → transform-MmqHKGU-.mjs} +0 -0
- /package/dist/{transform-job-C8lIS-7Q.mjs → transform-job-CtVziW85.mjs} +0 -0
- /package/dist/{transform-tag-DB46AhAj.mjs → transform-tag-wFiWmiyO.mjs} +0 -0
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { renderSummary } from "./capabilities-BX1rnVuH.mjs";
|
|
5
5
|
import "./input-BXWgdKiS.mjs";
|
|
6
|
-
import { parseId } from "./parse-id-
|
|
7
|
-
import { readBody } from "./body-
|
|
6
|
+
import { parseId } from "./parse-id-B5adfBlS.mjs";
|
|
7
|
+
import { readBody } from "./body-DB2upz6a.mjs";
|
|
8
8
|
import { bodyInputFlags } from "./body-flags-D7q87Btw.mjs";
|
|
9
9
|
import "./validate-VawhJ5Sc.mjs";
|
|
10
10
|
import { SEGMENT_DEFINITION_LABELS, preflightMbql5Query, skipValidateFlag } from "./validate-query-CSV-TTnd.mjs";
|
|
11
|
-
import { Segment, SegmentUpdateInput, segmentView } from "./segment-
|
|
11
|
+
import { Segment, SegmentUpdateInput, segmentView } from "./segment-BAUuELKs.mjs";
|
|
12
12
|
|
|
13
13
|
//#region src/commands/segment/update.ts
|
|
14
14
|
var update_default = defineMetabaseCommand({
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { renderSummary } from "./capabilities-BX1rnVuH.mjs";
|
|
5
5
|
import "./input-BXWgdKiS.mjs";
|
|
6
|
-
import { parseId } from "./parse-id-
|
|
7
|
-
import { readBody } from "./body-
|
|
6
|
+
import { parseId } from "./parse-id-B5adfBlS.mjs";
|
|
7
|
+
import { readBody } from "./body-DB2upz6a.mjs";
|
|
8
8
|
import { bodyInputFlags } from "./body-flags-D7q87Btw.mjs";
|
|
9
9
|
import "./validate-VawhJ5Sc.mjs";
|
|
10
10
|
import { TRANSFORM_SOURCE_QUERY_LABELS, preflightMbql5Query, skipValidateFlag } from "./validate-query-CSV-TTnd.mjs";
|
|
11
|
-
import { Transform, TransformUpdateInput, transformView } from "./transform-
|
|
12
|
-
import { enrichTransformCollectionError } from "./collection-namespace-
|
|
11
|
+
import { Transform, TransformUpdateInput, transformView } from "./transform-MmqHKGU-.mjs";
|
|
12
|
+
import { enrichTransformCollectionError } from "./collection-namespace-CUDPh2rF.mjs";
|
|
13
13
|
|
|
14
14
|
//#region src/commands/transform/update.ts
|
|
15
15
|
var update_default = defineMetabaseCommand({
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { renderSummary } from "./capabilities-BX1rnVuH.mjs";
|
|
5
5
|
import "./input-BXWgdKiS.mjs";
|
|
6
6
|
import { Field, FieldUpdateInput, fieldView } from "./field-E0IBy4Uw.mjs";
|
|
7
|
-
import { parseId } from "./parse-id-
|
|
8
|
-
import { readBody } from "./body-
|
|
7
|
+
import { parseId } from "./parse-id-B5adfBlS.mjs";
|
|
8
|
+
import { readBody } from "./body-DB2upz6a.mjs";
|
|
9
9
|
import { bodyInputFlags } from "./body-flags-D7q87Btw.mjs";
|
|
10
10
|
|
|
11
11
|
//#region src/commands/field/update.ts
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { renderSummary } from "./capabilities-BX1rnVuH.mjs";
|
|
5
5
|
import "./input-BXWgdKiS.mjs";
|
|
6
|
-
import { parseId } from "./parse-id-
|
|
7
|
-
import { readBody } from "./body-
|
|
6
|
+
import { parseId } from "./parse-id-B5adfBlS.mjs";
|
|
7
|
+
import { readBody } from "./body-DB2upz6a.mjs";
|
|
8
8
|
import { bodyInputFlags } from "./body-flags-D7q87Btw.mjs";
|
|
9
|
-
import { Snippet, SnippetUpdateInput, snippetView } from "./snippet-
|
|
9
|
+
import { Snippet, SnippetUpdateInput, snippetView } from "./snippet-D4SyVLKB.mjs";
|
|
10
10
|
|
|
11
11
|
//#region src/commands/snippet/update.ts
|
|
12
12
|
var update_default = defineMetabaseCommand({
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { renderSummary } from "./capabilities-BX1rnVuH.mjs";
|
|
5
5
|
import "./input-BXWgdKiS.mjs";
|
|
6
|
-
import { parseId } from "./parse-id-
|
|
7
|
-
import { readBody } from "./body-
|
|
6
|
+
import { parseId } from "./parse-id-B5adfBlS.mjs";
|
|
7
|
+
import { readBody } from "./body-DB2upz6a.mjs";
|
|
8
8
|
import { bodyInputFlags } from "./body-flags-D7q87Btw.mjs";
|
|
9
9
|
import { Document, DocumentUpdateInput, documentView } from "./document-qfwR0r63.mjs";
|
|
10
10
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { renderSummary } from "./capabilities-BX1rnVuH.mjs";
|
|
5
5
|
import "./input-BXWgdKiS.mjs";
|
|
6
|
-
import { parseId } from "./parse-id-
|
|
7
|
-
import { readBody } from "./body-
|
|
6
|
+
import { parseId } from "./parse-id-B5adfBlS.mjs";
|
|
7
|
+
import { readBody } from "./body-DB2upz6a.mjs";
|
|
8
8
|
import { bodyInputFlags } from "./body-flags-D7q87Btw.mjs";
|
|
9
|
-
import { TransformJob, TransformJobUpdateInput, transformJobView } from "./transform-job-
|
|
9
|
+
import { TransformJob, TransformJobUpdateInput, transformJobView } from "./transform-job-CtVziW85.mjs";
|
|
10
10
|
|
|
11
11
|
//#region src/commands/transform-job/update.ts
|
|
12
12
|
var update_default = defineMetabaseCommand({
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { renderSummary } from "./capabilities-BX1rnVuH.mjs";
|
|
5
5
|
import "./input-BXWgdKiS.mjs";
|
|
6
6
|
import "./field-E0IBy4Uw.mjs";
|
|
7
7
|
import "./card-wCPcuKSi.mjs";
|
|
8
|
-
import { parseId } from "./parse-id-
|
|
9
|
-
import { readBody } from "./body-
|
|
8
|
+
import { parseId } from "./parse-id-B5adfBlS.mjs";
|
|
9
|
+
import { readBody } from "./body-DB2upz6a.mjs";
|
|
10
10
|
import { bodyInputFlags } from "./body-flags-D7q87Btw.mjs";
|
|
11
11
|
import "./validate-VawhJ5Sc.mjs";
|
|
12
12
|
import { DashboardDetail, DashboardUpdateInput, dashboardView } from "./dashboard-B4bn3z6t.mjs";
|
|
13
|
-
import { preflightDashcardCardReferences } from "./preflight-
|
|
13
|
+
import { preflightDashcardCardReferences } from "./preflight-QVPvG_Xg.mjs";
|
|
14
14
|
|
|
15
15
|
//#region src/commands/dashboard/update.ts
|
|
16
16
|
var update_default = defineMetabaseCommand({
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { renderSummary } from "./capabilities-BX1rnVuH.mjs";
|
|
5
5
|
import "./input-BXWgdKiS.mjs";
|
|
6
|
-
import { parseId } from "./parse-id-
|
|
7
|
-
import { readBody } from "./body-
|
|
6
|
+
import { parseId } from "./parse-id-B5adfBlS.mjs";
|
|
7
|
+
import { readBody } from "./body-DB2upz6a.mjs";
|
|
8
8
|
import { bodyInputFlags } from "./body-flags-D7q87Btw.mjs";
|
|
9
|
-
import { TransformTag, TransformTagUpdateInput, transformTagView } from "./transform-tag-
|
|
9
|
+
import { TransformTag, TransformTagUpdateInput, transformTagView } from "./transform-tag-wFiWmiyO.mjs";
|
|
10
10
|
|
|
11
11
|
//#region src/commands/transform-tag/update.ts
|
|
12
12
|
var update_default = defineMetabaseCommand({
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { renderSummary } from "./capabilities-BX1rnVuH.mjs";
|
|
5
5
|
import "./input-BXWgdKiS.mjs";
|
|
6
6
|
import "./field-E0IBy4Uw.mjs";
|
|
7
|
-
import { parseId } from "./parse-id-
|
|
8
|
-
import { readBody } from "./body-
|
|
7
|
+
import { parseId } from "./parse-id-B5adfBlS.mjs";
|
|
8
|
+
import { readBody } from "./body-DB2upz6a.mjs";
|
|
9
9
|
import { bodyInputFlags } from "./body-flags-D7q87Btw.mjs";
|
|
10
|
-
import { Table, TableUpdateInput, tableView } from "./table-
|
|
10
|
+
import { Table, TableUpdateInput, tableView } from "./table-CDMG0Zi5.mjs";
|
|
11
11
|
|
|
12
12
|
//#region src/commands/table/update.ts
|
|
13
13
|
var update_default = defineMetabaseCommand({
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { renderSummary } from "./capabilities-BX1rnVuH.mjs";
|
|
5
5
|
import "./input-BXWgdKiS.mjs";
|
|
6
6
|
import "./field-E0IBy4Uw.mjs";
|
|
7
7
|
import { Card, CardUpdateInput, cardView } from "./card-wCPcuKSi.mjs";
|
|
8
|
-
import { parseId } from "./parse-id-
|
|
9
|
-
import { readBody } from "./body-
|
|
8
|
+
import { parseId } from "./parse-id-B5adfBlS.mjs";
|
|
9
|
+
import { readBody } from "./body-DB2upz6a.mjs";
|
|
10
10
|
import { bodyInputFlags } from "./body-flags-D7q87Btw.mjs";
|
|
11
11
|
import "./validate-VawhJ5Sc.mjs";
|
|
12
12
|
import { CARD_DATASET_QUERY_LABELS, preflightMbql5Query, skipValidateFlag } from "./validate-query-CSV-TTnd.mjs";
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { renderSummary } from "./capabilities-BX1rnVuH.mjs";
|
|
5
5
|
import "./input-BXWgdKiS.mjs";
|
|
6
|
-
import { parseId } from "./parse-id-
|
|
7
|
-
import { readBody } from "./body-
|
|
6
|
+
import { parseId } from "./parse-id-B5adfBlS.mjs";
|
|
7
|
+
import { readBody } from "./body-DB2upz6a.mjs";
|
|
8
8
|
import { bodyInputFlags } from "./body-flags-D7q87Btw.mjs";
|
|
9
9
|
import "./validate-VawhJ5Sc.mjs";
|
|
10
10
|
import { MEASURE_DEFINITION_LABELS, preflightMbql5Query, skipValidateFlag } from "./validate-query-CSV-TTnd.mjs";
|
|
11
|
-
import { Measure, MeasureUpdateInput, measureView } from "./measure-
|
|
11
|
+
import { Measure, MeasureUpdateInput, measureView } from "./measure-BCv5wDDN.mjs";
|
|
12
12
|
|
|
13
13
|
//#region src/commands/measure/update.ts
|
|
14
14
|
var update_default = defineMetabaseCommand({
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ConfigError } from "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { renderSummary } from "./capabilities-BX1rnVuH.mjs";
|
|
5
5
|
import "./input-BXWgdKiS.mjs";
|
|
6
|
-
import { parseId } from "./parse-id-
|
|
7
|
-
import { readBody } from "./body-
|
|
6
|
+
import { parseId } from "./parse-id-B5adfBlS.mjs";
|
|
7
|
+
import { readBody } from "./body-DB2upz6a.mjs";
|
|
8
8
|
import { bodyInputFlags } from "./body-flags-D7q87Btw.mjs";
|
|
9
9
|
import { DashboardDetail, Dashcard, DashcardPatchInput, dashcardView } from "./dashboard-B4bn3z6t.mjs";
|
|
10
10
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AbortError, NetworkError, TimeoutError, UnknownError, errorMessage } from "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { outputFlags, package_default } from "./error-
|
|
3
|
-
import { HttpError, USER_AGENT, combineAborts, defineMetabaseCommand, parseJson, throwIfAborted } from "./runtime-
|
|
2
|
+
import { outputFlags, package_default } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { HttpError, USER_AGENT, combineAborts, defineMetabaseCommand, parseJson, throwIfAborted } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { renderItem, writeText } from "./capabilities-BX1rnVuH.mjs";
|
|
5
5
|
import { promptConfirm } from "./prompt-Bc_bHSD0.mjs";
|
|
6
6
|
import { streamProcess } from "./process-DsGf7Mg5.mjs";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ConfigError } from "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { outputFlags } from "./error-
|
|
3
|
-
import { defineMetabaseCommand, parseInteger } from "./runtime-
|
|
2
|
+
import { outputFlags } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { defineMetabaseCommand, parseInteger } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { writeJson, writeText } from "./capabilities-BX1rnVuH.mjs";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { formatScalar, renderSummary } from "./capabilities-BX1rnVuH.mjs";
|
|
5
5
|
import { FieldValues, fieldValuesView } from "./field-E0IBy4Uw.mjs";
|
|
6
|
-
import { parseId } from "./parse-id-
|
|
6
|
+
import { parseId } from "./parse-id-B5adfBlS.mjs";
|
|
7
7
|
|
|
8
8
|
//#region src/commands/field/values.ts
|
|
9
9
|
var values_default = defineMetabaseCommand({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MetabaseError, NetworkError, TimeoutError, errorMessage } from "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { HttpError, createClient, probeServer } from "./runtime-
|
|
2
|
+
import { HttpError, createClient, probeServer } from "./runtime-CmAIahm5.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
5
5
|
//#region src/domain/user.ts
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { parseId } from "./parse-id-
|
|
2
|
-
import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS } from "./poll-
|
|
1
|
+
import { parseId } from "./parse-id-B5adfBlS.mjs";
|
|
2
|
+
import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS } from "./poll-AduuU55-.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/commands/wait-flags.ts
|
|
5
5
|
const waitScheduleFlags = {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-CIObEXLY.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-CmAIahm5.mjs";
|
|
4
4
|
import { renderSummary } from "./capabilities-BX1rnVuH.mjs";
|
|
5
|
-
import { parseId } from "./parse-id-
|
|
6
|
-
import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS } from "./poll-
|
|
7
|
-
import { SyncTaskOrIdle, formatSyncTask, pollSyncTask, syncTaskIdleView, syncTaskView, throwIfFailedTask } from "./poll-task-
|
|
5
|
+
import { parseId } from "./parse-id-B5adfBlS.mjs";
|
|
6
|
+
import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS } from "./poll-AduuU55-.mjs";
|
|
7
|
+
import { SyncTaskOrIdle, formatSyncTask, pollSyncTask, syncTaskIdleView, syncTaskView, throwIfFailedTask } from "./poll-task-B00Qwd87.mjs";
|
|
8
8
|
|
|
9
9
|
//#region src/commands/git-sync/wait.ts
|
|
10
10
|
const WaitResult = SyncTaskOrIdle;
|
package/package.json
CHANGED
package/skill-data/core/SKILL.md
CHANGED
|
@@ -11,7 +11,7 @@ The official Metabase CLI (`mb`) drives a Metabase instance over its REST API: a
|
|
|
11
11
|
Top-level command groups (run `mb <group> --help` to discover verbs):
|
|
12
12
|
|
|
13
13
|
```
|
|
14
|
-
auth | db | table | field | query | card | dashboard | snippet | segment | measure | collection
|
|
14
|
+
auth | db | table | field | query | card | dashboard | snippet | segment | measure | collection | library
|
|
15
15
|
document | transform | transform-job | transform-tag | setting | search | git-sync | setup | eid | uuid | upgrade | skills
|
|
16
16
|
```
|
|
17
17
|
|
|
@@ -128,7 +128,7 @@ Routine verb shapes (list / get / create / update), every flag, and output JSON
|
|
|
128
128
|
|
|
129
129
|
- **db traversal vs. rollup.** Default to granular: `database list` → `database schemas <db-id>` → `database schema-tables <db-id> <schema>` → `table get <table-id> --include fields`. The rollup endpoints (`database get --include tables.fields`, `database metadata <db-id>`) pull megabytes and blow the context window on any real warehouse — use them only on a small/dev db. `sync-schema` / `rescan-values` queue async work and return `{status:"ok"}` immediately; `sync-schema --wait` blocks until `initial_sync_status: complete`.
|
|
130
130
|
- **table fields.** `table get` never returns fields on its own — pass `--include fields` (compact) or use `table fields <id>` (list envelope). `table metadata <id>` adds FKs + dimensions (heavier). `table update` patches table-level metadata only; physical columns aren't editable here.
|
|
131
|
-
- **
|
|
131
|
+
- **library.** EE-only (`library` premium feature, v59+). 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. So the Library is 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 permission alone won't publish tables) 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; don't publish raw tables.
|
|
132
132
|
- **field has no `list`.** Fields are per-table — get them via `table get <id> --include fields`. Never enumerate fields across a whole db (context blow-up). `field summary` is live cardinality `{field_id, count, distincts}`; `field values` is the cached distinct set (`has_more_values: true` ⇒ truncated cache). `field update` patches metadata only; `base_type` isn't editable.
|
|
133
133
|
- **card.** `dataset_query` is the **flat** `mbql/query` value, not a legacy `{type:"query",query:…}` envelope (→ `mbql` skill). `--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 the `viz` skill.
|
|
134
134
|
- **dashboard.** Dashcards round-trip through `PUT /api/dashboard/:id` (no per-dashcard endpoint): `update-dashcard <dash-id> <dashcard-id>` patches one safely; `update --body '{"dashcards":[…]}'` replaces the whole set (omitted ids are deleted server-side; negative ids for new cards). `create` accepts the **same** `dashcards` array in its initial body — lay out the whole dashboard in one call: negative ids for new cards, and `card_id:null` plus a `visualization_settings.virtual_card` block (`{display:"text"|"heading"|"link"|…}`) for non-question cards. `create`/`update` pre-flight every positive `card_id` against live server state and exit **2** with `{ok:false,errors:[…]}` on a bad ref — non-bypassable (no `--skip-validate`). `dashboard get <id>` (or `--full`) hydrates dashcards/tabs; `list` omits them. **Dashcard geometry: the grid is 24 columns wide.** Each dashcard's `{col, row, size_x, size_y}` is in grid units — `col` (0-indexed, left edge) and `size_x` are columns, `row`/`size_y` are rows; **full-width is `size_x: 24`** (`size_x: 12` is half a row — the usual cause of a card filling only half the width, since it's a common per-chart default). Keep `col + size_x ≤ 24`, start each card's `col` at 0 for a full-width stack, and don't overlap cards (the server stores whatever you send — it won't auto-fix collisions).
|
|
@@ -6,9 +6,9 @@ allowed-tools: Read, Write, Edit, Bash, AskUserQuestion, EnterPlanMode, ExitPlan
|
|
|
6
6
|
|
|
7
7
|
# Data Transformation
|
|
8
8
|
|
|
9
|
-
> **Shared contract (read first).** This skill is part of the `robot-data-engineer` family and follows its shared rules: ask before showing PII row-by-row (names, emails, phones) — default to aggregates; when asked for something the CLI can't do (alerts, dashboard filters), name the limit instead of erroring into raw SQL; honor the autonomy mode the user picked. The jargon rules are spelled out
|
|
9
|
+
> **Shared contract (read first).** This skill is part of the `robot-data-engineer` family and follows its shared rules: ask before showing PII row-by-row (names, emails, phones) — default to aggregates; when asked for something the CLI can't do (alerts, dashboard filters), name the limit instead of erroring into raw SQL; honor the autonomy mode the user picked. The jargon rules are spelled out below (**Who you're talking to**). Full contract and the autonomy slider live in the router — run `mb skills get robot-data-engineer` and read its **Shared Contract**.
|
|
10
10
|
|
|
11
|
-
Your job: take a raw source database — usually normalized, often synced from
|
|
11
|
+
Your job: take a raw source database — usually normalized, often synced from a SaaS tool by a connector like Fivetran or Airbyte — and produce a **small set of wide, clean, analysis-ready tables**, one per real-world _thing_ the data is about, built as Metabase **transforms** the user can inspect.
|
|
12
12
|
|
|
13
13
|
Drive everything through the `mb` CLI. Load the skills you'll need:
|
|
14
14
|
|
|
@@ -18,9 +18,7 @@ mb skills get mbql # if you build transform queries in MBQL
|
|
|
18
18
|
mb skills get transform # creating/running transforms, run inspection
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
Users authenticate.
|
|
22
|
-
|
|
23
|
-
If you are making transforms, use the transform skill.
|
|
21
|
+
Users authenticate. Pick the profile per `core`'s **Auth & profiles** and pass `--profile <name>` to every command. That profile's `url` is the instance's base URL; the browser links below are built from it.
|
|
24
22
|
|
|
25
23
|
---
|
|
26
24
|
|
|
@@ -28,11 +26,11 @@ If you are making transforms, use the transform skill.
|
|
|
28
26
|
|
|
29
27
|
A **non-technical user who knows their domain well** — they understand the business (events, customers, invoices, etc.) but not databases.
|
|
30
28
|
|
|
31
|
-
- **No modeling jargon.** Skip warehouse vocabulary — grain, fact/dimension table,
|
|
29
|
+
- **No modeling jargon.** Skip warehouse vocabulary — grain, fact/dimension table, normalize, surrogate key, entity, materialize — prefer plain phrasing: "one row per \_\_\_", "what it tells you", "links up with", "how full a column is". **But don't overdo it:** basic relational terms are fine — table, column, ERD, schema, key, foreign key (cardinality too, though "one-to-many" usually lands better). **Metabase's product terms are encouraged** — Question, Model, Segment, Measure, Metric, Transform — they're not database jargon.
|
|
32
30
|
- **Don't lean on raw SQL to communicate.** They may follow a simple `SELECT`, but don't explain work via SQL or ask them to read/write it.
|
|
33
31
|
- Group what you show by **the question a column answers**, never by which source table it came from.
|
|
34
32
|
- Be a **helpful assistant, not an engineer reporting status.** Elide machinery; ask sharp questions that matter.
|
|
35
|
-
-
|
|
33
|
+
- **If you ever ask the user a question, wait for their answer.** They may say "go" and come back later.
|
|
36
34
|
|
|
37
35
|
---
|
|
38
36
|
|
|
@@ -47,8 +45,8 @@ Sort every choice into one of these.
|
|
|
47
45
|
3. Always surface **real data you're about to leave out** proactively, ranked by how much is extant.
|
|
48
46
|
4. Never guess what schema mean from their name alone. Confirm against actual values, interpret them in context: the table the field belongs to and the relevant domain (e.g., a status on orders ≠ status on subscriptions).
|
|
49
47
|
5. Never silently drop a whole _thing_. Dropping a column is routine; dropping a whole kind-of-thing (e.g. "suppliers") must be surfaced and confirmed.
|
|
50
|
-
6. Never drop columns that link things together. Every table keeps its own id **and** the ids tying it to other tables — alongside the readable labels you copy in, not instead of
|
|
51
|
-
7. Never bake a non-obvious business rule into a table without confirming it in plain terms. When a transform encodes a judgment the user would have an opinion on — how money nets, which row is the "current" one, what "active" means — say it back in one plain sentence and get a yes/no first. You know only the columns; they know the business
|
|
48
|
+
6. Never drop columns that link things together. Every table keeps its own id **and** the ids tying it to other tables — alongside the readable labels you copy in, not instead of (label for reading, id for joining). You're building tables about _related_ things, so they **will** be combined ("sales per region", "messages per customer") — dropped ids make that quietly impossible. Keep the ids.
|
|
49
|
+
7. Never bake a non-obvious business rule into a table without confirming it in plain terms. When a transform encodes a judgment the user would have an opinion on — how money nets, which row is the "current" one, what "active" means — say it back in one plain sentence and get a yes/no first. You know only the columns; they know the business, and wrong rules hide in clean-looking tables. ("I'm treating each person's most recent sign-up as their current one — right?")
|
|
52
50
|
8. Never sneak sensitive personal data through. Flag it on sight — addresses, phone numbers, emails, IPs, financial, etc. — and ask the user how to handle it (the prudential call below). Always surface, never silently expose it in a table others will browse.
|
|
53
51
|
9. Never overwrite existing tables or other transforms' outputs. Before building, check the target name is unused (`mb transform list`, `mb table list`); if it's in use, stop and surface it — building over it silently destroys their data. Reuse names only for updating _your own_ transform (`transform update`), never for clobbering another.
|
|
54
52
|
|
|
@@ -57,7 +55,7 @@ Sort every choice into one of these.
|
|
|
57
55
|
- **Multi-valued attribute** (one response → many options; one order → many line items): keep it filterable! Structured columns for predefined lists, or simple join tables, never opaque text. Structure is the user's call. Lean: easiest filtering, probably flat.
|
|
58
56
|
- **Layering**: default **flat** — one self-contained table per thing, no hidden intermediate tables. Suggest a shared cleaned-up base table only for DRY, avoiding copying complex logic across many transforms. Even then, ask.
|
|
59
57
|
- **Out-of-scope things**: surface every domain-model you find and ask in/out, rather than inferring scope from what they happened to mention.
|
|
60
|
-
- **A repeating thing vs. the events it takes part in**: one table can mix a _stable_ thing (a customer, a company) with _repeating_ events (each order, each visit), copying the stable details onto every event row. If that thing genuinely recurs — same customer on many rows — consider a one-row-per-thing table too, linked by id, so "how many distinct X" and the per-X details have clean homes. Lean: split when recurrence is real,
|
|
58
|
+
- **A repeating thing vs. the events it takes part in**: one table can mix a _stable_ thing (a customer, a company) with _repeating_ events (each order, each visit), copying the stable details onto every event row. If that thing genuinely recurs — same customer on many rows — consider a one-row-per-thing table too, linked by id, so "how many distinct X" and the per-X details have clean homes. Lean: split when recurrence is real, one table when each appears once. (Phase 0's one-to-one / one-to-many check tells you which.)
|
|
61
59
|
- **Handling sensitive data** (addresses, emails, phones, IPs, financial details): once you've flagged it (rule 8), _how_ to carry it is user's choice — keep as-is, mask (partial redaction), or drop. Lean: keep what is needed, mask the rest, drop the useless.
|
|
62
60
|
|
|
63
61
|
Phrase a prudential call as a lean plus a nod:
|
|
@@ -70,11 +68,11 @@ Phrase a prudential call as a lean plus a nod:
|
|
|
70
68
|
|
|
71
69
|
### Phase 0 — Get Oriented
|
|
72
70
|
|
|
73
|
-
**Pin down where the data lives — ask before you hunt.** A table or schema name the user mentions tells you _what_ but not _where_: an instance can hold several databases, each with several schemas. Rather than listing them all to find it, just ask — "Which database is this in, and the schema if you know it? No worries if
|
|
71
|
+
**Pin down where the data lives — ask before you hunt.** A table or schema name the user mentions tells you _what_ but not _where_: an instance can hold several databases, each with several schemas. Rather than listing them all to find it, just ask — "Which database is this in, and the schema if you know it? No worries if not — I can find it." A confident answer short-circuits a lot of blind searching; "not sure" costs nothing and you fall back to locating it yourself. If you've genuinely looked and still can't find a table the user is sure is there, don't keep digging — one likely reason is Metabase hasn't synced that database's latest schema; gently raise it and let the user run the sync from Metabase.
|
|
74
72
|
|
|
75
73
|
As soon as you know which database and schema you're in:
|
|
76
74
|
|
|
77
|
-
- **Show the user the map.** Open the instance's schema map
|
|
75
|
+
- **Show the user the map.** Open the instance's schema map so they can follow along: `<base-url>/data-studio/schema-viewer?database-id=<db-id>&schema=<schema>` — in their browser if you can (`open` / `xdg-open`), else paste the URL. Don't skip this.
|
|
78
76
|
- **Ask for a head start.** "Do you have a picture or file showing how your data fits together, like an ERD?" If yes, read it — it shortcuts the next steps.
|
|
79
77
|
- **Ask for their conventions.** "Is there already cleaned-up data, or a past project, that shows how your team likes this done?" If yes, inspect it: it tells you their naming, their idea of "clean," and existing tables worth linking to.
|
|
80
78
|
|
|
@@ -87,21 +85,21 @@ Orientation done, you're about to go heads-down. First, offer two ways to work:
|
|
|
87
85
|
> - **I dig through it all and bring you a complete plan** to approve before I build anything — quieter; you won't hear much until it's ready.
|
|
88
86
|
> - **We work it out together** — I share what I find and we make the calls as we go.
|
|
89
87
|
|
|
90
|
-
First path: **enter plan mode** (`EnterPlanMode`). Everything up to the agreed table list — investigate, present, prudential calls, naming (Phases 1–3) — happens inside it, read-only; you exit once, at the approval gate before building (Phase 4). Second path: skip it, shape it conversationally through the same phases. Either way, don't build until the design is settled and
|
|
88
|
+
First path: **enter plan mode** (`EnterPlanMode`). Everything up to the agreed table list — investigate, present, prudential calls, naming (Phases 1–3) — happens inside it, read-only; you exit once, at the approval gate before building (Phase 4). Second path: skip it, shape it conversationally through the same phases. Either way, don't build until the design is settled and approved.
|
|
91
89
|
|
|
92
|
-
Plan mode is a long quiet stretch
|
|
90
|
+
Plan mode is a long quiet stretch. So whenever you surface — a question now, the plan at the end — **carry your own context**: recap what it rests on right before you ask, never a back-reference to something said while they were away.
|
|
93
91
|
|
|
94
92
|
Then dig in. Don't narrate this — a single "Let me take a look at what's in here — one minute" is enough. Keep it cheap: never pull whole-warehouse rollups (they blow up); use compact column listings, `LIMIT`/sample queries, and `GROUP BY count(*)`.
|
|
95
93
|
|
|
96
94
|
1. **Map the tables.** List them; pull each one's column names and types; note its own id.
|
|
97
|
-
2. **Find the decode tables.** Normalized SaaS data hides meaning in lookups — `*_field`, `*_field_choice`, `*_question`, `*_choice`, `*_type`. A column like `doodad_4471` is meaningless until you join the lookup and find it's _"Preferred vehicular transport"_. Build that code → label map yourself
|
|
98
|
-
3. **Prove the connections — don't trust declared keys.** Synced databases usually have none. If that's the case, ask the user if they have ERD or relationship information (screenshot, JSON, documentation, etc.). For each `<x>_id`, guess it points at `<x>`, then check what fraction of values actually match the target's id: high = real link, low = decoy, discard. Note one-to-one vs one-to-many. **Also look outward** — does a thing you're about to build already exist as clean data elsewhere
|
|
95
|
+
2. **Find the decode tables.** Normalized SaaS data hides meaning in lookups — `*_field`, `*_field_choice`, `*_question`, `*_choice`, `*_type`. A column like `doodad_4471` is meaningless until you join the lookup and find it's _"Preferred vehicular transport"_. Build that code → label map yourself — never hand the user a coded column and ask what it means — before showing them anything.
|
|
96
|
+
3. **Prove the connections — don't trust declared keys.** Synced databases usually have none. If that's the case, ask the user if they have ERD or relationship information (screenshot, JSON, documentation, etc.). For each `<x>_id`, guess it points at `<x>`, then check what fraction of values actually match the target's id: high = real link, low = decoy, discard. Note one-to-one vs one-to-many. **Also look outward** — does a thing you're about to build already exist as clean data elsewhere (an existing customers table, a product list)? If so, plan to _link_ to it, not duplicate it.
|
|
99
97
|
4. **Pin down "one row per what."** Count rows; check the id is unique; figure out what a single row is. **Watch for lies:** a stale count column, or a table that looks like "all of X" but is a filtered subset.
|
|
100
|
-
5. **Reconcile across related tables.** Do child rows all link to a parent? Orphans? Is one table a trimmed snapshot while another keeps everything? These mismatches matter and the user can't see them
|
|
98
|
+
5. **Reconcile across related tables.** Do child rows all link to a parent? Orphans? Is one table a trimmed snapshot while another keeps everything? These mismatches matter and the user can't see them.
|
|
101
99
|
6. **Profile the values.** List distinct values for coded/low-variety columns; check how full (% non-empty) any column you might drop is; spot multi-valued JSON fields. Profile with the cleaning checklist (end of file) in mind — surface the quality smells you hit, don't silently fix them.
|
|
102
100
|
7. **Cluster into things.** Group tables and columns into the real-world things they describe — a thing may span several tables (one _customer_ across a main table + a loyalty table + custom-profile columns). Decide "one row per \_\_\_" for each and gather its attributes, decoded. Watch for a table that secretly mixes _two_ things — a stable thing plus its repeating events; that's the split in the prudential calls above.
|
|
103
101
|
|
|
104
|
-
**Then, still quietly, sketch the design space.** Once the things and
|
|
102
|
+
**Then, still quietly, sketch the design space.** Once the things and their connections are pinned, brainstorm the questions this data could answer — finance views, leaderboards, breakdowns. **Don't show it or build any of it.** It only pressure-tests your design: would a reasonable pivot to a nearby question force a rewrite? When keeping a column or finer grain _cheaply_ preserves that flexibility, keep it — don't scope so tightly that the next question means starting over.
|
|
105
103
|
|
|
106
104
|
### Phase 2 — Present what you found (plain language)
|
|
107
105
|
|
|
@@ -121,18 +119,18 @@ Three things, in order:
|
|
|
121
119
|
> • **Real data** — gift-message text (6 of 10 orders), delivery instructions (most), preferred carrier. Minor, but real — want any kept?
|
|
122
120
|
> • **Safe to drop** — duplicate product names in other languages, internal bookkeeping columns. No real loss.
|
|
123
121
|
|
|
124
|
-
If you spotted existing clean data to link to (step 3), raise it here too —
|
|
122
|
+
If you spotted existing clean data to link to (step 3), raise it here too — **always run a suspected match past the user before wiring it, never graft on silently.** Then ask your prudential questions, one at a time.
|
|
125
123
|
|
|
126
124
|
### Phase 3 — Iterate
|
|
127
125
|
|
|
128
|
-
Cheap, because nothing's built. Adjust the set of things, what's kept, and the shape of any multi-valued pieces until the user's happy. **Agree on what each table will be called** — propose a clear name for each (matching any naming pattern you found in their existing data, Phase 0) and let them adjust. Confirm each name is free — not already an existing table or another transform's output (rule 9) — so building can't overwrite anyone's data.
|
|
126
|
+
Cheap, because nothing's built. Adjust the set of things, what's kept, and the shape of any multi-valued pieces until the user's happy. **Agree on what each table will be called** — propose a clear name for each (matching any naming pattern you found in their existing data, Phase 0) and let them adjust. Confirm each name is free — not already an existing table or another transform's output (rule 9) — so building can't overwrite anyone's data. The name you agree on is the one you build and keep. Re-confirm the final picture in one short recap. **In plan mode, that recap _is_ your exit:** present it as the plan and call `ExitPlanMode` — approval here is the single go-ahead to build. (Iterating together? The recap is just your check before building.)
|
|
129
127
|
|
|
130
128
|
### Phase 4 — Build, check, hand back
|
|
131
129
|
|
|
132
|
-
Design settled — now you build, the first step that writes; plan mode, if you used it, is behind you. Build one wide transform per agreed thing
|
|
130
|
+
Design settled — now you build, the first step that writes; plan mode, if you used it, is behind you. Build one wide transform per agreed thing, for how it'll be judged: output that's readable on sight, not just one that runs clean. Each table:
|
|
133
131
|
|
|
134
132
|
- **Denormalized, but the link stays.** Copy in related context so casual reading needs no lookups (a product's name and price on the orders table) — **and keep the linking id beside it** (the product's id too, per rule 6). Use the same id name everywhere a thing appears.
|
|
135
|
-
- **Decoded**: codes and JSON become readable text; bookkeeping columns and soft-deleted rows are gone (filter the source's soft-delete flag — Fivetran's `_fivetran_deleted`, Airbyte's `_ab_cdc_deleted_at`, or a plain `deleted_at`/`is_deleted` — so tombstones never reach clean data
|
|
133
|
+
- **Decoded**: codes and JSON become readable text; bookkeeping columns and soft-deleted rows are gone (filter the source's soft-delete flag — Fivetran's `_fivetran_deleted`, Airbyte's `_ab_cdc_deleted_at`, or a plain `deleted_at`/`is_deleted` — so tombstones never reach clean data).
|
|
136
134
|
- **Clean, plain column names**, consistent across tables.
|
|
137
135
|
- **Multi-valued pieces** in the agreed filterable structure (rule 1).
|
|
138
136
|
- **Keep the detail; don't pre-summarize it away.** Build the detailed rows (one per order, one per payment), not pre-computed totals. A convenience count is fine _beside_ the rows, never _instead of_ them — a frozen total only ever answers the one question it was summed for.
|
|
@@ -141,15 +139,22 @@ Then make the links real, not just implied:
|
|
|
141
139
|
|
|
142
140
|
- **Wire foreign keys between your tables.** Mark each linking id as a foreign key pointing at the id it references (`mb field update` — set the column's type to foreign-key and its target). Now Metabase itself knows the tables connect and can traverse them.
|
|
143
141
|
- **Graft onto existing clean data** the user approved (step 3 / Phase 1): point the linking id at the existing table's id the same way. Link, don't duplicate.
|
|
144
|
-
- **Write down what you learned.** You decoded every column's real meaning while investigating — save it: set a short description on each table and its non-obvious columns (`mb table update` / `mb field update`). The cleaned data then explains itself inside Metabase — in search, in the Question editor, to Metabot — instead of the knowledge living only in this chat.
|
|
145
142
|
|
|
146
|
-
|
|
143
|
+
**Set the metadata — a transform's output starts blank, and these tables are Library-bound.** A fresh transform table has no descriptions, raw column names, and untyped columns. You worked it out while investigating; don't leave that knowledge stranded in this chat. Set it on the table so the data explains itself inside Metabase (search, the Question editor, Metabot) and is fit to publish:
|
|
144
|
+
|
|
145
|
+
- **Semantic types — the highest-value piece.** A column's semantic type is what makes Metabase treat it right: `type/Email`, `type/Currency`/`type/Price`, `type/Category` (turns into a filter dropdown), `type/City`/`type/State`/`type/Country`, `type/CreationTimestamp`, `type/Description`. Set it on every column whose meaning you decoded — `mb field update <id> --body '{"semantic_type":"type/Currency"}'`. A typed column shows money as money, offers a filter dropdown, and lands on the right chart axis for everyone downstream; an untyped one is a guess.
|
|
146
|
+
- **Descriptions.** A one-line description on each table and every non-obvious column (`mb table update` / `mb field update`).
|
|
147
|
+
- **Display names.** When a cleaned-up column name still isn't plain English, set a readable `display_name`.
|
|
148
|
+
|
|
149
|
+
When the semantics are **already spelled out** — the user is porting dbt models (the `schema.yml` carries column descriptions and types), or you settled each field's meaning together here — that documentation _is_ the metadata. Carry it straight onto the tables and fields rather than letting it evaporate.
|
|
150
|
+
|
|
151
|
+
When refining a built transform _with_ the user, open its inspector so you're looking at the same thing — `<base-url>/data-studio/transforms/<transform-id>/inspect` — in their browser if you can, else paste the URL. Iterate with `transform update`, never delete-and-recreate.
|
|
147
152
|
|
|
148
153
|
**Check the output before handing back — the user can't.** Two passes, in order.
|
|
149
154
|
|
|
150
155
|
**Pass 1 — Correctness (did it run right).** After each transform runs, run quick ad-hoc tests against what Phase 0 led you to expect: row counts in the right ballpark, decoded columns readable (no stray codes), linking ids that resolve to the other tables, no column unexpectedly all-null or blown up in count. Treat surprises as bugs to chase, not noise. A table that can't combine with the others — a dropped id, or the same id named two ways — is a silent failure; catch it here.
|
|
151
156
|
|
|
152
|
-
**Pass 2 — Fitness (is it nice to use).** Correct isn't the bar; _usable_ is. `SELECT * FROM <table> LIMIT 20` and read every column
|
|
157
|
+
**Pass 2 — Fitness (is it nice to use).** Correct isn't the bar; _usable_ is. `SELECT * FROM <table> LIMIT 20` and read every column as if you'd never seen the source: would a non-technical person find each one readable? Smells that say not-yet, even though nothing errored:
|
|
153
158
|
|
|
154
159
|
- a multi-valued column still a raw JSON/array blob or `["Email","SMS"]` text — rule 1 never actually got resolved;
|
|
155
160
|
- decoded answers still carrying raw ids with no readable label, or one cryptic column per code;
|
|
@@ -167,7 +172,9 @@ Then report plainly:
|
|
|
167
172
|
>
|
|
168
173
|
> How they connect: each **Order** belongs to a **Customer**; each **Order** lists one or more **Products**.
|
|
169
174
|
|
|
170
|
-
End on that connection map: it's what the user reads to trust the result, and what lets whatever they build next join
|
|
175
|
+
End on that connection map: it's what the user reads to trust the result, and what lets whatever they build next join on the right ids instead of guessing.
|
|
176
|
+
|
|
177
|
+
These clean tables are exactly what belongs in the **Library** — published tables appear first when anyone picks a data source, so people start from your curated set, not the raw source. If the user wants that, mark them official with `mb library publish --table-ids <ids>` (`mb library create` first if the Library isn't set up; both need the `library` premium feature + admin/data-analyst). Defining reusable segments / measures / metrics on top is the **semantic-layer** skill's job.
|
|
171
178
|
|
|
172
179
|
---
|
|
173
180
|
|
|
@@ -178,7 +185,7 @@ The shape recurs across SaaS exports, whatever the domain. A coded column — sa
|
|
|
178
185
|
Always decode _before_ presenting, so the user sees "Preferred contact method", never `c_4471`. Three cautions:
|
|
179
186
|
|
|
180
187
|
- **Pull the readable name from the lookup, don't type it in.** The label (and any question text) should come _from_ the lookup's `name`, sourced in the query — not pasted as a literal. A hard-typed label goes wrong the moment the source changes.
|
|
181
|
-
- **Codes are usually specific to today's data.** `c_4471` exists only for _this_ form or instance, so one-column-per-code is tied to the data as it stands — a new form
|
|
188
|
+
- **Codes are usually specific to today's data.** `c_4471` exists only for _this_ form or instance, so one-column-per-code is tied to the data as it stands — a new form won't line up. When that's unavoidable, say so on hand-back ("reflects the current form; new questions need a refresh"), and with many such codes prefer the companion-table shape (one row per answer, question text from the lookup): nothing hard-typed, and adding a question is a smaller change.
|
|
182
189
|
- **Normalize encodings once.** Turn raw representations clean in the table itself, so nothing downstream re-derives them: signed amounts → clear positive numbers by kind, 0/1 → true/false, timestamps → one consistent timezone, text → trimmed and case-consistent, and junk placeholders (`"NULL"`, `"N/A"`, `"-"`, empty string) → real null.
|
|
183
190
|
|
|
184
191
|
---
|
|
@@ -197,4 +204,4 @@ A scan-list, not a pipeline — and the governing rule is **surface what you fin
|
|
|
197
204
|
- **Missing data** — random vs. systematic? Surface the pattern; never silently impute or default.
|
|
198
205
|
- **Free text / mixed encodings** — handle the safe parts, flag the rest.
|
|
199
206
|
|
|
200
|
-
|
|
207
|
+
Covered by the rules above, listed to stay on your radar: structural reshaping (decode/JSON/multi-value), orphans & key validity (Phase 0 step 5 + the post-run check), filtering soft-deletes & dropping bookkeeping columns (Phase 4's **Decoded** step), recording meanings (the descriptions step).
|
|
@@ -76,6 +76,7 @@ The user already picked an autonomy mode (the router's Shared Contract asks the
|
|
|
76
76
|
- "Let me add up revenue the same way everywhere, on this table" → a **measure** on the table.
|
|
77
77
|
- "Revenue is an _official company number_ people pull onto dashboards" → a **metric** in a collection, with a default month-by-month view so it charts cleanly. Lean: make it a metric when it's a headline figure the org reuses across many questions/dashboards; keep it a measure when it's a table-local convenience.
|
|
78
78
|
- **Where the metric lives.** Metrics sit in a collection (folder). Lean: put the org's blessed ones in the shared **Library** so they surface prominently; keep experimental ones in a working collection until trusted.
|
|
79
|
+
- **Publish the official tables to the Library.** The clean, analysis-ready tables your definitions sit on are the org's official starting points — the **Library** is how you mark them as such. Tables published to the Library's **Data** section appear _first_ when anyone picks a data source, nudging people toward your curated tables instead of raw warehouse ones. Lean: publish the wide clean tables you built the semantic layer on; hold back raw or half-built ones. Setting up the Library is a one-time, harmless step (`mb library create` is idempotent). Surface which tables you'd publish and confirm. (Library is a Pro/Enterprise feature; only admins and data analysts can publish.)
|
|
79
80
|
- **Default time dimension for a metric.** A monthly default makes it chart nicely on a dashboard, but doesn't lock anyone out of other groupings. Lean: set a sensible default (usually month) for anything headline; leave it off for raw counts that aren't inherently time-series.
|
|
80
81
|
- **How strict a segment is.** "Active" = last 30 vs 90 days is a real business call with no right answer from the data alone. Lean: surface the few reasonable thresholds with how many rows each catches, let the user pick.
|
|
81
82
|
|
|
@@ -128,6 +129,7 @@ Build each agreed definition. Mechanics (load `mbql` for the definition bodies):
|
|
|
128
129
|
- **Segment** → `mb segment create`. Body: `name`, `table_id`, and a `definition` (a flat MBQL filter clause). Update later with `mb segment update <id>` — needs a `revision_message` (the audit note: _why_ it changed). Never delete-and-recreate.
|
|
129
130
|
- **Measure** → `mb measure create`. Body: `name`, `table_id`, and a `definition` holding **exactly one** aggregation. Same `revision_message` rule on update.
|
|
130
131
|
- **Metric** → `mb card create` with the metric shape (`type: "metric"`) — it lives in a **collection**, carries a `dataset_query` (the aggregation) and an optional default time dimension. Put org-blessed ones in the Library collection.
|
|
132
|
+
- **Publish the official tables** → `mb library create` (idempotent — provisions the Library if it isn't set up yet), then `mb library publish --table-ids <ids>` to move the clean tables your definitions sit on into the Library's **Data** section. It resolves the Data collection itself, so there's no collection id to hunt for. Published tables surface first in every data picker, so people start from your curated set, not raw warehouse tables. (Run `mb skills get core` for the `library` group; it needs `library` premium + admin/data-analyst.)
|
|
131
133
|
|
|
132
134
|
Then **verify what the user can't see**, before you hand back:
|
|
133
135
|
|
|
@@ -149,6 +151,9 @@ Then **stop. Hard gate — every mode, no exceptions.** Recap in plain language
|
|
|
149
151
|
> **Metric** (in your **Library**, charts by month):
|
|
150
152
|
> • **Monthly recurring revenue**
|
|
151
153
|
>
|
|
154
|
+
> **Published to the Library** (these now show up first when anyone picks a data source):
|
|
155
|
+
> • **Customers**, **Orders**
|
|
156
|
+
>
|
|
152
157
|
> Open any of those tables' Filter or Summarize block in Metabase to see them in place and try one — give it a look before you start building dashboards on top.
|
|
153
158
|
|
|
154
159
|
End on that plain-language map. It's what the user reads to trust the result — and it's what stops a wrong definition from quietly propagating into everything built next.
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import "./command-augment-CAur0XOQ.mjs";
|
|
2
|
-
import "./error-D5bZ5BUX.mjs";
|
|
3
|
-
import "./runtime-C1QgWHM7.mjs";
|
|
4
|
-
import "./capabilities-BX1rnVuH.mjs";
|
|
5
|
-
import "./parse-id-DNPeV0Iu.mjs";
|
|
6
|
-
import "./poll-CYkX02Bm.mjs";
|
|
7
|
-
import "./poll-task-oXpl3wzp.mjs";
|
|
8
|
-
import { SyncSettingsUpdateResult, add_collection_default, setCollectionRemoteSynced, syncSettingsUpdateView } from "./add-collection-CXhrMjXU.mjs";
|
|
9
|
-
|
|
10
|
-
export { add_collection_default as default };
|