@metabase/cli 0.1.6 → 0.1.8-alpha.cleanup-workspaces.75fe1d5
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/.claude-plugin/marketplace.json +1 -1
- package/README.md +16 -238
- package/dist/add-collection-BGifL-7Y.mjs +10 -0
- package/dist/{add-collection-BU8r3r2M.mjs → add-collection-C5ijC4e-.mjs} +8 -6
- package/dist/{archive-BNinrUak.mjs → archive-2GZVq0n2.mjs} +7 -8
- package/dist/{archive-lWgqiFAt.mjs → archive-C5pXDf6a.mjs} +5 -6
- package/dist/{archive-C1enZgKV.mjs → archive-CTEybKPq.mjs} +6 -7
- package/dist/{archive-DMPS8Kih.mjs → archive-DEtOH_jf.mjs} +5 -6
- package/dist/{archive-CDA0KxL8.mjs → archive-DTrn90If.mjs} +5 -6
- package/dist/{archive-CRhiBpPJ.mjs → archive-nqKJOyOt.mjs} +5 -6
- package/dist/auth-Divr9vkY.mjs +19 -0
- package/dist/{body-DjdFxjpg.mjs → body-BMyDvOjf.mjs} +2 -2
- package/dist/{branches-B1WRfG7-.mjs → branches-B7Zf-nxr.mjs} +5 -6
- package/dist/{cancel-Dl_Ho056.mjs → cancel-WwjcCE2R.mjs} +6 -7
- package/dist/{cancel-task-CdigdCaO.mjs → cancel-task-E4cCeJTc.mjs} +6 -7
- package/dist/{render-CfznwleY.mjs → capabilities-Dj3NgPHg.mjs} +66 -10
- package/dist/card-BHAcovSB.mjs +20 -0
- package/dist/{card-DlCAaAPq.mjs → card-BtPiKjbB.mjs} +1 -1
- package/dist/{cards-BGiJS675.mjs → cards-BW0Spirk.mjs} +4 -5
- package/dist/cli.mjs +23 -24
- package/dist/collection-DZx-vWb2.mjs +20 -0
- package/dist/{create-BNiva__H.mjs → create-BV_VpyyI.mjs} +11 -12
- package/dist/{create-BTcpaop_.mjs → create-B_Ysb6Ex.mjs} +7 -8
- package/dist/{create-BYlIju0b.mjs → create-BgeD2GMZ.mjs} +10 -11
- package/dist/{create-DGth_uOp.mjs → create-Bxkik5Fs.mjs} +9 -10
- package/dist/{create-CzzrbL0u.mjs → create-CZfHpi_I.mjs} +8 -9
- package/dist/{create-Be_0Vier.mjs → create-CbwFOL9h.mjs} +8 -9
- package/dist/{create-dhxPxfF3.mjs → create-CbyY4xTG.mjs} +12 -13
- package/dist/{create-CwGtmwqm.mjs → create-HCCdsuZR.mjs} +9 -10
- package/dist/{create-branch-DKZkoQ64.mjs → create-branch-BNRq3tO2.mjs} +6 -7
- package/dist/{current-task-CCRzm0_7.mjs → current-task-ZvTjL4hP.mjs} +7 -8
- package/dist/dashboard-DCWGcx3e.mjs +21 -0
- package/dist/{database-lH-B3G1I.mjs → database-_Td7rG4o.mjs} +1 -1
- package/dist/db-bD6fwLwc.mjs +22 -0
- package/dist/{delete-ZjnV35OJ.mjs → delete-D5-ITH10.mjs} +8 -7
- package/dist/{delete-Dimc-2y8.mjs → delete-DvmHTMwf.mjs} +8 -7
- package/dist/{delete-runtime-B6RQo_pw.mjs → delete-runtime-Bo7v-0au.mjs} +6 -6
- package/dist/{delete-table-agZJpivt.mjs → delete-table-DjmO5Qe4.mjs} +8 -7
- package/dist/{dirty-D4d0yHqj.mjs → dirty-BJgU1SGQ.mjs} +5 -6
- package/dist/{eid-BXzaQh0o.mjs → eid-pqSVgO2g.mjs} +12 -8
- package/dist/{error-C9S6PN3-.mjs → error-Br6irjpM.mjs} +3 -2
- package/dist/{export-DTygoXBP.mjs → export-gVXTOxC2.mjs} +10 -10
- package/dist/field-BFWc8q2W.mjs +18 -0
- package/dist/{field-yomXlkvl.mjs → field-MGxpNQUH.mjs} +12 -3
- package/dist/{fields-CoQi99gv.mjs → fields-DK2TYRK2.mjs} +6 -7
- package/dist/{get-DQTZG_NP.mjs → get-BjArD6Er.mjs} +4 -5
- package/dist/{get-C3HdQ91a.mjs → get-C1RSXOhf.mjs} +5 -6
- package/dist/{get-DSWFjy7O.mjs → get-C3RI_hKG.mjs} +4 -5
- package/dist/{get-C_w1kvN3.mjs → get-C7UEEICF.mjs} +6 -7
- package/dist/{get-Bzys7vgp.mjs → get-D-3tOuWQ.mjs} +4 -5
- package/dist/{get-Hc93A0Yz.mjs → get-DDF7_apz.mjs} +5 -6
- package/dist/{get-D3SbEQSE.mjs → get-DYgLtHb8.mjs} +4 -5
- package/dist/{get-CP3Z3NiH.mjs → get-DnK3WGDH.mjs} +6 -7
- package/dist/{get-C2p383Qc.mjs → get-DnyZMx-0.mjs} +5 -6
- package/dist/{get-DFxZXaKz.mjs → get-DtG5ytvs.mjs} +5 -7
- package/dist/{get-CzuzeKSe.mjs → get-Dy4NedW5.mjs} +7 -8
- package/dist/{get-Ddr0XLh7.mjs → get-_JI4GiPa.mjs} +5 -6
- package/dist/{get-run-B7sKdaDU.mjs → get-run-CZwIo5QR.mjs} +5 -6
- package/dist/{get-lb7q3JYs.mjs → get-xo5_PD1n.mjs} +3 -4
- package/dist/git-sync-Ch00miSa.mjs +28 -0
- package/dist/{has-remote-changes-BY10-nnE.mjs → has-remote-changes-tuuoPdHV.mjs} +7 -7
- package/dist/{import-CiMz4Wz-.mjs → import-BOzyRPTk.mjs} +11 -10
- package/dist/{is-dirty-BZOaryxT.mjs → is-dirty-BXN1F9yR.mjs} +5 -5
- package/dist/is-dirty-Bc1UHnBU.mjs +9 -0
- package/dist/{items-BWfvkY-J.mjs → items-CC4sSWv7.mjs} +4 -5
- package/dist/{list-SOG0whQ-.mjs → list-BUpOvQsd.mjs} +3 -4
- package/dist/{list-Clz5igWg.mjs → list-BlMpI88r.mjs} +4 -6
- package/dist/{list-2j7GsXsl.mjs → list-BqTdYtOW.mjs} +3 -4
- package/dist/{list-C3hfovHv.mjs → list-BvTuDJZp.mjs} +4 -5
- package/dist/{list-DZ8fNUoQ.mjs → list-C48ZZLM5.mjs} +6 -7
- package/dist/{list-BI4zr8LW.mjs → list-CJe45jFT.mjs} +6 -7
- package/dist/{list-D4sFiqX8.mjs → list-CMoG5_mh.mjs} +5 -6
- package/dist/{list-d58BprgJ.mjs → list-CkI3hESA.mjs} +4 -5
- package/dist/{list-sD5N3fGk.mjs → list-CybLzPZw.mjs} +6 -7
- package/dist/{list-CL7eCOQE.mjs → list-DLhU81LP.mjs} +3 -4
- package/dist/{list-Brgh-Z2v.mjs → list-Ddyb5T-7.mjs} +4 -5
- package/dist/{list-DXH7TlkU.mjs → list-tveV3LKh.mjs} +4 -5
- package/dist/{list--OYdUTtu.mjs → list-u7cmunGG.mjs} +4 -5
- package/dist/{login-Bm2AnCez.mjs → login-Bfsf6jLq.mjs} +17 -14
- package/dist/{logout-BlyRJODO.mjs → logout-BCsE_1Yg.mjs} +9 -9
- package/dist/{manifest-BBR46KFM.mjs → manifest-B_OfG-Ss.mjs} +1 -2
- package/dist/measure-D_eiCKq9.mjs +19 -0
- package/dist/{metadata-B8ZSF9LA.mjs → metadata-Cbqx1-yW.mjs} +7 -8
- package/dist/{metadata-DqiI2q9q.mjs → metadata-CzbGy4b-.mjs} +6 -7
- package/dist/{parse-id-lk_K-CEF.mjs → parse-id-DBwNYb4Y.mjs} +1 -1
- package/dist/{path-AEtZ3mBq.mjs → path-DJ-DfUGC.mjs} +4 -6
- package/dist/{poll-DHKDpCiq.mjs → poll-DWkVceIk.mjs} +1 -1
- package/dist/{poll-task-Cooi0lQV.mjs → poll-task-DOvUDrgL.mjs} +19 -3
- package/dist/{preflight-aXV5LyDs.mjs → preflight-D-l6sLCX.mjs} +3 -3
- package/dist/{query-AaKzYnTY.mjs → query--05TZxmk.mjs} +9 -8
- package/dist/{query-BlsVNZpD.mjs → query-BbbDpt3u.mjs} +12 -12
- package/dist/query-result-PoQE05Pe.mjs +19 -0
- package/dist/{remove-collection-CoCmrrQs.mjs → remove-collection-Dco3yXa-.mjs} +10 -9
- package/dist/{render-OQn3iRsI.mjs → render-BQHJhSP1.mjs} +1 -1
- package/dist/{rescan-values-C0FDsjT7.mjs → rescan-values-B1vE6I62.mjs} +9 -10
- package/dist/{run-B4Wn43zm.mjs → run-CWb_yZbK.mjs} +14 -14
- package/dist/{runs-Bbaszr18.mjs → runs-BLwEO5sW.mjs} +5 -6
- package/dist/{runtime-Dmv5VtUK.mjs → runtime-DKLBPRhd.mjs} +16 -87
- package/dist/{schema-tables-CaWinbuK.mjs → schema-tables-D1qE25GS.mjs} +6 -7
- package/dist/{schemas-DUgGpAyB.mjs → schemas-CFuYnQDg.mjs} +4 -5
- package/dist/{search-BLrBXLUk.mjs → search-CF4A051Z.mjs} +4 -5
- package/dist/segment-BP_vDpYM.mjs +19 -0
- package/dist/{set-DfGsta5O.mjs → set-BJ8Rs-vI.mjs} +7 -7
- package/dist/setting-EYI0HqTq.mjs +17 -0
- package/dist/{setup-C9ikBRw_.mjs → setup-DI6EGOdH.mjs} +7 -8
- package/dist/{skills-CiN1OQ8W.mjs → skills-BDPVoBWU.mjs} +33 -2
- package/dist/{skills-CUHIcQS6.mjs → skills-CRECMGAo.mjs} +3 -3
- package/dist/snippet-BwK58D1F.mjs +19 -0
- package/dist/{stash-EIDcSvpF.mjs → stash-BpPS0uG8.mjs} +11 -10
- package/dist/{status-95ElRAu9.mjs → status-BqFA7Tqr.mjs} +10 -8
- package/dist/{status-B0_MiZEf.mjs → status-CU5LYX0i.mjs} +4 -5
- package/dist/{summary-C12LiEuJ.mjs → summary-CraRyIM_.mjs} +5 -6
- package/dist/{sync-schema-Ba8M3DiX.mjs → sync-schema-DkfwPESH.mjs} +9 -10
- package/dist/table-CJMN6ql8.mjs +19 -0
- package/dist/{table-C7a5V6Zn.mjs → table-CkWja2UH.mjs} +1 -1
- package/dist/transform-BqV5ssDN.mjs +24 -0
- package/dist/transform-job-DvdOLV9b.mjs +19 -0
- package/dist/{tree-Des2ZG9d.mjs → tree-Bd1i-Y4U.mjs} +3 -4
- package/dist/{update-DzAN4SPj.mjs → update-BLZHmA0X.mjs} +10 -11
- package/dist/{update-CyIZdbIQ.mjs → update-BncGqeWt.mjs} +9 -10
- package/dist/{update-DSgceARZ.mjs → update-C4f-8fsU.mjs} +9 -10
- package/dist/{update-njHe3j-s.mjs → update-CgpgyDjd.mjs} +10 -11
- package/dist/{update-DBi5U8zb.mjs → update-CsYa--Eb.mjs} +12 -13
- package/dist/{update-mYVnoYNV.mjs → update-DA9aPhRr.mjs} +11 -12
- package/dist/{update-_QfgNa53.mjs → update-DtO-1_tj.mjs} +10 -11
- package/dist/{update-Bx54nWEI.mjs → update-IPsv9Pj0.mjs} +12 -13
- package/dist/{update-F6DmZncY.mjs → update-OZoOTnlY.mjs} +9 -10
- package/dist/{update-dashcard-wpSjv4M7.mjs → update-dashcard-D0VAwfNO.mjs} +8 -9
- package/dist/{upgrade-iAuvhX-W.mjs → upgrade-Bb_q7hJ7.mjs} +41 -28
- package/dist/{uuid-CMKnS8-z.mjs → uuid-DTdRruiz.mjs} +3 -4
- package/dist/{validate-dPEOnOf8.mjs → validate-CqVB_3_p.mjs} +1 -1
- package/dist/{validate-query-Cw6WE5Y8.mjs → validate-query-BUTNK00f.mjs} +2 -2
- package/dist/values-Bpt6obVW.mjs +44 -0
- package/dist/{verify-D5YtTqqp.mjs → verify-COt2q73-.mjs} +1 -1
- package/dist/{wait-Bv3Tsnv4.mjs → wait-DoKPlspq.mjs} +8 -9
- package/dist/{wait-flags-Dzq9BGQY.mjs → wait-flags-D1jNm0JK.mjs} +2 -2
- package/package.json +1 -1
- package/skill-data/core/SKILL.md +15 -28
- package/skill-data/git-sync/SKILL.md +8 -63
- package/skill-data/mbql/SKILL.md +2 -0
- package/skill-data/transform/SKILL.md +16 -6
- package/skill-data/visualization/SKILL.md +158 -0
- package/skill-data/visualization/references/settings.md +414 -0
- package/skills/metabase-cli/SKILL.md +1 -1
- package/dist/add-collection-C0w6ACQF.mjs +0 -11
- package/dist/auth-CzXb_zB2.mjs +0 -19
- package/dist/capabilities-7e9MgquN.mjs +0 -29
- package/dist/card-DP4rfoOi.mjs +0 -21
- package/dist/collection-tY18ezvn.mjs +0 -21
- package/dist/create-CHF313Qg.mjs +0 -52
- package/dist/credentials-dzeq7ckm.mjs +0 -88
- package/dist/dashboard-ChM_Tu0l.mjs +0 -22
- package/dist/database-CIXwHKjK.mjs +0 -17
- package/dist/db-DrQn_i3W.mjs +0 -22
- package/dist/delete-CM3jnAeQ.mjs +0 -100
- package/dist/deprovision-CwxcIT3k.mjs +0 -65
- package/dist/docker-Oq80q3tu.mjs +0 -515
- package/dist/field-Z6Pcxf4n.mjs +0 -19
- package/dist/git-sync-CiGAad76.mjs +0 -28
- package/dist/is-dirty-Ume4oV0j.mjs +0 -10
- package/dist/license-Dxarh-gG.mjs +0 -17
- package/dist/list-zSO0DMw-.mjs +0 -36
- package/dist/logs-CywPikkL.mjs +0 -60
- package/dist/measure-C44EK_xt.mjs +0 -20
- package/dist/parse-schemas-BqUdWUwq.mjs +0 -12
- package/dist/process-C7V8LJ-j.mjs +0 -105
- package/dist/provision-UWcNDoDe.mjs +0 -82
- package/dist/ps-CJU0EbrC.mjs +0 -80
- package/dist/ps-DEroLgbI.mjs +0 -11
- package/dist/remove-BFWun0e8.mjs +0 -63
- package/dist/segment-B3Uwwcsm.mjs +0 -20
- package/dist/set-B8cUbRLD.mjs +0 -68
- package/dist/setting-D2p2MA7f.mjs +0 -18
- package/dist/snippet-B7D0uWlz.mjs +0 -20
- package/dist/start-3PX3ahjT.mjs +0 -413
- package/dist/status-CEplmC44.mjs +0 -34
- package/dist/stop-CQ0XGrN8.mjs +0 -83
- package/dist/table-e6h8SLVX.mjs +0 -20
- package/dist/transform-BMYh1lsC.mjs +0 -25
- package/dist/transform-job-Cm7z5TfH.mjs +0 -20
- package/dist/update-DHZubok3.mjs +0 -77
- package/dist/url-DWaT6WIZ.mjs +0 -56
- package/dist/values-BfSTAbzc.mjs +0 -37
- package/dist/wait-8yV9_WIo.mjs +0 -19
- package/dist/workspace-BBXJczJK.mjs +0 -72
- package/dist/workspace-CKLZrR7l.mjs +0 -26
- package/dist/workspace-credentials-BXpABsNZ.mjs +0 -100
- package/dist/yaml-YTQiYJ9s.mjs +0 -43
- package/skill-data/viz/SKILL.md +0 -137
- package/skill-data/viz/references/settings.md +0 -312
- package/skill-data/workspace/SKILL.md +0 -390
- /package/dist/{body-flags-D7q87Btw.mjs → body-flags-D78h_-Ua.mjs} +0 -0
- /package/dist/{input-cMSEqISy.mjs → input-xewHccej.mjs} +0 -0
- /package/dist/{parse-enum-CrEWOhuY.mjs → parse-enum-Dr7ACrTR.mjs} +0 -0
- /package/dist/{prompt-CFKoys7k.mjs → prompt-u4WhE4T5.mjs} +0 -0
- /package/dist/{snippet-COggaWxx.mjs → snippet-xh42tYly.mjs} +0 -0
- /package/dist/{transform-GTW3G-01.mjs → transform-DyJb0bV0.mjs} +0 -0
- /package/dist/{transform-job-DeTDPMxt.mjs → transform-job-DpDGoqQt.mjs} +0 -0
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { ConfigError } from "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { outputFlags } from "./error-
|
|
3
|
-
import { defineMetabaseCommand, parseInteger } from "./runtime-
|
|
4
|
-
import "./capabilities-
|
|
5
|
-
import { writeJson, writeText } from "./render-CfznwleY.mjs";
|
|
2
|
+
import { outputFlags } from "./error-Br6irjpM.mjs";
|
|
3
|
+
import { defineMetabaseCommand, parseInteger } from "./runtime-DKLBPRhd.mjs";
|
|
4
|
+
import { writeJson, writeText } from "./capabilities-Dj3NgPHg.mjs";
|
|
6
5
|
import { z } from "zod";
|
|
7
6
|
import { randomUUID } from "node:crypto";
|
|
8
7
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ConfigError, escapeJsonPointerSegment } from "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { isPlainObject } from "./capabilities-
|
|
2
|
+
import { isPlainObject } from "./capabilities-Dj3NgPHg.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import Ajv2020 from "ajv/dist/2020.js";
|
|
5
5
|
import addFormats from "ajv-formats";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ConfigError } from "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { writeJson } from "./
|
|
3
|
-
import { assertNotLegacyEnvelopeWrappingMbql5, isMbql5Query, validateQuery } from "./validate-
|
|
2
|
+
import { writeJson } from "./capabilities-Dj3NgPHg.mjs";
|
|
3
|
+
import { assertNotLegacyEnvelopeWrappingMbql5, isMbql5Query, validateQuery } from "./validate-CqVB_3_p.mjs";
|
|
4
4
|
|
|
5
5
|
//#region src/commands/validate-query.ts
|
|
6
6
|
const skipValidateFlag = { "skip-validate": {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-Br6irjpM.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-DKLBPRhd.mjs";
|
|
4
|
+
import { formatScalar, renderSummary } from "./capabilities-Dj3NgPHg.mjs";
|
|
5
|
+
import { FieldValues, fieldValuesView } from "./field-MGxpNQUH.mjs";
|
|
6
|
+
import { parseId } from "./parse-id-DBwNYb4Y.mjs";
|
|
7
|
+
|
|
8
|
+
//#region src/commands/field/values.ts
|
|
9
|
+
var values_default = defineMetabaseCommand({
|
|
10
|
+
meta: {
|
|
11
|
+
name: "values",
|
|
12
|
+
description: "Fetch the cached distinct values for a field (FieldValues list)"
|
|
13
|
+
},
|
|
14
|
+
capabilities: { minVersion: 58 },
|
|
15
|
+
args: {
|
|
16
|
+
...outputFlags,
|
|
17
|
+
...profileFlag,
|
|
18
|
+
...connectionFlags,
|
|
19
|
+
id: {
|
|
20
|
+
type: "positional",
|
|
21
|
+
description: "Field id",
|
|
22
|
+
required: true
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
outputSchema: FieldValues,
|
|
26
|
+
examples: ["mb field values 100", "mb field values 100 --json"],
|
|
27
|
+
async run({ args, ctx, getClient }) {
|
|
28
|
+
const id = parseId(args.id);
|
|
29
|
+
const client = await getClient();
|
|
30
|
+
const values = await client.requestParsed(FieldValues, `/api/field/${id}/values`);
|
|
31
|
+
const fieldId = values.field_id ?? id;
|
|
32
|
+
const count = values.values.length;
|
|
33
|
+
renderSummary(values, fieldValuesView, () => {
|
|
34
|
+
if (count === 0) return `Field ${fieldId} has no cached values.`;
|
|
35
|
+
const more = values.has_more_values === true ? " (more available; rescan for the full set)" : "";
|
|
36
|
+
const header = `Field ${fieldId} has ${count} cached value${count === 1 ? "" : "s"}${more}:`;
|
|
37
|
+
const lines = values.values.map((row) => ` ${formatScalar(row[0])}`);
|
|
38
|
+
return [header, ...lines].join("\n");
|
|
39
|
+
}, ctx);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
//#endregion
|
|
44
|
+
export { values_default as default };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { MetabaseError, NetworkError, TimeoutError, errorMessage } from "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { HttpError, createClient, probeServer } from "./runtime-
|
|
2
|
+
import { HttpError, createClient, probeServer } from "./runtime-DKLBPRhd.mjs";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
5
5
|
//#region src/domain/user.ts
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import "./command-augment-BH9qgQ5u.mjs";
|
|
2
|
-
import { connectionFlags, outputFlags, profileFlag } from "./error-
|
|
3
|
-
import { defineMetabaseCommand } from "./runtime-
|
|
4
|
-
import "./capabilities-
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS } from "./poll-DHKDpCiq.mjs";
|
|
2
|
+
import { connectionFlags, outputFlags, profileFlag } from "./error-Br6irjpM.mjs";
|
|
3
|
+
import { defineMetabaseCommand } from "./runtime-DKLBPRhd.mjs";
|
|
4
|
+
import { renderSummary } from "./capabilities-Dj3NgPHg.mjs";
|
|
5
|
+
import { parseId } from "./parse-id-DBwNYb4Y.mjs";
|
|
6
|
+
import { SyncTaskOrIdle, formatSyncTask, pollSyncTask, syncTaskIdleView, syncTaskView, throwIfFailedTask } from "./poll-task-DOvUDrgL.mjs";
|
|
7
|
+
import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS } from "./poll-DWkVceIk.mjs";
|
|
9
8
|
|
|
10
9
|
//#region src/commands/git-sync/wait.ts
|
|
11
10
|
const WaitResult = SyncTaskOrIdle;
|
|
@@ -45,10 +44,10 @@ var wait_default = defineMetabaseCommand({
|
|
|
45
44
|
});
|
|
46
45
|
if (final === null) {
|
|
47
46
|
const idle = { status: "idle" };
|
|
48
|
-
|
|
47
|
+
renderSummary(idle, syncTaskIdleView, "No git-sync task is running.", ctx);
|
|
49
48
|
return;
|
|
50
49
|
}
|
|
51
|
-
|
|
50
|
+
renderSummary(final, syncTaskView, formatSyncTask(final), ctx);
|
|
52
51
|
throwIfFailedTask(final, "task");
|
|
53
52
|
}
|
|
54
53
|
});
|
|
@@ -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-DBwNYb4Y.mjs";
|
|
2
|
+
import { DEFAULT_INTERVAL_MS, DEFAULT_TIMEOUT_MS } from "./poll-DWkVceIk.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/commands/wait-flags.ts
|
|
5
5
|
const waitScheduleFlags = {
|
package/package.json
CHANGED
package/skill-data/core/SKILL.md
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: core
|
|
3
|
-
description: Drive a Metabase instance from the terminal via the `mb` CLI — auth, databases, cards, dashboards, collections, transforms, queries, search, git-sync
|
|
3
|
+
description: Drive a Metabase instance from the terminal via the `mb` CLI — auth, databases, cards, dashboards, collections, transforms, queries, search, git-sync. Use for any `mb <verb>` task.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# metabase-cli (core)
|
|
8
8
|
|
|
9
|
-
The official Metabase CLI (`mb`) drives a Metabase instance over its REST API. It covers auth, list/get/create/update/delete on every resource, query and transform execution, content search, git-sync (representations ↔ instance),
|
|
9
|
+
The official Metabase CLI (`mb`) drives a Metabase instance over its REST API. It covers auth, list/get/create/update/delete on every resource, query and transform execution, content search, git-sync (representations ↔ instance), and entity-id translation.
|
|
10
10
|
|
|
11
11
|
Top-level command groups (run `mb <group> --help` to discover verbs):
|
|
12
12
|
|
|
13
13
|
```
|
|
14
14
|
auth | db | table | field | query | card | dashboard | snippet | segment | measure | collection
|
|
15
|
-
transform | transform-job | setting | search | git-sync |
|
|
15
|
+
transform | transform-job | setting | search | git-sync | setup | eid | uuid | upgrade | skills
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
The patterns below — auth, flag conventions, output flags, body input — apply across **every** group. Per-command flags, examples, and output schemas live in `mb __manifest` (see below). A few flows have their own specialized skills; load them on demand (see "Specialized skills"). Authoring any query body (cards, transforms, measures, segments, ad-hoc `mb query`) is one — load `mbql` whenever you build MBQL by hand.
|
|
@@ -21,8 +21,6 @@ The patterns below — auth, flag conventions, output flags, body input — appl
|
|
|
21
21
|
|
|
22
22
|
**The agent does not log in for the user.** Authentication is the human's job — they pick the base URL, paste credentials, and store them as a named profile. The agent's role is to _check_ what profiles exist, _ask_ which to use, and pass `--profile <name>` through every command.
|
|
23
23
|
|
|
24
|
-
**The one exception** is a freshly bootstrapped workspace child: its API key is minted by the parent the human already authorized, so the agent reads it via `mb workspace credentials <ws-id>` and saves it with `auth login` — piping the key on **stdin** (`printf '%s' "$KEY" | mb auth login …`), never on an `--api-key` flag (the CLI rejects the flag form). See the `workspace` skill, step 4.
|
|
25
|
-
|
|
26
24
|
### Discover what's already configured
|
|
27
25
|
|
|
28
26
|
```bash
|
|
@@ -35,17 +33,7 @@ mb auth status --profile <name> --json # → status of a specific profile
|
|
|
35
33
|
|
|
36
34
|
### Pick the profile to use
|
|
37
35
|
|
|
38
|
-
If exactly one profile is configured and the user's intent doesn't disambiguate, use it. If multiple profiles exist and the user hasn't named one, ask via `AskUserQuestion`, presenting the names from `auth list`. Once a name is established, pass `--profile <name>` to **every** subsequent command. Profile names are arbitrary local labels — `prod`, `staging
|
|
39
|
-
|
|
40
|
-
### Other secrets (license, warehouse passwords)
|
|
41
|
-
|
|
42
|
-
Same rule: the human runs the storing command. To check whether a license is present:
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
mb workspace license status --json # → {present: bool}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
If `present: false`, ask the user to run `echo "<your-token>" | mb workspace license set` from their terminal — don't paste the token in chat.
|
|
36
|
+
If exactly one profile is configured and the user's intent doesn't disambiguate, use it. If multiple profiles exist and the user hasn't named one, ask via `AskUserQuestion`, presenting the names from `auth list`. Once a name is established, pass `--profile <name>` to **every** subsequent command. Profile names are arbitrary local labels — `prod`, `staging` — let the user pick.
|
|
49
37
|
|
|
50
38
|
## Flag conventions
|
|
51
39
|
|
|
@@ -56,21 +44,21 @@ If `present: false`, ask the user to run `echo "<your-token>" | mb workspace lic
|
|
|
56
44
|
❌ mb --profile prod table list # → error: "Unknown command prod"
|
|
57
45
|
```
|
|
58
46
|
|
|
59
|
-
`--profile` attaches **after** the full verb chain (`table list`, `card get`, `
|
|
47
|
+
`--profile` attaches **after** the full verb chain (`table list`, `card get`, `git-sync export`).
|
|
60
48
|
|
|
61
49
|
### `--wait` for async operations
|
|
62
50
|
|
|
63
|
-
`
|
|
51
|
+
`transform run`, `git-sync import`, and similar async verbs return immediately by default. Pass `--wait` for any interactive flow where the next step depends on completion. Without it you'll race the operation and see "not ready" / transient connection refusals.
|
|
64
52
|
|
|
65
53
|
### Some outputs are JSON envelopes, not bare strings
|
|
66
54
|
|
|
67
|
-
A handful of "lookup" verbs return a JSON object even when you only want a single field. `mb
|
|
55
|
+
A handful of "lookup" verbs return a JSON object even when you only want a single field. `mb setting get <key>` returns `{"key": "...", "value": ...}`, not the bare value. Don't drop them raw into another flag — extract:
|
|
68
56
|
|
|
69
57
|
```bash
|
|
70
|
-
|
|
58
|
+
VALUE=$(mb setting get <key> --json | jq -r '.value')
|
|
71
59
|
```
|
|
72
60
|
|
|
73
|
-
If you find yourself
|
|
61
|
+
If you find yourself piping a `--json` envelope straight into another flag and the receiving command rejects it, this is what happened.
|
|
74
62
|
|
|
75
63
|
## Output
|
|
76
64
|
|
|
@@ -78,7 +66,7 @@ Every list/get verb supports the same output flags:
|
|
|
78
66
|
|
|
79
67
|
- `--json` — emit the full JSON envelope, safe for `jq`. Default is human-readable text.
|
|
80
68
|
- `--full` — include every field (compact projection is the default for list/get).
|
|
81
|
-
- `--fields a,b.c.d` — project specific dot-paths. Mutually exclusive with `--full`.
|
|
69
|
+
- `--fields a,b.c.d` — project specific dot-paths. Mutually exclusive with `--full`. **Paths are relative to each `data[]` item on list verbs, and to the root on single-item verbs.** So it's `--fields id,name` on `… list` / `database schema-tables` (the projection runs per row) — `data.id` and `data[].id` both fail with `unknown field path: "data.id"`. On single-object verbs the path is root-relative: `--fields id,name,display` on `card get`, and `--fields data.rows` on `mb query` (whose `data` is an object, not an array).
|
|
82
70
|
- `--max-bytes <n>` — cap **list** output size (drops trailing items, sets `truncated`). Default 65 536; `0` disables. Single-item commands (`get`, `metadata`) never truncate — they emit a stderr advisory when over the cap.
|
|
83
71
|
|
|
84
72
|
List envelope shape:
|
|
@@ -144,7 +132,7 @@ Routine verb shapes (list / get / create / update), every flag, and output JSON
|
|
|
144
132
|
- **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.
|
|
145
133
|
- **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.
|
|
146
134
|
- **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.
|
|
147
|
-
- **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; use negative ids for new 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.
|
|
135
|
+
- **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; use negative ids for new cards). `create` accepts the **same** `dashcards` array in its initial body, so you can 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.
|
|
148
136
|
- **snippet `--archived` is a swap, not a union** — list returns _either_ active _or_ archived rows, never both. (Same shape for `--filter archived` on dashboard/collection.)
|
|
149
137
|
- **segment / measure** `update` and `archive` require a non-blank `revision_message` (audit-logged); the CLI does not synthesize it on `update`. `archive` defaults to `"Archived via mb CLI"` — override with `--revision-message`. `definition` is a flat MBQL clause (→ `mbql` skill): segment = a filter, measure = exactly one aggregation.
|
|
150
138
|
- **collection `<ref>`** accepts four forms only — positive int, `root`, `trash`, or a 21-char entity_id — anything else is a client-side `ConfigError`. `collection items` auto-paginates (cap with `--limit`, which then omits `total`). `collection tree` is **JSON-only** — `--format text` is rejected.
|
|
@@ -157,11 +145,10 @@ Routine verb shapes (list / get / create / update), every flag, and output JSON
|
|
|
157
145
|
|
|
158
146
|
## Specialized skills (load on demand)
|
|
159
147
|
|
|
160
|
-
This core file is enough for any single-command task. Load the relevant skill **proactively** when intent matches — don't wing an MBQL body,
|
|
148
|
+
This core file is enough for any single-command task. Load the relevant skill **proactively** when intent matches — don't wing an MBQL body, a transform body, or the git-sync workflow from this overview alone. Load each via `mb skills get <name>`.
|
|
161
149
|
|
|
162
150
|
- **`mbql`** — authoring or fixing any MBQL query body: `mb query`, a card `dataset_query`, a transform `source.query`, a measure/segment `definition`, "aggregate and group by", reading `--dry-run` errors. The query-body reference.
|
|
163
151
|
- **`viz`** — choosing a card's `display` and authoring `visualization_settings`: "make it a bar chart", "set the pie dimension/metric", "format this column as currency", "the card renders as a table instead of a chart". The presentation counterpart to `mbql`.
|
|
164
|
-
- **`workspace`** — "spin up a workspace", "provision", "start a local Metabase against my prod", anything `mb workspace …`. **Mandatory** before `workspace start` — ask the user about Remote Sync up front (the bind mount is create-time only).
|
|
165
152
|
- **`transform`** — "create a transform", "run a transform", authoring transform body JSON, run inspection.
|
|
166
153
|
- **`git-sync`** — "import the latest changes", "export to git", "git sync", "dirty check", "stash before pulling".
|
|
167
154
|
|
|
@@ -169,9 +156,9 @@ If a task spans more than one, load each. Specialized skills assume the conventi
|
|
|
169
156
|
|
|
170
157
|
## Don't
|
|
171
158
|
|
|
172
|
-
- **Don't run `mb auth login` for the user** — authentication is theirs (see §Auth).
|
|
173
|
-
- Don't paste credentials
|
|
159
|
+
- **Don't run `mb auth login` for the user** — authentication is theirs (see §Auth).
|
|
160
|
+
- Don't paste credentials or warehouse passwords in chat. Have the user run the storing command.
|
|
174
161
|
- Don't put `--profile` before the verb chain — the CLI parses it as a subcommand and errors out.
|
|
175
|
-
- Don't omit `--wait` on `
|
|
162
|
+
- Don't omit `--wait` on `transform run` / `git-sync import` for interactive flows; the next step will race the operation.
|
|
176
163
|
- Don't drop a JSON-envelope verb's output raw into another flag. Extract with `--json | jq -r '.<field>'`.
|
|
177
164
|
- Don't add a third-party HTTP library or shell into `curl` against `/api/...` when a `mb <verb>` exists — that bypasses retries, schema validation, and credential redaction.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: git-sync
|
|
3
|
-
description: Round-trip Metabase content (cards, dashboards, transforms, snippets, collections) between an instance and a git remote via `mb git-sync …` — status, dirty / has-remote-changes checks, import
|
|
3
|
+
description: Round-trip Metabase content (cards, dashboards, transforms, snippets, collections) between an instance and a git remote via `mb git-sync …` — status, dirty / has-remote-changes checks, import, export (with branch guard), branches, stash, add/remove a collection from sync. Load when the user wants to "import the latest changes", "export to git", "git sync", "dirty check", "stash before pulling", "add a collection to sync", or anything `mb git-sync …`.
|
|
4
4
|
allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -75,25 +75,6 @@ Workflow:
|
|
|
75
75
|
2. `git-sync has-remote-changes` — confirm there's actually something to import.
|
|
76
76
|
3. `git-sync import --branch <branch>` — runs to terminal status by default.
|
|
77
77
|
|
|
78
|
-
### First import on a fresh workspace
|
|
79
|
-
|
|
80
|
-
After `workspace start --repo …` brings up a brand-new workspace, the repo content **must be applied** before any other work — without it the instance has none of the repo content and subsequent edits will diverge from what's on disk.
|
|
81
|
-
|
|
82
|
-
The container runs a boot-time auto-import on first start, so in most cases the import has already completed by the time `workspace start --wait` returns. Check `git-sync status` first — if `current_task.sync_task_type == "import"` with `status == "successful"` and `.branch` matches the host's branch, you're done; skip the explicit call (it's a wasted round-trip). Only run the explicit `git-sync import` when the auto-import hasn't landed yet.
|
|
83
|
-
|
|
84
|
-
When you do need the explicit import, the first one on a fresh instance can report `status: conflict` (typically `conflicts: ["Transforms"]`) even when nothing is dirty — the boot-time auto-import sometimes leaves a stale task record that the first explicit import collides with. Retry the same command once; the second call usually succeeds. If it keeps reporting conflict, `git-sync import --force` is safe in this specific case because the workspace is empty — there's no instance-side work for `--force` to discard. (This is a narrow exception to the usual "confirm with the user before `--force`" rule.)
|
|
85
|
-
|
|
86
|
-
```bash
|
|
87
|
-
HOST_BRANCH=$(git -C <repo-path> symbolic-ref --short HEAD)
|
|
88
|
-
SYNC_STATUS=$(mb git-sync status --profile <ws-name> --json)
|
|
89
|
-
if ! echo "$SYNC_STATUS" | jq -e --arg b "$HOST_BRANCH" \
|
|
90
|
-
'.current_task.sync_task_type == "import" and .current_task.status == "successful" and (.branch == $b)' >/dev/null; then
|
|
91
|
-
mb git-sync import --branch "$HOST_BRANCH" --profile <ws-name> --json \
|
|
92
|
-
|| mb git-sync import --branch "$HOST_BRANCH" --profile <ws-name> --json \
|
|
93
|
-
|| mb git-sync import --branch "$HOST_BRANCH" --force --profile <ws-name> --json
|
|
94
|
-
fi
|
|
95
|
-
```
|
|
96
|
-
|
|
97
78
|
## Export (instance → remote)
|
|
98
79
|
|
|
99
80
|
```bash
|
|
@@ -111,61 +92,26 @@ Pushes Metabase-side changes back to the configured remote. `-m` is the commit m
|
|
|
111
92
|
|
|
112
93
|
Workflow:
|
|
113
94
|
|
|
114
|
-
1. **Branch guard** (below) — confirm the
|
|
95
|
+
1. **Branch guard** (below) — confirm the instance isn't tracking `main`/`master`, or that the user has explicitly accepted exporting to it.
|
|
115
96
|
2. `git-sync is-dirty` — confirm there's something to export.
|
|
116
97
|
3. `git-sync export -m "..."` — pushes and polls.
|
|
117
98
|
4. (Optional) `git-sync status` — verify `dirty: false` after.
|
|
118
|
-
5. **Working-tree drift** (below) — if this is a `--repo` bind-mount workspace, the host repo's working tree + index will lag behind the new HEAD. Surface this and offer to realign.
|
|
119
99
|
|
|
120
100
|
### Branch guard: don't export to main/master without confirmation
|
|
121
101
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
Reading the current branch:
|
|
102
|
+
Sync work is conventionally done on a feature branch — exporting to `main` (or `master`) commits team-shared content directly. Before `git-sync export`, check the tracked branch and if it's `main`/`master`, ask the user whether to switch first.
|
|
125
103
|
|
|
126
|
-
|
|
127
|
-
- Otherwise: `mb git-sync status --profile <n> --json | jq -r '.branch'`.
|
|
104
|
+
Read the current branch with `mb git-sync status --profile <n> --json | jq -r '.branch'`.
|
|
128
105
|
|
|
129
106
|
If the branch is `main` or `master`, prompt with `AskUserQuestion`:
|
|
130
107
|
|
|
131
|
-
> "The
|
|
108
|
+
> "The instance is tracking `<branch>` — exporting commits straight to it. Switch to a feature branch first?"
|
|
132
109
|
>
|
|
133
|
-
> 1. **Create a feature branch
|
|
134
|
-
> 2. **
|
|
135
|
-
> 3. **Proceed on `main`/`master`** — explicitly accepted; surface the resulting commit (`git -C <repo> log --oneline -1`) afterwards so the user can amend or revert.
|
|
110
|
+
> 1. **Create a feature branch** — agent suggests a name (e.g., `agent/<task>`); run `mb git-sync create-branch <name> --profile <n>`. This exports current dirty state to the new branch and switches the instance's tracked branch to it; subsequent `git-sync export` calls go to that branch.
|
|
111
|
+
> 2. **Proceed on `main`/`master`** — explicitly accepted.
|
|
136
112
|
|
|
137
113
|
Skip the prompt only if the user's instructions already specified the branch (e.g., they explicitly said "export to main" or named a feature branch). Don't silently default to whatever `remote-sync-branch` happens to point at.
|
|
138
114
|
|
|
139
|
-
### Post-export: working-tree drift on `--repo` bind-mount workspaces
|
|
140
|
-
|
|
141
|
-
When the workspace exports against a host bind mount, the in-container serializer writes the new commit object directly into the bind-mounted `.git/` (creating tree/blob objects and advancing the branch ref) but **does not update the host's working tree or index**. After a successful export, the host repo state is:
|
|
142
|
-
|
|
143
|
-
- HEAD: the new export commit.
|
|
144
|
-
- Index: still matches the _previous_ HEAD (whatever the user had staged before).
|
|
145
|
-
- Working tree: still matches the _previous_ HEAD.
|
|
146
|
-
|
|
147
|
-
`git status` then shows "Changes to be committed" that look like the export's content reverting back — purely a display artifact, not an actual revert. The container does this on purpose to avoid clobbering work-in-progress on the host. **Realigning is _applying_ the new HEAD's content to your worktree, not discarding work** — the new commit was written by the exporter, not by your local edits, and your tree/index are stale relative to the new HEAD until you realign.
|
|
148
|
-
|
|
149
|
-
**Surface this to the user** after an export against a `--repo` workspace — don't leave them staring at a confusing `git status`. Offer to realign.
|
|
150
|
-
|
|
151
|
-
**Prefer `git restore` over `git reset --hard`.** When the only "changes" are the drift artifact (no real local edits), `git restore` does the same job and isn't classified as a destructive operation by Claude Code's permission system — `git reset --hard` is, and gets blocked even after a user-confirmation dialog:
|
|
152
|
-
|
|
153
|
-
```bash
|
|
154
|
-
git -C <repo> restore --staged --worktree . # non-destructive; aligns index + working tree to HEAD
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
This is the right default after a `git-sync export` realignment when the user had nothing else staged. If `git status` shows a mix of drift artifacts and real pending work, fall back to the stash sequence:
|
|
158
|
-
|
|
159
|
-
```bash
|
|
160
|
-
git -C <repo> stash --include-untracked
|
|
161
|
-
git -C <repo> restore --staged --worktree .
|
|
162
|
-
git -C <repo> stash pop
|
|
163
|
-
```
|
|
164
|
-
|
|
165
|
-
`git reset --hard HEAD` is the canonical equivalent and still valid — but **confirm with the user** before running it, and expect Claude Code to gate it as destructive even after the dialog. `git restore --staged --worktree .` produces the same end-state with less friction.
|
|
166
|
-
|
|
167
|
-
Or pull in the new files selectively with `git -C <repo> checkout HEAD -- <path>`. Quick check that this is what you're seeing: `git -C <repo> diff --cached HEAD~1 --stat` returns empty (the index matches the parent commit, not the new HEAD).
|
|
168
|
-
|
|
169
115
|
## Branches
|
|
170
116
|
|
|
171
117
|
```bash
|
|
@@ -191,6 +137,5 @@ Use `wait` after `import --no-wait` / `export --no-wait`. Use `cancel-task` if a
|
|
|
191
137
|
- Don't drive `git-sync` against a Metabase instance that doesn't have remote-sync configured — every verb returns an error pointing at the missing `remote-sync-*` settings. To check: `mb setting get remote-sync-url --profile <n> --json`.
|
|
192
138
|
- Don't author content directly via `card create` / `transform create` and then assume `git-sync export` will commit it cleanly — the instance and repo can drift if you mix direct API writes with sync-tracked changes. If you do, follow direct writes immediately with `git-sync export -m "..."` to keep them in step.
|
|
193
139
|
- Don't omit `-m` on `export` if the user wants a meaningful commit message — the default server-generated message is generic.
|
|
194
|
-
- Don't `git-sync export` to `main`/`master` without explicit user confirmation —
|
|
195
|
-
- Don't pretend the host's `git status` is clean after `git-sync export` against a `--repo` bind mount — the export advances HEAD but leaves the working tree + index behind. See "Working-tree drift" above.
|
|
140
|
+
- Don't `git-sync export` to `main`/`master` without explicit user confirmation — sync work is conventionally on a feature branch. See "Branch guard" above.
|
|
196
141
|
- Don't reach for `mb setting set` to mark a collection as remote-synced — that endpoint writes single-key settings, not the bulk `collections` map. Use `mb git-sync add-collection <id>` / `mb git-sync remove-collection <id>` (see "Adding / removing a directory (collection) to sync" above), and remember the toggle cascades to descendants.
|
package/skill-data/mbql/SKILL.md
CHANGED
|
@@ -87,6 +87,8 @@ mb query --file q.json --profile <n> --json # 3. validate +
|
|
|
87
87
|
|
|
88
88
|
`path` is a JSON Pointer into the body (`/stages/0/aggregation/0`); `message` is the validator error. Exit codes: `0` valid + ran, `2` validation failed / malformed body, `1` server-side error after a valid pre-flight.
|
|
89
89
|
|
|
90
|
+
A successful run emits the **full `/api/dataset` envelope** — `data.rows`, `data.cols`, plus heavy `data.results_metadata` and per-column fingerprints. For ad-hoc exploration project `--fields data.rows` (add `data.cols` if you need column names); without it even a few rows render as hundreds of lines of metadata. (`mb query` also runs a **native** body — `{database, type:"native", native:{query:"SELECT …"}}` — which skips pre-flight and is the quickest way to eyeball raw warehouse data; same `--fields data.rows` advice applies.)
|
|
91
|
+
|
|
90
92
|
`--skip-validate` bypasses the pre-flight and sends as-is — use only when the bundled schema disagrees with what the server actually accepts (drift / false negative). Mutually exclusive with `--dry-run`. The same flag exists on `card create/update` and `transform create/update`.
|
|
91
93
|
|
|
92
94
|
## Where MBQL 5 is consumed
|
|
@@ -8,7 +8,7 @@ allowed-tools: Read, Write, Edit, Bash, AskUserQuestion
|
|
|
8
8
|
|
|
9
9
|
A **transform** persists the result of a query (native SQL or MBQL) to a warehouse table the user can read from cards, dashboards, and other transforms. It runs on a schedule (via `transform-job`) or on-demand (`transform run`).
|
|
10
10
|
|
|
11
|
-
This skill covers the create-and-run flow. The general flag conventions, body-input precedence, and output flags live in the `core` skill (`mb skills get core`).
|
|
11
|
+
This skill covers the create-and-run flow. The general flag conventions, body-input precedence, and output flags live in the `core` skill (`mb skills get core`).
|
|
12
12
|
|
|
13
13
|
## Body shape
|
|
14
14
|
|
|
@@ -53,13 +53,14 @@ mb transform run "$TRANSFORM_ID" --wait --profile <name> --json
|
|
|
53
53
|
|
|
54
54
|
Notes:
|
|
55
55
|
|
|
56
|
-
- `<db-id>` comes from `mb database list --profile <name> --json`. Database ids are per-instance
|
|
57
|
-
- Target `schema` is the
|
|
56
|
+
- `<db-id>` comes from `mb database list --profile <name> --json`. Database ids are per-instance.
|
|
57
|
+
- Target `schema` is the schema the result table is written into (e.g. `public`).
|
|
58
58
|
- `--wait` on `transform run` polls until status is `succeeded` or `failed`. Without it you only get `{message: "Transform run started", run_id, final: null}` and have to poll yourself.
|
|
59
59
|
- The `--json` envelope is shape-stable: `{message, run_id, final}`. `final` is always present — `null` when `--wait` is omitted or the run never started, otherwise a full `TransformRun` object with `status` and `message`. On a failed run (`final.status` ∈ {`failed`, `timeout`, `canceled`}) the CLI exits 1 and writes a one-line summary `transform run <id> failed` to stderr; the failure detail lives only in `final.message` on stdout, so `jq -r '.final.message'` is where to look.
|
|
60
60
|
- The heredoc with single-quoted `'EOF'` prevents shell from interpolating any `$vars` inside the SQL.
|
|
61
61
|
- `transform create --json` returns the agent-facing compact projection: `{id, name, description, source_type, target: {type, database, schema, name}, target_db_id}`. Read `target.schema`/`target.name` directly off the create output — no follow-up `transform get` needed to verify where the transform will write.
|
|
62
62
|
- If a transform with the same `name` already has a YAML representation on disk under the configured remote-sync repo, `create` mints a `_2` suffix on the exported filename (the new transform gets a fresh `entity_id`; the prior one isn't touched). For "iterate on the same concept" workflows, prefer `transform update <id>` — see "Iterating on a failing transform" below.
|
|
63
|
+
- **`collection_id` only accepts a collection in the `:transforms` namespace.** Transforms aren't filed next to cards and dashboards — passing a normal analytics collection id (the kind a dashboard lives in) fails create/update with `collection_id: A Transform can only go in Collections in the :transforms namespace.` Omit `collection_id` to leave the transform uncollected (the common case), or pass a collection created in the transforms namespace. Cards and dashboards you build **on top of** the transform's output table go in ordinary collections as usual — so "put the transform and its dashboard in collection X" generally means *X holds the dashboard + cards; the transform stays in the transforms namespace.*
|
|
63
64
|
|
|
64
65
|
## Inspect
|
|
65
66
|
|
|
@@ -68,7 +69,16 @@ mb transform list --profile <name> --json
|
|
|
68
69
|
mb transform get <id> --profile <name> --full --json # full transform incl. last run summary
|
|
69
70
|
```
|
|
70
71
|
|
|
71
|
-
After a run, the materialized table
|
|
72
|
+
After a run, the materialized table physically exists in the warehouse, but Metabase doesn't know about it yet. **Native SQL** (a native `card`, or `mb query` against `<schema>.<name>`) reads it immediately — native runs straight against the warehouse. **MBQL and the Metabase UI cannot reference it until the instance syncs**, because they address tables and columns by numeric id and a brand-new table has none. To build MBQL cards on a fresh output table:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
mb database sync-schema <db-id> --profile <name> --json # async — returns {status:"ok"} at once
|
|
76
|
+
# poll until the new table appears (sync is not instant):
|
|
77
|
+
mb database schema-tables <db-id> <schema> --profile <name> --json --fields id,name
|
|
78
|
+
mb table get <table-id> --include fields --profile <name> --json # then grab the field ids
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Columns and types are inferred from the result set; if you change the SELECT shape, drop the table first (`transform delete-table <id>`) or the next run will fail on a column-mismatch error. A changed shape also needs a re-sync before MBQL sees the new/renamed columns.
|
|
72
82
|
|
|
73
83
|
## Inspect runs and cancel an in-flight run
|
|
74
84
|
|
|
@@ -107,10 +117,11 @@ Column "TAGS" not found; SQL statement:
|
|
|
107
117
|
UPDATE "TRANSFORM" SET "TAGS" = (), "UPDATED_AT" = NOW() WHERE "ID" = ? [42122-214]
|
|
108
118
|
```
|
|
109
119
|
|
|
110
|
-
|
|
120
|
+
Three specific footguns:
|
|
111
121
|
|
|
112
122
|
- **`tags` is not a key on the REST API.** The serdes/YAML representation uses `tags`; the REST contract uses `tag_ids` (an array of integer ids). If you pulled a YAML representation and want to PUT it, translate `tags: [...]` → `tag_ids: [...]` first (or omit it entirely if you're not changing tag membership).
|
|
113
123
|
- **`source_type`, `target_db_id`, `target_table_id`, `entity_id`** are derived/computed by the server. They appear in GET responses for the agent's benefit; the server doesn't accept them on update.
|
|
124
|
+
- **`collection_id` must be a `:transforms`-namespace collection** — a regular card/dashboard collection id is rejected with `A Transform can only go in Collections in the :transforms namespace.` Omit it unless you have one (see the create notes above). Round-tripping the existing value is safe; setting it to an ordinary collection is what fails.
|
|
114
125
|
|
|
115
126
|
Right shape — patch only what changes:
|
|
116
127
|
|
|
@@ -193,5 +204,4 @@ A schedule lives in a separate resource (`transform-job`) and references one or
|
|
|
193
204
|
|
|
194
205
|
- Don't put `transform run` calls in tight polling loops — pass `--wait` and let the CLI handle the polling. Manual loops without `--wait` will hammer the server.
|
|
195
206
|
- Don't author MBQL 4 (the legacy nested `{ type: "query", query: {...} }` shape) by hand — pull a sample with `mb transform get <id> --full --json`. MBQL 5 (`lib/type: "mbql/query"`) **is** authorable by hand thanks to the `mb query --print-schema` + `--dry-run` feedback loop; for non-trivial pipelines you may still prefer building in the UI and exporting.
|
|
196
|
-
- Don't write the workspace isolation schema into `target.schema` or SQL. See the `workspace` skill for the canonical-name rule.
|
|
197
207
|
- Don't paste a `transform get` body into `transform update` — the PUT endpoint only accepts writable keys, and unknown keys (notably `tags`, `source_type`, `entity_id`, `created_at`, `last_run`) leak as raw SQL errors. See "Update body: send only writable keys" above. Use `tag_ids` (not `tags`) on the REST contract.
|