@koda-sl/baker-cli 0.176.0 → 0.177.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -79,7 +79,7 @@ import {
79
79
  } from "./chunk-YL3HDEIJ.js";
80
80
 
81
81
  // src/cli.ts
82
- import { defineCommand as defineCommand188, runMain } from "citty";
82
+ import { defineCommand as defineCommand191, runMain } from "citty";
83
83
 
84
84
  // src/commands/actions/index.ts
85
85
  import { defineCommand as defineCommand18 } from "citty";
@@ -2440,7 +2440,13 @@ var CAPABILITY_SURFACE_SPECS = {
2440
2440
  label: "Google Analytics 4",
2441
2441
  provider: "google-analytics",
2442
2442
  resourceNoun: "property",
2443
- writePath: "read-only",
2443
+ // Like Tag Manager: staged during the chat, applied for real at publish,
2444
+ // with no simulated mode. A connection made before writes existed is
2445
+ // read-only until it is reconnected, and `access` does NOT say so — it
2446
+ // reports what the Baker app asks Google for, which is now app-wide
2447
+ // read-write. The per-company signal is `scopeBlockers`, which compares
2448
+ // `writeScopes` against the scopes that connection actually recorded.
2449
+ writePath: "staged-immediate",
2444
2450
  writeScopes: ["https://www.googleapis.com/auth/analytics.edit"],
2445
2451
  commands: "baker ga4"
2446
2452
  },
@@ -2538,6 +2544,7 @@ var chatChangeTypeSchema = z7.enum([
2538
2544
  "google-ads",
2539
2545
  "meta-ads",
2540
2546
  "tag-manager",
2547
+ "ga4",
2541
2548
  // Immediate (already-applied) library effects — see lib/chatChanges.ts.
2542
2549
  "image",
2543
2550
  "video",
@@ -26575,7 +26582,7 @@ Full guide: __tooling__/docs/tools/baker/flows.md`
26575
26582
  });
26576
26583
 
26577
26584
  // src/commands/ga4/index.ts
26578
- import { defineCommand as defineCommand108 } from "citty";
26585
+ import { defineCommand as defineCommand111 } from "citty";
26579
26586
 
26580
26587
  // src/commands/ga4/audit.ts
26581
26588
  import { defineCommand as defineCommand105 } from "citty";
@@ -26698,8 +26705,306 @@ Examples:
26698
26705
  }
26699
26706
  });
26700
26707
 
26701
- // src/commands/ga4/properties.ts
26708
+ // src/commands/ga4/config.ts
26702
26709
  import { defineCommand as defineCommand106 } from "citty";
26710
+
26711
+ // src/commands/ga4/shared.ts
26712
+ import { readFileSync as readFileSync10 } from "fs";
26713
+ function failValidation2(message) {
26714
+ writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
26715
+ process.exit(1);
26716
+ }
26717
+ function requireTarget4(args, entity) {
26718
+ const positional = Array.isArray(args._) ? args._[0] : void 0;
26719
+ const target = args.id ?? args.target ?? positional;
26720
+ if (typeof target !== "string" || target.length === 0) {
26721
+ failValidation2(`pass the ${entity} id as the positional argument`);
26722
+ }
26723
+ return target;
26724
+ }
26725
+ function readJsonSource(args, flag) {
26726
+ const inline = args[flag];
26727
+ const file = args.file;
26728
+ const raw = typeof file === "string" && file.length > 0 ? readFileSync10(file, "utf8") : typeof inline === "string" && inline.length > 0 ? inline : void 0;
26729
+ if (raw === void 0) {
26730
+ failValidation2(`pass --${flag} with inline JSON or --file with a path to a JSON file`);
26731
+ }
26732
+ try {
26733
+ return JSON.parse(raw);
26734
+ } catch {
26735
+ return failValidation2(`--${flag} is not valid JSON`);
26736
+ }
26737
+ }
26738
+ function asObject(value, flag, index) {
26739
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
26740
+ failValidation2(
26741
+ index === void 0 ? `--${flag} must be a JSON object` : `--${flag}[${index}] must be a JSON object`
26742
+ );
26743
+ }
26744
+ return value;
26745
+ }
26746
+ function loadJsonArg(args, flag = "json") {
26747
+ return asObject(readJsonSource(args, flag), flag);
26748
+ }
26749
+ function loadJsonPayloads(args) {
26750
+ const parsed = readJsonSource(args, "json");
26751
+ if (!Array.isArray(parsed)) {
26752
+ return [asObject(parsed, "json")];
26753
+ }
26754
+ if (parsed.length === 0) {
26755
+ failValidation2("--json is an empty list \u2014 pass at least one definition");
26756
+ }
26757
+ return parsed.map((entry, index) => asObject(entry, "json", index));
26758
+ }
26759
+ var RETRYABLE_CODES = /* @__PURE__ */ new Set(["RATE_LIMITED", "INTERNAL_ERROR", "NETWORK_ERROR", "TIMEOUT"]);
26760
+ function handleError(err) {
26761
+ if (err instanceof ApiError) {
26762
+ const readOnly = err.code === "FORBIDDEN" && /read the property but not change it/i.test(err.message);
26763
+ writeJsonEnvelope({
26764
+ ok: false,
26765
+ error: {
26766
+ code: err.code,
26767
+ message: err.message,
26768
+ ...readOnly ? {
26769
+ fix: {
26770
+ action: "reconnect",
26771
+ explanation: "The Google Analytics connection is read-only. Ask the user to reconnect Google Analytics \u2014 in the dashboard, Brain \u2192 Integrations \u2192 Tools \u2192 Google Analytics \u2014 which grants the permission to change the property. Reporting (`baker ga4 query`, `baker ga4 audit`) keeps working meanwhile, so carry on with the rest of the job and tell them what you will set up once they have reconnected. Do NOT claim anything was configured."
26772
+ }
26773
+ } : err.code === "UNAUTHORIZED" || err.code === "FORBIDDEN" && isNotConnectedError(err.code, err.message) ? {
26774
+ fix: {
26775
+ action: "request_connection",
26776
+ explanation: 'Google Analytics is not connected for this company yet, or no property has been picked. Do NOT send the user to Settings \u2014 call the `request_connection` tool with { platform: "google-analytics", reason } and they connect and pick their property from inside the chat. If `request_connection` is not available to you, say so plainly and point them at dashboard \u2192 Brain \u2192 Integrations \u2192 Tools \u2192 Google Analytics. Carry on with the rest of the task meanwhile.'
26777
+ }
26778
+ } : {},
26779
+ retryable: RETRYABLE_CODES.has(err.code)
26780
+ }
26781
+ });
26782
+ process.exit(1);
26783
+ }
26784
+ writeJsonEnvelope({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error", retryable: true } });
26785
+ process.exit(1);
26786
+ }
26787
+ var STAGE_HINTS = [
26788
+ "Staged only \u2014 nothing has changed in Google Analytics yet. These apply when the chat completes, and an applied change takes effect on the property immediately: there is no version to publish afterwards and no undo. Say the changes are ready and take effect when the user completes the chat \u2014 not that they are done already."
26789
+ ];
26790
+ var WARNING_HINT = "Read the warnings above before telling the user this is ready.";
26791
+ async function stageOp3(op) {
26792
+ const chatId = requireChatId();
26793
+ try {
26794
+ const data = await apiPost("/api/ga4/draft/stage", { chatId, op });
26795
+ writeJsonEnvelope({
26796
+ ok: true,
26797
+ data,
26798
+ hints: [...STAGE_HINTS, ...data.warnings.length > 0 ? [WARNING_HINT] : []]
26799
+ });
26800
+ } catch (err) {
26801
+ handleError(err);
26802
+ }
26803
+ }
26804
+ async function stageOps(ops) {
26805
+ const [only] = ops;
26806
+ if (ops.length === 1 && only) {
26807
+ await stageOp3(only);
26808
+ return;
26809
+ }
26810
+ const chatId = requireChatId();
26811
+ try {
26812
+ const data = await apiPost("/api/ga4/draft/stage-batch", { chatId, ops });
26813
+ writeJsonEnvelope({
26814
+ ok: true,
26815
+ data,
26816
+ hints: [...STAGE_HINTS, ...data.ops.some((op) => op.warnings.length > 0) ? [WARNING_HINT] : []]
26817
+ });
26818
+ } catch (err) {
26819
+ handleError(err);
26820
+ }
26821
+ }
26822
+ async function draftAction2(path28, body, chat) {
26823
+ const chatId = resolveChatId(chat);
26824
+ try {
26825
+ const data = await apiPost(path28, { chatId, ...body });
26826
+ writeJsonEnvelope({ ok: true, data });
26827
+ return data;
26828
+ } catch (err) {
26829
+ handleError(err);
26830
+ }
26831
+ }
26832
+ function renderDraft(response) {
26833
+ if (response.count === 0) {
26834
+ return "No Google Analytics changes staged on this chat.";
26835
+ }
26836
+ const lines = [
26837
+ `${response.count} staged Google Analytics change(s)`,
26838
+ ...response.ops.map((op) => {
26839
+ const status = op.result ? ` [${op.result.status}]` : "";
26840
+ return ` ${op.ref} ${op.summary}${status}`;
26841
+ })
26842
+ ];
26843
+ if (response.status === "applied") {
26844
+ const failed = response.ops.filter((op) => op.result?.status !== "applied");
26845
+ lines.push(
26846
+ "",
26847
+ failed.length === 0 ? "All applied \u2014 these are in effect on the property now." : `${failed.length} of ${response.count} did not apply. The rest are in effect on the property.`
26848
+ );
26849
+ }
26850
+ if (response.publishError) {
26851
+ lines.push("", response.publishError);
26852
+ }
26853
+ return lines.join("\n");
26854
+ }
26855
+ async function draftList(json, chat) {
26856
+ const chatId = resolveChatId(chat);
26857
+ try {
26858
+ const data = await apiPost("/api/ga4/draft", { chatId });
26859
+ if (json) {
26860
+ writeJsonEnvelope({ ok: true, data });
26861
+ return;
26862
+ }
26863
+ process.stdout.write(`${renderDraft(data)}
26864
+ `);
26865
+ } catch (err) {
26866
+ handleError(err);
26867
+ }
26868
+ }
26869
+
26870
+ // src/commands/ga4/config.ts
26871
+ registerSchema({
26872
+ command: "ga4.config",
26873
+ description: "Read how a Google Analytics property is configured to measure: key events (conversions), custom dimensions and metrics, custom events, data streams and the data retention window. Start here before staging any change \u2014 every id an update or removal targets comes from this, and `canWrite` says whether this connection may change anything at all. Compact by default; pass --full for the raw Analytics objects.",
26874
+ args: {
26875
+ "property-id": { type: "string", description: "GA4 property id (optional when one is connected)", required: false },
26876
+ full: { type: "boolean", description: "Include the raw Analytics object for each entity", required: false }
26877
+ }
26878
+ });
26879
+ function configHints(config) {
26880
+ const hints = [];
26881
+ if (!config.canWrite) {
26882
+ hints.push(
26883
+ "This connection can READ this property but not change it. Do not promise to configure anything \u2014 ask the user to reconnect Google Analytics in the dashboard first, and carry on with the reporting side of the job."
26884
+ );
26885
+ }
26886
+ if (config.keyEvents.length === 0) {
26887
+ hints.push(
26888
+ "This property has no key events, so nothing is being counted as a conversion and Google Ads has nothing to import. Ask what counts as a lead or sale before proposing anything else."
26889
+ );
26890
+ }
26891
+ if (config.dataRetention.eventDataRetention === "TWO_MONTHS") {
26892
+ hints.push(
26893
+ "Event data is only kept for 2 months, which makes any long-window analysis impossible. `baker ga4 data-retention set --event-data 14` stages the fix."
26894
+ );
26895
+ }
26896
+ if (config.dataStreams.filter((stream) => stream.type === "WEB_DATA_STREAM").length > 1) {
26897
+ hints.push("This property has more than one website data stream \u2014 pass --data-stream when staging a custom event.");
26898
+ }
26899
+ return hints;
26900
+ }
26901
+ var configCommand = defineCommand106({
26902
+ meta: {
26903
+ name: "config",
26904
+ description: `Read how the property is configured to measure \u2014 key events, custom definitions, custom events, retention
26905
+
26906
+ Examples:
26907
+ baker ga4 config
26908
+ baker ga4 config --property-id 123456789
26909
+ baker ga4 config --full`
26910
+ },
26911
+ args: {
26912
+ "property-id": { type: "string", description: "GA4 property id", required: false },
26913
+ full: { type: "boolean", description: "Include raw Analytics objects", required: false }
26914
+ },
26915
+ run: async ({ args }) => {
26916
+ try {
26917
+ const data = await apiPost("/api/ga4/config", {
26918
+ ...typeof args["property-id"] === "string" ? { propertyId: args["property-id"] } : {},
26919
+ ...args.full === true ? { full: true } : {}
26920
+ });
26921
+ writeJsonEnvelope({ ok: true, data, hints: configHints(data) });
26922
+ } catch (err) {
26923
+ handleError(err);
26924
+ }
26925
+ }
26926
+ });
26927
+
26928
+ // src/commands/ga4/draft.ts
26929
+ import { defineCommand as defineCommand107 } from "citty";
26930
+ registerSchema({
26931
+ command: "ga4.draft",
26932
+ description: "Review and undo the Google Analytics changes staged on this chat. Use `list` to see everything staged, `show` to inspect one change in full before the chat completes, `amend` to correct one in place, and `remove`/`clear` to drop them. `list` and `show` take --chat <id> to read an earlier chat's changes instead.",
26933
+ args: {
26934
+ json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list", required: false },
26935
+ chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
26936
+ }
26937
+ });
26938
+ var draftCommand3 = defineCommand107({
26939
+ meta: {
26940
+ name: "draft",
26941
+ description: "List, show, amend, remove or clear the Google Analytics changes staged on this chat. `list` and `show` take --chat <id> to read an earlier chat's changes instead."
26942
+ },
26943
+ subCommands: {
26944
+ list: defineCommand107({
26945
+ meta: { name: "list", description: "Review everything staged on this chat (--json for the raw envelope)" },
26946
+ args: {
26947
+ json: { type: "boolean", description: "Print the raw JSON envelope", required: false },
26948
+ chat: CHAT_READ_ARG
26949
+ },
26950
+ run: async ({ args }) => {
26951
+ await draftList(args.json === true, args.chat);
26952
+ }
26953
+ }),
26954
+ show: defineCommand107({
26955
+ meta: {
26956
+ name: "show",
26957
+ description: "Print the full staged payload for one change, alongside how the property looks today \u2014 the receipt to verify it before the chat completes (never truncated)."
26958
+ },
26959
+ args: {
26960
+ ref: { type: "positional", description: "Staged ref or target id", required: false },
26961
+ chat: CHAT_READ_ARG
26962
+ },
26963
+ run: async ({ args }) => {
26964
+ await draftAction2(
26965
+ "/api/ga4/draft/show",
26966
+ { ref: requireTarget4(args, "change") },
26967
+ args.chat
26968
+ );
26969
+ }
26970
+ }),
26971
+ amend: defineCommand107({
26972
+ meta: {
26973
+ name: "amend",
26974
+ description: "Update a staged change in place \u2014 merges a JSON patch into its payload (objects deep-merge, null deletes a key, arrays/scalars replace) and re-runs every check. Use this instead of remove + re-create."
26975
+ },
26976
+ args: {
26977
+ ref: { type: "positional", description: "Staged ref or target id", required: false },
26978
+ patch: { type: "string", description: "Inline JSON patch object", required: false },
26979
+ file: { type: "string", description: "JSON file with the patch object", required: false }
26980
+ },
26981
+ run: async ({ args }) => {
26982
+ await draftAction2("/api/ga4/draft/amend", {
26983
+ ref: requireTarget4(args, "change"),
26984
+ patch: loadJsonArg(args, "patch")
26985
+ });
26986
+ }
26987
+ }),
26988
+ remove: defineCommand107({
26989
+ meta: { name: "remove", description: "Remove one staged change" },
26990
+ args: { ref: { type: "positional", description: "Staged ref or target id", required: false } },
26991
+ run: async ({ args }) => {
26992
+ await draftAction2("/api/ga4/draft/remove", {
26993
+ ref: requireTarget4(args, "change")
26994
+ });
26995
+ }
26996
+ }),
26997
+ clear: defineCommand107({
26998
+ meta: { name: "clear", description: "Discard all Google Analytics changes staged on this chat" },
26999
+ run: async () => {
27000
+ await draftAction2("/api/ga4/draft/clear", {});
27001
+ }
27002
+ })
27003
+ }
27004
+ });
27005
+
27006
+ // src/commands/ga4/properties.ts
27007
+ import { defineCommand as defineCommand108 } from "citty";
26703
27008
  registerSchema({
26704
27009
  command: "ga4.properties",
26705
27010
  description: "List the GA4 properties this company connected \u2014 there can be several, and every one of them is yours to query. Returns the property IDs the query and audit commands take. Run this first to find property IDs.",
@@ -26715,7 +27020,7 @@ function propertyHints(properties) {
26715
27020
  resources: properties.map((property) => ({ id: property.externalId, label: property.name }))
26716
27021
  });
26717
27022
  }
26718
- var propertiesCommand = defineCommand106({
27023
+ var propertiesCommand = defineCommand108({
26719
27024
  meta: {
26720
27025
  name: "properties",
26721
27026
  description: `List accessible GA4 properties.
@@ -26763,9 +27068,9 @@ Examples:
26763
27068
  });
26764
27069
 
26765
27070
  // src/commands/ga4/query.ts
26766
- import { appendFileSync as appendFileSync2, existsSync as existsSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync3 } from "fs";
27071
+ import { appendFileSync as appendFileSync2, existsSync as existsSync5, readFileSync as readFileSync11, writeFileSync as writeFileSync3 } from "fs";
26767
27072
  import { resolve as resolve2 } from "path";
26768
- import { defineCommand as defineCommand107 } from "citty";
27073
+ import { defineCommand as defineCommand109 } from "citty";
26769
27074
 
26770
27075
  // src/commands/ga4/presets.ts
