@koda-sl/baker-cli 0.384.0-dev.4699b7308 → 0.385.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
@@ -70,7 +70,7 @@ import {
70
70
  validateCanvasDeep,
71
71
  withoutCastName,
72
72
  ytDlpBlockSignal
73
- } from "./chunk-CHJOTJTZ.js";
73
+ } from "./chunk-FGHMWBUD.js";
74
74
  import {
75
75
  NAME_CONTAINS_ARG,
76
76
  csvOrJson,
@@ -299,6 +299,7 @@ var chatActionDraftOpViewSchema = z.object({
299
299
  targetActionId: z.string().optional(),
300
300
  tempId: z.string().optional(),
301
301
  tags: z.array(z.string()).optional(),
302
+ priority: actionPrioritySchema.nullable().optional(),
302
303
  reason: z.string().optional(),
303
304
  note: z.string().optional(),
304
305
  name: z.string().optional(),
@@ -5123,16 +5124,6 @@ var FLOW_SIDE_EFFECT_CATALOG = [
5123
5124
  },
5124
5125
  "`advancedMatching` is how Meta re-identifies the visitor, and it is the difference between a matched conversion and a discarded one. Fill at least `em` and `ph` from the form: `baker flows map <slug> --map em=email --map ph=phone`."
5125
5126
  ),
5126
- eventSideEffect(
5127
- "chatgptAds",
5128
- "Fires a ChatGPT Ads pixel conversion and mirrors it through the Conversions API when a key is configured.",
5129
- {
5130
- eventType: "standard",
5131
- eventParams: [],
5132
- advancedMatching: matchingSlots("em", "ph", "fn", "ln", "external_id", "ct", "st", "zp", "country")
5133
- },
5134
- "Use ChatGPT Ads event names such as lead_created, order_created or appointment_scheduled. For a custom event use a lowercase name of 1\u201364 letters, digits, underscores or dashes. Only value (major currency units) and currency are supported in eventParams. Map em from the form to improve conversion matching."
5135
- ),
5136
5127
  eventSideEffect("googleAnalytics", "Fires a GA4 event.", { eventType: "custom", eventParams: [] }),
5137
5128
  {
5138
5129
  kind: "side-effect",
@@ -8045,7 +8036,6 @@ var studioImproveResponseSchema = z27.object({ prompt: z27.string(), original: z
8045
8036
  import { z as z28 } from "zod";
8046
8037
  var TAG_TYPES = [
8047
8038
  "meta",
8048
- "chatgptAds",
8049
8039
  "amplitude",
8050
8040
  "googleAds",
8051
8041
  "tiktok",
@@ -8067,7 +8057,6 @@ var TAG_TYPES = [
8067
8057
  var tagTypeSchema = z28.enum(TAG_TYPES);
8068
8058
  var TAG_IDENTIFYING_FIELD = {
8069
8059
  meta: "pixelId",
8070
- chatgptAds: "pixelId",
8071
8060
  googleAds: "conversionID",
8072
8061
  tiktok: "pixelCode",
8073
8062
  pinterest: "tagId",
@@ -15038,14 +15027,7 @@ function parseEventKey(key) {
15038
15027
  }
15039
15028
 
15040
15029
  // ../api/src/analytics/sends.ts
15041
- var SEND_PLATFORMS = [
15042
- "meta",
15043
- "chatgptAds",
15044
- "googleAds",
15045
- "linkedinInsightTag",
15046
- "twitterAds",
15047
- "googleAnalytics"
15048
- ];
15030
+ var SEND_PLATFORMS = ["meta", "googleAds", "linkedinInsightTag", "twitterAds", "googleAnalytics"];
15049
15031
  function isSendPlatform(value) {
15050
15032
  return SEND_PLATFORMS.includes(value);
15051
15033
  }
@@ -15057,13 +15039,6 @@ var SEND_PLATFORM_SPECS = {
15057
15039
  credentialFields: ["accessToken"],
15058
15040
  setupHint: "Add the Conversions API access token to the Meta pixel in Tracking"
15059
15041
  },
15060
- chatgptAds: {
15061
- title: "ChatGPT Ads",
15062
- eventMeans: "A ChatGPT Ads event \u2014 lead_created, order_created, or a custom name",
15063
- eventKind: "name",
15064
- credentialFields: ["apiKey"],
15065
- setupHint: "Add the Conversions API key to the ChatGPT Ads pixel in Tracking"
15066
- },
15067
15042
  googleAds: {
15068
15043
  title: "Google Ads",
15069
15044
  eventMeans: "One of the account's conversion actions, picked from its list",
@@ -15114,7 +15089,6 @@ function isConversionSend(type) {
15114
15089
  }
15115
15090
  var SERVER_SIDE_SENDER_TAG = {
15116
15091
  metaCapi: "meta",
15117
- chatgptAdsCapi: "chatgptAds",
15118
15092
  googleAdsCapi: "googleAds",
15119
15093
  linkedinCapi: "linkedinInsightTag",
15120
15094
  twitterAdsCapi: "twitterAds",
@@ -20571,9 +20545,8 @@ function requireTargets(args5, entity) {
20571
20545
  var CHAT_READ_ARG_DESCRIPTION = CHAT_READ_ARG.description;
20572
20546
  registerSchema({
20573
20547
  command: "ads.linkedin.accounts",
20574
- description: "List LinkedIn ad accounts in the company's connected scope. Pass --include-all to list every account the OAuth token can see.",
20548
+ description: "List LinkedIn ad accounts in the company's connected scope.",
20575
20549
  args: {
20576
- "include-all": { type: "boolean", description: "Ignore picker scope", required: false },
20577
20550
  "no-cache": NO_CACHE_ARG,
20578
20551
  output: { type: "string", description: "json|csv|jsonl|md", required: false, default: "json" }
20579
20552
  }
@@ -22284,11 +22257,7 @@ Examples:
22284
22257
 
22285
22258
  // src/commands/ads/linkedin/accounts.ts
22286
22259
  import { defineCommand as defineCommand35 } from "citty";
22287
- var ACCOUNTS_TTL_MS = 60 * 60 * 1e3;
22288
- function accountHints2(accounts, includeAll) {
22289
- if (includeAll) {
22290
- return [];
22291
- }
22260
+ function accountHints2(accounts) {
22292
22261
  return connectedResourceHints({
22293
22262
  plural: "LinkedIn ad accounts",
22294
22263
  singular: "LinkedIn ad account",
@@ -22303,44 +22272,23 @@ var accountsCommand2 = defineCommand35({
22303
22272
 
22304
22273
  Examples:
22305
22274
  baker ads linkedin accounts
22306
- baker ads linkedin accounts --include-all # ignore picker scope, list every account the token can see
22307
22275
  baker ads linkedin accounts --output csv`
22308
22276
  },
22309
22277
  args: {
22310
- "include-all": { type: "boolean", description: "List all accessible accounts, ignoring picker scope" },
22311
22278
  "no-cache": NO_CACHE_ARG,
22312
22279
  output: { type: "string", description: "Output format: json|csv|jsonl|md", default: "json" }
22313
22280
  },
22314
22281
  run: async ({ args: args5 }) => {
22315
- const includeAll = args5["include-all"] === true;
22316
- const useCache = !args5["no-cache"];
22317
- const cacheKey = `accounts:${includeAll ? "all" : "scoped"}`;
22318
- if (useCache) {
22319
- const cached = cacheGet("linkedin-accounts", cacheKey);
22320
- if (cached) {
22321
- writeJsonEnvelope({
22322
- ok: true,
22323
- data: cached.data,
22324
- cached: true,
22325
- hints: accountHints2(cached.data, includeAll)
22326
- });
22327
- return;
22328
- }
22329
- }
22330
22282
  try {
22331
22283
  const params = {};
22332
- if (includeAll) params["include-all"] = "true";
22333
- if (!useCache) params["skip-cache"] = "true";
22284
+ if (args5["no-cache"]) params["skip-cache"] = "true";
22334
22285
  const data = await apiGet("/api/ads/linkedin/accounts", params);
22335
- if (useCache) {
22336
- cacheSet("linkedin-accounts", cacheKey, data, ACCOUNTS_TTL_MS);
22337
- }
22338
22286
  const fmt = csvOrJson2(args5);
22339
22287
  if (fmt !== "json") {
22340
22288
  writeAdsOutput(data, fmt);
22341
22289
  return;
22342
22290
  }
22343
- writeJsonEnvelope({ ok: true, data, hints: accountHints2(data, includeAll) });
22291
+ writeJsonEnvelope({ ok: true, data, hints: accountHints2(data) });
22344
22292
  } catch (err) {
22345
22293
  handleLinkedinError(err);
22346
22294
  }
@@ -24339,7 +24287,6 @@ var linkedinCommand = defineCommand53({
24339
24287
 
24340
24288
  Discovery:
24341
24289
  baker ads linkedin accounts \u2014 accounts in this company's connected scope
24342
- baker ads linkedin accounts --include-all \u2014 every account the token can see
24343
24290
  baker ads linkedin account --account-id 503001492 \u2014 single-account detail (currency, type, status)
24344
24291
  baker ads linkedin url-params [--ad-sets] \u2014 UTMs in effect today, and keys set at two levels
24345
24292
 
@@ -24434,10 +24381,7 @@ Examples:
24434
24381
 
24435
24382
  // src/commands/ads/meta/accounts.ts
24436
24383
  import { defineCommand as defineCommand55 } from "citty";
24437
- function accountHints3(accounts, includeAll) {
24438
- if (includeAll) {
24439
- return [];
24440
- }
24384
+ function accountHints3(accounts) {
24441
24385
  return connectedResourceHints({
24442
24386
  plural: "Meta ad accounts",
24443
24387
  singular: "Meta ad account",
@@ -24455,44 +24399,23 @@ var accountsCommand3 = defineCommand55({
24455
24399
 
24456
24400
  Examples:
24457
24401
  baker ads meta accounts
24458
- baker ads meta accounts --include-all # ignore picker scope and list every account the token can see
24459
24402
  baker ads meta accounts --output csv`
24460
24403
  },
24461
24404
  args: {
24462
- "include-all": { type: "boolean", description: "List all accessible accounts, ignoring picker scope" },
24463
24405
  "no-cache": NO_CACHE_ARG,
24464
24406
  output: { type: "string", description: "Output format: json|csv|jsonl|md", default: "json" }
24465
24407
  },
24466
24408
  run: async ({ args: args5 }) => {
24467
- const includeAll = args5["include-all"] === true;
24468
- const useCache = !args5["no-cache"];
24469
- const cacheKey = `accounts:${includeAll ? "all" : "scoped"}`;
24470
- if (useCache) {
24471
- const cached = cacheGet("meta-accounts", cacheKey);
24472
- if (cached) {
24473
- writeJsonEnvelope({
24474
- ok: true,
24475
- data: cached.data,
24476
- cached: true,
24477
- hints: accountHints3(cached.data, includeAll)
24478
- });
24479
- return;
24480
- }
24481
- }
24482
24409
  try {
24483
24410
  const params = {};
24484
- if (includeAll) params["include-all"] = "true";
24485
- if (!useCache) params["skip-cache"] = "true";
24411
+ if (args5["no-cache"]) params["skip-cache"] = "true";
24486
24412
  const data = await apiGet("/api/ads/meta/accounts", params);
24487
- if (useCache) {
24488
- cacheSet("meta-accounts", cacheKey, data, 60 * 60 * 1e3);
24489
- }
24490
24413
  const fmt = csvOrJson(args5);
24491
24414
  if (fmt !== "json") {
24492
24415
  writeAdsOutput(data, fmt);
24493
24416
  return;
24494
24417
  }
24495
- writeJsonEnvelope({ ok: true, data, hints: accountHints3(data, includeAll) });
24418
+ writeJsonEnvelope({ ok: true, data, hints: accountHints3(data) });
24496
24419
  } catch (err) {
24497
24420
  handleMetaError(err);
24498
24421
  }
@@ -27378,7 +27301,7 @@ import { defineCommand as defineCommand61 } from "citty";
27378
27301
  var businessesCommand = defineCommand61({
27379
27302
  meta: {
27380
27303
  name: "businesses",
27381
- description: `List Meta Business Manager accounts the connected user has access to. Required for ad-studies and product-catalogs commands.
27304
+ description: `List Meta Business Manager accounts linked to this company's selected ad accounts. Required for ad-studies and product-catalogs commands.
27382
27305
 
27383
27306
  Examples:
27384
27307
  baker ads meta businesses`
@@ -28248,9 +28171,13 @@ Async is automatic for heavy queries; pass --async to force it, or --no-async to
28248
28171
  import { defineCommand as defineCommand67 } from "citty";
28249
28172
  registerSchema({
28250
28173
  command: "ads.meta.lead-forms",
28251
- description: "List the instant (lead) forms on a Facebook Page, with how many leads each has collected. Start here: a lead is fetched by form id, and `baker ads meta pages` gives the page id.",
28174
+ description: "List the instant (lead) forms on a Facebook Page, with how many leads each has collected. Start here: a lead is fetched by form id. Use a Page from `baker ads meta pages` with hasPageAccessToken: true.",
28252
28175
  args: {
28253
- "page-id": { type: "string", description: "Facebook Page ID \u2014 from `baker ads meta pages`", required: true },
28176
+ "page-id": {
28177
+ type: "string",
28178
+ description: "Facebook Page ID \u2014 from `baker ads meta pages` with hasPageAccessToken: true",
28179
+ required: true
28180
+ },
28254
28181
  full: { type: "boolean", description: "Include each form's questions", required: false },
28255
28182
  output: { type: "string", description: "json|csv", required: false, default: "json" }
28256
28183
  }
@@ -28323,7 +28250,7 @@ function leadPageHints(page, full) {
28323
28250
  var leadFormsCommand2 = defineCommand67({
28324
28251
  meta: {
28325
28252
  name: "lead-forms",
28326
- description: `List the instant (lead) forms on a Facebook Page, with each form's lead count. A lead is read by form id, so start here \u2014 get the Page id from \`baker ads meta pages\`.
28253
+ description: `List the instant (lead) forms on a Facebook Page, with each form's lead count. A lead is read by form id, so start here \u2014 get a Page id with hasPageAccessToken: true from \`baker ads meta pages\`.
28327
28254
 
28328
28255
  Examples:
28329
28256
  baker ads meta lead-forms --page-id 100635183117758
@@ -28338,7 +28265,11 @@ Examples:
28338
28265
  try {
28339
28266
  const pageId = args5["page-id"];
28340
28267
  if (!pageId) {
28341
- handleLeadsError(new Error("--page-id is required. Run `baker ads meta pages` to find it."));
28268
+ handleLeadsError(
28269
+ new Error(
28270
+ "--page-id is required. Run `baker ads meta pages` and choose a Page with hasPageAccessToken: true."
28271
+ )
28272
+ );
28342
28273
  }
28343
28274
  const params = { "page-id": pageId };
28344
28275
  if (args5.full) params.full = "true";
@@ -28424,27 +28355,21 @@ var metaMediaCommand = defineCommand68({
28424
28355
 
28425
28356
  // src/commands/ads/meta/pages.ts
28426
28357
  import { defineCommand as defineCommand69 } from "citty";
28427
- function advertisablePages(data) {
28428
- return data.filter((p) => Array.isArray(p.tasks) && p.tasks.includes("ADVERTISE"));
28429
- }
28430
28358
  function pageSelectionHints(data) {
28431
- const advertisable = advertisablePages(data);
28432
- if (advertisable.length > 1) {
28433
- return [
28434
- "MULTIPLE Pages can run ads \u2014 do NOT guess. Confirm with the user which Page an ad should run from before passing --page to `creatives create`; a wrong Page publishes the ad under the wrong brand identity and staging will not catch it."
28435
- ];
28436
- }
28437
- if (data.length > 0 && advertisable.length === 0) {
28359
+ if (data.length === 0) return [];
28360
+ const accountHint = "Use a Page only with an ad account listed in its promotingAccountIds. hasPageAccessToken must be true to read instant forms; null means Meta could not check it. Form reads also require the company's lead-ads permissions.";
28361
+ if (data.length > 1) {
28438
28362
  return [
28439
- "NO Page can run ads \u2014 none of the connected user's Pages carry the ADVERTISE task. Ask the user to grant Advertise access to the right Page before creating an ad; a readable-but-non-advertising Page still passes staging and would fail or run under the wrong identity."
28363
+ accountHint,
28364
+ "MULTIPLE Pages can run ads from the selected Meta ad accounts \u2014 do NOT guess. Confirm with the user which Page an ad should run from before passing --page to `creatives create`; a wrong Page publishes the ad under the wrong brand identity and staging will not catch it."
28440
28365
  ];
28441
28366
  }
28442
- return [];
28367
+ return [accountHint];
28443
28368
  }
28444
28369
  var pagesCommand = defineCommand69({
28445
28370
  meta: {
28446
28371
  name: "pages",
28447
- description: `List the Facebook Pages the connected user manages. Every Meta ad publishes from a Page, so use this to identify the Page an ad should run from. The 'tasks' field shows what the user can do on each Page (ADVERTISE means it can back ads). If exactly one Page can ADVERTISE, use it; if more than one can, confirm with the user which Page to use; if none can, ask the user to grant Advertise access \u2014 a wrong or non-advertising Page publishes under the wrong brand identity.
28372
+ description: `List the Facebook Pages that the selected Meta ad accounts can promote, showing which accounts can promote each Page. Every Meta ad publishes from a Page, so match its promotingAccountIds to the target account. hasPageAccessToken shows whether the connected person can also read that Page's instant forms. If more than one Page is listed, confirm the brand with the user.
28448
28373
 
28449
28374
  Examples:
28450
28375
  baker ads meta pages`
@@ -28703,9 +28628,8 @@ var metaCommand = defineCommand72({
28703
28628
 
28704
28629
  Discovery:
28705
28630
  baker ads meta accounts \u2014 accounts in this company's connected scope
28706
- baker ads meta accounts --include-all \u2014 every account the token can see
28707
28631
  baker ads meta businesses \u2014 Business Manager IDs
28708
- baker ads meta pages \u2014 Facebook Pages the user manages (an ad's identity)
28632
+ baker ads meta pages \u2014 Facebook Pages the selected ad accounts can promote (an ad's identity)
28709
28633
  baker ads meta lead-forms --page-id 100635183117758 \u2014 instant (lead) forms on a Page, with lead counts
28710
28634
  baker ads meta leads --form-id 987654321 \u2014 the leads one form collected (contact details masked)
28711
28635
 
@@ -49595,14 +49519,6 @@ var MAPPING_SLOTS = {
49595
49519
  code: [PAYLOAD("eventProperties")],
49596
49520
  datafast: [PAYLOAD("goalParams")],
49597
49521
  meta: [PAYLOAD("eventParams"), { kind: "record", key: "advancedMatching", allowed: META_MATCHING }],
49598
- chatgptAds: [
49599
- PAYLOAD("eventParams"),
49600
- {
49601
- kind: "record",
49602
- key: "advancedMatching",
49603
- allowed: ["em", "ph", "fn", "ln", "external_id", "ct", "st", "zp", "country"]
49604
- }
49605
- ],
49606
49522
  tiktok: [
49607
49523
  PAYLOAD("eventParams"),
49608
49524
  { kind: "record", key: "identify", allowed: ["email", "phone_number", "external_id"] }
@@ -66999,7 +66915,7 @@ var draftCommand5 = defineCommand218({
66999
66915
  import { defineCommand as defineCommand219 } from "citty";
67000
66916
  registerSchema({
67001
66917
  command: "tagManager.containers",
67002
- 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.",
66918
+ description: "List the Google Tag Manager containers this company selected. There can be several, and Baker may read and change all of them. Start here to confirm which containers you are managing.",
67003
66919
  args: {}
67004
66920
  });
67005
66921
  registerSchema({
@@ -67020,27 +66936,34 @@ registerSchema({
67020
66936
  full: { type: "boolean", description: "Include the raw Tag Manager object for each entity", required: false }
67021
66937
  }
67022
66938
  });
67023
- function containersHints(containers) {
67024
- const connected = containers.filter((container) => container.connected);
67025
- if (connected.length === 0) {
67026
- return [
67027
- "None of the containers this company connected came back from Tag Manager. The connected Google account may have lost access to them \u2014 ask the user to reconnect or pick a container again."
67028
- ];
67029
- }
67030
- return connectedResourceHints({
66939
+ function containersHints(containers, unavailableContainers = []) {
66940
+ const hints2 = connectedResourceHints({
67031
66941
  plural: "Tag Manager containers",
67032
66942
  singular: "Tag Manager container",
67033
66943
  flag: "--container",
67034
- resources: connected.map((container) => ({
66944
+ resources: containers.map((container) => ({
67035
66945
  id: container.containerId,
67036
66946
  label: `${container.publicId} \xB7 ${container.name}`
67037
66947
  }))
67038
66948
  });
66949
+ if (unavailableContainers.length > 0) {
66950
+ const [available] = containers;
66951
+ if (containers.length === 1 && available) {
66952
+ hints2.length = 0;
66953
+ hints2.push(
66954
+ `Use --container ${available.containerId} for ${available.publicId} (${available.name}); another selected container cannot be opened.`
66955
+ );
66956
+ }
66957
+ hints2.push(
66958
+ `Tag Manager cannot open ${unavailableContainers.map((container) => `${container.publicId} (${container.name})`).join(", ")}. Ask the user to reconnect with a Google account that has access to these containers.`
66959
+ );
66960
+ }
66961
+ return hints2;
67039
66962
  }
67040
66963
  var containersCommand = defineCommand219({
67041
66964
  meta: {
67042
66965
  name: "containers",
67043
- description: `List Tag Manager containers reachable by this company's connection.
66966
+ description: `List Tag Manager containers selected by this company.
67044
66967
 
67045
66968
  Start here:
67046
66969
  baker tag-manager containers`
@@ -67048,7 +66971,7 @@ Start here:
67048
66971
  run: async () => {
67049
66972
  try {
67050
66973
  const data = await apiGet("/api/tag-manager/containers");
67051
- writeJsonEnvelope({ ok: true, data, hints: containersHints(data.containers) });
66974
+ writeJsonEnvelope({ ok: true, data, hints: containersHints(data.containers, data.unavailableContainers) });
67052
66975
  } catch (err) {
67053
66976
  handleError8(err);
67054
66977
  }