@koda-sl/baker-cli 0.141.0-dev.253d2418a → 0.141.0-dev.86f91edc8

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
@@ -73,7 +73,7 @@ import {
73
73
  } from "./chunk-RK67WL4O.js";
74
74
 
75
75
  // src/cli.ts
76
- import { defineCommand as defineCommand175, runMain } from "citty";
76
+ import { defineCommand as defineCommand179, runMain } from "citty";
77
77
 
78
78
  // src/commands/actions/index.ts
79
79
  import { defineCommand as defineCommand18 } from "citty";
@@ -1980,6 +1980,7 @@ var chatChangeTypeSchema = z5.enum([
1980
1980
  "linkedin-ads",
1981
1981
  "google-ads",
1982
1982
  "meta-ads",
1983
+ "tag-manager",
1983
1984
  "briefs"
1984
1985
  ]);
1985
1986
  var chatChangeActionSchema = z5.enum(["created", "updated", "deleted"]);
@@ -3711,8 +3712,7 @@ Examples:
3711
3712
  baker actions claim <id>
3712
3713
  baker actions create --name "Build hero" --tags landing,creative --description "..."
3713
3714
  baker actions complete <id>
3714
- baker actions discard <id> --reason "obsolete"
3715
- Full guide: __tooling__/docs/tools/baker/actions.md`
3715
+ baker actions discard <id> --reason "obsolete"`
3716
3716
  },
3717
3717
  subCommands: {
3718
3718
  list: listCommand2,
@@ -7685,8 +7685,7 @@ Staged writes (never touch Google until the chat is published):
7685
7685
  baker ads google budgets create --customer-id 1234567890 --name "Search" --amount 50
7686
7686
  baker ads google campaigns create --customer-id 1234567890 --name "Brand" --channel-type SEARCH --budget-ref g_temp_\u2026 --bidding-strategy MANUAL_CPC
7687
7687
  baker ads google keyword-lists create --customer-id 1234567890 --name "Brand exclusions"
7688
- baker ads google draft list \u2014 review staged Google Ads changes
7689
- Full guide: __tooling__/docs/tools/baker/ads-google.md`
7688
+ baker ads google draft list \u2014 review staged Google Ads changes`
7690
7689
  },
7691
7690
  subCommands: {
7692
7691
  accounts: accountsCommand,
@@ -11146,8 +11145,7 @@ published; if the company's LinkedIn-write flag is off the publish is simulated)
11146
11145
 
11147
11146
  Account ID format:
11148
11147
  --account-id accepts numeric (503001492) or URN (urn:li:sponsoredAccount:503001492).
11149
- Set BAKER_LINKEDIN_AD_ACCOUNT_ID env to skip --account-id on every call.
11150
- Full guide: __tooling__/docs/tools/baker/ads-linkedin.md`
11148
+ Set BAKER_LINKEDIN_AD_ACCOUNT_ID env to skip --account-id on every call.`
11151
11149
  },