26771
27076
  var GA4_PRESETS = [
@@ -26854,7 +27159,7 @@ function writeRowsToFile2(filePath, rows, append) {
26854
27159
  writeFileSync3(filePath, content, "utf-8");
26855
27160
  }
26856
27161
  } else if (append && existsSync5(filePath)) {
26857
- const existing = JSON.parse(readFileSync10(filePath, "utf-8"));
27162
+ const existing = JSON.parse(readFileSync11(filePath, "utf-8"));
26858
27163
  writeFileSync3(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
26859
27164
  } else {
26860
27165
  writeFileSync3(filePath, JSON.stringify(rows, null, 2), "utf-8");
@@ -26886,7 +27191,7 @@ function buildRequestBody(args, propertyId, useCache) {
26886
27191
  if (!useCache) body.skipCache = true;
26887
27192
  return body;
26888
27193
  }
26889
- function handleError(err) {
27194
+ function handleError2(err) {
26890
27195
  if (err instanceof ApiError) {
26891
27196
  if (isNotConnectedError(err.code, err.message)) {
26892
27197
  handleConnectionError("ga4", err.message);
@@ -26900,7 +27205,7 @@ function handleError(err) {
26900
27205
  });
26901
27206
  process.exit(1);
26902
27207
  }
26903
- var queryCommand2 = defineCommand107({
27208
+ var queryCommand2 = defineCommand109({
26904
27209
  meta: {
26905
27210
  name: "query",
26906
27211
  description: `Run GA4 Data API reports. Preset-first with free-form escape hatch.
@@ -26965,42 +27270,421 @@ Free-form (escape hatch):
26965
27270
  }
26966
27271
  outputRows(response.data ?? [], args, response, false);
26967
27272
  } catch (err) {
26968
- handleError(err);
27273
+ handleError2(err);
27274
+ }
27275
+ }
27276
+ });
27277
+
27278
+ // src/commands/ga4/write-commands.ts
27279
+ import { defineCommand as defineCommand110 } from "citty";
27280
+ var PROPERTY_ARG_DESCRIPTION = "GA4 property id (optional only when one property is connected \u2014 run `baker ga4 properties`)";
27281
+ var propertyArg = { type: "string", description: PROPERTY_ARG_DESCRIPTION, required: false };
27282
+ function createJsonDescription(noun) {
27283
+ return `Inline JSON ${noun} definition, or a JSON array of them to stage several in one call (all or none)`;
27284
+ }
27285
+ function withProperty(args) {
27286
+ return typeof args["property-id"] === "string" ? { propertyId: args["property-id"] } : {};
27287
+ }
27288
+ registerSchema({
27289
+ command: "ga4.keyEvent",
27290
+ description: "Mark an event as a key event (what Google Analytics calls a conversion, and what Google Ads imports for bidding), change how it is counted, or stop counting it. Read `baker ga4 config` first: the event has to be one the site actually sends, and marking an automatic event like page_view poisons Smart Bidding.",
27291
+ args: {
27292
+ json: { type: "string", description: createJsonDescription("key-event"), required: false },
27293
+ file: { type: "string", description: "Path to a JSON file with the definition", required: false },
27294
+ "property-id": { type: "string", description: PROPERTY_ARG_DESCRIPTION, required: false }
27295
+ }
27296
+ });
27297
+ var keyEventCommand = defineCommand110({
27298
+ meta: {
27299
+ name: "key-event",
27300
+ description: `Stage key-event (conversion) changes
27301
+
27302
+ Examples:
27303
+ baker ga4 key-event create --json '{"eventName":"generate_lead","countingMethod":"ONCE_PER_EVENT"}'
27304
+ baker ga4 key-event create --json '{"eventName":"purchase","countingMethod":"ONCE_PER_EVENT","defaultValue":{"numericValue":50,"currencyCode":"EUR"}}'
27305
+ baker ga4 key-event create --json '[{\u2026}, {\u2026}]' \u2014 several in one call, one read of the property
27306
+ baker ga4 key-event update 4185 --json '{"countingMethod":"ONCE_PER_SESSION"}'
27307
+ baker ga4 key-event delete 4185`
27308
+ },
27309
+ subCommands: {
27310
+ create: defineCommand110({
27311
+ meta: {
27312
+ name: "create",
27313
+ description: "Stage a new key event. Needs eventName and countingMethod (ONCE_PER_EVENT or ONCE_PER_SESSION); defaultValue sets a monetary value when the event does not send one."
27314
+ },
27315
+ args: {
27316
+ json: { type: "string", description: createJsonDescription("key-event"), required: false },
27317
+ file: { type: "string", description: "Path to a JSON file", required: false },
27318
+ "property-id": propertyArg
27319
+ },
27320
+ run: async ({ args }) => {
27321
+ const input = args;
27322
+ await stageOps(
27323
+ loadJsonPayloads(input).map((payload) => ({
27324
+ kind: "ga4.keyEvent.create",
27325
+ payload,
27326
+ ...withProperty(input)
27327
+ }))
27328
+ );
27329
+ }
27330
+ }),
27331
+ update: defineCommand110({
27332
+ meta: {
27333
+ name: "update",
27334
+ description: "Stage a change to an existing key event (pass its id). Only countingMethod and defaultValue can change \u2014 Google will not rename a key event."
27335
+ },
27336
+ args: {
27337
+ id: { type: "positional", description: "Key event id", required: false },
27338
+ json: { type: "string", description: "Inline JSON with the changed fields", required: false },
27339
+ file: { type: "string", description: "Path to a JSON file", required: false },
27340
+ "property-id": propertyArg
27341
+ },
27342
+ run: async ({ args }) => {
27343
+ await stageOp3({
27344
+ kind: "ga4.keyEvent.update",
27345
+ target: requireTarget4(args, "key event"),
27346
+ payload: loadJsonArg(args),
27347
+ ...withProperty(args)
27348
+ });
27349
+ }
27350
+ }),
27351
+ delete: defineCommand110({
27352
+ meta: {
27353
+ name: "delete",
27354
+ description: "Stage removing a key event, so the event stops counting as a conversion. The event itself keeps being collected. Irreversible once the chat completes \u2014 confirm with the user first."
27355
+ },
27356
+ args: {
27357
+ id: { type: "positional", description: "Key event id", required: false },
27358
+ "property-id": propertyArg
27359
+ },
27360
+ run: async ({ args }) => {
27361
+ await stageOp3({
27362
+ kind: "ga4.keyEvent.delete",
27363
+ target: requireTarget4(args, "key event"),
27364
+ ...withProperty(args)
27365
+ });
27366
+ }
27367
+ })
27368
+ }
27369
+ });
27370
+ var DEFINITIONS = [
27371
+ {
27372
+ command: "custom-dimension",
27373
+ kind: "customDimension",
27374
+ noun: "custom dimension",
27375
+ createHint: "Needs parameterName (the event parameter the site sends), displayName, and scope (EVENT, USER or ITEM). Until a parameter has a custom dimension, it is collected but cannot be reported on.",
27376
+ example: '{"parameterName":"plan_tier","displayName":"Plan tier","scope":"EVENT"}'
27377
+ },
27378
+ {
27379
+ command: "custom-metric",
27380
+ kind: "customMetric",
27381
+ noun: "custom metric",
27382
+ createHint: "Needs parameterName, displayName, scope EVENT and measurementUnit (STANDARD, CURRENCY, SECONDS\u2026). A CURRENCY metric must also declare restrictedMetricType: COST_DATA or REVENUE_DATA.",
27383
+ example: '{"parameterName":"deal_value","displayName":"Deal value","scope":"EVENT","measurementUnit":"CURRENCY","restrictedMetricType":["REVENUE_DATA"]}'
27384
+ }
27385
+ ];
27386
+ for (const { kind, noun, createHint } of DEFINITIONS) {
27387
+ registerSchema({
27388
+ command: `ga4.${kind}`,
27389
+ description: `Create, update or archive a Google Analytics ${noun}. ${createHint} Archiving frees the slot and takes it out of reporting; historical data stays. Read \`baker ga4 config\` first \u2014 a duplicate parameter name is refused.`,
27390
+ args: {
27391
+ json: { type: "string", description: createJsonDescription(noun), required: false },
27392
+ file: { type: "string", description: "Path to a JSON file", required: false },
27393
+ "property-id": { type: "string", description: PROPERTY_ARG_DESCRIPTION, required: false }
27394
+ }
27395
+ });
27396
+ }
27397
+ function definitionCommand(definition) {
27398
+ const { command, kind, noun, example } = definition;
27399
+ return defineCommand110({
27400
+ meta: {
27401
+ name: command,
27402
+ description: `Stage ${noun} changes
27403
+
27404
+ Examples:
27405
+ baker ga4 ${command} create --json '${example}'
27406
+ baker ga4 ${command} create --json '[${example}, \u2026]' \u2014 several in one call, one read of the property
27407
+ baker ga4 ${command} update 12 --json '{"displayName":"Renamed"}'
27408
+ baker ga4 ${command} archive 12`
27409
+ },
27410
+ subCommands: {
27411
+ create: defineCommand110({
27412
+ meta: { name: "create", description: `Stage a new ${noun} (or a JSON array of them, staged together)` },
27413
+ args: {
27414
+ json: { type: "string", description: createJsonDescription(noun), required: false },
27415
+ file: { type: "string", description: "Path to a JSON file", required: false },
27416
+ "property-id": propertyArg
27417
+ },
27418
+ run: async ({ args }) => {
27419
+ const input = args;
27420
+ await stageOps(
27421
+ loadJsonPayloads(input).map((payload) => ({
27422
+ kind: `ga4.${kind}.create`,
27423
+ payload,
27424
+ ...withProperty(input)
27425
+ }))
27426
+ );
27427
+ }
27428
+ }),
27429
+ update: defineCommand110({
27430
+ meta: {
27431
+ name: "update",
27432
+ description: `Stage a change to an existing ${noun} (pass its id). The parameter name and scope cannot change \u2014 archive and recreate for that.`
27433
+ },
27434
+ args: {
27435
+ id: { type: "positional", description: `${noun} id`, required: false },
27436
+ json: { type: "string", description: "Inline JSON with the changed fields", required: false },
27437
+ file: { type: "string", description: "Path to a JSON file", required: false },
27438
+ "property-id": propertyArg
27439
+ },
27440
+ run: async ({ args }) => {
27441
+ await stageOp3({
27442
+ kind: `ga4.${kind}.update`,
27443
+ target: requireTarget4(args, noun),
27444
+ payload: loadJsonArg(args),
27445
+ ...withProperty(args)
27446
+ });
27447
+ }
27448
+ }),
27449
+ archive: defineCommand110({
27450
+ meta: {
27451
+ name: "archive",
27452
+ description: `Stage archiving a ${noun} (pass its id). It stops collecting and leaves reporting; past data stays. Irreversible once the chat completes \u2014 confirm with the user first.`
27453
+ },
27454
+ args: {
27455
+ id: { type: "positional", description: `${noun} id`, required: false },
27456
+ "property-id": propertyArg
27457
+ },
27458
+ run: async ({ args }) => {
27459
+ await stageOp3({
27460
+ kind: `ga4.${kind}.archive`,
27461
+ target: requireTarget4(args, noun),
27462
+ ...withProperty(args)
27463
+ });
27464
+ }
27465
+ })
26969
27466
  }
27467
+ });
27468
+ }
27469
+ var customDimensionCommand = definitionCommand(DEFINITIONS[0]);
27470
+ var customMetricCommand = definitionCommand(DEFINITIONS[1]);
27471
+ registerSchema({
27472
+ command: "ga4.customEvent",
27473
+ description: "Create a new Google Analytics event out of one the site already sends \u2014 the 'Create event' rule in the Analytics interface. Use it to turn a generic event into a meaningful one (a form_submit on the quote page becomes quote_request) so it can be marked a key event. Needs destinationEvent and 1-10 eventConditions; sourceCopyParameters carries the original parameters over.",
27474
+ args: {
27475
+ json: { type: "string", description: createJsonDescription("custom-event rule"), required: false },
27476
+ file: { type: "string", description: "Path to a JSON file", required: false },
27477
+ "data-stream": {
27478
+ type: "string",
27479
+ description: "Data stream id (optional when the property has one website stream)",
27480
+ required: false
27481
+ },
27482
+ "property-id": { type: "string", description: PROPERTY_ARG_DESCRIPTION, required: false }
27483
+ }
27484
+ });
27485
+ var CUSTOM_EVENT_EXAMPLE = '{"destinationEvent":"quote_request","eventConditions":[{"field":"event_name","comparisonType":"EQUALS","value":"form_submit"},{"field":"page_location","comparisonType":"CONTAINS","value":"/quote"}],"sourceCopyParameters":true}';
27486
+ var dataStreamArg = {
27487
+ type: "string",
27488
+ description: "Data stream id (optional when the property has one website stream)",
27489
+ required: false
27490
+ };
27491
+ function withStream(args) {
27492
+ return typeof args["data-stream"] === "string" ? { dataStream: args["data-stream"] } : {};
27493
+ }
27494
+ var customEventCommand = defineCommand110({
27495
+ meta: {
27496
+ name: "custom-event",
27497
+ description: `Stage custom events \u2014 new events built from events the site already sends
27498
+
27499
+ Examples:
27500
+ baker ga4 custom-event create --json '${CUSTOM_EVENT_EXAMPLE}'
27501
+ baker ga4 custom-event update 7 --json '{"sourceCopyParameters":false}'
27502
+ baker ga4 custom-event delete 7`
27503
+ },
27504
+ subCommands: {
27505
+ create: defineCommand110({
27506
+ meta: {
27507
+ name: "create",
27508
+ description: "Stage a new custom event. Conditions match the source event: use field `event_name` to match the event itself, or any parameter name to match its value."
27509
+ },
27510
+ args: {
27511
+ json: { type: "string", description: createJsonDescription("custom event"), required: false },
27512
+ file: { type: "string", description: "Path to a JSON file", required: false },
27513
+ "data-stream": dataStreamArg,
27514
+ "property-id": propertyArg
27515
+ },
27516
+ run: async ({ args }) => {
27517
+ const input = args;
27518
+ await stageOps(
27519
+ loadJsonPayloads(input).map((payload) => ({
27520
+ kind: "ga4.eventCreateRule.create",
27521
+ payload,
27522
+ ...withStream(input),
27523
+ ...withProperty(input)
27524
+ }))
27525
+ );
27526
+ }
27527
+ }),
27528
+ update: defineCommand110({
27529
+ meta: { name: "update", description: "Stage a change to an existing custom event (pass its id)" },
27530
+ args: {
27531
+ id: { type: "positional", description: "Custom event rule id", required: false },
27532
+ json: { type: "string", description: "Inline JSON with the changed fields", required: false },
27533
+ file: { type: "string", description: "Path to a JSON file", required: false },
27534
+ "data-stream": dataStreamArg,
27535
+ "property-id": propertyArg
27536
+ },
27537
+ run: async ({ args }) => {
27538
+ await stageOp3({
27539
+ kind: "ga4.eventCreateRule.update",
27540
+ target: requireTarget4(args, "custom event"),
27541
+ payload: loadJsonArg(args),
27542
+ ...withStream(args),
27543
+ ...withProperty(args)
27544
+ });
27545
+ }
27546
+ }),
27547
+ delete: defineCommand110({
27548
+ meta: {
27549
+ name: "delete",
27550
+ description: "Stage removing a custom event (pass its id). The event stops being created from then on; data already collected under it stays. Confirm with the user first."
27551
+ },
27552
+ args: {
27553
+ id: { type: "positional", description: "Custom event rule id", required: false },
27554
+ "data-stream": dataStreamArg,
27555
+ "property-id": propertyArg
27556
+ },
27557
+ run: async ({ args }) => {
27558
+ await stageOp3({
27559
+ kind: "ga4.eventCreateRule.delete",
27560
+ target: requireTarget4(args, "custom event"),
27561
+ ...withStream(args),
27562
+ ...withProperty(args)
27563
+ });
27564
+ }
27565
+ })
27566
+ }
27567
+ });
27568
+ registerSchema({
27569
+ command: "ga4.dataRetention",
27570
+ description: "Set how long Google Analytics keeps event and user data. Standard properties allow 2 or 14 months; longer windows need an Analytics 360 licence. Two months is the default on many properties and makes year-on-year and long-window attribution impossible, so 14 is almost always the right answer.",
27571
+ args: {
27572
+ "event-data": { type: "string", description: "Months to keep event data: 2, 14, 26, 38 or 50", required: false },
27573
+ "user-data": { type: "string", description: "Months to keep user data: 2, 14, 26, 38 or 50", required: false },
27574
+ "reset-on-activity": {
27575
+ type: "string",
27576
+ description: "true|false \u2014 restart a user's retention window on every new event from them",
27577
+ required: false
27578
+ },
27579
+ "property-id": { type: "string", description: PROPERTY_ARG_DESCRIPTION, required: false }
27580
+ }
27581
+ });
27582
+ var RETENTION_BY_MONTHS = {
27583
+ "2": "TWO_MONTHS",
27584
+ "14": "FOURTEEN_MONTHS",
27585
+ "26": "TWENTY_SIX_MONTHS",
27586
+ "38": "THIRTY_EIGHT_MONTHS",
27587
+ "50": "FIFTY_MONTHS"
27588
+ };
27589
+ function retentionValue(input, flag) {
27590
+ const normalized = input.trim();
27591
+ const mapped = RETENTION_BY_MONTHS[normalized] ?? (Object.values(RETENTION_BY_MONTHS).includes(normalized.toUpperCase()) ? normalized.toUpperCase() : void 0);
27592
+ if (!mapped) {
27593
+ failValidation2(`--${flag} must be one of 2, 14, 26, 38 or 50 (months)`);
27594
+ }
27595
+ return mapped;
27596
+ }
27597
+ function booleanArg(input, flag) {
27598
+ if (input === "true") return true;
27599
+ if (input === "false") return false;
27600
+ return failValidation2(`--${flag} must be true or false`);
27601
+ }
27602
+ var dataRetentionCommand = defineCommand110({
27603
+ meta: {
27604
+ name: "data-retention",
27605
+ description: `Stage a change to how long Google Analytics keeps data
27606
+
27607
+ Examples:
27608
+ baker ga4 data-retention set --event-data 14
27609
+ baker ga4 data-retention set --event-data 14 --user-data 14 --reset-on-activity true`
27610
+ },
27611
+ subCommands: {
27612
+ set: defineCommand110({
27613
+ meta: { name: "set", description: "Stage the retention window (months)" },
27614
+ args: {
27615
+ "event-data": { type: "string", description: "2, 14, 26, 38 or 50", required: false },
27616
+ "user-data": { type: "string", description: "2, 14, 26, 38 or 50", required: false },
27617
+ "reset-on-activity": { type: "string", description: "true|false", required: false },
27618
+ "property-id": propertyArg
27619
+ },
27620
+ run: async ({ args }) => {
27621
+ const payload = {};
27622
+ if (typeof args["event-data"] === "string") {
27623
+ payload.eventDataRetention = retentionValue(args["event-data"], "event-data");
27624
+ }
27625
+ if (typeof args["user-data"] === "string") {
27626
+ payload.userDataRetention = retentionValue(args["user-data"], "user-data");
27627
+ }
27628
+ if (typeof args["reset-on-activity"] === "string") {
27629
+ payload.resetUserDataOnNewActivity = booleanArg(args["reset-on-activity"], "reset-on-activity");
27630
+ }
27631
+ if (Object.keys(payload).length === 0) {
27632
+ failValidation2("pass at least one of --event-data, --user-data or --reset-on-activity");
27633
+ }
27634
+ await stageOp3({ kind: "ga4.dataRetention.update", payload, ...withProperty(args) });
27635
+ }
27636
+ })
26970
27637
  }
26971
27638
  });
26972
27639
 
26973
27640
  // src/commands/ga4/index.ts
26974
- var ga4Command = defineCommand108({
27641
+ var ga4Command = defineCommand111({
26975
27642
  meta: {
26976
27643
  name: "ga4",
26977
- description: `Google Analytics 4 commands. Audit property config, run playbook-aligned reports.
27644
+ description: `Google Analytics 4. Report on a property, audit its config, and change what it measures.
26978
27645
 
26979
27646
  Start here:
26980
27647
  baker ga4 properties \u2014 list accessible properties
27648
+ baker ga4 config \u2014 what the property measures today (and whether Baker may change it)
26981
27649
  baker ga4 query --list-presets \u2014 see available report presets
26982
27650
 
26983
- Examples:
27651
+ Report:
26984
27652
  baker ga4 audit \u2014 full property health check
26985
27653
  baker ga4 query --preset tracking-health \u2014 compare GA4 vs GAds data
26986
- baker ga4 query --preset lp-performance --days 14 \u2014 landing page UX audit
26987
27654
  baker ga4 query --dimensions "date" --metrics "sessions" --days 7 \u2014 free-form query
27655
+
27656
+ Then stage changes (nothing is sent to Google Analytics until the chat completes):
27657
+ baker ga4 key-event create --json '{"eventName":"generate_lead","countingMethod":"ONCE_PER_EVENT"}'
27658
+ baker ga4 custom-event create --json '{"destinationEvent":"quote_request","eventConditions":[...]}'
27659
+ baker ga4 custom-dimension create --json '{"parameterName":"plan_tier","displayName":"Plan tier","scope":"EVENT"}'
27660
+ baker ga4 draft list \u2014 review everything staged
27661
+
27662
+ An applied change takes effect on the property immediately \u2014 there is no version to publish afterwards
27663
+ and no undo. Agree the changes with the user before the chat completes, not after.
27664
+
26988
27665
  Full guide: __tooling__/docs/tools/baker/ga4.md`
26989
27666
  },
26990
27667
  subCommands: {
26991
27668
  properties: propertiesCommand,
27669
+ config: configCommand,
26992
27670
  audit: auditCommand2,
26993
- query: queryCommand2
27671
+ query: queryCommand2,
27672
+ "key-event": keyEventCommand,
27673
+ "custom-dimension": customDimensionCommand,
27674
+ "custom-metric": customMetricCommand,
27675
+ "custom-event": customEventCommand,
27676
+ "data-retention": dataRetentionCommand,
27677
+ draft: draftCommand3
26994
27678
  }
26995
27679
  });
26996
27680
 
26997
27681
  // src/commands/gsc/index.ts
26998
- import { defineCommand as defineCommand112 } from "citty";
27682
+ import { defineCommand as defineCommand115 } from "citty";
26999
27683
 
27000
27684
  // src/commands/gsc/query.ts
27001
- import { appendFileSync as appendFileSync3, existsSync as existsSync6, readFileSync as readFileSync11, writeFileSync as writeFileSync4 } from "fs";
27685
+ import { appendFileSync as appendFileSync3, existsSync as existsSync6, readFileSync as readFileSync12, writeFileSync as writeFileSync4 } from "fs";
27002
27686
  import { resolve as resolve3 } from "path";
27003
- import { defineCommand as defineCommand109 } from "citty";
27687
+ import { defineCommand as defineCommand112 } from "citty";
27004
27688
 
27005
27689
  // src/commands/gsc/presets.ts
27006
27690
  var GSC_PRESETS = [
@@ -27146,7 +27830,7 @@ function writeRowsToFile3(filePath, rows, append) {
27146
27830
  writeFileSync4(filePath, content, "utf-8");
27147
27831
  }
27148
27832
  } else if (append && existsSync6(filePath)) {
27149
- const existing = JSON.parse(readFileSync11(filePath, "utf-8"));
27833
+ const existing = JSON.parse(readFileSync12(filePath, "utf-8"));
27150
27834
  writeFileSync4(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
27151
27835
  } else {
27152
27836
  writeFileSync4(filePath, JSON.stringify(rows, null, 2), "utf-8");
@@ -27180,7 +27864,7 @@ function buildRequestBody2(args, siteUrl, useCache) {
27180
27864
  if (!useCache) body.skipCache = true;
27181
27865
  return body;
27182
27866
  }
27183
- function handleError2(err) {
27867
+ function handleError3(err) {
27184
27868
  if (err instanceof ApiError) {
27185
27869
  if (isNotConnectedError(err.code, err.message)) {
27186
27870
  handleConnectionError("gsc", err.message);
@@ -27194,7 +27878,7 @@ function handleError2(err) {
27194
27878
  });
27195
27879
  process.exit(1);
27196
27880
  }
27197
- var queryCommand3 = defineCommand109({
27881
+ var queryCommand3 = defineCommand112({
27198
27882
  meta: {
27199
27883
  name: "query",
27200
27884
  description: `Run GSC Search Analytics queries. Preset-first with free-form escape hatch.
@@ -27266,13 +27950,13 @@ Free-form (escape hatch):
27266
27950
  }
27267
27951
  outputRows2(response.data ?? [], args, response, false);
27268
27952
  } catch (err) {
27269
- handleError2(err);
27953
+ handleError3(err);
27270
27954
  }
27271
27955
  }
27272
27956
  });
27273
27957
 
27274
27958
  // src/commands/gsc/sitemaps.ts
27275
- import { defineCommand as defineCommand110 } from "citty";
27959
+ import { defineCommand as defineCommand113 } from "citty";
27276
27960
  registerSchema({
27277
27961
  command: "gsc.sitemaps",
27278
27962
  description: "List sitemaps for a Search Console site. Check sitemap health and errors.",
@@ -27281,7 +27965,7 @@ registerSchema({
27281
27965
  "no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
27282
27966
  }
27283
27967
  });
27284
- var sitemapsCommand = defineCommand110({
27968
+ var sitemapsCommand = defineCommand113({
27285
27969
  meta: {
27286
27970
  name: "sitemaps",
27287
27971
  description: `List sitemaps for a site. Check health and errors.
@@ -27334,7 +28018,7 @@ Examples:
27334
28018
  });
27335
28019
 
27336
28020
  // src/commands/gsc/sites.ts
27337
- import { defineCommand as defineCommand111 } from "citty";
28021
+ import { defineCommand as defineCommand114 } from "citty";
27338
28022
  registerSchema({
27339
28023
  command: "gsc.sites",
27340
28024
  description: "List the Search Console sites this company connected \u2014 there can be several, and every one of them is yours to query. Returns the site URLs the query and sitemaps commands take.",
@@ -27350,7 +28034,7 @@ function siteHints(sites) {
27350
28034
  resources: sites.map((site) => ({ id: site.siteUrl, label: site.permissionLevel }))
27351
28035
  });
27352
28036
  }
27353
- var sitesCommand = defineCommand111({
28037
+ var sitesCommand = defineCommand114({
27354
28038
  meta: {
27355
28039
  name: "sites",
27356
28040
  description: `List verified Search Console sites.
@@ -27398,7 +28082,7 @@ Examples:
27398
28082
  });
27399
28083
 
27400
28084
  // src/commands/gsc/index.ts
27401
- var gscCommand = defineCommand112({
28085
+ var gscCommand = defineCommand115({
27402
28086
  meta: {
27403
28087
  name: "gsc",
27404
28088
  description: `Google Search Console commands. PPC-SEO arbitrage, brand halo analysis, negative keyword discovery.
@@ -27422,7 +28106,7 @@ Full guide: __tooling__/docs/tools/baker/gsc.md`
27422
28106
  });
27423
28107
 
27424
28108
  // src/commands/history/index.ts
27425
- import { defineCommand as defineCommand113 } from "citty";
28109
+ import { defineCommand as defineCommand116 } from "citty";
27426
28110
  registerSchema({
27427
28111
  command: "history.list",
27428
28112
  description: "Start here: unified account history (audit log) \u2014 everything that changed on this account, newest first: publishes, chat lifecycle, backlog actions, team changes, setup links, tags, schedules, ad-platform writes, followed advertisers, media, creatives, reports, domains, and integrations. Use it to see what happened recently before planning work. Compact by default; add --full for raw metadata per entry.",
@@ -27477,7 +28161,7 @@ function parseBoundedInt2(raw, name, min, max) {
27477
28161
  }
27478
28162
  return value;
27479
28163
  }
27480
- var listCommand12 = defineCommand113({
28164
+ var listCommand12 = defineCommand116({
27481
28165
  meta: {
27482
28166
  name: "list",
27483
28167
  description: "List recent account changes (unified audit log), newest first."
@@ -27523,7 +28207,7 @@ var listCommand12 = defineCommand113({
27523
28207
  }
27524
28208
  }
27525
28209
  });
27526
- var historyCommand = defineCommand113({
28210
+ var historyCommand = defineCommand116({
27527
28211
  meta: {
27528
28212
  name: "history",
27529
28213
  description: `Unified account history (audit log): what changed, who did it, and when.
@@ -27533,7 +28217,7 @@ Full guide: __tooling__/docs/tools/baker/history.md`
27533
28217
  });
27534
28218
 
27535
28219
  // src/commands/hubspot/index.ts
27536
- import { defineCommand as defineCommand114 } from "citty";
28220
+ import { defineCommand as defineCommand117 } from "citty";
27537
28221
  var EMBED_TYPES = ["legacy", "v4", "unknown"];
27538
28222
  function failNotConnected(err) {
27539
28223
  if (err instanceof ApiError && err.code === "FORBIDDEN" && err.message.includes(HUBSPOT_MISSING_GRANT_MARKER)) {
@@ -27670,7 +28354,7 @@ registerSchema({
27670
28354
  }
27671
28355
  }
27672
28356
  });
27673
- var formsListCommand = defineCommand114({
28357
+ var formsListCommand = defineCommand117({
27674
28358
  meta: {
27675
28359
  name: "list",
27676
28360
  description: "List HubSpot forms with embed type and post-submit action. Example: baker hubspot forms list --redirecting-only"
@@ -27715,7 +28399,7 @@ var formsListCommand = defineCommand114({
27715
28399
  }
27716
28400
  }
27717
28401
  });
27718
- var formsViewCommand = defineCommand114({
28402
+ var formsViewCommand = defineCommand117({
27719
28403
  meta: {
27720
28404
  name: "view",
27721
28405
  description: "Show one HubSpot form's fields and configuration. Example: baker hubspot forms view 1a2b3c"
@@ -27767,7 +28451,7 @@ var formsViewCommand = defineCommand114({
27767
28451
  }
27768
28452
  }
27769
28453
  });
27770
- var meetingsListCommand = defineCommand114({
28454
+ var meetingsListCommand = defineCommand117({
27771
28455
  meta: {
27772
28456
  name: "list",
27773
28457
  description: "List HubSpot meeting links (calendars). Example: baker hubspot meetings list"
@@ -27809,7 +28493,7 @@ var meetingsListCommand = defineCommand114({
27809
28493
  }
27810
28494
  }
27811
28495
  });
27812
- var meetingsViewCommand = defineCommand114({
28496
+ var meetingsViewCommand = defineCommand117({
27813
28497
  meta: {
27814
28498
  name: "view",
27815
28499
  description: "Show one HubSpot meeting link's booking fields. Example: baker hubspot meetings view discovery-call"
@@ -27853,7 +28537,7 @@ var meetingsViewCommand = defineCommand114({
27853
28537
  }
27854
28538
  }
27855
28539
  });
27856
- var formsSubmissionsCommand = defineCommand114({
28540
+ var formsSubmissionsCommand = defineCommand117({
27857
28541
  meta: {
27858
28542
  name: "submissions",
27859
28543
  description: "How many leads a form received, and when. Example: baker hubspot forms submissions <formId> --days 30"
@@ -27902,7 +28586,7 @@ var formsSubmissionsCommand = defineCommand114({
27902
28586
  }
27903
28587
  }
27904
28588
  });
27905
- var workflowsListCommand = defineCommand114({
28589
+ var workflowsListCommand = defineCommand117({
27906
28590
  meta: {
27907
28591
  name: "list",
27908
28592
  description: "List HubSpot workflows. Example: baker hubspot workflows list --enabled-only"
@@ -27938,7 +28622,7 @@ var workflowsListCommand = defineCommand114({
27938
28622
  }
27939
28623
  }
27940
28624
  });
27941
- var pipelinesListCommand = defineCommand114({
28625
+ var pipelinesListCommand = defineCommand117({
27942
28626
  meta: {
27943
28627
  name: "list",
27944
28628
  description: "List HubSpot deal pipelines and their stages. Example: baker hubspot pipelines list"
@@ -27955,7 +28639,7 @@ var pipelinesListCommand = defineCommand114({
27955
28639
  }
27956
28640
  }
27957
28641
  });
27958
- var contactsSummaryCommand = defineCommand114({
28642
+ var contactsSummaryCommand = defineCommand117({
27959
28643
  meta: {
27960
28644
  name: "summary",
27961
28645
  description: "Whether recent leads are being worked, as counts. Example: baker hubspot contacts summary --days 30"
@@ -28025,7 +28709,7 @@ function contactLookupHints(data) {
28025
28709
  }
28026
28710
  return hints;
28027
28711
  }
28028
- var contactsLookupCommand = defineCommand114({
28712
+ var contactsLookupCommand = defineCommand117({
28029
28713
  meta: {
28030
28714
  name: "lookup",
28031
28715
  description: "Find one contact by email and see whether it was worked. Example: baker hubspot contacts lookup a@b.com"
@@ -28049,27 +28733,27 @@ var contactsLookupCommand = defineCommand114({
28049
28733
  }
28050
28734
  }
28051
28735
  });
28052
- var contactsCommand = defineCommand114({
28736
+ var contactsCommand = defineCommand117({
28053
28737
  meta: { name: "contacts", description: "Contacts on the connected HubSpot account." },
28054
28738
  subCommands: { summary: contactsSummaryCommand, lookup: contactsLookupCommand }
28055
28739
  });
28056
- var formsCommand = defineCommand114({
28740
+ var formsCommand = defineCommand117({
28057
28741
  meta: { name: "forms", description: "HubSpot forms on the connected account." },
28058
28742
  subCommands: { list: formsListCommand, view: formsViewCommand, submissions: formsSubmissionsCommand }
28059
28743
  });
28060
- var workflowsCommand = defineCommand114({
28744
+ var workflowsCommand = defineCommand117({
28061
28745
  meta: { name: "workflows", description: "HubSpot workflows on the connected account." },
28062
28746
  subCommands: { list: workflowsListCommand }
28063
28747
  });
28064
- var pipelinesCommand = defineCommand114({
28748
+ var pipelinesCommand = defineCommand117({
28065
28749
  meta: { name: "pipelines", description: "HubSpot deal pipelines on the connected account." },
28066
28750
  subCommands: { list: pipelinesListCommand }
28067
28751
  });
28068
- var meetingsCommand = defineCommand114({
28752
+ var meetingsCommand = defineCommand117({
28069
28753
  meta: { name: "meetings", description: "HubSpot meeting links (calendars) on the connected account." },
28070
28754
  subCommands: { list: meetingsListCommand, view: meetingsViewCommand }
28071
28755
  });
28072
- var hubspotCommand = defineCommand114({
28756
+ var hubspotCommand = defineCommand117({
28073
28757
  meta: {
28074
28758
  name: "hubspot",
28075
28759
  description: `Read the connected HubSpot account \u2014 forms, the leads they received, workflows, deal pipelines and
@@ -28106,10 +28790,10 @@ Full guide: __tooling__/docs/tools/baker/hubspot.md`
28106
28790
  });
28107
28791
 
28108
28792
  // src/commands/images/index.ts
28109
- import { defineCommand as defineCommand138 } from "citty";
28793
+ import { defineCommand as defineCommand141 } from "citty";
28110
28794
 
28111
28795
  // src/commands/images/crop.ts
28112
- import { defineCommand as defineCommand115 } from "citty";
28796
+ import { defineCommand as defineCommand118 } from "citty";
28113
28797
 
28114
28798
  // src/lib/image/crop-sprite.ts
28115
28799
  import sharp from "sharp";
@@ -28234,7 +28918,7 @@ function emitError2(err) {
28234
28918
  }
28235
28919
  process.exit(1);
28236
28920
  }
28237
- var cropCommand = defineCommand115({
28921
+ var cropCommand = defineCommand118({
28238
28922
  meta: {
28239
28923
  name: "crop",
28240
28924
  description: "Crop a rectangular region from an image.\n\nExample: baker images crop sprite.png --x 0 --y 0 --width 64 --height 64 --output icon.png"
@@ -28270,7 +28954,7 @@ var cropCommand = defineCommand115({
28270
28954
  });
28271
28955
 
28272
28956
  // src/commands/images/delete.ts
28273
- import { defineCommand as defineCommand116 } from "citty";
28957
+ import { defineCommand as defineCommand119 } from "citty";
28274
28958
  registerSchema({
28275
28959
  command: "images.delete",
28276
28960
  description: "Delete an image by ID",
@@ -28284,7 +28968,7 @@ registerSchema({
28284
28968
  }
28285
28969
  }
28286
28970
  });
28287
- var deleteCommand = defineCommand116({
28971
+ var deleteCommand = defineCommand119({
28288
28972
  meta: {
28289
28973
  name: "delete",
28290
28974
  description: "Delete an image by ID. Use --dry-run to preview. Example: baker images delete j571abc123 --dry-run"
@@ -28325,7 +29009,7 @@ var deleteCommand = defineCommand116({
28325
29009
  });
28326
29010
 
28327
29011
  // src/commands/images/dimensions.ts
28328
- import { defineCommand as defineCommand117 } from "citty";
29012
+ import { defineCommand as defineCommand120 } from "citty";
28329
29013
 
28330
29014
  // src/lib/image/dimensions.ts
28331
29015
  import { imageSize } from "image-size";
@@ -28348,7 +29032,7 @@ registerSchema({
28348
29032
  target: { type: "string", description: "Local file path or remote http(s) URL", required: true }
28349
29033
  }
28350
29034
  });
28351
- var dimensionsCommand = defineCommand117({
29035
+ var dimensionsCommand = defineCommand120({
28352
29036
  meta: {
28353
29037
  name: "dimensions",
28354
29038
  description: "Read image dimensions without decoding the full file.\n\nExample: baker images dimensions ./logo.png\nExample: baker images dimensions https://acme.com/hero.png"
@@ -28392,7 +29076,7 @@ var dimensionsCommand = defineCommand117({
28392
29076
  });
28393
29077
 
28394
29078
  // src/commands/images/extract.ts
28395
- import { defineCommand as defineCommand118 } from "citty";
29079
+ import { defineCommand as defineCommand121 } from "citty";
28396
29080
  registerSchema({
28397
29081
  command: "images.extract",
28398
29082
  description: "Extract images from a URL via Firecrawl (formats: images).",
@@ -28408,7 +29092,7 @@ registerSchema({
28408
29092
  }
28409
29093
  }
28410
29094
  });
28411
- var extractCommand = defineCommand118({
29095
+ var extractCommand = defineCommand121({
28412
29096
  meta: {
28413
29097
  name: "extract",
28414
29098
  description: "Pull every image from a single URL via Firecrawl. ~$0.001/scrape. Cap auto-ingest at 20.\n\nExample: baker images extract https://stripe.com --auto-ingest 5"
@@ -28446,7 +29130,7 @@ var extractCommand = defineCommand118({
28446
29130
  });
28447
29131
 
28448
29132
  // src/commands/images/find.ts
28449
- import { defineCommand as defineCommand119 } from "citty";
29133
+ import { defineCommand as defineCommand122 } from "citty";
28450
29134
  registerSchema({
28451
29135
  command: "images.find",
28452
29136
  description: "Fanout image search: library first, then opted-in external providers.",
@@ -28478,7 +29162,7 @@ registerSchema({
28478
29162
  }
28479
29163
  }
28480
29164
  });
28481
- var findCommand = defineCommand119({
29165
+ var findCommand = defineCommand122({
28482
29166
  meta: {
28483
29167
  name: "find",
28484
29168
  description: "Library-first fanout image search. Opt in to providers with --sources. `--fallback` short-circuits to externals only when library is thin. With --auto-ingest, ingested external hits return Baker-owned URLs.\n\nExample: baker images find 'office' --sources library,magnific --limit 20"
@@ -28527,7 +29211,7 @@ var findCommand = defineCommand119({
28527
29211
 
28528
29212
  // src/commands/images/generate.ts
28529
29213
  import { readFile as readFile20 } from "fs/promises";
28530
- import { defineCommand as defineCommand120 } from "citty";
29214
+ import { defineCommand as defineCommand123 } from "citty";
28531
29215
  import sharp2 from "sharp";
28532
29216
  var GENERATE_TIMEOUT_MS = 18e4;
28533
29217
  var REFERENCE_MAX_EDGE = 1536;
@@ -28630,7 +29314,7 @@ async function resolveReferences(spec) {
28630
29314
  }
28631
29315
  return out;
28632
29316
  }
28633
- var generateCommand = defineCommand120({
29317
+ var generateCommand = defineCommand123({
28634
29318
  meta: {
28635
29319
  name: "generate",
28636
29320
  description: "Generate an image with AI and store it in the library (cost-tracked per request via OpenRouter usage). Models mirror the canvas: google/gemini-3.1-flash-image-preview (Nano Banana flash \u2014 default, fast, extreme aspect ratios), google/gemini-3-pro-image-preview (Nano Banana Pro \u2014 highest fidelity), openai/gpt-image-2 (photoreal, cleanest in-image text, best for ad/landing reproduction \u2014 no --image-size, and no 4:5 / 5:4), recraft/recraft-v4.1-pro-vector (vector/SVG-style with palette control). The result is auto-ingested (describe + embed), so the next `baker images library` query finds it. Pass --reference with image URLs and/or local file paths (Pinterest, stock, brand assets, sandbox files) to ground generation in reality.\n\nExamples:\n baker images generate 'a friendly golden retriever sitting in a bright modern living room' --aspect-ratio 16:9\n baker images generate 'hero shot of a matte black water bottle on marble' --model openai/gpt-image-2 --aspect-ratio 3:2\n baker images generate 'lifestyle photo matching this mood' --reference 'https://\u2026/ref1.jpg,https://\u2026/ref2.jpg'\n baker images generate 'put this product on a marble countertop, soft daylight' --reference './src/brand/logos/product.png,./refs/kitchen-mood.jpg'\n baker images generate 'flat geometric mascot, brand palette' --model recraft/recraft-v4.1-pro-vector --rgb-colors '[[10,10,10],[255,80,0]]'"
@@ -28682,7 +29366,7 @@ var generateCommand = defineCommand120({
28682
29366
  });
28683
29367
 
28684
29368
  // src/commands/images/get.ts
28685
- import { defineCommand as defineCommand121 } from "citty";
29369
+ import { defineCommand as defineCommand124 } from "citty";
28686
29370
  registerSchema({
28687
29371
  command: "images.get",
28688
29372
  description: "Get a single image by ID",
@@ -28690,7 +29374,7 @@ registerSchema({
28690
29374
  id: { type: "string", description: "Image ID", required: true }
28691
29375
  }
28692
29376
  });
28693
- var getCommand2 = defineCommand121({
29377
+ var getCommand2 = defineCommand124({
28694
29378
  meta: { name: "get", description: "Get a single image by ID. Example: baker images get j571abc123" },
28695
29379
  args: {
28696
29380
  id: { type: "positional", description: "Image ID", required: false },
@@ -28726,7 +29410,7 @@ var getCommand2 = defineCommand121({
28726
29410
  });
28727
29411
 
28728
29412
  // src/commands/images/gif.ts
28729
- import { defineCommand as defineCommand122 } from "citty";
29413
+ import { defineCommand as defineCommand125 } from "citty";
28730
29414
  registerSchema({
28731
29415
  command: "images.gif",
28732
29416
  description: "Search Giphy for GIFs / reaction memes (paid social creative).",
@@ -28758,7 +29442,7 @@ registerSchema({
28758
29442
  }
28759
29443
  }
28760
29444
  });
28761
- var gifCommand = defineCommand122({
29445
+ var gifCommand = defineCommand125({
28762
29446
  meta: {
28763
29447
  name: "gif",
28764
29448
  description: "Search Giphy for GIFs / reaction memes \u2014 built for paid-social creative (Meta, TikTok, LinkedIn, X). Free API. Each hit carries WebP + GIF + MP4 URLs in providerMeta so you can pick the right format per platform.\n\nExample: baker images gif 'this is fine' --limit 10\nExample: baker images gif 'office reaction' --rating pg --auto-ingest 2\nExample: baker images gif --trending --limit 25"
@@ -28805,7 +29489,7 @@ var gifCommand = defineCommand122({
28805
29489
  });
28806
29490
 
28807
29491
  // src/commands/images/google.ts
28808
- import { defineCommand as defineCommand123 } from "citty";
29492
+ import { defineCommand as defineCommand126 } from "citty";
28809
29493
 
28810
29494
  // src/commands/images/searchHints.ts
28811
29495
  var FALLBACK = {
@@ -28869,7 +29553,7 @@ registerSchema({
28869
29553
  }
28870
29554
  }
28871
29555
  });
28872
- var googleCommand2 = defineCommand123({
29556
+ var googleCommand2 = defineCommand126({
28873
29557
  meta: {
28874
29558
  name: "google",
28875
29559
  description: "Google Images via the official Custom Search JSON API ($0.005/query, free 100/day). \u26A0 Source unverified \u2014 watermarks, low-res, mislabeled results are common. Use as last resort. With --auto-ingest, ingested hits return Baker-owned URLs.\n\nExample: baker images google 'industrial workshop' --type photo --size large --limit 20"
@@ -28925,7 +29609,7 @@ var googleCommand2 = defineCommand123({
28925
29609
  });
28926
29610
 
28927
29611
  // src/commands/images/icon.ts
28928
- import { defineCommand as defineCommand124 } from "citty";
29612
+ import { defineCommand as defineCommand127 } from "citty";
28929
29613
  registerSchema({
28930
29614
  command: "images.icon",
28931
29615
  description: "Icon lookup via Iconify (200+ icon sets, free CDN).",
@@ -28951,7 +29635,7 @@ registerSchema({
28951
29635
  }
28952
29636
  }
28953
29637
  });
28954
- var iconCommand = defineCommand124({
29638
+ var iconCommand = defineCommand127({
28955
29639
  meta: {
28956
29640
  name: "icon",
28957
29641
  description: "Icon via Iconify (simple-icons, logos, lucide, devicon, heroicons, tabler, phosphor, material-symbols, \u2026). Free CDN, no API key.\n\nExample: baker images icon react --set devicon\nExample: baker images icon lucide:check --color '#0a0a0a'"
@@ -28991,7 +29675,7 @@ var iconCommand = defineCommand124({
28991
29675
  });
28992
29676
 
28993
29677
  // src/commands/images/ingest.ts
28994
- import { defineCommand as defineCommand125 } from "citty";
29678
+ import { defineCommand as defineCommand128 } from "citty";
28995
29679
  registerSchema({
28996
29680
  command: "images.ingest",
28997
29681
  description: "Ingest a remote image URL into the library (full describe + embed).",
@@ -29003,7 +29687,7 @@ registerSchema({
29003
29687
  context: { type: "string", description: "Description context hint", required: false }
29004
29688
  }
29005
29689
  });
29006
- var ingestCommand = defineCommand125({
29690
+ var ingestCommand = defineCommand128({
29007
29691
  meta: {
29008
29692
  name: "ingest",
29009
29693
  description: "Download a remote URL and store it in the library. Hash-deduped on bytes + externalId.\n\nExample: baker images ingest https://img.freepik.com/free-photo/xyz.jpg --source magnific --external-id 12345"
@@ -29045,7 +29729,7 @@ var ingestCommand = defineCommand125({
29045
29729
  });
29046
29730
 
29047
29731
  // src/commands/images/library.ts
29048
- import { defineCommand as defineCommand126 } from "citty";
29732
+ import { defineCommand as defineCommand129 } from "citty";
29049
29733
  registerSchema({
29050
29734
  command: "images.library",
29051
29735
  description: "Search the company image library. Returns only ready images.",
@@ -29071,7 +29755,7 @@ registerSchema({
29071
29755
  }
29072
29756
  }
29073
29757
  });
29074
- var libraryCommand = defineCommand126({
29758
+ var libraryCommand = defineCommand129({
29075
29759
  meta: {
29076
29760
  name: "library",
29077
29761
  description: "Search the company image library (hybrid BM25 + vector + Cohere rerank). Use this BEFORE any external provider.\n\nExample: baker images library 'hero banner' --aspect-ratio 16:9 --source magnific"
@@ -29128,7 +29812,7 @@ var libraryCommand = defineCommand126({
29128
29812
  });
29129
29813
 
29130
29814
  // src/commands/images/logo.ts
29131
- import { defineCommand as defineCommand127 } from "citty";
29815
+ import { defineCommand as defineCommand130 } from "citty";
29132
29816
  registerSchema({
29133
29817
  command: "images.logo",
29134
29818
  description: "Brand logo lookup via Brandfetch CDN (fallback/404). Auto-ingests by default.",
@@ -29153,7 +29837,7 @@ registerSchema({
29153
29837
  }
29154
29838
  }
29155
29839
  });
29156
- var logoCommand = defineCommand127({
29840
+ var logoCommand = defineCommand130({
29157
29841
  meta: {
29158
29842
  name: "logo",
29159
29843
  description: "Brand logo via Brandfetch CDN. Returns up to 5 variants (icon, light/dark logo, light/dark symbol). Auto-ingests the first variant.\n\nExample: baker images logo stripe.com --variant logo"
@@ -29191,7 +29875,7 @@ var logoCommand = defineCommand127({
29191
29875
  });
29192
29876
 
29193
29877
  // src/commands/images/normalize.ts
29194
- import { defineCommand as defineCommand128 } from "citty";
29878
+ import { defineCommand as defineCommand131 } from "citty";
29195
29879
 
29196
29880
  // src/lib/image/color-changer.ts
29197
29881
  import quantize from "quantize";
@@ -29923,7 +30607,7 @@ function coerceRawArgs(args) {
29923
30607
  "dry-run": bool(args["dry-run"])
29924
30608
  };
29925
30609
  }
29926
- var normalizeCommand = defineCommand128({
30610
+ var normalizeCommand = defineCommand131({
29927
30611
  meta: {
29928
30612
  name: "normalize",
29929
30613
  description: `Normalize logos / images: declarative recolor + bg removal + trim + resize. Operates on local files; writes in-place by default.
@@ -29978,7 +30662,7 @@ Examples:
29978
30662
  });
29979
30663
 
29980
30664
  // src/commands/images/pinterest.ts
29981
- import { defineCommand as defineCommand129 } from "citty";
30665
+ import { defineCommand as defineCommand132 } from "citty";
29982
30666
  registerSchema({
29983
30667
  command: "images.pinterest",
29984
30668
  description: "Pinterest image search via ScrapeCreators. Reference-grade real-world photography, product styling, interiors, fashion, food, and aesthetic mood boards. Inspect before placing \u2014 Pinterest is unverified, trademark-bearing web content.",
@@ -29998,7 +30682,7 @@ registerSchema({
29998
30682
  }
29999
30683
  }
30000
30684
  });
30001
- var pinterestCommand = defineCommand129({
30685
+ var pinterestCommand = defineCommand132({
30002
30686
  meta: {
30003
30687
  name: "pinterest",
30004
30688
  description: "Pinterest image search via ScrapeCreators ($0.00188/request). Best for photo-realistic reference imagery \u2014 lifestyle, interiors, fashion, food, product styling, and mood boards to brief AI generation against. \u26A0 Unverified, trademark-bearing web content \u2014 inspect and respect rights before placing on a customer page. Browse first; auto-ingest only the pins you commit to.\n\nExamples:\n baker images pinterest 'scandinavian living room'\n baker images pinterest 'minimalist skincare product photography' --limit 20\n baker images pinterest 'cozy coffee shop interior' --auto-ingest 2 --context 'Mood reference for hero photography'"
@@ -30038,7 +30722,7 @@ var pinterestCommand = defineCommand129({
30038
30722
  });
30039
30723
 
30040
30724
  // src/commands/images/screenshot.ts
30041
- import { defineCommand as defineCommand130 } from "citty";
30725
+ import { defineCommand as defineCommand133 } from "citty";
30042
30726
  registerSchema({
30043
30727
  command: "images.screenshot",
30044
30728
  description: "Capture a website screenshot via ScreenshotOne. Auto-ingests on success.",
@@ -30054,7 +30738,7 @@ registerSchema({
30054
30738
  }
30055
30739
  }
30056
30740
  });
30057
- var screenshotCommand = defineCommand130({
30741
+ var screenshotCommand = defineCommand133({
30058
30742
  meta: {
30059
30743
  name: "screenshot",
30060
30744
  description: "Screenshot a URL via ScreenshotOne. $0.009/capture. Auto-ingests to library.\n\nExample: baker images screenshot https://stripe.com --full-page"
@@ -30117,7 +30801,7 @@ var screenshotCommand = defineCommand130({
30117
30801
  });
30118
30802
 
30119
30803
  // src/commands/images/search.ts
30120
- import { defineCommand as defineCommand131 } from "citty";
30804
+ import { defineCommand as defineCommand134 } from "citty";
30121
30805
  registerSchema({
30122
30806
  command: "images.search",
30123
30807
  description: "Search images by text query. Only returns ready images.",
@@ -30133,7 +30817,7 @@ registerSchema({
30133
30817
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
30134
30818
  }
30135
30819
  });
30136
- var searchCommand = defineCommand131({
30820
+ var searchCommand = defineCommand134({
30137
30821
  meta: {
30138
30822
  name: "search",
30139
30823
  description: "Semantic search images by text query. Uses hybrid BM25 + vector + reranking. Example: baker images search 'hero banner' --aspect-ratio 16:9 --tags logo"
@@ -30193,7 +30877,7 @@ var searchCommand = defineCommand131({
30193
30877
  });
30194
30878
 
30195
30879
  // src/commands/images/sticker.ts
30196
- import { defineCommand as defineCommand132 } from "citty";
30880
+ import { defineCommand as defineCommand135 } from "citty";
30197
30881
  registerSchema({
30198
30882
  command: "images.sticker",
30199
30883
  description: "Search Giphy stickers \u2014 transparent-background overlays for ad creative.",
@@ -30225,7 +30909,7 @@ registerSchema({
30225
30909
  }
30226
30910
  }
30227
30911
  });
30228
- var stickerCommand = defineCommand132({
30912
+ var stickerCommand = defineCommand135({
30229
30913
  meta: {
30230
30914
  name: "sticker",
30231
30915
  description: "Search Giphy's sticker corpus \u2014 transparent-background WebPs / GIFs ideal for overlaying on ad creative (Meta, TikTok, Stories). Same Giphy free API as `baker images gif`; results carry WebP + GIF + MP4 URLs in providerMeta.\n\nExample: baker images sticker 'thumbs up' --limit 10\nExample: baker images sticker celebration --rating g --auto-ingest 3\nExample: baker images sticker --trending --limit 25"
@@ -30272,7 +30956,7 @@ var stickerCommand = defineCommand132({
30272
30956
  });
30273
30957
 
30274
30958
  // src/commands/images/stock.ts
30275
- import { defineCommand as defineCommand133 } from "citty";
30959
+ import { defineCommand as defineCommand136 } from "citty";
30276
30960
  var STOCK_ERROR_FIX = {
30277
30961
  action: "use_different_resource",
30278
30962
  explanation: "Switch provider instead of retrying stock search. Stock search is one of several image sources. Run `baker images find <query> --sources library,pinterest,google` (`--sources` is required \u2014 `find` alone searches the library only) or `baker images generate` to make the asset. Never sleep-and-retry this command \u2014 the CLI already backs off on rate limits. If no image can be sourced, continue the rest of the task with a placeholder rather than aborting it."
@@ -30349,7 +31033,7 @@ function buildStockRequest(query, args) {
30349
31033
  if (args.context) body.descriptionContext = args.context;
30350
31034
  return body;
30351
31035
  }
30352
- var stockCommand = defineCommand133({
31036
+ var stockCommand = defineCommand136({
30353
31037
  meta: {
30354
31038
  name: "stock",
30355
31039
  description: "Stock search via Magnific \u2014 Freepik's developer API (~250M assets: photos, vectors, illustrations, icons, PSDs). $0.002/req. With --auto-ingest, ingested hits return Baker-owned URLs.\n\nExamples:\n baker images stock 'minimalist office'\n baker images stock 'flat office workers' --type vector\n baker images stock 'hero photo of a kitchen' --type photo --orientation landscape --ai exclude\n baker images stock 'brand pattern' --color '#0a0a0a' --license freemium --auto-ingest 2"
@@ -30405,7 +31089,7 @@ var stockCommand = defineCommand133({
30405
31089
  });
30406
31090
 
30407
31091
  // src/lib/tags-command.ts
30408
- import { defineCommand as defineCommand134 } from "citty";
31092
+ import { defineCommand as defineCommand137 } from "citty";
30409
31093
  function makeTagsCommand(command, label, endpoint) {
30410
31094
  registerSchema({
30411
31095
  command: `${command}.tags`,
@@ -30414,7 +31098,7 @@ function makeTagsCommand(command, label, endpoint) {
30414
31098
  output: { type: "string", description: "Output format: md|json", required: false, default: "md" }
30415
31099
  }
30416
31100
  });
30417
- return defineCommand134({
31101
+ return defineCommand137({
30418
31102
  meta: {
30419
31103
  name: "tags",
30420
31104
  description: `List the available ${label} tag names (defaults + company custom tags). Use before filtering with --tags. Example: baker ${command} tags`
@@ -30450,7 +31134,7 @@ function makeTagsCommand(command, label, endpoint) {
30450
31134
  var tagsCommand2 = makeTagsCommand("images", "image", "/api/images/tags");
30451
31135
 
30452
31136
  // src/commands/images/upload.ts
30453
- import { defineCommand as defineCommand135 } from "citty";
31137
+ import { defineCommand as defineCommand138 } from "citty";
30454
31138
  registerSchema({
30455
31139
  command: "images.upload",
30456
31140
  description: "Upload an image to the library \u2014 local file path or remote http(s) URL.",
@@ -30488,7 +31172,7 @@ registerSchema({
30488
31172
  function isRemoteUrl2(value) {
30489
31173
  return /^https?:\/\//i.test(value);
30490
31174
  }
30491
- var uploadCommand = defineCommand135({
31175
+ var uploadCommand = defineCommand138({
30492
31176
  meta: {
30493
31177
  name: "upload",
30494
31178
  description: "Upload an image to the library \u2014 accepts a local file path OR a remote http(s) URL.\n\nLocal: reads bytes, sends to /api/images/upload, content-type auto-detected from extension.\nRemote: dispatches to /api/images/ingest with hash-dedup on bytes + externalId.\n\nExamples:\n baker images upload ./logo.png --source uploaded\n baker images upload ./cert.png --context 'ISO 27001 badge \u2014 enterprise tier'\n baker images upload https://acme.com/hero.png --source firecrawl --context 'Acme competitor pricing hero'"
@@ -30581,7 +31265,7 @@ async function uploadLocal(target, args) {
30581
31265
  }
30582
31266
 
30583
31267
  // src/commands/images/upscale.ts
30584
- import { defineCommand as defineCommand136 } from "citty";
31268
+ import { defineCommand as defineCommand139 } from "citty";
30585
31269
  registerSchema({
30586
31270
  command: "images.upscale",
30587
31271
  description: "Upscale a library image via the backend (Replicate, cost-tracked). Waits for completion by default. The image must be status 'ready' and raster (not SVG/AVIF).",
@@ -30596,7 +31280,7 @@ registerSchema({
30596
31280
  }
30597
31281
  });
30598
31282
  var POLL_INTERVAL_MS3 = 1500;
30599
- var upscaleCommand = defineCommand136({
31283
+ var upscaleCommand = defineCommand139({
30600
31284
  meta: {
30601
31285
  name: "upscale",
30602
31286
  description: "Upscale a library image via the Convex backend (Replicate, cost-tracked at $0.05/image). Waits for completion by default.\n\nExample: baker images upscale j571abc123def\nExample: baker images upscale j571abc123def --max-wait 0 # fire-and-forget"
@@ -30651,7 +31335,7 @@ var upscaleCommand = defineCommand136({
30651
31335
  });
30652
31336
 
30653
31337
  // src/commands/images/use.ts
30654
- import { defineCommand as defineCommand137 } from "citty";
31338
+ import { defineCommand as defineCommand140 } from "citty";
30655
31339
  registerSchema({
30656
31340
  command: "images.use",
30657
31341
  description: "Ingest a URL and wait for the library record to be ready.",
@@ -30667,7 +31351,7 @@ registerSchema({
30667
31351
  }
30668
31352
  });
30669
31353
  var POLL_INTERVAL_MS4 = 1500;
30670
- var useCommand = defineCommand137({
31354
+ var useCommand = defineCommand140({
30671
31355
  meta: {
30672
31356
  name: "use",
30673
31357
  description: "Sugar over `ingest`: download \u2192 store \u2192 wait until describe + embed complete \u2192 return ready library record.\n\nExample: baker images use https://cdn.example.com/hero.png --source uploaded"
@@ -30713,7 +31397,7 @@ var useCommand = defineCommand137({
30713
31397
  });
30714
31398
 
30715
31399
  // src/commands/images/index.ts
30716
- var imagesCommand = defineCommand138({
31400
+ var imagesCommand = defineCommand141({
30717
31401
  meta: {
30718
31402
  name: "images",
30719
31403
  description: `Find, source, and normalize images. Subcommands route by provider so cost + license are explicit.
@@ -30784,12 +31468,12 @@ Full guide: __tooling__/docs/tools/baker/images.md`
30784
31468
  });
30785
31469
 
30786
31470
  // src/commands/landing/index.ts
30787
- import { defineCommand as defineCommand140 } from "citty";
31471
+ import { defineCommand as defineCommand143 } from "citty";
30788
31472
 
30789
31473
  // src/commands/landing/critique.ts
30790
31474
  import { readdir as readdir8, stat as stat6 } from "fs/promises";
30791
31475
  import path27 from "path";
30792
- import { defineCommand as defineCommand139 } from "citty";
31476
+ import { defineCommand as defineCommand142 } from "citty";
30793
31477
 
30794
31478
  // src/engine/landing/lib/brand-tokens.ts
30795
31479
  import { readFile as readFile21 } from "fs/promises";
@@ -32064,7 +32748,7 @@ function fail5(code, message, fix) {
32064
32748
  );
32065
32749
  process.exit(2);
32066
32750
  }
32067
- var critiqueCommand2 = defineCommand139({
32751
+ var critiqueCommand2 = defineCommand142({
32068
32752
  meta: {
32069
32753
  name: "critique",
32070
32754
  description: "Start here: `baker landing critique <slug>` after building or editing a landing. Deterministic design-quality critic (ADVISORY \u2014 findings never fail it). Flags the known AI design tells (gradient text, overused fonts, side-tab borders, cream palettes, buzzword copy, broken images) tiered block/warn/advisory, respecting the client's BRAND.md as the allowlist. Also records the critique that publishing requires \u2014 run it before finishing a landing."
@@ -32173,7 +32857,7 @@ async function isDir(p) {
32173
32857
  }
32174
32858
 
32175
32859
  // src/commands/landing/index.ts
32176
- var landingCommand = defineCommand140({
32860
+ var landingCommand = defineCommand143({
32177
32861
  meta: {
32178
32862
  name: "landing",
32179
32863
  description: `Design-quality tools for landing pages (src/pages/<slug>/).
@@ -32189,7 +32873,7 @@ Subcommands:
32189
32873
  });
32190
32874
 
32191
32875
  // src/commands/mcp/index.ts
32192
- import { defineCommand as defineCommand141 } from "citty";
32876
+ import { defineCommand as defineCommand144 } from "citty";
32193
32877
 
32194
32878
  // src/commands/mcp/platforms.ts
32195
32879
  function readsKey(label) {
@@ -32258,7 +32942,7 @@ registerSchema({
32258
32942
  description: "List everything this chat can reach: managed integrations (Attio, Slack, Gmail, Google Sheets, \u2026), custom MCP servers, and the platforms the company signed in to (HubSpot, Google Ads, GA4, Search Console, Tag Manager) which you read through their own `baker` commands. Start here when the user mentions an external tool or platform.",
32259
32943
  args: {}
32260
32944
  });
32261
- var connectedCommand = defineCommand141({
32945
+ var connectedCommand = defineCommand144({
32262
32946
  meta: {
32263
32947
  name: "connected",
32264
32948
  description: `Everything this chat can reach \u2014 managed integrations, custom MCP servers, and connected platforms.
@@ -32317,7 +33001,7 @@ registerSchema({
32317
33001
  description: "List the custom MCP servers this company's chats see (org + company + your own user scope).",
32318
33002
  args: {}
32319
33003
  });
32320
- var listCommand13 = defineCommand141({
33004
+ var listCommand13 = defineCommand144({
32321
33005
  meta: { name: "list", description: "List custom MCP servers visible to this company's chats." },
32322
33006
  run: async () => {
32323
33007
  try {
@@ -32354,7 +33038,7 @@ registerSchema({
32354
33038
  header: { type: "string", description: 'Auth header "Key: Value" (repeatable)', required: false }
32355
33039
  }
32356
33040
  });
32357
- var addCommand = defineCommand141({
33041
+ var addCommand = defineCommand144({
32358
33042
  meta: {
32359
33043
  name: "add",
32360
33044
  description: `Register a custom MCP server. Tools appear as mcp__<name>__* on the NEXT message.
@@ -32406,7 +33090,7 @@ registerSchema({
32406
33090
  description: "Remove a company custom MCP server by name.",
32407
33091
  args: { name: { type: "string", description: "Server name to remove", required: true } }
32408
33092
  });
32409
- var removeCommand4 = defineCommand141({
33093
+ var removeCommand4 = defineCommand144({
32410
33094
  meta: {
32411
33095
  name: "remove",
32412
33096
  description: `Remove a company custom MCP server by name.
@@ -32428,7 +33112,7 @@ Example:
32428
33112
  }
32429
33113
  }
32430
33114
  });
32431
- var mcpCommand = defineCommand141({
33115
+ var mcpCommand = defineCommand144({
32432
33116
  meta: {
32433
33117
  name: "mcp",
32434
33118
  description: `Third-party tools for this company \u2014 see what's connected, register custom HTTPS MCP endpoints.
@@ -32454,10 +33138,10 @@ Full guide: __tooling__/docs/tools/baker/mcp.md`
32454
33138
  });
32455
33139
 
32456
33140
  // src/commands/research/index.ts
32457
- import { defineCommand as defineCommand152 } from "citty";
33141
+ import { defineCommand as defineCommand155 } from "citty";
32458
33142
 
32459
33143
  // src/commands/research/advertisers.ts
32460
- import { defineCommand as defineCommand142 } from "citty";
33144
+ import { defineCommand as defineCommand145 } from "citty";
32461
33145
 
32462
33146
  // src/commands/research/output.ts
32463
33147
  var RESEARCH_DATA_NOTE = "Estimates based on third-party SERP data \u2014 not exact figures. Use for directional insights, not precise measurement.";
@@ -32570,7 +33254,7 @@ var FIELDS3 = {
32570
33254
  etv: "Estimated traffic value (USD)",
32571
33255
  visibility: "SERP visibility score (0-1)"
32572
33256
  };
32573
- var advertisersCommand = defineCommand142({
33257
+ var advertisersCommand = defineCommand145({
32574
33258
  meta: {
32575
33259
  name: "advertisers",
32576
33260
  description: `Find domains competing for a keyword in Google SERPs.
@@ -32617,7 +33301,7 @@ Examples:
32617
33301
  });
32618
33302
 
32619
33303
  // src/commands/research/autocomplete.ts
32620
- import { defineCommand as defineCommand143 } from "citty";
33304
+ import { defineCommand as defineCommand146 } from "citty";
32621
33305
  registerSchema({
32622
33306
  command: "research.autocomplete",
32623
33307
  description: "Get Google Autocomplete suggestions for a seed keyword. Useful for keyword expansion and discovering what people actually search for. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en).",
@@ -32640,7 +33324,7 @@ registerSchema({
32640
33324
  var FIELDS4 = {
32641
33325
  suggestion: "Autocomplete suggestion from Google"
32642
33326
  };
32643
- var autocompleteCommand = defineCommand143({
33327
+ var autocompleteCommand = defineCommand146({
32644
33328
  meta: {
32645
33329
  name: "autocomplete",
32646
33330
  description: `Get Google Autocomplete suggestions for keyword expansion.
@@ -32686,7 +33370,7 @@ Examples:
32686
33370
  });
32687
33371
 
32688
33372
  // src/commands/research/countries.ts
32689
- import { defineCommand as defineCommand144 } from "citty";
33373
+ import { defineCommand as defineCommand147 } from "citty";
32690
33374
  registerSchema({
32691
33375
  command: "research.countries",
32692
33376
  description: "List all supported country codes for --location flag in research commands.",
@@ -32743,7 +33427,7 @@ var FIELDS5 = {
32743
33427
  code: "Country code to pass as --location",
32744
33428
  name: "Country name"
32745
33429
  };
32746
- var countriesCommand = defineCommand144({
33430
+ var countriesCommand = defineCommand147({
32747
33431
  meta: {
32748
33432
  name: "countries",
32749
33433
  description: "List all supported country codes for --location flag."
@@ -32754,7 +33438,7 @@ var countriesCommand = defineCommand144({
32754
33438
  });
32755
33439
 
32756
33440
  // src/commands/research/intent.ts
32757
- import { defineCommand as defineCommand145 } from "citty";
33441
+ import { defineCommand as defineCommand148 } from "citty";
32758
33442
  registerSchema({
32759
33443
  command: "research.intent",
32760
33444
  description: "Classify Google Search intent for keywords. Determines if someone searching is looking to buy, research, or navigate. IMPORTANT: If --language is omitted, defaults to English (en). The response includes a query_context object showing which language was used.",
@@ -32777,7 +33461,7 @@ var FIELDS6 = {
32777
33461
  intent: "Primary Google Search intent: informational, navigational, commercial, transactional",
32778
33462
  probability: "Confidence score 0.0-1.0"
32779
33463
  };
32780
- var intentCommand = defineCommand145({
33464
+ var intentCommand = defineCommand148({
32781
33465
  meta: {
32782
33466
  name: "intent",
32783
33467
  description: `Classify Google Search intent for keywords. Returns intent type and confidence.
@@ -32825,7 +33509,7 @@ Examples:
32825
33509
  });
32826
33510
 
32827
33511
  // src/commands/research/keyword-gap.ts
32828
- import { defineCommand as defineCommand146 } from "citty";
33512
+ import { defineCommand as defineCommand149 } from "citty";
32829
33513
  registerSchema({
32830
33514
  command: "research.keyword-gap",
32831
33515
  description: "Find keywords a competitor ranks for (organic or paid) that you don't. Discovers expansion opportunities. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en). The response includes a query_context object showing which location/language were used.",
@@ -32854,7 +33538,7 @@ var FIELDS7 = {
32854
33538
  cpc: "Cost per click USD",
32855
33539
  their_position: "Competitor's ranking position"
32856
33540
  };
32857
- var keywordGapCommand = defineCommand146({
33541
+ var keywordGapCommand = defineCommand149({
32858
33542
  meta: {
32859
33543
  name: "keyword-gap",
32860
33544
  description: `Find keywords a competitor has that you don't. Supports pagination via --offset.
@@ -32928,7 +33612,7 @@ Examples:
32928
33612
  });
32929
33613
 
32930
33614
  // src/commands/research/keywords-for-site.ts
32931
- import { defineCommand as defineCommand147 } from "citty";
33615
+ import { defineCommand as defineCommand150 } from "citty";
32932
33616
  registerSchema({
32933
33617
  command: "research.keywords-for-site",
32934
33618
  description: "Get keywords a competitor targets in Google. Use --type paid to see only paid keywords, --type organic for organic only. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en). The response includes a query_context object showing which location/language were used.",
@@ -32961,7 +33645,7 @@ var FIELDS8 = {
32961
33645
  competition: "LOW, MEDIUM, or HIGH",
32962
33646
  competition_index: "Competition score 0-100"
32963
33647
  };
32964
- var keywordsForSiteCommand = defineCommand147({
33648
+ var keywordsForSiteCommand = defineCommand150({
32965
33649
  meta: {
32966
33650
  name: "keywords-for-site",
32967
33651
  description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.
@@ -33014,7 +33698,7 @@ Examples:
33014
33698
  });
33015
33699
 
33016
33700
  // src/commands/research/languages.ts
33017
- import { defineCommand as defineCommand148 } from "citty";
33701
+ import { defineCommand as defineCommand151 } from "citty";
33018
33702
  registerSchema({
33019
33703
  command: "research.languages",
33020
33704
  description: "List all supported language codes for --language flag in research commands.",
@@ -33044,7 +33728,7 @@ var FIELDS9 = {
33044
33728
  code: "Language code to pass as --language",
33045
33729
  name: "Language name (also accepted by --language)"
33046
33730
  };
33047
- var languagesCommand2 = defineCommand148({
33731
+ var languagesCommand2 = defineCommand151({
33048
33732
  meta: {
33049
33733
  name: "languages",
33050
33734
  description: "List all supported language codes for --language flag."
@@ -33055,7 +33739,7 @@ var languagesCommand2 = defineCommand148({
33055
33739
  });
33056
33740
 
33057
33741
  // src/commands/research/lighthouse.ts
33058
- import { defineCommand as defineCommand149 } from "citty";
33742
+ import { defineCommand as defineCommand152 } from "citty";
33059
33743
  registerSchema({
33060
33744
  command: "research.lighthouse",
33061
33745
  description: "Landing page performance audit. Returns metrics that affect Google Ads Quality Score and CPC.",
@@ -33074,7 +33758,7 @@ var FIELDS10 = {
33074
33758
  speed_index_ms: "Speed Index in ms (good: < 3400)",
33075
33759
  interactive_ms: "Time to Interactive in ms (good: < 3800)"
33076
33760
  };
33077
- var lighthouseCommand = defineCommand149({
33761
+ var lighthouseCommand = defineCommand152({
33078
33762
  meta: {
33079
33763
  name: "lighthouse",
33080
33764
  description: `Landing page performance audit. Metrics affecting Google Ads Quality Score.
@@ -33112,7 +33796,7 @@ Examples:
33112
33796
  });
33113
33797
 
33114
33798
  // src/commands/research/relevant-pages.ts
33115
- import { defineCommand as defineCommand150 } from "citty";
33799
+ import { defineCommand as defineCommand153 } from "citty";
33116
33800
  registerSchema({
33117
33801
  command: "research.relevant-pages",
33118
33802
  description: "Get the top pages of a competitor domain with organic traffic and ranking data. Shows which pages drive the most traffic. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en).",
@@ -33138,7 +33822,7 @@ var FIELDS11 = {
33138
33822
  keywords: "Total organic keywords the page ranks for",
33139
33823
  top_10: "Keywords in positions 1-10"
33140
33824
  };
33141
- var relevantPagesCommand = defineCommand150({
33825
+ var relevantPagesCommand = defineCommand153({
33142
33826
  meta: {
33143
33827
  name: "relevant-pages",
33144
33828
  description: `Get the top pages of a competitor domain with traffic data.
@@ -33184,7 +33868,7 @@ Examples:
33184
33868
  });
33185
33869
 
33186
33870
  // src/commands/research/web.ts
33187
- import { defineCommand as defineCommand151 } from "citty";
33871
+ import { defineCommand as defineCommand154 } from "citty";
33188
33872
  registerSchema({
33189
33873
  command: "research.web",
33190
33874
  description: "Search the web with AI to answer marketing questions \u2014 competitors, ICP, pricing, pain points, market trends. Three depth levels: medium (quick, default), high (thorough), xhigh (exhaustive deep research).",
@@ -33235,7 +33919,7 @@ async function runDeepResearch(question) {
33235
33919
  }
33236
33920
  throw new Error("Deep research timed out");
33237
33921
  }
33238
- var webCommand = defineCommand151({
33922
+ var webCommand = defineCommand154({
33239
33923
  meta: {
33240
33924
  name: "web",
33241
33925
  description: `Search the web with AI to answer any open-ended marketing question. Uses live internet data via Google Search.
@@ -33295,7 +33979,7 @@ Examples:
33295
33979
  });
33296
33980
 
33297
33981
  // src/commands/research/index.ts
33298
- var researchCommand = defineCommand152({
33982
+ var researchCommand = defineCommand155({
33299
33983
  meta: {
33300
33984
  name: "research",
33301
33985
  description: `Competitive intelligence and AI-powered research commands.
@@ -33336,10 +34020,10 @@ Full guide: __tooling__/docs/tools/baker/research.md`
33336
34020
  });
33337
34021
 
33338
34022
  // src/commands/scheduled-actions/index.ts
33339
- import { defineCommand as defineCommand159 } from "citty";
34023
+ import { defineCommand as defineCommand162 } from "citty";
33340
34024
 
33341
34025
  // src/commands/scheduled-actions/create.ts
33342
- import { defineCommand as defineCommand153 } from "citty";
34026
+ import { defineCommand as defineCommand156 } from "citty";
33343
34027
 
33344
34028
  // src/commands/scheduled-actions/shared.ts
33345
34029
  var TEMP_SCHEDULED_ACTION_PREFIX = "temp_sched_";
@@ -33347,7 +34031,7 @@ var TEMP_ID_PREFIX = "temp_";
33347
34031
  function writeOk2(data) {
33348
34032
  writeJson({ ok: true, data: data ?? null });
33349
34033
  }
33350
- function failValidation2(message) {
34034
+ function failValidation3(message) {
33351
34035
  writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message } });
33352
34036
  process.exit(1);
33353
34037
  }
@@ -33371,7 +34055,7 @@ function isOtherTempId(id) {
33371
34055
  }
33372
34056
  function validateScheduledActionRef(ref) {
33373
34057
  if (isOtherTempId(ref)) {
33374
- failValidation2(`Scheduled action temp IDs must start with ${TEMP_SCHEDULED_ACTION_PREFIX}.`);
34058
+ failValidation3(`Scheduled action temp IDs must start with ${TEMP_SCHEDULED_ACTION_PREFIX}.`);
33375
34059
  }
33376
34060
  if (!isTempScheduledActionId(ref)) {
33377
34061
  validateConvexId(ref);
@@ -33385,7 +34069,7 @@ function isPromptWithoutAgent(args, agentDisabled) {
33385
34069
  }
33386
34070
  function failIfPromptWithoutAgent(args, agentDisabled) {
33387
34071
  if (isPromptWithoutAgent(args, agentDisabled)) {
33388
- failValidation2(
34072
+ failValidation3(
33389
34073
  "--prompt only applies when an agent is spawned; it has no effect with --no-spawn-agent or --spawn-agent false."
33390
34074
  );
33391
34075
  }
@@ -33400,21 +34084,21 @@ function parseBooleanFlag(raw, flagName) {
33400
34084
  if (raw === false || raw === "false") {
33401
34085
  return false;
33402
34086
  }
33403
- failValidation2(`${flagName} must be true or false.`);
34087
+ failValidation3(`${flagName} must be true or false.`);
33404
34088
  }
33405
34089
  function buildScheduleBody(args, options) {
33406
34090
  const cron = args.cron;
33407
34091
  const runAt = args["run-at"];
33408
34092
  const timezone = args.timezone;
33409
34093
  if (cron && runAt) {
33410
- failValidation2("--cron and --run-at are mutually exclusive.");
34094
+ failValidation3("--cron and --run-at are mutually exclusive.");
33411
34095
  }
33412
34096
  if (runAt) {
33413
34097
  if (!runAt.endsWith("Z")) {
33414
- failValidation2("--run-at must be an ISO UTC timestamp ending in Z.");
34098
+ failValidation3("--run-at must be an ISO UTC timestamp ending in Z.");
33415
34099
  }
33416
34100
  if (!Number.isFinite(Date.parse(runAt))) {
33417
- failValidation2("--run-at must be a valid ISO timestamp.");
34101
+ failValidation3("--run-at must be a valid ISO timestamp.");
33418
34102
  }
33419
34103
  return { runAt, ...timezone ? { timezone } : {} };
33420
34104
  }
@@ -33425,7 +34109,7 @@ function buildScheduleBody(args, options) {
33425
34109
  return { timezone };
33426
34110
  }
33427
34111
  if (options.required) {
33428
- failValidation2("Provide exactly one of --cron or --run-at.");
34112
+ failValidation3("Provide exactly one of --cron or --run-at.");
33429
34113
  }
33430
34114
  return void 0;
33431
34115
  }
@@ -33454,7 +34138,7 @@ registerSchema({
33454
34138
  prompt: { type: "string", description: "Additional prompt instructions for the spawned agent", required: false }
33455
34139
  }
33456
34140
  });
33457
- var createCommand2 = defineCommand153({
34141
+ var createCommand2 = defineCommand156({
33458
34142
  meta: {
33459
34143
  name: "create",
33460
34144
  description: 'Stage a scheduled action. Example: baker scheduled-actions create --name "Weekly report" --description "..." --cron "0 9 * * MON"'
@@ -33474,10 +34158,10 @@ var createCommand2 = defineCommand153({
33474
34158
  const name = args.name;
33475
34159
  const description = args.description;
33476
34160
  if (!name || name.trim().length === 0) {
33477
- failValidation2("--name is required.");
34161
+ failValidation3("--name is required.");
33478
34162
  }
33479
34163
  if (!description || description.trim().length === 0) {
33480
- failValidation2("--description is required.");
34164
+ failValidation3("--description is required.");
33481
34165
  }
33482
34166
  const schedule = buildScheduleBody(args, { required: true });
33483
34167
  const chatId = requireChatId();
@@ -33503,7 +34187,7 @@ var createCommand2 = defineCommand153({
33503
34187
  });
33504
34188
 
33505
34189
  // src/commands/scheduled-actions/delete.ts
33506
- import { defineCommand as defineCommand154 } from "citty";
34190
+ import { defineCommand as defineCommand157 } from "citty";
33507
34191
  registerSchema({
33508
34192
  command: "scheduled-actions.delete",
33509
34193
  description: "Stage deletion of a published scheduled action or cancellation of a temp_sched_* draft creation.",
@@ -33511,7 +34195,7 @@ registerSchema({
33511
34195
  id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
33512
34196
  }
33513
34197
  });
33514
- var deleteCommand2 = defineCommand154({
34198
+ var deleteCommand2 = defineCommand157({
33515
34199
  meta: {
33516
34200
  name: "delete",
33517
34201
  description: "Stage scheduled action deletion. Example: baker scheduled-actions delete <id-or-temp_sched_id>"
@@ -33528,7 +34212,7 @@ var deleteCommand2 = defineCommand154({
33528
34212
  try {
33529
34213
  const id = args.id || args["scheduled-action-id"];
33530
34214
  if (!id) {
33531
- failValidation2("Scheduled action ID is required.");
34215
+ failValidation3("Scheduled action ID is required.");
33532
34216
  }
33533
34217
  validateScheduledActionRef(id);
33534
34218
  await apiPost("/api/scheduled-actions/delete", { chatId: requireChatId(), id });
@@ -33540,7 +34224,7 @@ var deleteCommand2 = defineCommand154({
33540
34224
  });
33541
34225
 
33542
34226
  // src/commands/scheduled-actions/get.ts
33543
- import { defineCommand as defineCommand155 } from "citty";
34227
+ import { defineCommand as defineCommand158 } from "citty";
33544
34228
  registerSchema({
33545
34229
  command: "scheduled-actions.get",
33546
34230
  description: "Get a published scheduled action or a temp_sched_* draft-created scheduled action.",
@@ -33549,7 +34233,7 @@ registerSchema({
33549
34233
  chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
33550
34234
  }
33551
34235
  });
33552
- var getCommand3 = defineCommand155({
34236
+ var getCommand3 = defineCommand158({
33553
34237
  meta: {
33554
34238
  name: "get",
33555
34239
  description: "Get a scheduled action. Example: baker scheduled-actions get <id-or-temp_sched_id>"
@@ -33567,13 +34251,13 @@ var getCommand3 = defineCommand155({
33567
34251
  try {
33568
34252
  const id = args.id || args["scheduled-action-id"];
33569
34253
  if (!id) {
33570
- failValidation2("Scheduled action ID is required.");
34254
+ failValidation3("Scheduled action ID is required.");
33571
34255
  }
33572
34256
  validateScheduledActionRef(id);
33573
34257
  const env = getEnv();
33574
34258
  const chatId = typeof args.chat === "string" && args.chat.length > 0 ? args.chat : env.BAKER_CHAT_ID;
33575
34259
  if (isTempScheduledActionId(id) && !chatId) {
33576
- failValidation2("BAKER_CHAT_ID or --chat is required to get a temp scheduled action ID.");
34260
+ failValidation3("BAKER_CHAT_ID or --chat is required to get a temp scheduled action ID.");
33577
34261
  }
33578
34262
  const body = { id };
33579
34263
  if (chatId) {
@@ -33588,7 +34272,7 @@ var getCommand3 = defineCommand155({
33588
34272
  });
33589
34273
 
33590
34274
  // src/commands/scheduled-actions/list.ts
33591
- import { defineCommand as defineCommand156 } from "citty";
34275
+ import { defineCommand as defineCommand159 } from "citty";
33592
34276
  registerSchema({
33593
34277
  command: "scheduled-actions.list",
33594
34278
  description: "List published scheduled actions. Includes draft state when BAKER_CHAT_ID is set, or --chat <id> to read an earlier chat's staged schedules instead.",
@@ -33596,7 +34280,7 @@ registerSchema({
33596
34280
  chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
33597
34281
  }
33598
34282
  });
33599
- var listCommand14 = defineCommand156({
34283
+ var listCommand14 = defineCommand159({
33600
34284
  meta: {
33601
34285
  name: "list",
33602
34286
  description: "List scheduled actions. Includes staged draft ops when BAKER_CHAT_ID is set, or --chat <id> to read an earlier chat's staged schedules instead."
@@ -33619,7 +34303,7 @@ var listCommand14 = defineCommand156({
33619
34303
  });
33620
34304
 
33621
34305
  // src/commands/scheduled-actions/trigger.ts
33622
- import { defineCommand as defineCommand157 } from "citty";
34306
+ import { defineCommand as defineCommand160 } from "citty";
33623
34307
  registerSchema({
33624
34308
  command: "scheduled-actions.trigger",
33625
34309
  description: "Immediately trigger a published scheduled action. Does not require BAKER_CHAT_ID and rejects temp_sched_* IDs.",
@@ -33627,7 +34311,7 @@ registerSchema({
33627
34311
  id: { type: "string", description: "Published scheduled action ID", required: true }
33628
34312
  }
33629
34313
  });
33630
- var triggerCommand = defineCommand157({
34314
+ var triggerCommand = defineCommand160({
33631
34315
  meta: {
33632
34316
  name: "trigger",
33633
34317
  description: "Immediately trigger a published scheduled action. Example: baker scheduled-actions trigger <id>"
@@ -33644,10 +34328,10 @@ var triggerCommand = defineCommand157({
33644
34328
  try {
33645
34329
  const id = args.id || args["scheduled-action-id"];
33646
34330
  if (!id) {
33647
- failValidation2("Scheduled action ID is required.");
34331
+ failValidation3("Scheduled action ID is required.");
33648
34332
  }
33649
34333
  if (isTempScheduledActionId(id)) {
33650
- failValidation2("trigger requires a published scheduled action ID, not temp_sched_*.");
34334
+ failValidation3("trigger requires a published scheduled action ID, not temp_sched_*.");
33651
34335
  }
33652
34336
  validateConvexId(id);
33653
34337
  const env = getEnv();
@@ -33664,7 +34348,7 @@ var triggerCommand = defineCommand157({
33664
34348
  });
33665
34349
 
33666
34350
  // src/commands/scheduled-actions/update.ts
33667
- import { defineCommand as defineCommand158 } from "citty";
34351
+ import { defineCommand as defineCommand161 } from "citty";
33668
34352
  registerSchema({
33669
34353
  command: "scheduled-actions.update",
33670
34354
  description: "Stage an update to a published scheduled action or temp_sched_* draft-created scheduled action.",
@@ -33689,7 +34373,7 @@ registerSchema({
33689
34373
  prompt: { type: "string", description: "Replacement additional spawned-agent instructions", required: false }
33690
34374
  }
33691
34375
  });
33692
- var updateCommand2 = defineCommand158({
34376
+ var updateCommand2 = defineCommand161({
33693
34377
  meta: {
33694
34378
  name: "update",
33695
34379
  description: "Stage a scheduled action update. Example: baker scheduled-actions update <id> --enabled false"
@@ -33714,7 +34398,7 @@ var updateCommand2 = defineCommand158({
33714
34398
  try {
33715
34399
  const id = args.id || args["scheduled-action-id"];
33716
34400
  if (!id) {
33717
- failValidation2("Scheduled action ID is required.");
34401
+ failValidation3("Scheduled action ID is required.");
33718
34402
  }
33719
34403
  validateScheduledActionRef(id);
33720
34404
  const body = { id };
@@ -33746,7 +34430,7 @@ var updateCommand2 = defineCommand158({
33746
34430
  hasPatch = true;
33747
34431
  }
33748
34432
  if (!hasPatch) {
33749
- failValidation2(
34433
+ failValidation3(
33750
34434
  "Provide at least one of --name, --description, --cron, --run-at, --timezone, --enabled, --spawn-agent, --prompt."
33751
34435
  );
33752
34436
  }
@@ -33760,7 +34444,7 @@ var updateCommand2 = defineCommand158({
33760
34444
  });
33761
34445
 
33762
34446
  // src/commands/scheduled-actions/index.ts
33763
- var scheduledActionsCommand = defineCommand159({
34447
+ var scheduledActionsCommand = defineCommand162({
33764
34448
  meta: {
33765
34449
  name: "scheduled-actions",
33766
34450
  description: `Manage Scheduled Actions. Subcommands: list, get, create, update, delete, trigger.
@@ -33787,14 +34471,14 @@ Full guide: __tooling__/docs/tools/baker/scheduled-actions.md`
33787
34471
  });
33788
34472
 
33789
34473
  // src/commands/schema.ts
33790
- import { defineCommand as defineCommand160 } from "citty";
34474
+ import { defineCommand as defineCommand163 } from "citty";
33791
34475
  function narrowToFamily(commandName, available) {
33792
34476
  const segments = commandName.split(".");
33793
34477
  const prefix = segments[0] === "ads" && segments[1] ? `ads.${segments[1]}.` : `${segments[0]}.`;
33794
34478
  const siblings = available.filter((name) => name.startsWith(prefix));
33795
34479
  return siblings.length > 0 ? siblings : available;
33796
34480
  }
33797
- var schemaCommand = defineCommand160({
34481
+ var schemaCommand = defineCommand163({
33798
34482
  meta: {
33799
34483
  name: "schema",
33800
34484
  description: "Inspect command argument schemas (for AI agent introspection). Lists all commands if no argument given. Example: baker schema images.search"
@@ -33838,44 +34522,44 @@ var schemaCommand = defineCommand160({
33838
34522
  });
33839
34523
 
33840
34524
  // src/commands/tag-manager/index.ts
33841
- import { defineCommand as defineCommand164 } from "citty";
34525
+ import { defineCommand as defineCommand167 } from "citty";
33842
34526
 
33843
34527
  // src/commands/tag-manager/draft.ts
33844
- import { defineCommand as defineCommand161 } from "citty";
34528
+ import { defineCommand as defineCommand164 } from "citty";
33845
34529
 
33846
34530
  // src/commands/tag-manager/shared.ts
33847
- import { readFileSync as readFileSync12 } from "fs";
33848
- function failValidation3(message) {
34531
+ import { readFileSync as readFileSync13 } from "fs";
34532
+ function failValidation4(message) {
33849
34533
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
33850
34534
  process.exit(1);
33851
34535
  }
33852
- function requireTarget4(args, entity) {
34536
+ function requireTarget5(args, entity) {
33853
34537
  const positional = Array.isArray(args._) ? args._[0] : void 0;
33854
34538
  const target = args.id ?? args.target ?? positional;
33855
34539
  if (typeof target !== "string" || target.length === 0) {
33856
- failValidation3(`pass the ${entity} id or path as the positional argument`);
34540
+ failValidation4(`pass the ${entity} id or path as the positional argument`);
33857
34541
  }
33858
34542
  return target;
33859
34543
  }
33860
- function loadJsonArg(args, flag = "json") {
34544
+ function loadJsonArg2(args, flag = "json") {
33861
34545
  const inline = args[flag];
33862
34546
  const file = args.file;
33863
- const raw = typeof file === "string" && file.length > 0 ? readFileSync12(file, "utf8") : typeof inline === "string" && inline.length > 0 ? inline : void 0;
34547
+ const raw = typeof file === "string" && file.length > 0 ? readFileSync13(file, "utf8") : typeof inline === "string" && inline.length > 0 ? inline : void 0;
33864
34548
  if (raw === void 0) {
33865
- failValidation3(`pass --${flag} with inline JSON or --file with a path to a JSON file`);
34549
+ failValidation4(`pass --${flag} with inline JSON or --file with a path to a JSON file`);
33866
34550
  }
33867
34551
  try {
33868
34552
  const parsed = JSON.parse(raw);
33869
34553
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
33870
- failValidation3(`--${flag} must be a JSON object`);
34554
+ failValidation4(`--${flag} must be a JSON object`);
33871
34555
  }
33872
34556
  return parsed;
33873
34557
  } catch {
33874
- return failValidation3(`--${flag} is not valid JSON`);
34558
+ return failValidation4(`--${flag} is not valid JSON`);
33875
34559
  }
33876
34560
  }
33877
- var RETRYABLE_CODES = /* @__PURE__ */ new Set(["RATE_LIMITED", "INTERNAL_ERROR", "NETWORK_ERROR", "TIMEOUT"]);
33878
- function handleError3(err) {
34561
+ var RETRYABLE_CODES2 = /* @__PURE__ */ new Set(["RATE_LIMITED", "INTERNAL_ERROR", "NETWORK_ERROR", "TIMEOUT"]);
34562
+ function handleError4(err) {
33879
34563
  if (err instanceof ApiError) {
33880
34564
  writeJsonEnvelope({
33881
34565
  ok: false,
@@ -33888,7 +34572,7 @@ function handleError3(err) {
33888
34572
  explanation: 'Tag Manager is not connected for this company yet, or no container has been picked. Do NOT send the user to Settings \u2014 call the `request_connection` tool with { platform: "google-tag-manager", reason } and they connect and pick their containers (they can pick more than one) from inside the chat. `request_tag_input` is NOT the route: that form manages the container snippet on the site, not what runs inside the container, and it cannot pick a container. If `request_connection` is not available to you, say so plainly and point them at dashboard \u2192 Brain \u2192 Integrations \u2192 Tools \u2192 Google Tag Manager, where they also pick the container. Carry on with the rest of the task meanwhile.'
33889
34573
  }
33890
34574
  } : {},
33891
- retryable: RETRYABLE_CODES.has(err.code)
34575
+ retryable: RETRYABLE_CODES2.has(err.code)
33892
34576
  }
33893
34577
  });
33894
34578
  process.exit(1);
@@ -33896,29 +34580,29 @@ function handleError3(err) {
33896
34580
  writeJsonEnvelope({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error", retryable: true } });
33897
34581
  process.exit(1);
33898
34582
  }
33899
- var STAGE_HINTS = [
34583
+ var STAGE_HINTS2 = [
33900
34584
  "Staged only \u2014 nothing has changed in Tag Manager yet. These apply when the chat completes, in dependency order, and close as a Tag Manager version that is then published, so they do go live on the user's site. Say the changes are ready and go live when they publish \u2014 not that they are live already."
33901
34585
  ];
33902
- async function stageOp3(op) {
34586
+ async function stageOp4(op) {
33903
34587
  const chatId = requireChatId();
33904
34588
  try {
33905
34589
  const data = await apiPost("/api/tag-manager/draft/stage", { chatId, op });
33906
- writeJsonEnvelope({ ok: true, data, hints: STAGE_HINTS });
34590
+ writeJsonEnvelope({ ok: true, data, hints: STAGE_HINTS2 });
33907
34591
  } catch (err) {
33908
- handleError3(err);
34592
+ handleError4(err);
33909
34593
  }
33910
34594
  }
33911
- async function draftAction2(path28, body, chat) {
34595
+ async function draftAction3(path28, body, chat) {
33912
34596
  const chatId = resolveChatId(chat);
33913
34597
  try {
33914
34598
  const data = await apiPost(path28, { chatId, ...body });
33915
34599
  writeJsonEnvelope({ ok: true, data });
33916
34600
  return data;
33917
34601
  } catch (err) {
33918
- handleError3(err);
34602
+ handleError4(err);
33919
34603
  }
33920
34604
  }
33921
- function renderDraft(response) {
34605
+ function renderDraft2(response) {
33922
34606
  if (response.count === 0) {
33923
34607
  return "No Tag Manager changes staged on this chat.";
33924
34608
  }
@@ -33940,7 +34624,7 @@ function renderDraft(response) {
33940
34624
  }
33941
34625
  return lines.join("\n");
33942
34626
  }
33943
- async function draftList(json, chat) {
34627
+ async function draftList2(json, chat) {
33944
34628
  const chatId = resolveChatId(chat);
33945
34629
  try {
33946
34630
  const data = await apiPost("/api/tag-manager/draft", { chatId });
@@ -33948,10 +34632,10 @@ async function draftList(json, chat) {
33948
34632
  writeJsonEnvelope({ ok: true, data });
33949
34633
  return;
33950
34634
  }
33951
- process.stdout.write(`${renderDraft(data)}
34635
+ process.stdout.write(`${renderDraft2(data)}
33952
34636
  `);
33953
34637
  } catch (err) {
33954
- handleError3(err);
34638
+ handleError4(err);
33955
34639
  }
33956
34640
  }
33957
34641
 
@@ -33964,13 +34648,13 @@ registerSchema({
33964
34648
  chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
33965
34649
  }
33966
34650
  });
33967
- var draftCommand3 = defineCommand161({
34651
+ var draftCommand4 = defineCommand164({
33968
34652
  meta: {
33969
34653
  name: "draft",
33970
34654
  description: "List, show, amend, remove, or clear staged Tag Manager changes for this chat. `list` and `show` take --chat <id> to read an earlier chat's changes instead."
33971
34655
  },
33972
34656
  subCommands: {
33973
- list: defineCommand161({
34657
+ list: defineCommand164({
33974
34658
  meta: {
33975
34659
  name: "list",
33976
34660
  description: "Review everything staged on this chat (--json for the raw envelope)"
@@ -33980,10 +34664,10 @@ var draftCommand3 = defineCommand161({
33980
34664
  chat: CHAT_READ_ARG
33981
34665
  },
33982
34666
  run: async ({ args }) => {
33983
- await draftList(args.json === true, args.chat);
34667
+ await draftList2(args.json === true, args.chat);
33984
34668
  }
33985
34669
  }),
33986
- show: defineCommand161({
34670
+ show: defineCommand164({
33987
34671
  meta: {
33988
34672
  name: "show",
33989
34673
  description: "Print the full staged payload for one change \u2014 the receipt to verify it looks right before publish (never truncated)."
@@ -33993,14 +34677,14 @@ var draftCommand3 = defineCommand161({
33993
34677
  chat: CHAT_READ_ARG
33994
34678
  },
33995
34679
  run: async ({ args }) => {
33996
- await draftAction2(
34680
+ await draftAction3(
33997
34681
  "/api/tag-manager/draft/show",
33998
- { ref: requireTarget4(args, "change") },
34682
+ { ref: requireTarget5(args, "change") },
33999
34683
  args.chat
34000
34684
  );
34001
34685
  }
34002
34686
  }),
34003
- amend: defineCommand161({
34687
+ amend: defineCommand164({
34004
34688
  meta: {
34005
34689
  name: "amend",
34006
34690
  description: "Update a staged change in place \u2014 merges a JSON patch into its payload (objects deep-merge, null deletes a key, arrays/scalars replace) and re-validates. Use this instead of remove + re-create."
@@ -34011,32 +34695,32 @@ var draftCommand3 = defineCommand161({
34011
34695
  file: { type: "string", description: "JSON file with the patch object", required: false }
34012
34696
  },
34013
34697
  run: async ({ args }) => {
34014
- await draftAction2("/api/tag-manager/draft/amend", {
34015
- ref: requireTarget4(args, "change"),
34016
- patch: loadJsonArg(args, "patch")
34698
+ await draftAction3("/api/tag-manager/draft/amend", {
34699
+ ref: requireTarget5(args, "change"),
34700
+ patch: loadJsonArg2(args, "patch")
34017
34701
  });
34018
34702
  }
34019
34703
  }),
34020
- remove: defineCommand161({
34704
+ remove: defineCommand164({
34021
34705
  meta: { name: "remove", description: "Remove one staged change (cascades to anything depending on it)" },
34022
34706
  args: { ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false } },
34023
34707
  run: async ({ args }) => {
34024
- await draftAction2("/api/tag-manager/draft/remove", {
34025
- ref: requireTarget4(args, "change")
34708
+ await draftAction3("/api/tag-manager/draft/remove", {
34709
+ ref: requireTarget5(args, "change")
34026
34710
  });
34027
34711
  }
34028
34712
  }),
34029
- clear: defineCommand161({
34713
+ clear: defineCommand164({
34030
34714
  meta: { name: "clear", description: "Discard all Tag Manager changes staged on this chat" },
34031
34715
  run: async () => {
34032
- await draftAction2("/api/tag-manager/draft/clear", {});
34716
+ await draftAction3("/api/tag-manager/draft/clear", {});
34033
34717
  }
34034
34718
  })
34035
34719
  }
34036
34720
  });
34037
34721
 
34038
34722
  // src/commands/tag-manager/read.ts
34039
- import { defineCommand as defineCommand162 } from "citty";
34723
+ import { defineCommand as defineCommand165 } from "citty";
34040
34724
  registerSchema({
34041
34725
  command: "tagManager.containers",
34042
34726
  description: "List the Google Tag Manager containers this company's connection can reach. Every container the company connected is flagged `connected: true` \u2014 there can be several, and Baker may read and change all of them. Start here to confirm which containers you are managing.",
@@ -34077,7 +34761,7 @@ function containersHints(containers) {
34077
34761
  }))
34078
34762
  });
34079
34763
  }
34080
- var containersCommand = defineCommand162({
34764
+ var containersCommand = defineCommand165({
34081
34765
  meta: {
34082
34766
  name: "containers",
34083
34767
  description: `List Tag Manager containers reachable by this company's connection.
@@ -34090,11 +34774,11 @@ Start here:
34090
34774
  const data = await apiGet("/api/tag-manager/containers");
34091
34775
  writeJsonEnvelope({ ok: true, data, hints: containersHints(data.containers) });
34092
34776
  } catch (err) {
34093
- handleError3(err);
34777
+ handleError4(err);
34094
34778
  }
34095
34779
  }
34096
34780
  });
34097
- var readCommand = defineCommand162({
34781
+ var readCommand = defineCommand165({
34098
34782
  meta: {
34099
34783
  name: "read",
34100
34784
  description: `Read the current contents of the Tag Manager container \u2014 always do this before staging changes.
@@ -34130,13 +34814,13 @@ Examples:
34130
34814
  );
34131
34815
  writeJsonEnvelope({ ok: true, data, hints });
34132
34816
  } catch (err) {
34133
- handleError3(err);
34817
+ handleError4(err);
34134
34818
  }
34135
34819
  }
34136
34820
  });
34137
34821
 
34138
34822
  // src/commands/tag-manager/write-commands.ts
34139
- import { defineCommand as defineCommand163 } from "citty";
34823
+ import { defineCommand as defineCommand166 } from "citty";
34140
34824
  var CONTAINER_ARG_DESCRIPTION = "Numeric container id (optional only when one container is connected \u2014 run `baker tag-manager containers`)";
34141
34825
  var ENTITIES = [
34142
34826
  {
@@ -34192,10 +34876,10 @@ for (const { entity, noun, createHint } of ENTITIES) {
34192
34876
  });
34193
34877
  }
34194
34878
  function entityCommand(entity, noun, example) {
34195
- return defineCommand163({
34879
+ return defineCommand166({
34196
34880
  meta: { name: entity, description: `Stage ${noun} changes on this chat's Tag Manager draft` },
34197
34881
  subCommands: {
34198
- create: defineCommand163({
34882
+ create: defineCommand166({
34199
34883
  meta: {
34200
34884
  name: "create",
34201
34885
  description: `Stage a new ${noun}
@@ -34210,14 +34894,14 @@ Examples:
34210
34894
  container: { type: "string", description: CONTAINER_ARG_DESCRIPTION, required: false }
34211
34895
  },
34212
34896
  run: async ({ args }) => {
34213
- await stageOp3({
34897
+ await stageOp4({
34214
34898
  kind: `tagManager.${entity}.create`,
34215
- payload: loadJsonArg(args),
34899
+ payload: loadJsonArg2(args),
34216
34900
  ...typeof args.container === "string" ? { containerId: args.container } : {}
34217
34901
  });
34218
34902
  }
34219
34903
  }),
34220
- update: defineCommand163({
34904
+ update: defineCommand166({
34221
34905
  meta: {
34222
34906
  name: "update",
34223
34907
  description: `Stage an update to an existing ${noun} (pass its id or path)`
@@ -34229,24 +34913,24 @@ Examples:
34229
34913
  container: { type: "string", description: CONTAINER_ARG_DESCRIPTION, required: false }
34230
34914
  },
34231
34915
  run: async ({ args }) => {
34232
- await stageOp3({
34916
+ await stageOp4({
34233
34917
  kind: `tagManager.${entity}.update`,
34234
- target: requireTarget4(args, noun),
34235
- payload: loadJsonArg(args),
34918
+ target: requireTarget5(args, noun),
34919
+ payload: loadJsonArg2(args),
34236
34920
  ...typeof args.container === "string" ? { containerId: args.container } : {}
34237
34921
  });
34238
34922
  }
34239
34923
  }),
34240
- delete: defineCommand163({
34924
+ delete: defineCommand166({
34241
34925
  meta: { name: "delete", description: `Stage the deletion of a ${noun} (pass its id or path)` },
34242
34926
  args: {
34243
34927
  id: { type: "positional", description: `${noun} id or path`, required: false },
34244
34928
  container: { type: "string", description: CONTAINER_ARG_DESCRIPTION, required: false }
34245
34929
  },
34246
34930
  run: async ({ args }) => {
34247
- await stageOp3({
34931
+ await stageOp4({
34248
34932
  kind: `tagManager.${entity}.delete`,
34249
- target: requireTarget4(args, noun),
34933
+ target: requireTarget5(args, noun),
34250
34934
  ...typeof args.container === "string" ? { containerId: args.container } : {}
34251
34935
  });
34252
34936
  }
@@ -34278,7 +34962,7 @@ function builtinTypes(args) {
34278
34962
  }
34279
34963
  return raw.split(",").map((entry) => entry.trim());
34280
34964
  }
34281
- var builtinCommand = defineCommand163({
34965
+ var builtinCommand = defineCommand166({
34282
34966
  meta: {
34283
34967
  name: "builtin",
34284
34968
  description: `Enable or disable built-in variables
@@ -34288,28 +34972,28 @@ Examples:
34288
34972
  baker tag-manager builtin disable --types formId`
34289
34973
  },
34290
34974
  subCommands: {
34291
- enable: defineCommand163({
34975
+ enable: defineCommand166({
34292
34976
  meta: { name: "enable", description: "Stage enabling built-in variables" },
34293
34977
  args: {
34294
34978
  types: { type: "string", description: "Comma-separated types", required: false },
34295
34979
  container: { type: "string", description: CONTAINER_ARG_DESCRIPTION, required: false }
34296
34980
  },
34297
34981
  run: async ({ args }) => {
34298
- await stageOp3({
34982
+ await stageOp4({
34299
34983
  kind: "tagManager.builtInVariable.enable",
34300
34984
  payload: { type: builtinTypes(args) },
34301
34985
  ...typeof args.container === "string" ? { containerId: args.container } : {}
34302
34986
  });
34303
34987
  }
34304
34988
  }),
34305
- disable: defineCommand163({
34989
+ disable: defineCommand166({
34306
34990
  meta: { name: "disable", description: "Stage disabling built-in variables" },
34307
34991
  args: {
34308
34992
  types: { type: "string", description: "Comma-separated types", required: false },
34309
34993
  container: { type: "string", description: CONTAINER_ARG_DESCRIPTION, required: false }
34310
34994
  },
34311
34995
  run: async ({ args }) => {
34312
- await stageOp3({
34996
+ await stageOp4({
34313
34997
  kind: "tagManager.builtInVariable.disable",
34314
34998
  payload: { type: builtinTypes(args) },
34315
34999
  ...typeof args.container === "string" ? { containerId: args.container } : {}
@@ -34320,7 +35004,7 @@ Examples:
34320
35004
  });
34321
35005
 
34322
35006
  // src/commands/tag-manager/index.ts
34323
- var tagManagerCommand = defineCommand164({
35007
+ var tagManagerCommand = defineCommand167({
34324
35008
  meta: {
34325
35009
  name: "tag-manager",
34326
35010
  description: `Read and change what lives inside the client's Google Tag Manager container \u2014 tags, triggers, variables, folders and built-in variables.
@@ -34349,12 +35033,12 @@ Full guide: __tooling__/docs/tools/baker/tag-manager.md`
34349
35033
  variable: variableCommand,
34350
35034
  folder: folderCommand,
34351
35035
  builtin: builtinCommand,
34352
- draft: draftCommand3
35036
+ draft: draftCommand4
34353
35037
  }
34354
35038
  });
34355
35039
 
34356
35040
  // src/commands/tags/index.ts
34357
- import { defineCommand as defineCommand165 } from "citty";
35041
+ import { defineCommand as defineCommand168 } from "citty";
34358
35042
 
34359
35043
  // src/commands/tags/shared.ts
34360
35044
  function failApi3(err) {
@@ -34423,7 +35107,7 @@ async function listTags(json) {
34423
35107
  var listArgs9 = {
34424
35108
  json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" }
34425
35109
  };
34426
- var listCommand15 = defineCommand165({
35110
+ var listCommand15 = defineCommand168({
34427
35111
  meta: {
34428
35112
  name: "list",
34429
35113
  description: "Effective tags for this chat (production + staged), with each tag's full readable config (secrets excluded) \u2014 reuse a stored value to pre-fill a change rather than asking the user. Refs printed here are what flow side-effect tagIds should use. Example: baker tags list"
@@ -34442,7 +35126,7 @@ async function listDraft3(chat) {
34442
35126
  failApi3(err);
34443
35127
  }
34444
35128
  }
34445
- var draftCommand4 = defineCommand165({
35129
+ var draftCommand5 = defineCommand168({
34446
35130
  meta: {
34447
35131
  name: "draft",
34448
35132
  description: "Review the tag changes staged in this chat (read-only). Staged changes were approved via request_tag_input and apply when the chat is published; to amend or drop one, propose a follow-up change through the same tool (a delete on a tag_temp_* ref drops the staged create). Takes --chat <id> to read an earlier chat's staged changes instead."
@@ -34452,7 +35136,7 @@ var draftCommand4 = defineCommand165({
34452
35136
  await listDraft3(args.chat);
34453
35137
  }
34454
35138
  });
34455
- var tagsCommand3 = defineCommand165({
35139
+ var tagsCommand3 = defineCommand168({
34456
35140
  meta: {
34457
35141
  name: "tags",
34458
35142
  description: `Read the client's marketing/analytics tags (Meta pixel, GA4, Google Ads, GTM, Clarity, Hotjar, \u2026) \u2014 production tags plus the changes staged in this chat.
@@ -34470,7 +35154,7 @@ Full guide: __tooling__/docs/tools/baker/tags.md`
34470
35154
  },
34471
35155
  subCommands: {
34472
35156
  list: listCommand15,
34473
- draft: draftCommand4
35157
+ draft: draftCommand5
34474
35158
  },
34475
35159
  // Bare `baker tags` lists the effective tags. `args` stays so citty knows this
34476
35160
  // command's flags when it scans rawArgs for a subcommand name, and `default` (not
@@ -34481,10 +35165,10 @@ Full guide: __tooling__/docs/tools/baker/tags.md`
34481
35165
  });
34482
35166
 
34483
35167
  // src/commands/testimonials/index.ts
34484
- import { defineCommand as defineCommand169 } from "citty";
35168
+ import { defineCommand as defineCommand172 } from "citty";
34485
35169
 
34486
35170
  // src/commands/testimonials/get.ts
34487
- import { defineCommand as defineCommand166 } from "citty";
35171
+ import { defineCommand as defineCommand169 } from "citty";
34488
35172
  registerSchema({
34489
35173
  command: "testimonials.get",
34490
35174
  description: "Get a single testimonial by ID",
@@ -34492,7 +35176,7 @@ registerSchema({
34492
35176
  id: { type: "string", description: "Testimonial ID", required: true }
34493
35177
  }
34494
35178
  });
34495
- var getCommand4 = defineCommand166({
35179
+ var getCommand4 = defineCommand169({
34496
35180
  meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
34497
35181
  args: {
34498
35182
  id: { type: "positional", description: "Testimonial ID", required: false },
@@ -34529,7 +35213,7 @@ var getCommand4 = defineCommand166({
34529
35213
  });
34530
35214
 
34531
35215
  // src/commands/testimonials/list.ts
34532
- import { defineCommand as defineCommand167 } from "citty";
35216
+ import { defineCommand as defineCommand170 } from "citty";
34533
35217
  registerSchema({
34534
35218
  command: "testimonials.list",
34535
35219
  description: "List testimonials with optional filters.",
@@ -34559,7 +35243,7 @@ registerSchema({
34559
35243
  limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
34560
35244
  }
34561
35245
  });
34562
- var listCommand16 = defineCommand167({
35246
+ var listCommand16 = defineCommand170({
34563
35247
  meta: {
34564
35248
  name: "list",
34565
35249
  description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
@@ -34608,7 +35292,7 @@ var listCommand16 = defineCommand167({
34608
35292
  });
34609
35293
 
34610
35294
  // src/commands/testimonials/search.ts
34611
- import { defineCommand as defineCommand168 } from "citty";
35295
+ import { defineCommand as defineCommand171 } from "citty";
34612
35296
  function languageBiasHint(results, requestedLanguage) {
34613
35297
  if (requestedLanguage) {
34614
35298
  return null;
@@ -34686,7 +35370,7 @@ function buildSearchRequest(query, args) {
34686
35370
  }
34687
35371
  return body;
34688
35372
  }
34689
- var searchCommand2 = defineCommand168({
35373
+ var searchCommand2 = defineCommand171({
34690
35374
  meta: {
34691
35375
  name: "search",
34692
35376
  description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
@@ -34742,7 +35426,7 @@ var searchCommand2 = defineCommand168({
34742
35426
  var tagsCommand4 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
34743
35427
 
34744
35428
  // src/commands/testimonials/index.ts
34745
- var testimonialsCommand = defineCommand169({
35429
+ var testimonialsCommand = defineCommand172({
34746
35430
  meta: {
34747
35431
  name: "testimonials",
34748
35432
  description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
@@ -34764,10 +35448,10 @@ Full guide: __tooling__/docs/tools/baker/testimonials.md`
34764
35448
  });
34765
35449
 
34766
35450
  // src/commands/videos/index.ts
34767
- import { defineCommand as defineCommand174 } from "citty";
35451
+ import { defineCommand as defineCommand177 } from "citty";
34768
35452
 
34769
35453
  // src/commands/videos/delete.ts
34770
- import { defineCommand as defineCommand170 } from "citty";
35454
+ import { defineCommand as defineCommand173 } from "citty";
34771
35455
  registerSchema({
34772
35456
  command: "videos.delete",
34773
35457
  description: "Delete a video by ID",
@@ -34781,7 +35465,7 @@ registerSchema({
34781
35465
  }
34782
35466
  }
34783
35467
  });
34784
- var deleteCommand3 = defineCommand170({
35468
+ var deleteCommand3 = defineCommand173({
34785
35469
  meta: {
34786
35470
  name: "delete",
34787
35471
  description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
@@ -34822,7 +35506,7 @@ var deleteCommand3 = defineCommand170({
34822
35506
  });
34823
35507
 
34824
35508
  // src/commands/videos/get.ts
34825
- import { defineCommand as defineCommand171 } from "citty";
35509
+ import { defineCommand as defineCommand174 } from "citty";
34826
35510
  registerSchema({
34827
35511
  command: "videos.get",
34828
35512
  description: "Get a single video by ID",
@@ -34830,7 +35514,7 @@ registerSchema({
34830
35514
  id: { type: "string", description: "Video ID", required: true }
34831
35515
  }
34832
35516
  });
34833
- var getCommand5 = defineCommand171({
35517
+ var getCommand5 = defineCommand174({
34834
35518
  meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
34835
35519
  args: {
34836
35520
  id: { type: "positional", description: "Video ID", required: false },
@@ -34867,7 +35551,7 @@ var getCommand5 = defineCommand171({
34867
35551
  });
34868
35552
 
34869
35553
  // src/commands/videos/search.ts
34870
- import { defineCommand as defineCommand172 } from "citty";
35554
+ import { defineCommand as defineCommand175 } from "citty";
34871
35555
  registerSchema({
34872
35556
  command: "videos.search",
34873
35557
  description: "Search videos by text query. Only returns ready videos.",
@@ -34877,7 +35561,7 @@ registerSchema({
34877
35561
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
34878
35562
  }
34879
35563
  });
34880
- var searchCommand3 = defineCommand172({
35564
+ var searchCommand3 = defineCommand175({
34881
35565
  meta: {
34882
35566
  name: "search",
34883
35567
  description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
@@ -34929,7 +35613,7 @@ var tagsCommand5 = makeTagsCommand("videos", "video", "/api/videos/tags");
34929
35613
  // src/commands/videos/upload.ts
34930
35614
  import { readFile as readFile23, stat as stat7 } from "fs/promises";
34931
35615
  import { extname as extname3 } from "path";
34932
- import { defineCommand as defineCommand173 } from "citty";
35616
+ import { defineCommand as defineCommand176 } from "citty";
34933
35617
  var MIME_MAP = {
34934
35618
  ".mp4": "video/mp4",
34935
35619
  ".mov": "video/quicktime",
@@ -34963,7 +35647,7 @@ function detectContentType(filePath) {
34963
35647
  }
34964
35648
  return mime;
34965
35649
  }
34966
- var uploadCommand2 = defineCommand173({
35650
+ var uploadCommand2 = defineCommand176({
34967
35651
  meta: {
34968
35652
  name: "upload",
34969
35653
  description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
@@ -35017,7 +35701,7 @@ var uploadCommand2 = defineCommand173({
35017
35701
  });
35018
35702
 
35019
35703
  // src/commands/videos/index.ts
35020
- var videosCommand = defineCommand174({
35704
+ var videosCommand = defineCommand177({
35021
35705
  meta: {
35022
35706
  name: "videos",
35023
35707
  description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
@@ -35041,10 +35725,10 @@ Full guide: __tooling__/docs/tools/baker/videos.md`
35041
35725
  });
35042
35726
 
35043
35727
  // src/commands/winning-ads/index.ts
35044
- import { defineCommand as defineCommand187 } from "citty";
35728
+ import { defineCommand as defineCommand190 } from "citty";
35045
35729
 
35046
35730
  // src/commands/winning-ads/advertisers.ts
35047
- import { defineCommand as defineCommand175 } from "citty";
35731
+ import { defineCommand as defineCommand178 } from "citty";
35048
35732
 
35049
35733
  // src/commands/winning-ads/shared.ts
35050
35734
  function splitList(value) {
@@ -35097,7 +35781,7 @@ function advertiserNormalizer(record, full) {
35097
35781
  last_synced_at: record.last_synced_at ?? null
35098
35782
  };
35099
35783
  }
35100
- var advertisersCommand2 = defineCommand175({
35784
+ var advertisersCommand2 = defineCommand178({
35101
35785
  meta: {
35102
35786
  name: "advertisers",
35103
35787
  description: 'List corpus advertisers by name or domain. Find your own advertiser for --exclude-advertiser, or a competitor for --advertiser-id / winners. Example: baker winning-ads advertisers "Deel" --output md'
@@ -35155,7 +35839,7 @@ var advertisersCommand2 = defineCommand175({
35155
35839
  });
35156
35840
 
35157
35841
  // src/commands/winning-ads/brief.ts
35158
- import { defineCommand as defineCommand176 } from "citty";
35842
+ import { defineCommand as defineCommand179 } from "citty";
35159
35843
  registerSchema({
35160
35844
  command: "winning-ads.brief",
35161
35845
  description: "Generate a creative brief grounded in strategically-similar winning ads. Optionally describe the target creative with --dna (JSON) and steer with --notes.",
@@ -35201,7 +35885,7 @@ function parseDna(raw) {
35201
35885
  }
35202
35886
  return parsed;
35203
35887
  }
35204
- var briefCommand = defineCommand176({
35888
+ var briefCommand = defineCommand179({
35205
35889
  meta: {
35206
35890
  name: "brief",
35207
35891
  description: `Generate a creative brief from winning references. Example: baker winning-ads brief --dna '{"angle":"cost savings"}' --notes "B2B, LinkedIn video" --k 8`
@@ -35237,7 +35921,7 @@ var briefCommand = defineCommand176({
35237
35921
  });
35238
35922
 
35239
35923
  // src/commands/winning-ads/content.ts
35240
- import { defineCommand as defineCommand177 } from "citty";
35924
+ import { defineCommand as defineCommand180 } from "citty";
35241
35925
  registerSchema({
35242
35926
  command: "winning-ads.content",
35243
35927
  description: "Read what's INSIDE one winning ad: the spoken transcript, the on-screen text, and the ad copy. Use this after `search`/`winners`/`feed` return a shortlist \u2014 pass an ad_id to understand a reference before reproducing it. Add --full for speech, pacing, and soundtrack detail. Video ads carry the transcript/on-screen text; static ads carry only the copy.",
@@ -35250,7 +35934,7 @@ registerSchema({
35250
35934
  }
35251
35935
  }
35252
35936
  });
35253
- var contentCommand = defineCommand177({
35937
+ var contentCommand = defineCommand180({
35254
35938
  meta: {
35255
35939
  name: "content",
35256
35940
  description: "Read the transcript + on-screen text + copy of one winning ad. Example: baker winning-ads content adg_123 --platform meta --full --output md"
@@ -35299,7 +35983,7 @@ var contentCommand = defineCommand177({
35299
35983
  });
35300
35984
 
35301
35985
  // src/commands/winning-ads/feed.ts
35302
- import { defineCommand as defineCommand178 } from "citty";
35986
+ import { defineCommand as defineCommand181 } from "citty";
35303
35987
  function buildFeedParams(input) {
35304
35988
  const params = {};
35305
35989
  const advertiser = splitList(input.advertiser);
@@ -35351,7 +36035,7 @@ registerSchema({
35351
36035
  format: { type: "string", description: "Comma-separated formats to include (e.g. static,video)", required: false }
35352
36036
  }
35353
36037
  });
35354
- var feedCommand = defineCommand178({
36038
+ var feedCommand = defineCommand181({
35355
36039
  meta: {
35356
36040
  name: "feed",
35357
36041
  description: "Winners across every brand you follow (browse, then trim per advertiser). Example: baker winning-ads feed --per-advertiser 5 --output md"
@@ -35436,7 +36120,7 @@ var feedCommand = defineCommand178({
35436
36120
  });
35437
36121
 
35438
36122
  // src/commands/winning-ads/follow.ts
35439
- import { defineCommand as defineCommand179 } from "citty";
36123
+ import { defineCommand as defineCommand182 } from "citty";
35440
36124
  var PLATFORMS = ["meta", "linkedin"];
35441
36125
  registerSchema({
35442
36126
  command: "winning-ads.follow",
@@ -35451,7 +36135,7 @@ registerSchema({
35451
36135
  label: { type: "string", description: "Optional display label (defaults to the resolved name)", required: false }
35452
36136
  }
35453
36137
  });
35454
- var followCommand = defineCommand179({
36138
+ var followCommand = defineCommand182({
35455
36139
  meta: {
35456
36140
  name: "follow",
35457
36141
  description: 'Follow a brand to track ALL its ads \u2014 every platform and country. --platform is how we read your input, not a limit. A domain tracks both Meta + LinkedIn. Example: baker winning-ads follow "deel.com" --platform meta'
@@ -35498,7 +36182,7 @@ var followCommand = defineCommand179({
35498
36182
  });
35499
36183
 
35500
36184
  // src/commands/winning-ads/follow-competitors.ts
35501
- import { defineCommand as defineCommand180 } from "citty";
36185
+ import { defineCommand as defineCommand183 } from "citty";
35502
36186
  var PLATFORMS2 = ["meta", "linkedin"];
35503
36187
  var BATCH_TIMEOUT_MS = 3e5;
35504
36188
  function buildFollowBatchBody(input) {
@@ -35531,7 +36215,7 @@ registerSchema({
35531
36215
  }
35532
36216
  }
35533
36217
  });
35534
- var followCompetitorsCommand = defineCommand180({
36218
+ var followCompetitorsCommand = defineCommand183({
35535
36219
  meta: {
35536
36220
  name: "follow-competitors",
35537
36221
  description: 'Follow many brands at once by domain \u2014 add every competitor in one call. Example: baker winning-ads follow-competitors "deel.com,notion.so,hubspot.com"'
@@ -35606,7 +36290,7 @@ var followCompetitorsCommand = defineCommand180({
35606
36290
  });
35607
36291
 
35608
36292
  // src/commands/winning-ads/following.ts
35609
- import { defineCommand as defineCommand181 } from "citty";
36293
+ import { defineCommand as defineCommand184 } from "citty";
35610
36294
  registerSchema({
35611
36295
  command: "winning-ads.following",
35612
36296
  description: "List the brands you follow in your ad-dna library, with each one's status (ready vs still adding) and cached ad counts.",
@@ -35639,7 +36323,7 @@ function followingNormalizer(record, full) {
35639
36323
  platforms: Array.isArray(record.platforms) ? record.platforms : []
35640
36324
  };
35641
36325
  }
35642
- var followingCommand = defineCommand181({
36326
+ var followingCommand = defineCommand184({
35643
36327
  meta: {
35644
36328
  name: "following",
35645
36329
  description: "List brands you follow, with status (ready / adding\u2026) and cached counts. Example: baker winning-ads following --output md"
@@ -35674,7 +36358,7 @@ var followingCommand = defineCommand181({
35674
36358
  });
35675
36359
 
35676
36360
  // src/commands/winning-ads/patterns.ts
35677
- import { defineCommand as defineCommand182 } from "citty";
36361
+ import { defineCommand as defineCommand185 } from "citty";
35678
36362
  registerSchema({
35679
36363
  command: "winning-ads.patterns",
35680
36364
  description: "Mine what separates two cohorts of ads: pass a comma-list of winning ad ids (--winners) and a comma-list of weaker ad ids (--duds). Returns the discriminating DNA fields.",
@@ -35713,7 +36397,7 @@ function discriminatorRow(record) {
35713
36397
  top_values_duds: Array.isArray(record.top_values_b) ? record.top_values_b.join(", ") : ""
35714
36398
  };
35715
36399
  }
35716
- var patternsCommand = defineCommand182({
36400
+ var patternsCommand = defineCommand185({
35717
36401
  meta: {
35718
36402
  name: "patterns",
35719
36403
  description: "Discover what separates winning ads from weak ones. Example: baker winning-ads patterns --winners a_1,a_2,a_3 --duds a_9,a_8 --output md"
@@ -35769,7 +36453,7 @@ var patternsCommand = defineCommand182({
35769
36453
  });
35770
36454
 
35771
36455
  // src/commands/winning-ads/search.ts
35772
- import { defineCommand as defineCommand183 } from "citty";
36456
+ import { defineCommand as defineCommand186 } from "citty";
35773
36457
  registerSchema({
35774
36458
  command: "winning-ads.search",
35775
36459
  description: "Search the ad-dna corpus of scored winning ads. Returns a lean shortlist (advertiser, summary, scores, media_url) to pick a reference to reproduce.",
@@ -35877,7 +36561,7 @@ function buildSearchBody(args) {
35877
36561
  }
35878
36562
  return body;
35879
36563
  }
35880
- var searchCommand4 = defineCommand183({
36564
+ var searchCommand4 = defineCommand186({
35881
36565
  meta: {
35882
36566
  name: "search",
35883
36567
  description: "Search winning reference ads. Example: baker winning-ads search 'B2B SaaS before/after AI automation' --platform meta --format static --winner-category winner --exclude-advertiser adv_123 --output md"
@@ -35992,7 +36676,7 @@ var searchCommand4 = defineCommand183({
35992
36676
  });
35993
36677
 
35994
36678
  // src/commands/winning-ads/seeds.ts
35995
- import { defineCommand as defineCommand184 } from "citty";
36679
+ import { defineCommand as defineCommand187 } from "citty";
35996
36680
  function leanRow(r) {
35997
36681
  return {
35998
36682
  key: r.key,
@@ -36020,7 +36704,7 @@ function makeSeedCommand(opts) {
36020
36704
  limit: { type: "number", description: "Max keys 1-100 (default 20)", required: false, default: 20 }
36021
36705
  }
36022
36706
  });
36023
- return defineCommand184({
36707
+ return defineCommand187({
36024
36708
  meta: { name: opts.name, description: opts.description },
36025
36709
  args: {
36026
36710
  platform: { type: "string", description: "Single platform to segment on", required: false },
@@ -36069,7 +36753,7 @@ var formatsCommand = makeSeedCommand({
36069
36753
  });
36070
36754
 
36071
36755
  // src/commands/winning-ads/unfollow.ts
36072
- import { defineCommand as defineCommand185 } from "citty";
36756
+ import { defineCommand as defineCommand188 } from "citty";
36073
36757
  registerSchema({
36074
36758
  command: "winning-ads.unfollow",
36075
36759
  description: "Stop following a brand \u2014 removes it from your ad-dna library by advertiser id.",
@@ -36077,7 +36761,7 @@ registerSchema({
36077
36761
  advertiser: { type: "string", description: "Advertiser id to unfollow", required: true }
36078
36762
  }
36079
36763
  });
36080
- var unfollowCommand = defineCommand185({
36764
+ var unfollowCommand = defineCommand188({
36081
36765
  meta: {
36082
36766
  name: "unfollow",
36083
36767
  description: "Stop following a brand by advertiser id. Example: baker winning-ads unfollow adv_123"
@@ -36098,7 +36782,7 @@ var unfollowCommand = defineCommand185({
36098
36782
  });
36099
36783
 
36100
36784
  // src/commands/winning-ads/winners.ts
36101
- import { defineCommand as defineCommand186 } from "citty";
36785
+ import { defineCommand as defineCommand189 } from "citty";
36102
36786
  registerSchema({
36103
36787
  command: "winning-ads.winners",
36104
36788
  description: "Top winning ads for one advertiser id (from `advertisers` or `following`). Returns lean winner cards; add --full for DNA + longevity.",
@@ -36108,7 +36792,7 @@ registerSchema({
36108
36792
  platform: { type: "string", description: "Filter to a single platform: meta|linkedin", required: false }
36109
36793
  }
36110
36794
  });
36111
- var winnersCommand = defineCommand186({
36795
+ var winnersCommand = defineCommand189({
36112
36796
  meta: {
36113
36797
  name: "winners",
36114
36798
  description: "Top winning ads for a specific advertiser id. Example: baker winning-ads winners adv_123 --top 15 --output md"
@@ -36158,7 +36842,7 @@ var winnersCommand = defineCommand186({
36158
36842
  });
36159
36843
 
36160
36844
  // src/commands/winning-ads/index.ts
36161
- var winningAdsCommand = defineCommand187({
36845
+ var winningAdsCommand = defineCommand190({
36162
36846
  meta: {
36163
36847
  name: "winning-ads",
36164
36848
  description: `Search the ad-dna corpus of scored "winning" ads for reference creatives to reproduce, and manage the brands your library tracks. Proxied through the Baker backend (BAKER_API_KEY) \u2014 no separate token needed.
@@ -36214,7 +36898,7 @@ Full guide: __tooling__/docs/tools/baker/winning-ads.md`
36214
36898
  });
36215
36899
 
36216
36900
  // src/version.ts
36217
- import { readFileSync as readFileSync13 } from "fs";
36901
+ import { readFileSync as readFileSync14 } from "fs";
36218
36902
  function packageJsonUrl() {
36219
36903
  return new URL("../package.json", import.meta.url);
36220
36904
  }
@@ -36226,11 +36910,11 @@ function parsePackageVersion(raw) {
36226
36910
  throw new Error("Invalid CLI package.json: missing version");
36227
36911
  }
36228
36912
  function getCliVersion() {
36229
- return parsePackageVersion(readFileSync13(packageJsonUrl(), "utf8"));
36913
+ return parsePackageVersion(readFileSync14(packageJsonUrl(), "utf8"));
36230
36914
  }
36231
36915
 
36232
36916
  // src/cli.ts
36233
- var main = defineCommand188({
36917
+ var main = defineCommand191({
36234
36918
  meta: {
36235
36919
  name: "baker",
36236
36920
  version: getCliVersion(),