11152
11150
  subCommands: {
11153
11151
  accounts: accountsCommand2,
@@ -11348,13 +11346,11 @@ var SPECIAL_AD_CATEGORIES = [
11348
11346
  "NONE",
11349
11347
  "HOUSING",
11350
11348
  "EMPLOYMENT",
11351
- /** Deprecated by Meta on 2025-01-14 — replaced by FINANCIAL_PRODUCTS_SERVICES. Still accepted as input and mapped on the wire. */
11352
11349
  "CREDIT",
11353
11350
  "ISSUES_ELECTIONS_POLITICS",
11354
11351
  "FINANCIAL_PRODUCTS_SERVICES",
11355
11352
  "ONLINE_GAMBLING_AND_GAMING"
11356
11353
  ];
11357
- var SPECIAL_CATEGORIES_REQUIRING_COUNTRY = ["ISSUES_ELECTIONS_POLITICS"];
11358
11354
  var BUYING_TYPES = ["AUCTION", "RESERVED"];
11359
11355
  var BID_STRATEGIES = [
11360
11356
  "LOWEST_COST_WITHOUT_CAP",
@@ -11363,10 +11359,6 @@ var BID_STRATEGIES = [
11363
11359
  "LOWEST_COST_WITH_MIN_ROAS"
11364
11360
  ];
11365
11361
  var BID_STRATEGIES_REQUIRING_AMOUNT = ["LOWEST_COST_WITH_BID_CAP", "COST_CAP"];
11366
- var BID_STRATEGIES_FORBIDDING_AMOUNT = [
11367
- "LOWEST_COST_WITHOUT_CAP",
11368
- "LOWEST_COST_WITH_MIN_ROAS"
11369
- ];
11370
11362
  var BILLING_EVENTS = [
11371
11363
  "APP_INSTALLS",
11372
11364
  "CLICKS",
@@ -11406,9 +11398,6 @@ var OPTIMIZATION_GOALS_REQUIRING_PAGE = [
11406
11398
  "QUALITY_LEAD",
11407
11399
  "PAGE_LIKES"
11408
11400
  ];
11409
- var OPTIMIZATION_GOALS_REQUIRING_PIXEL = ["OFFSITE_CONVERSIONS"];
11410
- var OPTIMIZATION_GOALS_REQUIRING_CONVERSION_SOURCE = ["VALUE"];
11411
- var OPTIMIZATION_GOALS_REQUIRING_APP = ["APP_INSTALLS"];
11412
11401
  var DESTINATION_TYPES = [
11413
11402
  "WEBSITE",
11414
11403
  "APP",
@@ -11438,8 +11427,6 @@ var CUSTOM_EVENT_TYPES = [
11438
11427
  "OTHER"
11439
11428
  ];
11440
11429
  var ATTRIBUTION_EVENT_TYPES = ["CLICK_THROUGH", "VIEW_THROUGH", "ENGAGED_VIDEO_VIEW"];
11441
- var ADVANTAGE_AUDIENCE_OPEN_AGE_MAX = 65;
11442
- var ADVANTAGE_AUDIENCE_MAX_HARD_AGE_MIN = 25;
11443
11430
  var CTA_TYPES2 = [
11444
11431
  "LEARN_MORE",
11445
11432
  "SHOP_NOW",
@@ -11537,44 +11524,6 @@ var metaTargetingSchema = z14.object({
11537
11524
  device_platforms: z14.array(z14.string()).optional(),
11538
11525
  targeting_automation: z14.object({ advantage_audience: z14.union([z14.literal(0), z14.literal(1)]) }).partial().optional()
11539
11526
  }).catchall(z14.unknown());
11540
- var GEO_INCLUSION_KEYS = [
11541
- "countries",
11542
- "country_groups",
11543
- "regions",
11544
- "cities",
11545
- "zips",
11546
- "geo_markets",
11547
- "places",
11548
- "custom_locations",
11549
- "electoral_districts",
11550
- "subcities",
11551
- "neighborhoods"
11552
- ];
11553
- function targetingHasGeo(t) {
11554
- const geo = t?.geo_locations;
11555
- return Boolean(
11556
- geo && GEO_INCLUSION_KEYS.some((key) => Array.isArray(geo[key]) && geo[key].length > 0)
11557
- );
11558
- }
11559
- function targetingHasGeoOrAudience(t) {
11560
- if (!t) {
11561
- return false;
11562
- }
11563
- return targetingHasGeo(t) || Boolean(t.custom_audiences?.length);
11564
- }
11565
- function advantageAudienceSetting(t) {
11566
- const value = t.targeting_automation?.advantage_audience;
11567
- return value === 0 || value === 1 ? value : void 0;
11568
- }
11569
- function targetingHardLimitsDemographics(t) {
11570
- if (!t) {
11571
- return false;
11572
- }
11573
- const narrowsAgeMax = typeof t.age_max === "number" && t.age_max < ADVANTAGE_AUDIENCE_OPEN_AGE_MAX;
11574
- const narrowsAgeMin = typeof t.age_min === "number" && t.age_min > ADVANTAGE_AUDIENCE_MAX_HARD_AGE_MIN;
11575
- const narrowsGender = Array.isArray(t.genders) && t.genders.length === 1;
11576
- return narrowsAgeMax || narrowsAgeMin || narrowsGender;
11577
- }
11578
11527
  var specialAdCategoriesSchema = z14.array(z14.enum(SPECIAL_AD_CATEGORIES)).default(["NONE"]);
11579
11528
  var campaignCreateSchema3 = z14.object({
11580
11529
  name: z14.string().min(1).max(META_LIMITS.campaign.nameMax),
@@ -11598,14 +11547,6 @@ var campaignCreateSchema3 = z14.object({
11598
11547
  if (p.stop_time && p.start_time && p.stop_time <= p.start_time) {
11599
11548
  ctx.addIssue({ code: "custom", path: ["stop_time"], message: "stop_time must be after start_time" });
11600
11549
  }
11601
- const needsCountry = p.special_ad_categories.some((c) => SPECIAL_CATEGORIES_REQUIRING_COUNTRY.includes(c));
11602
- if (needsCountry && !p.special_ad_category_country?.length) {
11603
- ctx.addIssue({
11604
- code: "custom",
11605
- path: ["special_ad_category_country"],
11606
- message: "ISSUES_ELECTIONS_POLITICS campaigns need special_ad_category_country \u2014 pass the 2-letter country code(s) the ads run in"
11607
- });
11608
- }
11609
11550
  });
11610
11551
  var campaignUpdateSchema3 = z14.object({
11611
11552
  name: z14.string().min(1).max(META_LIMITS.campaign.nameMax).optional(),
@@ -11657,41 +11598,8 @@ var adSetFields = {
11657
11598
  attribution_spec: attributionSpecSchema.optional(),
11658
11599
  start_time: z14.number().int().positive().optional(),
11659
11600
  end_time: z14.number().int().positive().optional(),
11660
- targeting: metaTargetingSchema,
11661
- /** EU Digital Services Act: who benefits from / pays for the ad. Auto-filled from the account for EU geo when omitted. */
11662
- dsa_beneficiary: z14.string().min(1).max(100).optional(),
11663
- dsa_payor: z14.string().min(1).max(100).optional()
11601
+ targeting: metaTargetingSchema
11664
11602
  };
11665
- function validateBidStrategy(p, ctx) {
11666
- const strategy = p.bid_strategy;
11667
- if (!strategy) {
11668
- return;
11669
- }
11670
- if (BID_STRATEGIES_REQUIRING_AMOUNT.includes(strategy) && !p.bidAmount) {
11671
- ctx.addIssue({ code: "custom", path: ["bidAmount"], message: `${strategy} requires a bidAmount` });
11672
- }
11673
- if (BID_STRATEGIES_FORBIDDING_AMOUNT.includes(strategy) && p.bidAmount) {
11674
- ctx.addIssue({
11675
- code: "custom",
11676
- path: ["bidAmount"],
11677
- message: `${strategy} must not set a bidAmount \u2014 Meta rejects one (it bids automatically)`
11678
- });
11679
- }
11680
- if (strategy === "COST_CAP" && p.billing_event && p.billing_event !== "IMPRESSIONS") {
11681
- ctx.addIssue({
11682
- code: "custom",
11683
- path: ["billing_event"],
11684
- message: "COST_CAP requires billing_event IMPRESSIONS"
11685
- });
11686
- }
11687
- if (strategy === "LOWEST_COST_WITH_MIN_ROAS" && p.optimization_goal && p.optimization_goal !== "VALUE") {
11688
- ctx.addIssue({
11689
- code: "custom",
11690
- path: ["bid_strategy"],
11691
- message: "LOWEST_COST_WITH_MIN_ROAS requires optimization_goal VALUE"
11692
- });
11693
- }
11694
- }
11695
11603
  function validateAdSetBudgetAndBid(p, ctx) {
11696
11604
  if (p.dailyBudget && p.lifetimeBudget) {
11697
11605
  ctx.addIssue({ code: "custom", path: ["dailyBudget"], message: "set only one of dailyBudget or lifetimeBudget" });
@@ -11700,74 +11608,25 @@ function validateAdSetBudgetAndBid(p, ctx) {
11700
11608
  if (p.lifetimeBudget && !p.end_time) {
11701
11609
  ctx.addIssue({ code: "custom", path: ["end_time"], message: "lifetimeBudget ad sets need an end_time" });
11702
11610
  }
11703
- validateBidStrategy(p, ctx);
11611
+ if (p.bid_strategy && BID_STRATEGIES_REQUIRING_AMOUNT.includes(p.bid_strategy) && !p.bidAmount) {
11612
+ ctx.addIssue({ code: "custom", path: ["bidAmount"], message: `${p.bid_strategy} requires a bidAmount` });
11613
+ }
11704
11614
  if (p.end_time && p.start_time && p.end_time <= p.start_time) {
11705
11615
  ctx.addIssue({ code: "custom", path: ["end_time"], message: "end_time must be after start_time" });
11706
11616
  }
11707
11617
  }
11708
11618
  function validateAdSetPromotedObject(p, ctx) {
11709
- const goal = p.optimization_goal;
11710
- if (!goal) {
11711
- return;
11712
- }
11713
- const po = p.promoted_object;
11714
- if (OPTIMIZATION_GOALS_REQUIRING_PAGE.includes(goal) && !po?.page_id) {
11619
+ if (p.optimization_goal && OPTIMIZATION_GOALS_REQUIRING_PAGE.includes(p.optimization_goal) && !p.promoted_object?.page_id) {
11715
11620
  ctx.addIssue({
11716
11621
  code: "custom",
11717
11622
  path: ["promoted_object", "page_id"],
11718
- message: `optimization_goal ${goal} needs promoted_object.page_id \u2014 pass --page-id with the Facebook Page the leads/likes belong to`
11719
- });
11720
- }
11721
- if (OPTIMIZATION_GOALS_REQUIRING_PIXEL.includes(goal) && !po?.pixel_id) {
11722
- ctx.addIssue({
11723
- code: "custom",
11724
- path: ["promoted_object", "pixel_id"],
11725
- message: `optimization_goal ${goal} needs promoted_object.pixel_id \u2014 pass --pixel-id with the conversion pixel`
11726
- });
11727
- }
11728
- if (OPTIMIZATION_GOALS_REQUIRING_CONVERSION_SOURCE.includes(goal) && !po?.pixel_id && !po?.application_id) {
11729
- ctx.addIssue({
11730
- code: "custom",
11731
- path: ["promoted_object", "pixel_id"],
11732
- message: `optimization_goal ${goal} needs a conversion source \u2014 pass promoted_object.pixel_id (web value optimization) or promoted_object.application_id (app value optimization)`
11733
- });
11734
- }
11735
- if ((OPTIMIZATION_GOALS_REQUIRING_PIXEL.includes(goal) || OPTIMIZATION_GOALS_REQUIRING_CONVERSION_SOURCE.includes(goal)) && !po?.custom_event_type) {
11736
- ctx.addIssue({
11737
- code: "custom",
11738
- path: ["promoted_object", "custom_event_type"],
11739
- message: `optimization_goal ${goal} needs promoted_object.custom_event_type \u2014 pass --custom-event-type (e.g. PURCHASE, LEAD)`
11740
- });
11741
- }
11742
- if (OPTIMIZATION_GOALS_REQUIRING_APP.includes(goal) && !po?.application_id) {
11743
- ctx.addIssue({
11744
- code: "custom",
11745
- path: ["promoted_object", "application_id"],
11746
- message: `optimization_goal ${goal} needs promoted_object.application_id`
11747
- });
11748
- }
11749
- }
11750
- function validateAdvantageAudience(p, ctx) {
11751
- const t = p.targeting;
11752
- if (t && targetingHardLimitsDemographics(t) && advantageAudienceSetting(t) === 1) {
11753
- ctx.addIssue({
11754
- code: "custom",
11755
- path: ["targeting", "targeting_automation", "advantage_audience"],
11756
- message: "Advantage+ Audience (advantage_audience: 1) treats age and gender as suggestions, so a hard age/gender limit is rejected \u2014 set advantage_audience: 0 to enforce the limit, or drop the age_max/age_min/gender restriction"
11623
+ message: `optimization_goal ${p.optimization_goal} needs promoted_object.page_id \u2014 pass --page-id with the Facebook Page the leads/likes belong to`
11757
11624
  });
11758
11625
  }
11759
11626
  }
11760
11627
  var adSetCreateSchema = z14.object(adSetFields).superRefine((p, ctx) => {
11761
11628
  validateAdSetBudgetAndBid(p, ctx);
11762
11629
  validateAdSetPromotedObject(p, ctx);
11763
- validateAdvantageAudience(p, ctx);
11764
- if (!targetingHasGeoOrAudience(p.targeting)) {
11765
- ctx.addIssue({
11766
- code: "custom",
11767
- path: ["targeting", "geo_locations"],
11768
- message: 'targeting needs a location \u2014 set targeting.geo_locations (e.g. countries: ["US"]) or include a custom audience; Meta rejects an ad set with no geo'
11769
- });
11770
- }
11771
11630
  });
11772
11631
  var adSetUpdateSchema = z14.object({
11773
11632
  name: adSetFields.name.optional(),
@@ -11782,9 +11641,7 @@ var adSetUpdateSchema = z14.object({
11782
11641
  attribution_spec: attributionSpecSchema.optional(),
11783
11642
  start_time: z14.number().int().positive().optional(),
11784
11643
  end_time: z14.number().int().positive().optional(),
11785
- targeting: metaTargetingSchema.optional(),
11786
- dsa_beneficiary: z14.string().min(1).max(100).optional(),
11787
- dsa_payor: z14.string().min(1).max(100).optional()
11644
+ targeting: metaTargetingSchema.optional()
11788
11645
  }).superRefine((p, ctx) => {
11789
11646
  if (!Object.values(p).some((val) => val !== void 0)) {
11790
11647
  ctx.addIssue({ code: "custom", message: "update needs at least one field" });
@@ -11793,7 +11650,6 @@ var adSetUpdateSchema = z14.object({
11793
11650
  if (p.optimization_goal) {
11794
11651
  validateAdSetPromotedObject(p, ctx);
11795
11652
  }
11796
- validateAdvantageAudience(p, ctx);
11797
11653
  });
11798
11654
  var messageSchema = z14.string().min(1).max(META_LIMITS.creative.messageHardMax);
11799
11655
  var headlineSchema2 = z14.string().min(1).max(META_LIMITS.creative.headlineMax);
@@ -13572,8 +13428,7 @@ Performance (the workhorse):
13572
13428
 
13573
13429
  Audit & review:
13574
13430
  baker ads meta activities --account-id act_123 --days 14
13575
- baker ads meta preview --creative-id 9988 --ad-format MOBILE_FEED_STANDARD --out-file /tmp/p.html
13576
- Full guide: __tooling__/docs/tools/baker/ads-meta.md`
13431
+ baker ads meta preview --creative-id 9988 --ad-format MOBILE_FEED_STANDARD --out-file /tmp/p.html`
13577
13432
  },
13578
13433
  subCommands: {
13579
13434
  accounts: accountsCommand3,
@@ -15037,8 +14892,7 @@ Examples:
15037
14892
  --start-time 2026-04-01T00:00:00Z --end-time 2026-05-01T00:00:00Z \\
15038
14893
  --metric-groups ENGAGEMENT,BILLING --segmentation-type LOCATIONS
15039
14894
 
15040
- The CLI auto-detects --account-id when exactly one X Ads account is connected, or via BAKER_X_ADS_ACCOUNT_ID.
15041
- Full guide: __tooling__/docs/tools/baker/ads-x.md`
14895
+ The CLI auto-detects --account-id when exactly one X Ads account is connected, or via BAKER_X_ADS_ACCOUNT_ID.`
15042
14896
  },
15043
14897
  subCommands: {
15044
14898
  accounts: accountsCommand4,
@@ -15076,8 +14930,7 @@ Examples:
15076
14930
  baker ads meta insights --object act_123 --level ad --date-preset last_7d --fields impressions,spend,ctr
15077
14931
  baker ads linkedin accounts
15078
14932
  baker ads x accounts
15079
- baker ads x stats sync --preset campaign-engagement-7d --entity-ids abc,def
15080
- Full guides: __tooling__/docs/tools/baker/ads-<platform>.md (google|meta|linkedin|x)`
14933
+ baker ads x stats sync --preset campaign-engagement-7d --entity-ids abc,def`
15081
14934
  },
15082
14935
  subCommands: {
15083
14936
  google: googleCommand,
@@ -21774,8 +21627,7 @@ Subcommands:
21774
21627
  baker canvas catalog \u2014 print the agent-facing node + composition catalog (JSON Schema)
21775
21628
  baker canvas inspect <run_id> \u2014 one-page summary of a completed run
21776
21629
  baker canvas scaffold-video <video> \u2014 turn a reference video into a runnable reproduction canvas (deconstruct + recurring-element detection)
21777
- baker canvas scaffold-static-ad <image> \u2014 turn a source image into a runnable static-ad canvas (describe + element detection)
21778
- Full guide: __tooling__/docs/tools/baker/canvas.md`
21630
+ baker canvas scaffold-static-ad <image> \u2014 turn a source image into a runnable static-ad canvas (describe + element detection)`
21779
21631
  },
21780
21632
  subCommands: {
21781
21633
  run: runCommand,
@@ -22012,8 +21864,7 @@ var diffCommand = defineCommand96({
22012
21864
  var chatsCommand = defineCommand96({
22013
21865
  meta: {
22014
21866
  name: "chats",
22015
- description: `Inspect other Sessions on this account (read-only): list them, view what they produced, read their conversation, and see their real file changes \u2014 so you can reuse past work for a new goal.
22016
- Full guide: __tooling__/docs/tools/baker/chats.md`
21867
+ description: "Inspect other Sessions on this account (read-only): list them, view what they produced, read their conversation, and see their real file changes \u2014 so you can reuse past work for a new goal."
22017
21868
  },
22018
21869
  subCommands: {
22019
21870
  list: listCommand5,
@@ -22237,8 +22088,7 @@ var creativesCommand3 = defineCommand98({
22237
22088
  Static creative handoff:
22238
22089
  baker creatives publish ./canvas/run/final.png --title "Spring Offer Static Ad"
22239
22090
 
22240
- Publishing uploads the image to the Company image library, applies the official creative tag, and returns an image reference for chat previews.
22241
- Full guide: __tooling__/docs/tools/baker/creatives.md`
22091
+ Publishing uploads the image to the Company image library, applies the official creative tag, and returns an image reference for chat previews.`
22242
22092
  },
22243
22093
  subCommands: {
22244
22094
  publish: publishCommand
@@ -22446,8 +22296,7 @@ This command is READ-ONLY and never reveals secret values. Author a Form's struc
22446
22296
  Examples:
22447
22297
  baker flows list # every Form + how many confidential fields still need setup
22448
22298
  baker flows show contact # one Form's confidential fields and their status
22449
- baker flows show contact --full
22450
- Full guide: __tooling__/docs/tools/baker/flows.md`
22299
+ baker flows show contact --full`
22451
22300
  },
22452
22301
  subCommands: {
22453
22302
  list: listCommand6,
@@ -22856,8 +22705,7 @@ Examples:
22856
22705
  baker ga4 audit \u2014 full property health check
22857
22706
  baker ga4 query --preset tracking-health \u2014 compare GA4 vs GAds data
22858
22707
  baker ga4 query --preset lp-performance --days 14 \u2014 landing page UX audit
22859
- baker ga4 query --dimensions "date" --metrics "sessions" --days 7 \u2014 free-form query
22860
- Full guide: __tooling__/docs/tools/baker/ga4.md`
22708
+ baker ga4 query --dimensions "date" --metrics "sessions" --days 7 \u2014 free-form query`
22861
22709
  },
22862
22710
  subCommands: {
22863
22711
  properties: propertiesCommand,
@@ -23266,8 +23114,7 @@ Examples:
23266
23114
  baker gsc query --preset cannibalization \u2014 find PPC-SEO overlap
23267
23115
  baker gsc query --preset brand-halo --brand "Acme" --days 90 \u2014 brand search trends
23268
23116
  baker gsc query --dimensions "query,page" --days 28 \u2014 free-form query
23269
- baker gsc sitemaps \u2014 check sitemap health
23270
- Full guide: __tooling__/docs/tools/baker/gsc.md`
23117
+ baker gsc sitemaps \u2014 check sitemap health`
23271
23118
  },
23272
23119
  subCommands: {
23273
23120
  sites: sitesCommand,
@@ -23381,8 +23228,7 @@ var listCommand7 = defineCommand108({
23381
23228
  var historyCommand = defineCommand108({
23382
23229
  meta: {
23383
23230
  name: "history",
23384
- description: `Unified account history (audit log): what changed, who did it, and when.
23385
- Full guide: __tooling__/docs/tools/baker/history.md`
23231
+ description: "Unified account history (audit log): what changed, who did it, and when."
23386
23232
  },
23387
23233
  subCommands: { list: listCommand7 }
23388
23234
  });
@@ -25980,8 +25826,7 @@ Taxonomy:
25980
25826
  baker images tags List available image tag names (defaults + company custom tags)
25981
25827
 
25982
25828
  Paid transforms (run on the Convex backend, cost-tracked):
25983
- baker images upscale <imageId> Real-ESRGAN super-resolution ($0.05/image, waits for completion)
25984
- Full guide: __tooling__/docs/tools/baker/images.md`
25829
+ baker images upscale <imageId> Real-ESRGAN super-resolution ($0.05/image, waits for completion)`
25985
25830
  },
25986
25831
  subCommands: {
25987
25832
  get: getCommand2,
@@ -26045,44 +25890,6 @@ function fail4(err) {
26045
25890
  writeJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
26046
25891
  process.exit(1);
26047
25892
  }
26048
- registerSchema({
26049
- command: "mcp.connected",
26050
- description: "List every third-party tool this chat can reach: managed integrations (Attio, Slack, Gmail, Google Sheets, \u2026) plus custom MCP servers. Start here when the user mentions an external tool.",
26051
- args: {}
26052
- });
26053
- var connectedCommand = defineCommand133({
26054
- meta: {
26055
- name: "connected",
26056
- description: `List all connected third-party tools \u2014 managed integrations plus custom MCP servers.
26057
-
26058
- Managed tools ride the composio servers (mcp__composio_<scope>__*); custom servers expose mcp__<name>__*.
26059
- A tool the user names that is NOT listed here is simply not connected yet.`
26060
- },
26061
- run: async () => {
26062
- try {
26063
- const user = actingUserId();
26064
- const data = await apiGet("/api/mcp/connected", user ? { actingUserId: user } : void 0);
26065
- const managed = data.managed.map((c) => ({
26066
- toolkit: c.toolkitSlug,
26067
- scope: c.scope,
26068
- ...c.status !== "ACTIVE" ? { status: c.status } : {},
26069
- ...c.accountLabel ? { account: c.accountLabel } : {},
26070
- ...c.readOnly ? { readOnly: true } : {}
26071
- }));
26072
- const custom = data.custom.map((s) => ({ name: s.name, scope: s.scope, enabled: s.enabled }));
26073
- const hints = [];
26074
- if (data.managedDisabled) {
26075
- hints.push("Managed integrations are disabled for this company \u2014 only custom MCP servers load.");
26076
- }
26077
- hints.push(
26078
- "Not listed = not connected. Managed app (Slack, HubSpot, Attio, \u2026) \u2192 the user connects it in the dashboard: Brain \u2192 Integrations \u2192 Tools. Custom HTTPS MCP endpoint \u2192 `baker mcp add`."
26079
- );
26080
- writeJson({ ok: true, data: { managed, custom }, hints });
26081
- } catch (err) {
26082
- fail4(err);
26083
- }
26084
- }
26085
- });
26086
25893
  registerSchema({
26087
25894
  command: "mcp.list",
26088
25895
  description: "List the custom MCP servers this company's chats see (org + company + your own user scope).",
@@ -26179,22 +25986,20 @@ Example:
26179
25986
  var mcpCommand = defineCommand133({
26180
25987
  meta: {
26181
25988
  name: "mcp",
26182
- description: `Third-party tools for this company \u2014 see what's connected, register custom HTTPS MCP endpoints.
25989
+ description: `Custom MCP servers for this company \u2014 point the agent at any HTTPS MCP endpoint.
26183
25990
 
26184
25991
  Tools from a registered server appear as mcp__<name>__* on the next message.
26185
25992
  Managed here are **company-scoped** servers; user- and org-scoped servers are managed in the dashboard.
26186
25993
 
26187
25994
  Start here:
26188
- baker mcp connected # everything this chat can reach: managed integrations + custom servers
25995
+ baker mcp list
26189
25996
 
26190
25997
  Examples:
26191
25998
  baker mcp add --name weather --url https://mcp.example.com/mcp
26192
25999
  baker mcp add --name acme --url https://acme.dev/mcp --header "Authorization: Bearer sk-\u2026"
26193
- baker mcp remove --name weather
26194
- Full guide: __tooling__/docs/tools/baker/mcp.md`
26000
+ baker mcp remove --name weather`
26195
26001
  },
26196
26002
  subCommands: {
26197
- connected: connectedCommand,
26198
26003
  list: listCommand8,
26199
26004
  add: addCommand,
26200
26005
  remove: removeCommand4
@@ -27066,8 +26871,7 @@ Examples:
27066
26871
  baker research advertisers "running shoes"
27067
26872
  baker research intent "buy running shoes,best running shoes 2026"
27068
26873
  baker research keywords-for-site "competitor.com"
27069
- baker research keyword-gap "them.com" "us.com"
27070
- Full guide: __tooling__/docs/tools/baker/research.md`
26874
+ baker research keyword-gap "them.com" "us.com"`
27071
26875
  },
27072
26876
  subCommands: {
27073
26877
  web: webCommand,
@@ -27514,8 +27318,7 @@ Examples:
27514
27318
  baker scheduled-actions create --name "Weekly report" --description "Prepare weekly report" --cron "0 9 * * MON"
27515
27319
  baker scheduled-actions update <id-or-temp_sched_id> --enabled false
27516
27320
  baker scheduled-actions delete <id-or-temp_sched_id>
27517
- baker scheduled-actions trigger <id>
27518
- Full guide: __tooling__/docs/tools/baker/scheduled-actions.md`
27321
+ baker scheduled-actions trigger <id>`
27519
27322
  },
27520
27323
  subCommands: {
27521
27324
  list: listCommand9,
@@ -27551,17 +27354,11 @@ var schemaCommand = defineCommand152({
27551
27354
  const schema = getSchema(commandName);
27552
27355
  if (!schema) {
27553
27356
  const available = listSchemas();
27554
- const segments = commandName.split(".");
27555
- const family = segments[0] === "ads" && segments[1] ? `ads-${segments[1]}` : segments[0];
27556
27357
  writeJson({
27557
27358
  ok: false,
27558
27359
  error: {
27559
27360
  code: "NOT_FOUND",
27560
- message: `Schema "${commandName}" not found. Available: ${available.join(", ")}`,
27561
- fix: {
27562
- action: `Run the command with --help for exact args, and read __tooling__/docs/tools/baker/${family}.md`,
27563
- explanation: "Not every command registers a schema; --help and the family doc are the ground truth for those."
27564
- }
27361
+ message: `Schema "${commandName}" not found. Available: ${available.join(", ")}`
27565
27362
  }
27566
27363
  });
27567
27364
  process.exit(1);
@@ -27570,9 +27367,512 @@ var schemaCommand = defineCommand152({
27570
27367
  }
27571
27368
  });
27572
27369
 
27573
- // src/commands/tags/index.ts
27370
+ // src/commands/tag-manager/index.ts
27371
+ import { defineCommand as defineCommand156 } from "citty";
27372
+
27373
+ // src/commands/tag-manager/draft.ts
27574
27374
  import { defineCommand as defineCommand153 } from "citty";
27575
27375
 
27376
+ // src/commands/tag-manager/shared.ts
27377
+ import { readFileSync as readFileSync12 } from "fs";
27378
+ function failValidation3(message) {
27379
+ writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
27380
+ process.exit(1);
27381
+ }
27382
+ function requireTarget4(args, entity) {
27383
+ const positional = Array.isArray(args._) ? args._[0] : void 0;
27384
+ const target = args.id ?? args.target ?? positional;
27385
+ if (typeof target !== "string" || target.length === 0) {
27386
+ failValidation3(`pass the ${entity} id or path as the positional argument`);
27387
+ }
27388
+ return target;
27389
+ }
27390
+ function loadJsonArg(args, flag = "json") {
27391
+ const inline = args[flag];
27392
+ const file = args.file;
27393
+ const raw = typeof file === "string" && file.length > 0 ? readFileSync12(file, "utf8") : typeof inline === "string" && inline.length > 0 ? inline : void 0;
27394
+ if (raw === void 0) {
27395
+ failValidation3(`pass --${flag} with inline JSON or --file with a path to a JSON file`);
27396
+ }
27397
+ try {
27398
+ const parsed = JSON.parse(raw);
27399
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
27400
+ failValidation3(`--${flag} must be a JSON object`);
27401
+ }
27402
+ return parsed;
27403
+ } catch {
27404
+ return failValidation3(`--${flag} is not valid JSON`);
27405
+ }
27406
+ }
27407
+ function handleError3(err) {
27408
+ if (err instanceof ApiError) {
27409
+ const notConnected = err.code === "NOT_FOUND" || err.code === "UNAUTHORIZED";
27410
+ writeJsonEnvelope({
27411
+ ok: false,
27412
+ error: {
27413
+ code: err.code,
27414
+ message: err.message,
27415
+ ...notConnected ? {
27416
+ fix: {
27417
+ action: "ask_user",
27418
+ explanation: "Tag Manager is not connected for this company yet. Ask the user to connect Tag Manager in Settings \u2192 Connections and pick the container to manage, then retry. Continue with the rest of the task in the meantime."
27419
+ }
27420
+ } : {},
27421
+ retryable: false
27422
+ }
27423
+ });
27424
+ process.exit(1);
27425
+ }
27426
+ writeJsonEnvelope({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
27427
+ process.exit(1);
27428
+ }
27429
+ function stageHints(response) {
27430
+ const hints = [];
27431
+ if (response.mode === "simulated") {
27432
+ hints.push(
27433
+ "Tag Manager writes are SIMULATED for this company \u2014 this change will not reach the real container on publish."
27434
+ );
27435
+ }
27436
+ hints.push(
27437
+ "Staged only. On publish these changes land in a new Tag Manager version that is NOT published \u2014 tell the user to publish that version in Tag Manager to make it live."
27438
+ );
27439
+ return hints;
27440
+ }
27441
+ async function stageOp3(op) {
27442
+ const chatId = requireChatId();
27443
+ try {
27444
+ const data = await apiPost("/api/tag-manager/draft/stage", { chatId, op });
27445
+ writeJsonEnvelope({ ok: true, data, hints: stageHints(data) });
27446
+ } catch (err) {
27447
+ handleError3(err);
27448
+ }
27449
+ }
27450
+ async function draftAction2(path23, body) {
27451
+ const chatId = requireChatId();
27452
+ try {
27453
+ const data = await apiPost(path23, { chatId, ...body });
27454
+ writeJsonEnvelope({ ok: true, data });
27455
+ return data;
27456
+ } catch (err) {
27457
+ handleError3(err);
27458
+ }
27459
+ }
27460
+ function renderDraft(response) {
27461
+ if (response.count === 0) {
27462
+ return "No Tag Manager changes staged on this chat.";
27463
+ }
27464
+ const lines = [
27465
+ `${response.count} staged Tag Manager change(s) \u2014 mode: ${response.mode}`,
27466
+ ...response.ops.map((op) => {
27467
+ const status = op.result ? ` [${op.result.status}]` : "";
27468
+ return ` ${op.ref} ${op.summary}${status}`;
27469
+ })
27470
+ ];
27471
+ if (response.versionId) {
27472
+ lines.push(
27473
+ "",
27474
+ `Applied into Tag Manager version ${response.versionId}. It is NOT published \u2014 publish it in Tag Manager to go live.`
27475
+ );
27476
+ }
27477
+ if (response.compilerError) {
27478
+ lines.push("", `Tag Manager reported a problem building the version: ${response.compilerError}`);
27479
+ }
27480
+ return lines.join("\n");
27481
+ }
27482
+ async function draftList(json) {
27483
+ const chatId = requireChatId();
27484
+ try {
27485
+ const data = await apiPost("/api/tag-manager/draft", { chatId });
27486
+ if (json) {
27487
+ writeJsonEnvelope({ ok: true, data });
27488
+ return;
27489
+ }
27490
+ process.stdout.write(`${renderDraft(data)}
27491
+ `);
27492
+ } catch (err) {
27493
+ handleError3(err);
27494
+ }
27495
+ }
27496
+
27497
+ // src/commands/tag-manager/draft.ts
27498
+ registerSchema({
27499
+ command: "tagManager.draft",
27500
+ description: "Review and undo the Tag Manager changes staged on this chat. Use `list` to see everything staged, `show` to inspect one change in full before publish, `amend` to correct one in place, and `remove`/`clear` to drop them.",
27501
+ args: {
27502
+ json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list", required: false }
27503
+ }
27504
+ });
27505
+ var draftCommand3 = defineCommand153({
27506
+ meta: {
27507
+ name: "draft",
27508
+ description: "List, show, amend, remove, or clear staged Tag Manager changes for this chat"
27509
+ },
27510
+ subCommands: {
27511
+ list: defineCommand153({
27512
+ meta: {
27513
+ name: "list",
27514
+ description: "Review everything staged on this chat (--json for the raw envelope)"
27515
+ },
27516
+ args: { json: { type: "boolean", description: "Print the raw JSON envelope", required: false } },
27517
+ run: async ({ args }) => {
27518
+ await draftList(args.json === true);
27519
+ }
27520
+ }),
27521
+ show: defineCommand153({
27522
+ meta: {
27523
+ name: "show",
27524
+ description: "Print the full staged payload for one change \u2014 the receipt to verify it looks right before publish (never truncated)."
27525
+ },
27526
+ args: { ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false } },
27527
+ run: async ({ args }) => {
27528
+ await draftAction2("/api/tag-manager/draft/show", {
27529
+ ref: requireTarget4(args, "change")
27530
+ });
27531
+ }
27532
+ }),
27533
+ amend: defineCommand153({
27534
+ meta: {
27535
+ name: "amend",
27536
+ 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."
27537
+ },
27538
+ args: {
27539
+ ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false },
27540
+ patch: { type: "string", description: "Inline JSON patch object", required: false },
27541
+ file: { type: "string", description: "JSON file with the patch object", required: false }
27542
+ },
27543
+ run: async ({ args }) => {
27544
+ await draftAction2("/api/tag-manager/draft/amend", {
27545
+ ref: requireTarget4(args, "change"),
27546
+ patch: loadJsonArg(args, "patch")
27547
+ });
27548
+ }
27549
+ }),
27550
+ remove: defineCommand153({
27551
+ meta: { name: "remove", description: "Remove one staged change (cascades to anything depending on it)" },
27552
+ args: { ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false } },
27553
+ run: async ({ args }) => {
27554
+ await draftAction2("/api/tag-manager/draft/remove", {
27555
+ ref: requireTarget4(args, "change")
27556
+ });
27557
+ }
27558
+ }),
27559
+ clear: defineCommand153({
27560
+ meta: { name: "clear", description: "Discard all Tag Manager changes staged on this chat" },
27561
+ run: async () => {
27562
+ await draftAction2("/api/tag-manager/draft/clear", {});
27563
+ }
27564
+ })
27565
+ }
27566
+ });
27567
+
27568
+ // src/commands/tag-manager/read.ts
27569
+ import { defineCommand as defineCommand154 } from "citty";
27570
+ registerSchema({
27571
+ command: "tagManager.containers",
27572
+ description: "List the Google Tag Manager containers this company's connection can reach. The connected container is flagged. Start here to confirm which container you are managing.",
27573
+ args: {}
27574
+ });
27575
+ registerSchema({
27576
+ command: "tagManager.read",
27577
+ description: "Read what is currently inside a Tag Manager container: tags, triggers, variables, folders and enabled built-in variables. Start here before proposing any change, so you edit what exists instead of duplicating it. Compact by default; pass --full for raw Tag Manager objects.",
27578
+ args: {
27579
+ container: { type: "string", description: "Numeric container id (defaults to the connected one)", required: false },
27580
+ workspace: { type: "string", description: "Workspace id (defaults to the default workspace)", required: false },
27581
+ entities: {
27582
+ type: "string",
27583
+ description: "Comma-separated subset: tag,trigger,variable,folder,builtInVariable",
27584
+ required: false
27585
+ },
27586
+ full: { type: "boolean", description: "Include the raw Tag Manager object for each entity", required: false }
27587
+ }
27588
+ });
27589
+ function fail5(err) {
27590
+ if (err instanceof ApiError) {
27591
+ const notConnected = err.code === "NOT_FOUND" || err.code === "UNAUTHORIZED";
27592
+ writeJsonEnvelope({
27593
+ ok: false,
27594
+ error: {
27595
+ code: err.code,
27596
+ message: err.message,
27597
+ ...notConnected ? {
27598
+ fix: {
27599
+ action: "ask_user",
27600
+ explanation: "Tag Manager is not connected for this company yet. Ask the user to connect Tag Manager in Settings \u2192 Connections and choose the container to manage, then retry. Continue with the rest of the task in the meantime."
27601
+ }
27602
+ } : {},
27603
+ retryable: false
27604
+ }
27605
+ });
27606
+ process.exit(1);
27607
+ }
27608
+ writeJsonEnvelope({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
27609
+ process.exit(1);
27610
+ }
27611
+ var containersCommand = defineCommand154({
27612
+ meta: {
27613
+ name: "containers",
27614
+ description: `List Tag Manager containers reachable by this company's connection.
27615
+
27616
+ Start here:
27617
+ baker tag-manager containers`
27618
+ },
27619
+ run: async () => {
27620
+ try {
27621
+ const data = await apiGet("/api/tag-manager/containers");
27622
+ writeJsonEnvelope({ ok: true, data });
27623
+ } catch (err) {
27624
+ fail5(err);
27625
+ }
27626
+ }
27627
+ });
27628
+ var readCommand = defineCommand154({
27629
+ meta: {
27630
+ name: "read",
27631
+ description: `Read the current contents of the Tag Manager container \u2014 always do this before staging changes.
27632
+
27633
+ Examples:
27634
+ baker tag-manager read
27635
+ baker tag-manager read --entities tag,trigger
27636
+ baker tag-manager read --full`
27637
+ },
27638
+ args: {
27639
+ container: { type: "string", description: "Numeric container id", required: false },
27640
+ workspace: { type: "string", description: "Workspace id", required: false },
27641
+ entities: { type: "string", description: "Comma-separated entity subset", required: false },
27642
+ full: { type: "boolean", description: "Include raw Tag Manager objects", required: false }
27643
+ },
27644
+ run: async ({ args }) => {
27645
+ const entities = typeof args.entities === "string" && args.entities.length > 0 ? args.entities.split(",").map((entry) => entry.trim()) : void 0;
27646
+ try {
27647
+ const data = await apiPost("/api/tag-manager/read", {
27648
+ containerId: args.container,
27649
+ workspaceId: args.workspace,
27650
+ entities,
27651
+ full: args.full === true
27652
+ });
27653
+ const hints = [];
27654
+ if (data.installedContainerMismatch) {
27655
+ hints.push(data.installedContainerMismatch);
27656
+ }
27657
+ hints.push(
27658
+ "Reference an existing trigger or variable by its numeric id or {{Name}}. To reference something you are staging in this same chat, use its gtm_temp_* ref and the executor resolves it at publish."
27659
+ );
27660
+ writeJsonEnvelope({ ok: true, data, hints });
27661
+ } catch (err) {
27662
+ fail5(err);
27663
+ }
27664
+ }
27665
+ });
27666
+
27667
+ // src/commands/tag-manager/write-commands.ts
27668
+ import { defineCommand as defineCommand155 } from "citty";
27669
+ var ENTITIES = [
27670
+ {
27671
+ entity: "tag",
27672
+ noun: "tag",
27673
+ createHint: 'Payload needs name + type (e.g. "gaawe" for a GA4 event) and usually parameter[] and firingTriggerId[]. Reference a trigger by its numeric id, or by a gtm_temp_* ref if you are staging it in this same chat.'
27674
+ },
27675
+ {
27676
+ entity: "trigger",
27677
+ noun: "trigger",
27678
+ createHint: 'Payload needs name + type (e.g. "pageview", "click", "customEvent"). Stage the trigger BEFORE the tag that fires on it, then reference it by its gtm_temp_* ref.'
27679
+ },
27680
+ {
27681
+ entity: "variable",
27682
+ noun: "variable",
27683
+ createHint: 'Payload needs name + type (e.g. "v" for a data layer variable, "c" for a constant). Other entities reference a variable by NAME as {{Variable Name}}.'
27684
+ },
27685
+ {
27686
+ entity: "folder",
27687
+ noun: "folder",
27688
+ createHint: "Payload needs name. Use folders to keep a large container legible."
27689
+ }
27690
+ ];
27691
+ for (const { entity, noun, createHint } of ENTITIES) {
27692
+ registerSchema({
27693
+ command: `tagManager.${entity}.create`,
27694
+ description: `Stage the creation of a Tag Manager ${noun}. ${createHint} Staged only \u2014 applies on publish into an unpublished container version.`,
27695
+ args: {
27696
+ json: { type: "string", description: `Inline JSON ${noun} definition`, required: false },
27697
+ file: { type: "string", description: `Path to a JSON file with the ${noun} definition`, required: false },
27698
+ container: { type: "string", description: "Numeric container id", required: false }
27699
+ }
27700
+ });
27701
+ registerSchema({
27702
+ command: `tagManager.${entity}.update`,
27703
+ description: `Stage an update to an existing Tag Manager ${noun}. Pass the ${noun} id or path as the positional argument and the changed fields as JSON. Read the container first so you send the fields you mean to change.`,
27704
+ args: {
27705
+ json: { type: "string", description: "Inline JSON with the changed fields", required: false },
27706
+ file: { type: "string", description: "Path to a JSON file with the changed fields", required: false }
27707
+ }
27708
+ });
27709
+ registerSchema({
27710
+ command: `tagManager.${entity}.delete`,
27711
+ description: `Stage the deletion of a Tag Manager ${noun}. Pass its id or path as the positional argument. Deleting is irreversible once the resulting version is published \u2014 confirm with the user first.`,
27712
+ args: {}
27713
+ });
27714
+ }
27715
+ function entityCommand(entity, noun) {
27716
+ return defineCommand155({
27717
+ meta: { name: entity, description: `Stage ${noun} changes on this chat's Tag Manager draft` },
27718
+ subCommands: {
27719
+ create: defineCommand155({
27720
+ meta: {
27721
+ name: "create",
27722
+ description: `Stage a new ${noun}
27723
+
27724
+ Examples:
27725
+ baker tag-manager ${entity} create --json '{"name":"GA4 Config","type":"googtag"}'
27726
+ baker tag-manager ${entity} create --file ./${entity}.json`
27727
+ },
27728
+ args: {
27729
+ json: { type: "string", description: "Inline JSON definition", required: false },
27730
+ file: { type: "string", description: "Path to a JSON file", required: false },
27731
+ container: { type: "string", description: "Numeric container id", required: false }
27732
+ },
27733
+ run: async ({ args }) => {
27734
+ await stageOp3({
27735
+ kind: `tagManager.${entity}.create`,
27736
+ payload: loadJsonArg(args),
27737
+ ...typeof args.container === "string" ? { containerId: args.container } : {}
27738
+ });
27739
+ }
27740
+ }),
27741
+ update: defineCommand155({
27742
+ meta: {
27743
+ name: "update",
27744
+ description: `Stage an update to an existing ${noun} (pass its id or path)`
27745
+ },
27746
+ args: {
27747
+ id: { type: "positional", description: `${noun} id or path`, required: false },
27748
+ json: { type: "string", description: "Inline JSON with changed fields", required: false },
27749
+ file: { type: "string", description: "Path to a JSON file", required: false },
27750
+ container: { type: "string", description: "Numeric container id", required: false }
27751
+ },
27752
+ run: async ({ args }) => {
27753
+ await stageOp3({
27754
+ kind: `tagManager.${entity}.update`,
27755
+ target: requireTarget4(args, noun),
27756
+ payload: loadJsonArg(args),
27757
+ ...typeof args.container === "string" ? { containerId: args.container } : {}
27758
+ });
27759
+ }
27760
+ }),
27761
+ delete: defineCommand155({
27762
+ meta: { name: "delete", description: `Stage the deletion of a ${noun} (pass its id or path)` },
27763
+ args: {
27764
+ id: { type: "positional", description: `${noun} id or path`, required: false },
27765
+ container: { type: "string", description: "Numeric container id", required: false }
27766
+ },
27767
+ run: async ({ args }) => {
27768
+ await stageOp3({
27769
+ kind: `tagManager.${entity}.delete`,
27770
+ target: requireTarget4(args, noun),
27771
+ ...typeof args.container === "string" ? { containerId: args.container } : {}
27772
+ });
27773
+ }
27774
+ })
27775
+ }
27776
+ });
27777
+ }
27778
+ var tagCommand = entityCommand("tag", "tag");
27779
+ var triggerCommand2 = entityCommand("trigger", "trigger");
27780
+ var variableCommand = entityCommand("variable", "variable");
27781
+ var folderCommand = entityCommand("folder", "folder");
27782
+ registerSchema({
27783
+ command: "tagManager.builtin",
27784
+ description: "Enable or disable Tag Manager built-in variables by type (e.g. clickUrl, pageUrl, formId). Built-in variables must be enabled before a trigger or tag can reference them as {{Click URL}}.",
27785
+ args: {
27786
+ types: { type: "string", description: "Comma-separated built-in variable types", required: true }
27787
+ }
27788
+ });
27789
+ function builtinTypes(args) {
27790
+ const raw = args.types;
27791
+ if (typeof raw !== "string" || raw.length === 0) {
27792
+ process.stdout.write(
27793
+ `${JSON.stringify({ ok: false, error: { code: "VALIDATION_ERROR", message: "pass --types with comma-separated built-in variable types" } }, null, 2)}
27794
+ `
27795
+ );
27796
+ process.exit(1);
27797
+ }
27798
+ return raw.split(",").map((entry) => entry.trim());
27799
+ }
27800
+ var builtinCommand = defineCommand155({
27801
+ meta: {
27802
+ name: "builtin",
27803
+ description: `Enable or disable built-in variables
27804
+
27805
+ Examples:
27806
+ baker tag-manager builtin enable --types clickUrl,clickText
27807
+ baker tag-manager builtin disable --types formId`
27808
+ },
27809
+ subCommands: {
27810
+ enable: defineCommand155({
27811
+ meta: { name: "enable", description: "Stage enabling built-in variables" },
27812
+ args: {
27813
+ types: { type: "string", description: "Comma-separated types", required: false },
27814
+ container: { type: "string", description: "Numeric container id", required: false }
27815
+ },
27816
+ run: async ({ args }) => {
27817
+ await stageOp3({
27818
+ kind: "tagManager.builtInVariable.enable",
27819
+ payload: { type: builtinTypes(args) },
27820
+ ...typeof args.container === "string" ? { containerId: args.container } : {}
27821
+ });
27822
+ }
27823
+ }),
27824
+ disable: defineCommand155({
27825
+ meta: { name: "disable", description: "Stage disabling built-in variables" },
27826
+ args: {
27827
+ types: { type: "string", description: "Comma-separated types", required: false },
27828
+ container: { type: "string", description: "Numeric container id", required: false }
27829
+ },
27830
+ run: async ({ args }) => {
27831
+ await stageOp3({
27832
+ kind: "tagManager.builtInVariable.disable",
27833
+ payload: { type: builtinTypes(args) },
27834
+ ...typeof args.container === "string" ? { containerId: args.container } : {}
27835
+ });
27836
+ }
27837
+ })
27838
+ }
27839
+ });
27840
+
27841
+ // src/commands/tag-manager/index.ts
27842
+ var tagManagerCommand = defineCommand156({
27843
+ meta: {
27844
+ name: "tag-manager",
27845
+ description: `Read and change what lives inside the client's Google Tag Manager container \u2014 tags, triggers, variables, folders and built-in variables.
27846
+
27847
+ Start here:
27848
+ baker tag-manager read \u2014 see what the container holds today
27849
+
27850
+ Then stage changes (nothing is sent to Tag Manager until publish):
27851
+ baker tag-manager trigger create --json '{"name":"Quote Submit","type":"customEvent"}'
27852
+ baker tag-manager tag create --json '{"name":"GA4 Quote","type":"gaawe","firingTriggerId":["gtm_temp_trigger_..."]}'
27853
+ baker tag-manager draft list \u2014 review everything staged
27854
+
27855
+ On publish, staged changes are written into a new Tag Manager version that is NOT published.
27856
+ Tell the user to publish that version in Tag Manager to make it live.
27857
+
27858
+ This owns the CONTENTS of the container. Installing the container snippet on the site is a
27859
+ different job \u2014 that is \`baker tags\` with the googleTagManager tag.`
27860
+ },
27861
+ subCommands: {
27862
+ containers: containersCommand,
27863
+ read: readCommand,
27864
+ tag: tagCommand,
27865
+ trigger: triggerCommand2,
27866
+ variable: variableCommand,
27867
+ folder: folderCommand,
27868
+ builtin: builtinCommand,
27869
+ draft: draftCommand3
27870
+ }
27871
+ });
27872
+
27873
+ // src/commands/tags/index.ts
27874
+ import { defineCommand as defineCommand157 } from "citty";
27875
+
27576
27876
  // src/commands/tags/shared.ts
27577
27877
  function failApi3(err) {
27578
27878
  if (err instanceof ApiError) {
@@ -27637,7 +27937,7 @@ async function listTags(json) {
27637
27937
  failApi3(err);
27638
27938
  }
27639
27939
  }
27640
- var listCommand10 = defineCommand153({
27940
+ var listCommand10 = defineCommand157({
27641
27941
  meta: {
27642
27942
  name: "list",
27643
27943
  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"
@@ -27656,7 +27956,7 @@ async function listDraft3() {
27656
27956
  failApi3(err);
27657
27957
  }
27658
27958
  }
27659
- var draftCommand3 = defineCommand153({
27959
+ var draftCommand4 = defineCommand157({
27660
27960
  meta: {
27661
27961
  name: "draft",
27662
27962
  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)."
@@ -27665,7 +27965,7 @@ var draftCommand3 = defineCommand153({
27665
27965
  await listDraft3();
27666
27966
  }
27667
27967
  });
27668
- var tagsCommand3 = defineCommand153({
27968
+ var tagsCommand3 = defineCommand157({
27669
27969
  meta: {
27670
27970
  name: "tags",
27671
27971
  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.
@@ -27678,12 +27978,11 @@ Refs: \`baker tags list\` prints each tag's ref \u2014 a real tag id, or tag_tem
27678
27978
 
27679
27979
  Examples:
27680
27980
  baker tags list # production + staged, full readable config + secret status
27681
- baker tags draft # review the staged changes awaiting publish
27682
- Full guide: __tooling__/docs/tools/baker/tags.md`
27981
+ baker tags draft # review the staged changes awaiting publish`
27683
27982
  },
27684
27983
  subCommands: {
27685
27984
  list: listCommand10,
27686
- draft: draftCommand3
27985
+ draft: draftCommand4
27687
27986
  },
27688
27987
  run: async () => {
27689
27988
  await listTags(false);
@@ -27691,10 +27990,10 @@ Full guide: __tooling__/docs/tools/baker/tags.md`
27691
27990
  });
27692
27991
 
27693
27992
  // src/commands/testimonials/index.ts
27694
- import { defineCommand as defineCommand157 } from "citty";
27993
+ import { defineCommand as defineCommand161 } from "citty";
27695
27994
 
27696
27995
  // src/commands/testimonials/get.ts
27697
- import { defineCommand as defineCommand154 } from "citty";
27996
+ import { defineCommand as defineCommand158 } from "citty";
27698
27997
  registerSchema({
27699
27998
  command: "testimonials.get",
27700
27999
  description: "Get a single testimonial by ID",
@@ -27702,7 +28001,7 @@ registerSchema({
27702
28001
  id: { type: "string", description: "Testimonial ID", required: true }
27703
28002
  }
27704
28003
  });
27705
- var getCommand4 = defineCommand154({
28004
+ var getCommand4 = defineCommand158({
27706
28005
  meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
27707
28006
  args: {
27708
28007
  id: { type: "positional", description: "Testimonial ID", required: false },
@@ -27739,7 +28038,7 @@ var getCommand4 = defineCommand154({
27739
28038
  });
27740
28039
 
27741
28040
  // src/commands/testimonials/list.ts
27742
- import { defineCommand as defineCommand155 } from "citty";
28041
+ import { defineCommand as defineCommand159 } from "citty";
27743
28042
  registerSchema({
27744
28043
  command: "testimonials.list",
27745
28044
  description: "List testimonials with optional filters.",
@@ -27769,7 +28068,7 @@ registerSchema({
27769
28068
  limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
27770
28069
  }
27771
28070
  });
27772
- var listCommand11 = defineCommand155({
28071
+ var listCommand11 = defineCommand159({
27773
28072
  meta: {
27774
28073
  name: "list",
27775
28074
  description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
@@ -27818,7 +28117,7 @@ var listCommand11 = defineCommand155({
27818
28117
  });
27819
28118
 
27820
28119
  // src/commands/testimonials/search.ts
27821
- import { defineCommand as defineCommand156 } from "citty";
28120
+ import { defineCommand as defineCommand160 } from "citty";
27822
28121
  function languageBiasHint(results, requestedLanguage) {
27823
28122
  if (requestedLanguage) {
27824
28123
  return null;
@@ -27896,7 +28195,7 @@ function buildSearchRequest(query, args) {
27896
28195
  }
27897
28196
  return body;
27898
28197
  }
27899
- var searchCommand2 = defineCommand156({
28198
+ var searchCommand2 = defineCommand160({
27900
28199
  meta: {
27901
28200
  name: "search",
27902
28201
  description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
@@ -27952,7 +28251,7 @@ var searchCommand2 = defineCommand156({
27952
28251
  var tagsCommand4 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
27953
28252
 
27954
28253
  // src/commands/testimonials/index.ts
27955
- var testimonialsCommand = defineCommand157({
28254
+ var testimonialsCommand = defineCommand161({
27956
28255
  meta: {
27957
28256
  name: "testimonials",
27958
28257
  description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
@@ -27962,8 +28261,7 @@ Examples:
27962
28261
  baker testimonials search "value for money" --rating-min 4
27963
28262
  baker testimonials get <testimonial-id>
27964
28263
  baker testimonials list --source google --sentiment positive
27965
- baker testimonials tags
27966
- Full guide: __tooling__/docs/tools/baker/testimonials.md`
28264
+ baker testimonials tags`
27967
28265
  },
27968
28266
  subCommands: {
27969
28267
  get: getCommand4,
@@ -27974,10 +28272,10 @@ Full guide: __tooling__/docs/tools/baker/testimonials.md`
27974
28272
  });
27975
28273
 
27976
28274
  // src/commands/videos/index.ts
27977
- import { defineCommand as defineCommand162 } from "citty";
28275
+ import { defineCommand as defineCommand166 } from "citty";
27978
28276
 
27979
28277
  // src/commands/videos/delete.ts
27980
- import { defineCommand as defineCommand158 } from "citty";
28278
+ import { defineCommand as defineCommand162 } from "citty";
27981
28279
  registerSchema({
27982
28280
  command: "videos.delete",
27983
28281
  description: "Delete a video by ID",
@@ -27991,7 +28289,7 @@ registerSchema({
27991
28289
  }
27992
28290
  }
27993
28291
  });
27994
- var deleteCommand3 = defineCommand158({
28292
+ var deleteCommand3 = defineCommand162({
27995
28293
  meta: {
27996
28294
  name: "delete",
27997
28295
  description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
@@ -28032,7 +28330,7 @@ var deleteCommand3 = defineCommand158({
28032
28330
  });
28033
28331
 
28034
28332
  // src/commands/videos/get.ts
28035
- import { defineCommand as defineCommand159 } from "citty";
28333
+ import { defineCommand as defineCommand163 } from "citty";
28036
28334
  registerSchema({
28037
28335
  command: "videos.get",
28038
28336
  description: "Get a single video by ID",
@@ -28040,7 +28338,7 @@ registerSchema({
28040
28338
  id: { type: "string", description: "Video ID", required: true }
28041
28339
  }
28042
28340
  });
28043
- var getCommand5 = defineCommand159({
28341
+ var getCommand5 = defineCommand163({
28044
28342
  meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
28045
28343
  args: {
28046
28344
  id: { type: "positional", description: "Video ID", required: false },
@@ -28077,7 +28375,7 @@ var getCommand5 = defineCommand159({
28077
28375
  });
28078
28376
 
28079
28377
  // src/commands/videos/search.ts
28080
- import { defineCommand as defineCommand160 } from "citty";
28378
+ import { defineCommand as defineCommand164 } from "citty";
28081
28379
  registerSchema({
28082
28380
  command: "videos.search",
28083
28381
  description: "Search videos by text query. Only returns ready videos.",
@@ -28087,7 +28385,7 @@ registerSchema({
28087
28385
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
28088
28386
  }
28089
28387
  });
28090
- var searchCommand3 = defineCommand160({
28388
+ var searchCommand3 = defineCommand164({
28091
28389
  meta: {
28092
28390
  name: "search",
28093
28391
  description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
@@ -28139,7 +28437,7 @@ var tagsCommand5 = makeTagsCommand("videos", "video", "/api/videos/tags");
28139
28437
  // src/commands/videos/upload.ts
28140
28438
  import { readFile as readFile20, stat as stat5 } from "fs/promises";
28141
28439
  import { extname as extname3 } from "path";
28142
- import { defineCommand as defineCommand161 } from "citty";
28440
+ import { defineCommand as defineCommand165 } from "citty";
28143
28441
  var MIME_MAP = {
28144
28442
  ".mp4": "video/mp4",
28145
28443
  ".mov": "video/quicktime",
@@ -28173,7 +28471,7 @@ function detectContentType(filePath) {
28173
28471
  }
28174
28472
  return mime;
28175
28473
  }
28176
- var uploadCommand2 = defineCommand161({
28474
+ var uploadCommand2 = defineCommand165({
28177
28475
  meta: {
28178
28476
  name: "upload",
28179
28477
  description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
@@ -28227,7 +28525,7 @@ var uploadCommand2 = defineCommand161({
28227
28525
  });
28228
28526
 
28229
28527
  // src/commands/videos/index.ts
28230
- var videosCommand = defineCommand162({
28528
+ var videosCommand = defineCommand166({
28231
28529
  meta: {
28232
28530
  name: "videos",
28233
28531
  description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
@@ -28238,8 +28536,7 @@ Examples:
28238
28536
  baker videos get <video-id>
28239
28537
  baker videos upload ./demo.mp4
28240
28538
  baker videos delete <video-id> --dry-run
28241
- baker videos tags
28242
- Full guide: __tooling__/docs/tools/baker/videos.md`
28539
+ baker videos tags`
28243
28540
  },
28244
28541
  subCommands: {
28245
28542
  get: getCommand5,
@@ -28251,10 +28548,10 @@ Full guide: __tooling__/docs/tools/baker/videos.md`
28251
28548
  });
28252
28549
 
28253
28550
  // src/commands/winning-ads/index.ts
28254
- import { defineCommand as defineCommand174 } from "citty";
28551
+ import { defineCommand as defineCommand178 } from "citty";
28255
28552
 
28256
28553
  // src/commands/winning-ads/advertisers.ts
28257
- import { defineCommand as defineCommand163 } from "citty";
28554
+ import { defineCommand as defineCommand167 } from "citty";
28258
28555
 
28259
28556
  // src/commands/winning-ads/shared.ts
28260
28557
  function splitList(value) {
@@ -28307,7 +28604,7 @@ function advertiserNormalizer(record, full) {
28307
28604
  last_synced_at: record.last_synced_at ?? null
28308
28605
  };
28309
28606
  }
28310
- var advertisersCommand2 = defineCommand163({
28607
+ var advertisersCommand2 = defineCommand167({
28311
28608
  meta: {
28312
28609
  name: "advertisers",
28313
28610
  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'
@@ -28365,7 +28662,7 @@ var advertisersCommand2 = defineCommand163({
28365
28662
  });
28366
28663
 
28367
28664
  // src/commands/winning-ads/brief.ts
28368
- import { defineCommand as defineCommand164 } from "citty";
28665
+ import { defineCommand as defineCommand168 } from "citty";
28369
28666
  registerSchema({
28370
28667
  command: "winning-ads.brief",
28371
28668
  description: "Generate a creative brief grounded in strategically-similar winning ads. Optionally describe the target creative with --dna (JSON) and steer with --notes.",
@@ -28411,7 +28708,7 @@ function parseDna(raw) {
28411
28708
  }
28412
28709
  return parsed;
28413
28710
  }
28414
- var briefCommand = defineCommand164({
28711
+ var briefCommand = defineCommand168({
28415
28712
  meta: {
28416
28713
  name: "brief",
28417
28714
  description: `Generate a creative brief from winning references. Example: baker winning-ads brief --dna '{"angle":"cost savings"}' --notes "B2B, LinkedIn video" --k 8`
@@ -28447,7 +28744,7 @@ var briefCommand = defineCommand164({
28447
28744
  });
28448
28745
 
28449
28746
  // src/commands/winning-ads/feed.ts
28450
- import { defineCommand as defineCommand165 } from "citty";
28747
+ import { defineCommand as defineCommand169 } from "citty";
28451
28748
  function buildFeedParams(input) {
28452
28749
  const params = {};
28453
28750
  const advertiser = splitList(input.advertiser);
@@ -28499,7 +28796,7 @@ registerSchema({
28499
28796
  format: { type: "string", description: "Comma-separated formats to include (e.g. static,video)", required: false }
28500
28797
  }
28501
28798
  });
28502
- var feedCommand = defineCommand165({
28799
+ var feedCommand = defineCommand169({
28503
28800
  meta: {
28504
28801
  name: "feed",
28505
28802
  description: "Winners across every brand you follow (browse, then trim per advertiser). Example: baker winning-ads feed --per-advertiser 5 --output md"
@@ -28584,7 +28881,7 @@ var feedCommand = defineCommand165({
28584
28881
  });
28585
28882
 
28586
28883
  // src/commands/winning-ads/follow.ts
28587
- import { defineCommand as defineCommand166 } from "citty";
28884
+ import { defineCommand as defineCommand170 } from "citty";
28588
28885
  var PLATFORMS = ["meta", "linkedin"];
28589
28886
  registerSchema({
28590
28887
  command: "winning-ads.follow",
@@ -28599,7 +28896,7 @@ registerSchema({
28599
28896
  label: { type: "string", description: "Optional display label (defaults to the resolved name)", required: false }
28600
28897
  }
28601
28898
  });
28602
- var followCommand = defineCommand166({
28899
+ var followCommand = defineCommand170({
28603
28900
  meta: {
28604
28901
  name: "follow",
28605
28902
  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'
@@ -28646,7 +28943,7 @@ var followCommand = defineCommand166({
28646
28943
  });
28647
28944
 
28648
28945
  // src/commands/winning-ads/follow-competitors.ts
28649
- import { defineCommand as defineCommand167 } from "citty";
28946
+ import { defineCommand as defineCommand171 } from "citty";
28650
28947
  var PLATFORMS2 = ["meta", "linkedin"];
28651
28948
  var BATCH_TIMEOUT_MS = 3e5;
28652
28949
  function buildFollowBatchBody(input) {
@@ -28679,7 +28976,7 @@ registerSchema({
28679
28976
  }
28680
28977
  }
28681
28978
  });
28682
- var followCompetitorsCommand = defineCommand167({
28979
+ var followCompetitorsCommand = defineCommand171({
28683
28980
  meta: {
28684
28981
  name: "follow-competitors",
28685
28982
  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"'
@@ -28754,7 +29051,7 @@ var followCompetitorsCommand = defineCommand167({
28754
29051
  });
28755
29052
 
28756
29053
  // src/commands/winning-ads/following.ts
28757
- import { defineCommand as defineCommand168 } from "citty";
29054
+ import { defineCommand as defineCommand172 } from "citty";
28758
29055
  registerSchema({
28759
29056
  command: "winning-ads.following",
28760
29057
  description: "List the brands you follow in your ad-dna library, with each one's status (ready vs still adding) and cached ad counts.",
@@ -28787,7 +29084,7 @@ function followingNormalizer(record, full) {
28787
29084
  platforms: Array.isArray(record.platforms) ? record.platforms : []
28788
29085
  };
28789
29086
  }
28790
- var followingCommand = defineCommand168({
29087
+ var followingCommand = defineCommand172({
28791
29088
  meta: {
28792
29089
  name: "following",
28793
29090
  description: "List brands you follow, with status (ready / adding\u2026) and cached counts. Example: baker winning-ads following --output md"
@@ -28822,7 +29119,7 @@ var followingCommand = defineCommand168({
28822
29119
  });
28823
29120
 
28824
29121
  // src/commands/winning-ads/patterns.ts
28825
- import { defineCommand as defineCommand169 } from "citty";
29122
+ import { defineCommand as defineCommand173 } from "citty";
28826
29123
  registerSchema({
28827
29124
  command: "winning-ads.patterns",
28828
29125
  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.",
@@ -28861,7 +29158,7 @@ function discriminatorRow(record) {
28861
29158
  top_values_duds: Array.isArray(record.top_values_b) ? record.top_values_b.join(", ") : ""
28862
29159
  };
28863
29160
  }
28864
- var patternsCommand = defineCommand169({
29161
+ var patternsCommand = defineCommand173({
28865
29162
  meta: {
28866
29163
  name: "patterns",
28867
29164
  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"
@@ -28917,7 +29214,7 @@ var patternsCommand = defineCommand169({
28917
29214
  });
28918
29215
 
28919
29216
  // src/commands/winning-ads/search.ts
28920
- import { defineCommand as defineCommand170 } from "citty";
29217
+ import { defineCommand as defineCommand174 } from "citty";
28921
29218
  registerSchema({
28922
29219
  command: "winning-ads.search",
28923
29220
  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.",
@@ -29025,7 +29322,7 @@ function buildSearchBody(args) {
29025
29322
  }
29026
29323
  return body;
29027
29324
  }
29028
- var searchCommand4 = defineCommand170({
29325
+ var searchCommand4 = defineCommand174({
29029
29326
  meta: {
29030
29327
  name: "search",
29031
29328
  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"
@@ -29140,7 +29437,7 @@ var searchCommand4 = defineCommand170({
29140
29437
  });
29141
29438
 
29142
29439
  // src/commands/winning-ads/seeds.ts
29143
- import { defineCommand as defineCommand171 } from "citty";
29440
+ import { defineCommand as defineCommand175 } from "citty";
29144
29441
  function leanRow(r) {
29145
29442
  return {
29146
29443
  key: r.key,
@@ -29168,7 +29465,7 @@ function makeSeedCommand(opts) {
29168
29465
  limit: { type: "number", description: "Max keys 1-100 (default 20)", required: false, default: 20 }
29169
29466
  }
29170
29467
  });
29171
- return defineCommand171({
29468
+ return defineCommand175({
29172
29469
  meta: { name: opts.name, description: opts.description },
29173
29470
  args: {
29174
29471
  platform: { type: "string", description: "Single platform to segment on", required: false },
@@ -29217,7 +29514,7 @@ var formatsCommand = makeSeedCommand({
29217
29514
  });
29218
29515
 
29219
29516
  // src/commands/winning-ads/unfollow.ts
29220
- import { defineCommand as defineCommand172 } from "citty";
29517
+ import { defineCommand as defineCommand176 } from "citty";
29221
29518
  registerSchema({
29222
29519
  command: "winning-ads.unfollow",
29223
29520
  description: "Stop following a brand \u2014 removes it from your ad-dna library by advertiser id.",
@@ -29225,7 +29522,7 @@ registerSchema({
29225
29522
  advertiser: { type: "string", description: "Advertiser id to unfollow", required: true }
29226
29523
  }
29227
29524
  });
29228
- var unfollowCommand = defineCommand172({
29525
+ var unfollowCommand = defineCommand176({
29229
29526
  meta: {
29230
29527
  name: "unfollow",
29231
29528
  description: "Stop following a brand by advertiser id. Example: baker winning-ads unfollow adv_123"
@@ -29246,7 +29543,7 @@ var unfollowCommand = defineCommand172({
29246
29543
  });
29247
29544
 
29248
29545
  // src/commands/winning-ads/winners.ts
29249
- import { defineCommand as defineCommand173 } from "citty";
29546
+ import { defineCommand as defineCommand177 } from "citty";
29250
29547
  registerSchema({
29251
29548
  command: "winning-ads.winners",
29252
29549
  description: "Top winning ads for one advertiser id (from `advertisers` or `following`). Returns lean winner cards; add --full for DNA + longevity.",
@@ -29256,7 +29553,7 @@ registerSchema({
29256
29553
  platform: { type: "string", description: "Filter to a single platform: meta|linkedin", required: false }
29257
29554
  }
29258
29555
  });
29259
- var winnersCommand = defineCommand173({
29556
+ var winnersCommand = defineCommand177({
29260
29557
  meta: {
29261
29558
  name: "winners",
29262
29559
  description: "Top winning ads for a specific advertiser id. Example: baker winning-ads winners adv_123 --top 15 --output md"
@@ -29306,7 +29603,7 @@ var winnersCommand = defineCommand173({
29306
29603
  });
29307
29604
 
29308
29605
  // src/commands/winning-ads/index.ts
29309
- var winningAdsCommand = defineCommand174({
29606
+ var winningAdsCommand = defineCommand178({
29310
29607
  meta: {
29311
29608
  name: "winning-ads",
29312
29609
  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.
@@ -29338,8 +29635,7 @@ Examples:
29338
29635
  baker winning-ads winners adv_123 --top 15 --output md
29339
29636
  baker winning-ads hooks --platform meta --awareness problem_aware --industry saas --output md
29340
29637
  baker winning-ads search "fintech onboarding" --hook-archetype callout --winner-category winner --output md
29341
- baker winning-ads patterns --winners a_1,a_2 --duds a_9,a_8 --output md
29342
- Full guide: __tooling__/docs/tools/baker/winning-ads.md`
29638
+ baker winning-ads patterns --winners a_1,a_2 --duds a_9,a_8 --output md`
29343
29639
  },
29344
29640
  subCommands: {
29345
29641
  search: searchCommand4,
@@ -29359,7 +29655,7 @@ Full guide: __tooling__/docs/tools/baker/winning-ads.md`
29359
29655
  });
29360
29656
 
29361
29657
  // src/version.ts
29362
- import { readFileSync as readFileSync12 } from "fs";
29658
+ import { readFileSync as readFileSync13 } from "fs";
29363
29659
  function packageJsonUrl() {
29364
29660
  return new URL("../package.json", import.meta.url);
29365
29661
  }
@@ -29371,15 +29667,15 @@ function parsePackageVersion(raw) {
29371
29667
  throw new Error("Invalid CLI package.json: missing version");
29372
29668
  }
29373
29669
  function getCliVersion() {
29374
- return parsePackageVersion(readFileSync12(packageJsonUrl(), "utf8"));
29670
+ return parsePackageVersion(readFileSync13(packageJsonUrl(), "utf8"));
29375
29671
  }
29376
29672
 
29377
29673
  // src/cli.ts
29378
- var main = defineCommand175({
29674
+ var main = defineCommand179({
29379
29675
  meta: {
29380
29676
  name: "baker",
29381
29677
  version: getCliVersion(),
29382
- description: `AI-agent CLI for finding and managing images, videos, testimonials, action items, scheduled actions, marketing tags, account history, and ad platform data in Baker.
29678
+ description: `AI-agent CLI for finding and managing images, videos, testimonials, action items, scheduled actions, marketing tags, Tag Manager containers, account history, and ad platform data in Baker.
29383
29679
 
29384
29680
  Auth: Set BAKER_API_KEY (starts with bk_) and BAKER_API_URL environment variables.
29385
29681
  Chat: Set BAKER_CHAT_ID for action and scheduled-action commands that stage changes against a chat.
@@ -29401,6 +29697,7 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
29401
29697
  testimonials: testimonialsCommand,
29402
29698
  canvas: canvasCommand,
29403
29699
  tags: tagsCommand3,
29700
+ "tag-manager": tagManagerCommand,
29404
29701
  chats: chatsCommand,
29405
29702
  history: historyCommand,
29406
29703
  "winning-ads": winningAdsCommand,