@koda-sl/baker-cli 0.174.0 → 0.177.0-dev.0cbdaa224

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.
Files changed (29) hide show
  1. package/README.md +81 -1
  2. package/dist/{chunk-7I2POXSJ.js → chunk-K3PWXVF7.js} +2 -2
  3. package/dist/{chunk-7QMWNMRW.js → chunk-PXXJ3HJW.js} +4 -4
  4. package/dist/{chunk-CG6OTNUU.js → chunk-QPVJGKV7.js} +6 -6
  5. package/dist/chunk-QPVJGKV7.js.map +1 -0
  6. package/dist/{chunk-TFPZLUVM.js → chunk-X5C6HE24.js} +5 -5
  7. package/dist/chunk-X5C6HE24.js.map +1 -0
  8. package/dist/{chunk-RK67WL4O.js → chunk-YL3HDEIJ.js} +6 -2
  9. package/dist/{chunk-RK67WL4O.js.map → chunk-YL3HDEIJ.js.map} +1 -1
  10. package/dist/{chunk-ZH6ZNYPB.js → chunk-ZWYQIEBI.js} +3 -3
  11. package/dist/cli.js +1643 -343
  12. package/dist/cli.js.map +1 -1
  13. package/dist/client-PJ7ID35L.js +15 -0
  14. package/dist/engine/index.js +3 -3
  15. package/dist/env-6QJCMTRK.js +13 -0
  16. package/dist/{output-FL7WRIJF.js → output-NWX3YW64.js} +5 -5
  17. package/dist/{shared-OIYLDW3G.js → shared-5ZEOG664.js} +6 -6
  18. package/package.json +1 -1
  19. package/dist/chunk-CG6OTNUU.js.map +0 -1
  20. package/dist/chunk-TFPZLUVM.js.map +0 -1
  21. package/dist/client-XRQWOADV.js +0 -15
  22. package/dist/env-3JMYIH25.js +0 -11
  23. /package/dist/{chunk-7I2POXSJ.js.map → chunk-K3PWXVF7.js.map} +0 -0
  24. /package/dist/{chunk-7QMWNMRW.js.map → chunk-PXXJ3HJW.js.map} +0 -0
  25. /package/dist/{chunk-ZH6ZNYPB.js.map → chunk-ZWYQIEBI.js.map} +0 -0
  26. /package/dist/{client-XRQWOADV.js.map → client-PJ7ID35L.js.map} +0 -0
  27. /package/dist/{env-3JMYIH25.js.map → env-6QJCMTRK.js.map} +0 -0
  28. /package/dist/{output-FL7WRIJF.js.map → output-NWX3YW64.js.map} +0 -0
  29. /package/dist/{shared-OIYLDW3G.js.map → shared-5ZEOG664.js.map} +0 -0
package/dist/cli.js CHANGED
@@ -36,7 +36,7 @@ import {
36
36
  toModelSafeImage,
37
37
  ulid,
38
38
  validateCanvasDeep
39
- } from "./chunk-CG6OTNUU.js";
39
+ } from "./chunk-QPVJGKV7.js";
40
40
  import {
41
41
  csvOrJson,
42
42
  daysAgoIso,
@@ -45,7 +45,7 @@ import {
45
45
  resolveAccountIdArg,
46
46
  resolveEffectiveStatus,
47
47
  todayIso
48
- } from "./chunk-7QMWNMRW.js";
48
+ } from "./chunk-PXXJ3HJW.js";
49
49
  import {
50
50
  buildQueryCacheKey,
51
51
  cacheGet,
@@ -61,24 +61,25 @@ import {
61
61
  writeAdsJson,
62
62
  writeAdsOutput,
63
63
  writeJsonEnvelope
64
- } from "./chunk-TFPZLUVM.js";
64
+ } from "./chunk-X5C6HE24.js";
65
65
  import {
66
66
  ApiError,
67
67
  apiGet,
68
68
  apiPost,
69
69
  validateConvexId
70
- } from "./chunk-ZH6ZNYPB.js";
70
+ } from "./chunk-ZWYQIEBI.js";
71
71
  import {
72
72
  installStreamTaps,
73
73
  logInvocation
74
- } from "./chunk-7I2POXSJ.js";
74
+ } from "./chunk-K3PWXVF7.js";
75
75
  import {
76
76
  getEnv,
77
- requireChatId
78
- } from "./chunk-RK67WL4O.js";
77
+ requireChatId,
78
+ resolveChatId
79
+ } from "./chunk-YL3HDEIJ.js";
79
80
 
80
81
  // src/cli.ts
81
- import { defineCommand as defineCommand188, runMain } from "citty";
82
+ import { defineCommand as defineCommand191, runMain } from "citty";
82
83
 
83
84
  // src/commands/actions/index.ts
84
85
  import { defineCommand as defineCommand18 } from "citty";
@@ -2439,7 +2440,13 @@ var CAPABILITY_SURFACE_SPECS = {
2439
2440
  label: "Google Analytics 4",
2440
2441
  provider: "google-analytics",
2441
2442
  resourceNoun: "property",
2442
- writePath: "read-only",
2443
+ // Like Tag Manager: staged during the chat, applied for real at publish,
2444
+ // with no simulated mode. A connection made before writes existed is
2445
+ // read-only until it is reconnected, and `access` does NOT say so — it
2446
+ // reports what the Baker app asks Google for, which is now app-wide
2447
+ // read-write. The per-company signal is `scopeBlockers`, which compares
2448
+ // `writeScopes` against the scopes that connection actually recorded.
2449
+ writePath: "staged-immediate",
2443
2450
  writeScopes: ["https://www.googleapis.com/auth/analytics.edit"],
2444
2451
  commands: "baker ga4"
2445
2452
  },
@@ -2537,6 +2544,7 @@ var chatChangeTypeSchema = z7.enum([
2537
2544
  "google-ads",
2538
2545
  "meta-ads",
2539
2546
  "tag-manager",
2547
+ "ga4",
2540
2548
  // Immediate (already-applied) library effects — see lib/chatChanges.ts.
2541
2549
  "image",
2542
2550
  "video",
@@ -2632,7 +2640,17 @@ var adEffectSchema = z7.object({
2632
2640
  staged: z7.boolean(),
2633
2641
  entity: z7.string().nullable(),
2634
2642
  operation: z7.string().nullable(),
2635
- summary: z7.string().nullable()
2643
+ summary: z7.string().nullable(),
2644
+ /** Addresses the op for `draft show --chat <thisChat> <ref>`, which returns the full payload. */
2645
+ ref: z7.string(),
2646
+ /**
2647
+ * What the publish did with this op, or null while it is still staged. Without it a reader cannot
2648
+ * tell a change that reached the platform from one that was rejected — a whole failed publish
2649
+ * reads exactly like a successful one.
2650
+ */
2651
+ outcome: z7.enum(["applied", "simulated", "failed", "skipped"]).nullable(),
2652
+ /** Why it failed, verbatim from the platform. Null unless the op failed. */
2653
+ error: z7.string().nullable()
2636
2654
  });
2637
2655
  var creativeEffectSchema = z7.object({
2638
2656
  op: effectOpSchema,
@@ -3907,11 +3925,21 @@ var discardCommand = defineCommand4({
3907
3925
 
3908
3926
  // src/commands/actions/draft.ts
3909
3927
  import { defineCommand as defineCommand5 } from "citty";
3928
+
3929
+ // src/commands/chat-arg.ts
3930
+ var CHAT_READ_ARG = {
3931
+ type: "string",
3932
+ description: "Read another chat's staged changes instead of this one's. Start here when asked to redo, reapply or explain what an earlier chat did \u2014 its changes are kept verbatim, including what happened to each one on publish. Never retype an earlier chat's work from a summary."
3933
+ };
3934
+
3935
+ // src/commands/actions/draft.ts
3910
3936
  var REMOVE_OP_KINDS = ["update", "complete", "discard"];
3911
3937
  registerSchema({
3912
3938
  command: "actions.draft.list",
3913
- description: "Review the action ops staged in THIS chat's draft before publish (creates/updates/completes/discards/links). Staged ops are invisible to `actions list`/`status` until the chat publishes \u2014 use this to verify what will apply and catch duplicates.",
3914
- args: {}
3939
+ description: "Review the action ops staged in THIS chat's draft before publish (creates/updates/completes/discards/links). Staged ops are invisible to `actions list`/`status` until the chat publishes \u2014 use this to verify what will apply and catch duplicates. Takes --chat <id> to read an earlier chat's staged ops instead.",
3940
+ args: {
3941
+ chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
3942
+ }
3915
3943
  });
3916
3944
  registerSchema({
3917
3945
  command: "actions.draft.remove",
@@ -3935,9 +3963,10 @@ var listCommand = defineCommand5({
3935
3963
  name: "list",
3936
3964
  description: "Show every action op staged in this chat's draft, with footgun warnings. Example: baker actions draft"
3937
3965
  },
3938
- run: async () => {
3966
+ args: { chat: CHAT_READ_ARG },
3967
+ run: async ({ args }) => {
3939
3968
  try {
3940
- const chatId = requireChatId();
3969
+ const chatId = resolveChatId(args.chat);
3941
3970
  const response = await apiPost("/api/actions/draft", { chatId });
3942
3971
  writeJson(response);
3943
3972
  } catch (err) {
@@ -4008,8 +4037,11 @@ var clearCommand = defineCommand5({
4008
4037
  var draftCommand = defineCommand5({
4009
4038
  meta: {
4010
4039
  name: "draft",
4011
- description: "Review and edit the action ops staged in this chat BEFORE publish. Subcommands: list (default), remove, clear. Staged ops are invisible to `actions list`/`status` until publish, so check here before finishing."
4040
+ description: "Review and edit the action ops staged in this chat BEFORE publish. Subcommands: list (default), remove, clear. Staged ops are invisible to `actions list`/`status` until publish, so check here before finishing. `list` takes --chat <id> to read an earlier chat's staged ops instead."
4012
4041
  },
4042
+ // Declared on the parent too: `default: "list"` dispatches the bare `draft --chat <id>` form, and
4043
+ // citty prints help for a flag the parent does not know instead of forwarding it.
4044
+ args: { chat: CHAT_READ_ARG },
4013
4045
  subCommands: {
4014
4046
  list: listCommand,
4015
4047
  remove: removeCommand,
@@ -5145,7 +5177,9 @@ var GOOGLE_ADS_LIMITS = {
5145
5177
  sitelinkLinkTextMax: 25,
5146
5178
  sitelinkDescriptionMax: 35,
5147
5179
  calloutTextMax: 25,
5148
- structuredSnippetHeaderMax: 25,
5180
+ // A snippet's HEADER has no length limit of its own — it has to be one of
5181
+ // Google's published headers (`structured-snippet-headers.ts`), the longest
5182
+ // of which is 29 characters. Only the values are capped.
5149
5183
  structuredSnippetValuesMin: 3,
5150
5184
  structuredSnippetValuesMax: 10
5151
5185
  },
@@ -5325,6 +5359,500 @@ var LANGUAGE_CONSTANT_REGEX = /^languageConstants\/\d+$/;
5325
5359
 
5326
5360
  // ../api/src/ads-google/ops.ts
5327
5361
  import { z as z15 } from "zod";
5362
+
5363
+ // ../api/src/ads-google/structured-snippet-headers.ts
5364
+ var STRUCTURED_SNIPPET_HEADERS_EN = [
5365
+ "Brands",
5366
+ "Amenities",
5367
+ "Styles",
5368
+ "Types",
5369
+ "Destinations",
5370
+ "Services",
5371
+ "Courses",
5372
+ "Neighborhoods",
5373
+ "Shows",
5374
+ "Insurance coverage",
5375
+ "Degree programs",
5376
+ "Featured hotels",
5377
+ "Models"
5378
+ ];
5379
+ var STRUCTURED_SNIPPET_HEADERS_LOCALIZED = [
5380
+ "Aanbevolen hotels",
5381
+ "Acara",
5382
+ "Apdro\u0161in\u0101\u0161ana",
5383
+ "Apkaimes",
5384
+ "Arredores",
5385
+ "Asigurare",
5386
+ "Asseguran\xE7a",
5387
+ "Ausstattung",
5388
+ "Automerkit",
5389
+ "Bairros",
5390
+ "Barrios",
5391
+ "Barris",
5392
+ "Bestemmingen",
5393
+ "Biztos\xEDt\xE1si m\xF3dozat",
5394
+ "Blagovne znamke",
5395
+ "Brand",
5396
+ "Br\xE4ndid",
5397
+ "Br\xE4ndit",
5398
+ "Buurten",
5399
+ "Cakupan asuransi",
5400
+ "Carreras universitarias",
5401
+ "Cartiere",
5402
+ "Ch\u01B0\u01A1ng tr\xECnh",
5403
+ "Cilji",
5404
+ "Cobertura de seguro",
5405
+ "Cobertura do seguro",
5406
+ "Comodidades",
5407
+ "Coperture assicurativa",
5408
+ "Corsi",
5409
+ "Corsi di laurea",
5410
+ "Cours",
5411
+ "Couverture d'assurance",
5412
+ "Cursos",
5413
+ "Cursuri",
5414
+ "Cursussen",
5415
+ "C\xEDle",
5416
+ "C\u1EA5p b\u1EB1ng",
5417
+ "Degree programmes",
5418
+ "Dekking",
5419
+ "Design",
5420
+ "Destinacions",
5421
+ "Destinasi",
5422
+ "Destinasjoner",
5423
+ "Destinationer",
5424
+ "Destinazioni",
5425
+ "Destina\u021Bii",
5426
+ "Destinos",
5427
+ "Destin\xE1cie",
5428
+ "Dienstleistungen",
5429
+ "Diplomaprogramok",
5430
+ "Dot\u0103ri",
5431
+ "Draudimo apr\u0117ptis",
5432
+ "Dzielnice",
5433
+ "D\u1ECBch v\u1EE5",
5434
+ "Emisije",
5435
+ "Emisiuni",
5436
+ "Espect\xE1culos",
5437
+ "Estilos",
5438
+ "Estils",
5439
+ "Faciliteter",
5440
+ "Fasilitas",
5441
+ "Fasiliteter",
5442
+ "Forsikringsdekning",
5443
+ "Forsikringsd\xE6kning",
5444
+ "F\xF6rs\xE4kringstyper",
5445
+ "Galam\u0113r\u0137i",
5446
+ "Gaya",
5447
+ "Hizmetler",
5448
+ "Hotel consigliati",
5449
+ "Hotel ditampilkan",
5450
+ "Hotel pilihan",
5451
+ "Hoteles destacados",
5452
+ "Hotels destacats",
5453
+ "Hoteluri prezentate",
5454
+ "Hot\xE9is em destaque",
5455
+ "Istaknuti hoteli",
5456
+ "Itinatampok na hotel",
5457
+ "Jenama",
5458
+ "Jenis",
5459
+ "Kaupunginosat",
5460
+ "Kawasan",
5461
+ "Kejiranan",
5462
+ "Kemudahan",
5463
+ "Kh\xE1ch s\u1EA1n n\u1ED5i b\u1EADt",
5464
+ "Kh\xF3a h\u1ECDc",
5465
+ "Kiemelt sz\xE1llod\xE1k",
5466
+ "Kierunki studi\xF3w",
5467
+ "Kindlustuskaitse",
5468
+ "Ki\u1EC3u",
5469
+ "Kohteet",
5470
+ "Kraadi\xF5ppeprogrammid",
5471
+ "Kritje zavarovanj",
5472
+ "Kurs",
5473
+ "Kursai",
5474
+ "Kurse",
5475
+ "Kurser",
5476
+ "Kursi",
5477
+ "Kurslar",
5478
+ "Kurssit",
5479
+ "Kursus",
5480
+ "Kursused",
5481
+ "Kursy",
5482
+ "Kurzy",
5483
+ "Laidos",
5484
+ "Layanan",
5485
+ "Licenciaturas",
5486
+ "Liputan insurans",
5487
+ "Lisans programlar\u0131",
5488
+ "Lis\xE4palvelut",
5489
+ "Lokalomr\xE5der",
5490
+ "Lo\u1EA1i",
5491
+ "Mahalleler",
5492
+ "Marcas",
5493
+ "Markalar",
5494
+ "Marken",
5495
+ "Marki",
5496
+ "Marques",
5497
+ "Mata pelajaran",
5498
+ "Merek",
5499
+ "Merken",
5500
+ "Merkevarer",
5501
+ "Mga Amenity",
5502
+ "Mga Brand",
5503
+ "Mga Destinasyon",
5504
+ "Mga Istilo",
5505
+ "Mga Komunidad",
5506
+ "Mga Kurso",
5507
+ "Mga Modelo",
5508
+ "Mga Palabas",
5509
+ "Mga Serbisyo",
5510
+ "Mga Uri",
5511
+ "Mga degree program",
5512
+ "Miejsca",
5513
+ "Model",
5514
+ "Modele",
5515
+ "Modeli",
5516
+ "Modeliai",
5517
+ "Modelle",
5518
+ "Modellek",
5519
+ "Modellen",
5520
+ "Modeller",
5521
+ "Modelli",
5522
+ "Modelos",
5523
+ "Modely",
5524
+ "Mode\u013Ci",
5525
+ "Mod\xE8les",
5526
+ "Moksliniai laipsniai",
5527
+ "Mudelid",
5528
+ "Mugavusteenused",
5529
+ "M\xE1rk\xE1k",
5530
+ "M\u0103rci",
5531
+ "M\u0171sorok",
5532
+ "Nabolag",
5533
+ "Nam\u0173 apylink\u0117s",
5534
+ "Neighbourhoods",
5535
+ "Oddaje",
5536
+ "Odpor\xFA\u010Dan\xE9 hotely",
5537
+ "Odredi\u0161ta",
5538
+ "Oppiaineet",
5539
+ "Osiguranje",
5540
+ "Pakalpojumi",
5541
+ "Palvelut",
5542
+ "Paskirties vietos",
5543
+ "Paslaugos",
5544
+ "Patogumai",
5545
+ "Perkhidmatan",
5546
+ "Ph\u1EA1m vi b\u1EA3o hi\u1EC3m",
5547
+ "Pied\u0101v\u0101t\u0101s viesn\u012Bcas",
5548
+ "Poistenie",
5549
+ "Poji\u0161t\u011Bn\xED",
5550
+ "Polecane hotele",
5551
+ "Ponudba",
5552
+ "Po\u0159ady",
5553
+ "Predstavljeni hoteli",
5554
+ "Preki\u0173 \u017Eenklai",
5555
+ "Program",
5556
+ "Program ijazah",
5557
+ "Program sarjana",
5558
+ "Programas",
5559
+ "Programas de gradua\xE7\xE3o",
5560
+ "Programe de studiu",
5561
+ "Programes",
5562
+ "Programlar",
5563
+ "Programmer",
5564
+ "Programmes d'\xE9tudes",
5565
+ "Programmi",
5566
+ "Programy",
5567
+ "P\u0101rraides",
5568
+ "Quartieri",
5569
+ "Quartiers",
5570
+ "Rancangan",
5571
+ "Rel\xE1cie",
5572
+ "Resm\xE5l",
5573
+ "Robne marke",
5574
+ "Saated ja etendused",
5575
+ "Sadr\u017Eaji",
5576
+ "Sakop ng insurance",
5577
+ "Serien",
5578
+ "Serier",
5579
+ "Serveis",
5580
+ "Serveis addicionals",
5581
+ "Servicii",
5582
+ "Servicios",
5583
+ "Servicios adicionales",
5584
+ "Servizi",
5585
+ "Servi\xE7os",
5586
+ "Show't",
5587
+ "Sigorta kapsam\u0131",
5588
+ "Sihtkohad",
5589
+ "Si\u016Blomi vie\u0161bu\u010Diai",
5590
+ "Slogi",
5591
+ "Slu\u017Eby",
5592
+ "Soovitatud hotellid",
5593
+ "Soseske",
5594
+ "Stiilid",
5595
+ "Stijlen",
5596
+ "Stilar",
5597
+ "Stile",
5598
+ "Stiler",
5599
+ "Stili",
5600
+ "Stiliai",
5601
+ "Stiller",
5602
+ "Stilovi",
5603
+ "Stiluri",
5604
+ "Storitve",
5605
+ "Studieng\xE4nge",
5606
+ "Studieprogramma's",
5607
+ "Studijn\xED programy",
5608
+ "Studijski programi",
5609
+ "Studiju programmas",
5610
+ "Style",
5611
+ "Styly",
5612
+ "St\xEDlusok",
5613
+ "Sunulan olanaklar",
5614
+ "Suositellut hotellit",
5615
+ "Szolg\xE1ltat\xE1sok",
5616
+ "S\xE9lection d'h\xF4tels",
5617
+ "Tanfolyamok",
5618
+ "Teenused",
5619
+ "Te\u010Dajevi",
5620
+ "Te\u010Daji",
5621
+ "Th\u01B0\u01A1ng hi\u1EC7u",
5622
+ "Tipai",
5623
+ "Tipi",
5624
+ "Tipos",
5625
+ "Tipuri",
5626
+ "Tipus",
5627
+ "Titulacions",
5628
+ "Ti\u1EC7n nghi",
5629
+ "Tjenester",
5630
+ "Tj\xE4nster",
5631
+ "Typen",
5632
+ "Typer",
5633
+ "Typy",
5634
+ "Tyylit",
5635
+ "Tyypit",
5636
+ "T\xEDpusok",
5637
+ "T\xFCrler",
5638
+ "T\xFC\xFCbid",
5639
+ "Ubezpieczenia",
5640
+ "Uddannelser",
5641
+ "Udogodnienia",
5642
+ "Udvalgte hoteller",
5643
+ "Usluge",
5644
+ "Us\u0142ugi",
5645
+ "Utbildningsprogram",
5646
+ "Utdanningsprogrammer",
5647
+ "Utvalda hotell",
5648
+ "Utvalgte hoteller",
5649
+ "Vakuutukset",
5650
+ "Varum\xE4rken",
5651
+ "Veidi",
5652
+ "Versicherungsleistung",
5653
+ "Viertel",
5654
+ "Voorzieningen",
5655
+ "Vorgestellte Hotels",
5656
+ "Vrste",
5657
+ "Vybavenie",
5658
+ "Vybaven\xED",
5659
+ "Vybran\xE9 hotely",
5660
+ "Vzdel\xE1vacie programy",
5661
+ "V\xE1rosr\xE9szek",
5662
+ "V\xF9ng l\xE2n c\u1EADn",
5663
+ "Ziele",
5664
+ "Zna\u010Dky",
5665
+ "Zn\xE1m\xE9 oblasti",
5666
+ "Z\u012Bmoli",
5667
+ "destinasyonlar",
5668
+ "\xC9missions",
5669
+ "\xC9quipements",
5670
+ "\xD6ne \xE7\u0131kan oteller",
5671
+ "\xDAti c\xE9lok",
5672
+ "\xDCmbruskonnad",
5673
+ "\u010Cetvrti",
5674
+ "\u0110i\u1EC3m \u0111\u1EBFn",
5675
+ "\u0112rt\u012Bbas",
5676
+ "\u0160tudijski programi",
5677
+ "\u0160tvrte",
5678
+ "\u0160t\xFDly",
5679
+ "\u0391\u03C3\u03C6\u03B1\u03BB\u03B9\u03C3\u03C4\u03B9\u03BA\u03AE \u03BA\u03AC\u03BB\u03C5\u03C8\u03B7",
5680
+ "\u0393\u03B5\u03B9\u03C4\u03BF\u03BD\u03B9\u03AD\u03C2",
5681
+ "\u0395\u03BA\u03C0\u03BF\u03BC\u03C0\u03AD\u03C2",
5682
+ "\u0395\u03C0\u03C9\u03BD\u03C5\u03BC\u03AF\u03B5\u03C2",
5683
+ "\u039C\u03B1\u03B8\u03AE\u03BC\u03B1\u03C4\u03B1",
5684
+ "\u039C\u03BF\u03BD\u03C4\u03AD\u03BB\u03B1",
5685
+ "\u039E\u03B5\u03BD\u03BF\u03B4\u03BF\u03C7\u03B5\u03AF\u03B1",
5686
+ "\u03A0\u03B1\u03C1\u03BF\u03C7\u03AD\u03C2",
5687
+ "\u03A0\u03C1\u03BF\u03B3\u03C1\u03AC\u03BC\u03BC\u03B1\u03C4\u03B1 \u03C0\u03C4\u03C5\u03C7\u03AF\u03C9\u03BD",
5688
+ "\u03A0\u03C1\u03BF\u03BF\u03C1\u03B9\u03C3\u03BC\u03BF\u03AF",
5689
+ "\u03A3\u03C4\u03C5\u03BB",
5690
+ "\u03A4\u03CD\u03C0\u03BF\u03B9",
5691
+ "\u03A5\u03C0\u03B7\u03C1\u03B5\u03C3\u03AF\u03B5\u03C2",
5692
+ "\u0411\u0440\u0435\u043D\u0434\u0438",
5693
+ "\u0411\u0440\u0435\u043D\u0434\u044B",
5694
+ "\u0414\u0435\u0441\u0442\u0438\u043D\u0430\u0446\u0438\u0438",
5695
+ "\u0417\u0430\u0441\u0442\u0440\u0430\u0445\u043E\u0432\u043A\u0430",
5696
+ "\u0417\u0440\u0443\u0447\u043D\u043E\u0441\u0442\u0456",
5697
+ "\u041A\u0432\u0430\u0440\u0442\u0430\u043B\u0438",
5698
+ "\u041A\u0443\u0440\u0441\u0438",
5699
+ "\u041A\u0443\u0440\u0441\u043E\u0432\u0435",
5700
+ "\u041A\u0443\u0440\u0441\u044B",
5701
+ "\u041C\u0430\u0440\u043A\u0438",
5702
+ "\u041C\u0435\u0441\u0442\u0430",
5703
+ "\u041C\u043E\u0434\u0435\u043B\u0438",
5704
+ "\u041C\u043E\u0434\u0435\u043B\u0456",
5705
+ "\u041C\u0456\u0441\u0446\u044F",
5706
+ "\u041E\u0441\u0432\u0456\u0442\u043D\u0456 \u043F\u0440\u043E\u0433\u0440\u0430\u043C\u0438",
5707
+ "\u041F\u043E\u0441\u043B\u0443\u0433\u0438",
5708
+ "\u041F\u0440\u0435\u0434\u0430\u0432\u0430\u043D\u0438\u044F",
5709
+ "\u041F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0435\u043D\u0438 \u0445\u043E\u0442\u0435\u043B\u0438",
5710
+ "\u041F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B \u0432\u044B\u0441\u0448\u0435\u0433\u043E \u043E\u0431\u0440\u0430\u0437\u043E\u0432\u0430\u043D\u0438\u044F",
5711
+ "\u0420\u0430\u0439\u043E\u043D\u044B",
5712
+ "\u0420\u0435\u043A\u043E\u043C\u0435\u043D\u0434\u043E\u0432\u0430\u043D\u0456 \u0433\u043E\u0442\u0435\u043B\u0456",
5713
+ "\u0420\u0435\u043A\u043E\u043C\u0435\u043D\u0434\u0443\u0435\u043C\u044B\u0435 \u043E\u0442\u0435\u043B\u0438",
5714
+ "\u0421\u043F\u0435\u0446\u0438\u0430\u043B\u043D\u043E\u0441\u0442\u0438",
5715
+ "\u0421\u0442\u0438\u043B\u0438",
5716
+ "\u0421\u0442\u0438\u043B\u043E\u0432\u0435",
5717
+ "\u0421\u0442\u0438\u043B\u0456",
5718
+ "\u0421\u0442\u0440\u0430\u0445\u043E\u0432\u0430\u044F \u0437\u0430\u0449\u0438\u0442\u0430",
5719
+ "\u0421\u0442\u0440\u0430\u0445\u043E\u0432\u0438\u0439 \u0437\u0430\u0445\u0438\u0441\u0442",
5720
+ "\u0422\u0438\u043F\u0438",
5721
+ "\u0422\u0438\u043F\u043E\u0432\u0435",
5722
+ "\u0422\u0438\u043F\u044B",
5723
+ "\u0423\u0434\u043E\u0431\u0441\u0442\u0432\u0430",
5724
+ "\u0423\u0441\u043B\u0443\u0433\u0438",
5725
+ "\u0428\u043E\u0443",
5726
+ "\u0431\u0440\u0435\u043D\u0434\u043E\u0432\u0438",
5727
+ "\u0434\u0435\u043B\u043E\u0432\u0438 \u0433\u0440\u0430\u0434\u0430",
5728
+ "\u0434\u0435\u0441\u0442\u0438\u043D\u0430\u0446\u0438\u0458\u0435",
5729
+ "\u0434\u0438\u043F\u043B\u043E\u043C\u0435",
5730
+ "\u0435\u043C\u0438\u0441\u0438\u0458\u0435",
5731
+ "\u0438\u0441\u0442\u0430\u043A\u043D\u0443\u0442\u0438 \u0445\u043E\u0442\u0435\u043B\u0438",
5732
+ "\u043A\u0443\u0440\u0441\u0435\u0432\u0438",
5733
+ "\u043C\u043E\u0434\u0435\u043B\u0438",
5734
+ "\u043E\u0441\u0438\u0433\u0443\u0440\u0430\u045A\u0435",
5735
+ "\u0441\u0430\u0434\u0440\u0436\u0430\u0458\u0438",
5736
+ "\u0441\u0442\u0438\u043B\u043E\u0432\u0438",
5737
+ "\u0442\u0438\u043F\u043E\u0432\u0438",
5738
+ "\u0443\u0441\u043B\u0443\u0433\u0435",
5739
+ "\u05D3\u05D2\u05DE\u05D9\u05DD",
5740
+ "\u05D4\u05D5\u05E4\u05E2\u05D5\u05EA \u05D5\u05EA\u05D5\u05DB\u05E0\u05D9\u05D5\u05EA",
5741
+ "\u05D9\u05E2\u05D3\u05D9\u05DD \u05D2\u05D9\u05D0\u05D5\u05D2\u05E8\u05E4\u05D9\u05D9\u05DD",
5742
+ "\u05DB\u05D9\u05E1\u05D5\u05D9 \u05D1\u05D9\u05D8\u05D5\u05D7\u05D9",
5743
+ "\u05DE\u05D5\u05EA\u05D2\u05D9\u05DD",
5744
+ "\u05DE\u05DC\u05D5\u05E0\u05D5\u05EA \u05DE\u05D5\u05DE\u05DC\u05E6\u05D9\u05DD",
5745
+ "\u05E1\u05D2\u05E0\u05D5\u05E0\u05D5\u05EA",
5746
+ "\u05E1\u05D5\u05D2\u05D9\u05DD",
5747
+ "\u05E7\u05D5\u05E8\u05E1\u05D9\u05DD",
5748
+ "\u05E9\u05D9\u05E8\u05D5\u05EA\u05D9 \u05D4\u05DE\u05E7\u05D5\u05DD",
5749
+ "\u05E9\u05D9\u05E8\u05D5\u05EA\u05D9\u05DD",
5750
+ "\u05E9\u05DB\u05D5\u05E0\u05D5\u05EA",
5751
+ "\u05EA\u05D5\u05DB\u05E0\u05D9\u05D5\u05EA \u05DC\u05DC\u05D9\u05DE\u05D5\u05D3\u05D9 \u05EA\u05D5\u05D0\u05E8",
5752
+ "\u0627\u0644\u0623\u062D\u064A\u0627\u0621",
5753
+ "\u0627\u0644\u0623\u0646\u0645\u0627\u0637",
5754
+ "\u0627\u0644\u0623\u0646\u0648\u0627\u0639",
5755
+ "\u0627\u0644\u062A\u063A\u0637\u064A\u0629 \u0627\u0644\u062A\u0623\u0645\u064A\u0646\u064A\u0629",
5756
+ "\u0627\u0644\u062E\u062F\u0645\u0627\u062A",
5757
+ "\u0627\u0644\u062F\u0648\u0631\u0627\u062A \u0627\u0644\u062A\u062F\u0631\u064A\u0628\u064A\u0629",
5758
+ "\u0627\u0644\u0639\u0631\u0648\u0636",
5759
+ "\u0627\u0644\u0639\u0644\u0627\u0645\u0627\u062A \u0627\u0644\u062A\u062C\u0627\u0631\u064A\u0629",
5760
+ "\u0627\u0644\u0641\u0646\u0627\u062F\u0642 \u0627\u0644\u0645\u0645\u064A\u0651\u0632\u0629",
5761
+ "\u0627\u0644\u0646\u0645\u0627\u0630\u062C",
5762
+ "\u0627\u0644\u0648\u062C\u0647\u0627\u062A",
5763
+ "\u0628\u0631\u0627\u0645\u062C \u0627\u0644\u0634\u0647\u0627\u062F\u0627\u062A",
5764
+ "\u0648\u0633\u0627\u0626\u0644 \u0627\u0644\u0631\u0627\u062D\u0629",
5765
+ "\u0906\u0938-\u092A\u0921\u093C\u094B\u0938",
5766
+ "\u0917\u0902\u0924\u0935\u094D\u092F",
5767
+ "\u0921\u093F\u0917\u094D\u0930\u0940 \u0915\u093E\u0930\u094D\u092F\u0915\u094D\u0930\u092E",
5768
+ "\u092A\u093E\u0920\u094D\u200D\u092F\u0915\u094D\u0930\u092E",
5769
+ "\u092A\u094D\u0930\u0915\u093E\u0930",
5770
+ "\u092A\u094D\u0930\u0926\u0930\u094D\u0936\u093F\u0924 \u0939\u094B\u091F\u0932",
5771
+ "\u092C\u0940\u092E\u093E \u0915\u0935\u0930\u0947\u091C",
5772
+ "\u092C\u094D\u0930\u093E\u0902\u0921",
5773
+ "\u092E\u0949\u0921\u0932",
5774
+ "\u0936\u0948\u0932\u093F\u092F\u093E\u0902",
5775
+ "\u0936\u094B",
5776
+ "\u0938\u0941\u0935\u093F\u0927\u093E\u090F\u0902",
5777
+ "\u0938\u0947\u0935\u093E\u090F\u0902",
5778
+ "\u0E04\u0E27\u0E32\u0E21\u0E04\u0E38\u0E49\u0E21\u0E04\u0E23\u0E2D\u0E07\u0E43\u0E19\u0E1B\u0E23\u0E30\u0E01\u0E31\u0E19",
5779
+ "\u0E1A\u0E23\u0E34\u0E01\u0E32\u0E23",
5780
+ "\u0E1B\u0E23\u0E30\u0E40\u0E20\u0E17",
5781
+ "\u0E1B\u0E25\u0E32\u0E22\u0E17\u0E32\u0E07",
5782
+ "\u0E22\u0E48\u0E32\u0E19\u0E43\u0E01\u0E25\u0E49\u0E40\u0E04\u0E35\u0E22\u0E07",
5783
+ "\u0E23\u0E38\u0E48\u0E19",
5784
+ "\u0E2A\u0E34\u0E48\u0E07\u0E2D\u0E33\u0E19\u0E27\u0E22\u0E04\u0E27\u0E32\u0E21\u0E2A\u0E30\u0E14\u0E27\u0E01",
5785
+ "\u0E2A\u0E44\u0E15\u0E25\u0E4C",
5786
+ "\u0E2B\u0E25\u0E31\u0E01\u0E2A\u0E39\u0E15\u0E23",
5787
+ "\u0E2B\u0E25\u0E31\u0E01\u0E2A\u0E39\u0E15\u0E23\u0E1B\u0E23\u0E34\u0E0D\u0E0D\u0E32",
5788
+ "\u0E41\u0E1A\u0E23\u0E19\u0E14\u0E4C",
5789
+ "\u0E42\u0E0A\u0E27\u0E4C",
5790
+ "\u0E42\u0E23\u0E07\u0E41\u0E23\u0E21\u0E40\u0E14\u0E48\u0E19",
5791
+ "\u304A\u3059\u3059\u3081\u306E\u30DB\u30C6\u30EB",
5792
+ "\u30B3\u30FC\u30B9",
5793
+ "\u30B5\u30FC\u30D3\u30B9",
5794
+ "\u30B9\u30BF\u30A4\u30EB",
5795
+ "\u30BF\u30A4\u30D7",
5796
+ "\u30D6\u30E9\u30F3\u30C9",
5797
+ "\u30E2\u30C7\u30EB",
5798
+ "\u4FDD\u967A\u306E\u4FDD\u969C",
5799
+ "\u4FDD\u969C\u7BC4\u570D",
5800
+ "\u5230\u7740\u5730",
5801
+ "\u5468\u8FBA\u5730\u57DF",
5802
+ "\u54C1\u724C",
5803
+ "\u578B\u53F7",
5804
+ "\u578B\u865F",
5805
+ "\u5B66\u4F4D\u30D7\u30ED\u30B0\u30E9\u30E0",
5806
+ "\u5B66\u4F4D\u8BFE\u7A0B",
5807
+ "\u5B78\u4F4D\u8AB2\u7A0B",
5808
+ "\u627F\u4FDD\u7BC4\u570D",
5809
+ "\u670D\u52A1",
5810
+ "\u670D\u52D9",
5811
+ "\u6B3E\u5F0F",
5812
+ "\u7279\u8272\u9152\u5E97",
5813
+ "\u756A\u7D44",
5814
+ "\u76EE\u7684\u5730",
5815
+ "\u793E\u533A",
5816
+ "\u793E\u5340",
5817
+ "\u7BC0\u76EE",
5818
+ "\u7C7B\u578B",
5819
+ "\u7CBE\u9009\u9152\u5E97",
5820
+ "\u7CBE\u9078\u98EF\u5E97",
5821
+ "\u8282\u76EE",
5822
+ "\u8A2D\u5099",
5823
+ "\u8A2D\u65BD",
5824
+ "\u8AB2\u7A0B",
5825
+ "\u8BBE\u65BD",
5826
+ "\u8BFE\u7A0B",
5827
+ "\u9669\u79CD",
5828
+ "\u985E\u578B",
5829
+ "\uACFC\uC815",
5830
+ "\uBAA8\uB378",
5831
+ "\uBAA9\uC801\uC9C0",
5832
+ "\uBCF4\uD5D8 \uBCF4\uC0C1 \uBC94\uC704",
5833
+ "\uBE0C\uB79C\uB4DC",
5834
+ "\uC11C\uBE44\uC2A4",
5835
+ "\uC2A4\uD0C0\uC77C",
5836
+ "\uC720\uD615",
5837
+ "\uC778\uADFC \uC9C0\uC5ED",
5838
+ "\uCD94\uCC9C \uD638\uD154",
5839
+ "\uD3B8\uC758 \uC2DC\uC124",
5840
+ "\uD504\uB85C\uADF8\uB7A8",
5841
+ "\uD559\uC704 \uCDE8\uB4DD \uD504\uB85C\uADF8\uB7A8"
5842
+ ];
5843
+ var HEADER_ALIASES = /* @__PURE__ */ new Map([["service catalog", "Services"]]);
5844
+ var ACCEPTED = /* @__PURE__ */ new Set([...STRUCTURED_SNIPPET_HEADERS_EN, ...STRUCTURED_SNIPPET_HEADERS_LOCALIZED]);
5845
+ var BY_FOLDED_CASE = new Map([...ACCEPTED].map((header) => [header.toLowerCase(), header]));
5846
+ function canonicalStructuredSnippetHeader(header) {
5847
+ const trimmed = header.trim();
5848
+ if (ACCEPTED.has(trimmed)) {
5849
+ return trimmed;
5850
+ }
5851
+ const folded = trimmed.toLowerCase();
5852
+ return HEADER_ALIASES.get(folded) ?? BY_FOLDED_CASE.get(folded);
5853
+ }
5854
+
5855
+ // ../api/src/ads-google/ops.ts
5328
5856
  var tempRefSchema2 = z15.string().regex(TEMP_REF_REGEX2, "expected a g_temp_* reference");
5329
5857
  var refSchema = z15.union([
5330
5858
  z15.string().regex(RESOURCE_NAME_REGEX, "expected a customers/\u2026/\u2026/\u2026 resource name"),
@@ -5626,9 +6154,20 @@ var calloutAssetSchema = z15.object({
5626
6154
  type: z15.literal("callout"),
5627
6155
  calloutText: z15.string().min(1).max(GOOGLE_ADS_LIMITS.asset.calloutTextMax)
5628
6156
  });
6157
+ var structuredSnippetHeaderSchema = z15.string().min(1).transform((header, ctx) => {
6158
+ const canonical2 = canonicalStructuredSnippetHeader(header);
6159
+ if (!canonical2) {
6160
+ ctx.addIssue({
6161
+ code: "custom",
6162
+ message: `Google Ads does not accept "${header}" as a structured snippet header. Use one of: ${STRUCTURED_SNIPPET_HEADERS_EN.join(", ")} \u2014 or that header in the campaign's language.`
6163
+ });
6164
+ return z15.NEVER;
6165
+ }
6166
+ return canonical2;
6167
+ });
5629
6168
  var structuredSnippetAssetSchema = z15.object({
5630
6169
  type: z15.literal("structuredSnippet"),
5631
- header: z15.string().min(1).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetHeaderMax),
6170
+ header: structuredSnippetHeaderSchema,
5632
6171
  values: z15.array(z15.string().min(1)).min(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMin).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMax)
5633
6172
  });
5634
6173
  var callToActionAssetSchema = z15.object({ type: z15.literal("callToAction"), callToAction: z15.string().min(1) });
@@ -5648,7 +6187,7 @@ var assetUpdateSchema = z15.object({
5648
6187
  description2: z15.string().max(GOOGLE_ADS_LIMITS.asset.sitelinkDescriptionMax).optional(),
5649
6188
  finalUrls: z15.array(httpsUrlSchema2).min(1).optional(),
5650
6189
  calloutText: z15.string().min(1).max(GOOGLE_ADS_LIMITS.asset.calloutTextMax).optional(),
5651
- header: z15.string().min(1).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetHeaderMax).optional(),
6190
+ header: structuredSnippetHeaderSchema.optional(),
5652
6191
  values: z15.array(z15.string().min(1)).min(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMin).max(GOOGLE_ADS_LIMITS.asset.structuredSnippetValuesMax).optional(),
5653
6192
  callToAction: z15.string().min(1).optional(),
5654
6193
  text: z15.string().min(1).optional()
@@ -7751,18 +8290,18 @@ async function stageUpdate(kind, customerId, target, payload, hints) {
7751
8290
  async function stageTarget(kind, customerId, target, hints) {
7752
8291
  await stageGoogleOp({ kind, customerId, target }, hints);
7753
8292
  }
7754
- async function draftAction(path28, body) {
8293
+ async function draftAction(path28, body, chat) {
7755
8294
  try {
7756
- const chatId = requireChatId();
8295
+ const chatId = resolveChatId(chat);
7757
8296
  const response = await apiPost(path28, { chatId, ...body });
7758
8297
  writeJsonEnvelope(response);
7759
8298
  } catch (err) {
7760
8299
  handleGoogleError(err);
7761
8300
  }
7762
8301
  }
7763
- async function draftListAction(json) {
8302
+ async function draftListAction(json, chat) {
7764
8303
  try {
7765
- const chatId = requireChatId();
8304
+ const chatId = resolveChatId(chat);
7766
8305
  const response = await apiPost("/api/ads/google/draft", { chatId });
7767
8306
  if (json || !response.ok || !response.data) {
7768
8307
  writeJsonEnvelope(response);
@@ -7777,16 +8316,22 @@ async function draftListAction(json) {
7777
8316
 
7778
8317
  // src/commands/ads/google/draft.ts
7779
8318
  var draftCommand2 = defineCommand22({
7780
- meta: { name: "draft", description: "List, remove, clear, amend, or show staged Google Ads write ops for this chat" },
8319
+ meta: {
8320
+ name: "draft",
8321
+ description: "List, remove, clear, amend, or show staged Google Ads write ops for this chat. `list` and `show` take --chat <id> to read an earlier chat's changes instead."
8322
+ },
7781
8323
  subCommands: {
7782
8324
  list: defineCommand22({
7783
8325
  meta: {
7784
8326
  name: "list",
7785
8327
  description: "Review everything staged as a campaign \u25B8 ad group \u25B8 ad tree (--json for the raw envelope)"
7786
8328
  },
7787
- args: { json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable tree" } },
8329
+ args: {
8330
+ json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable tree" },
8331
+ chat: CHAT_READ_ARG
8332
+ },
7788
8333
  run: async ({ args }) => {
7789
- await draftListAction(args.json === true);
8334
+ await draftListAction(args.json === true, args.chat);
7790
8335
  }
7791
8336
  }),
7792
8337
  remove: defineCommand22({
@@ -7832,10 +8377,11 @@ var draftCommand2 = defineCommand22({
7832
8377
  type: "positional",
7833
8378
  description: "Staged op ref (g_temp_*) or target id/resource name",
7834
8379
  required: false
7835
- }
8380
+ },
8381
+ chat: CHAT_READ_ARG
7836
8382
  },
7837
8383
  run: async ({ args }) => {
7838
- await draftAction("/api/ads/google/draft/show", { ref: requireTarget(args, "op") });
8384
+ await draftAction("/api/ads/google/draft/show", { ref: requireTarget(args, "op") }, args.chat);
7839
8385
  }
7840
8386
  })
7841
8387
  }
@@ -10606,6 +11152,7 @@ function requireTargets(args, entity) {
10606
11152
  }
10607
11153
 
10608
11154
  // src/commands/ads/linkedin/schemas.ts
11155
+ var CHAT_READ_ARG_DESCRIPTION = CHAT_READ_ARG.description;
10609
11156
  registerSchema({
10610
11157
  command: "ads.linkedin.accounts",
10611
11158
  description: "List LinkedIn ad accounts in the company's connected scope. Pass --include-all to list every account the OAuth token can see.",
@@ -11304,7 +11851,8 @@ registerSchema({
11304
11851
  type: "boolean",
11305
11852
  description: "Print the raw JSON envelope instead of the readable tree",
11306
11853
  required: false
11307
- }
11854
+ },
11855
+ chat: { type: "string", description: CHAT_READ_ARG_DESCRIPTION, required: false }
11308
11856
  }
11309
11857
  });
11310
11858
  registerSchema({
@@ -11318,6 +11866,18 @@ registerSchema({
11318
11866
  }
11319
11867
  }
11320
11868
  });
11869
+ registerSchema({
11870
+ command: "ads.linkedin.draft.show",
11871
+ description: "Print the full staged payload for one LinkedIn op \u2014 the receipt to verify a change looks right before publish (never truncated), and the only way to read back verbatim what an earlier chat wrote.",
11872
+ args: {
11873
+ ref: {
11874
+ type: "positional",
11875
+ description: "Op ref (li_temp_* for creates, target id/URN for updates)",
11876
+ required: true
11877
+ },
11878
+ chat: { type: "string", description: CHAT_READ_ARG_DESCRIPTION, required: false }
11879
+ }
11880
+ });
11321
11881
  registerSchema({
11322
11882
  command: "ads.linkedin.draft.clear",
11323
11883
  description: "Discard ALL staged LinkedIn ops in this chat's draft. Nothing applies on publish.",
@@ -13508,9 +14068,9 @@ function renderDraftStatus2(data) {
13508
14068
  }
13509
14069
 
13510
14070
  // src/commands/ads/linkedin/draft.ts
13511
- async function listDraft(json) {
14071
+ async function listDraft(json, chat) {
13512
14072
  try {
13513
- const chatId = requireChatId();
14073
+ const chatId = resolveChatId(chat);
13514
14074
  const response = await apiPost("/api/ads/linkedin/draft", {
13515
14075
  chatId
13516
14076
  });
@@ -13529,9 +14089,12 @@ var listCommand3 = defineCommand45({
13529
14089
  name: "list",
13530
14090
  description: "Review everything staged as a Campaign group \u25B8 Campaign \u25B8 Creative tree (--json for the raw envelope). Example: baker ads linkedin draft"
13531
14091
  },
13532
- args: { json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable tree" } },
14092
+ args: {
14093
+ json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable tree" },
14094
+ chat: CHAT_READ_ARG
14095
+ },
13533
14096
  run: async ({ args }) => {
13534
- await listDraft(args.json === true);
14097
+ await listDraft(args.json === true, args.chat);
13535
14098
  }
13536
14099
  });
13537
14100
  var removeCommand2 = defineCommand45({
@@ -13608,12 +14171,13 @@ var showCommand = defineCommand45({
13608
14171
  description: "Print the full staged payload for one op \u2014 the receipt to verify a change looks right before publish (never truncated)."
13609
14172
  },
13610
14173
  args: {
13611
- ref: { type: "positional", description: "Staged op ref (li_temp_*) or target id/URN", required: true }
14174
+ ref: { type: "positional", description: "Staged op ref (li_temp_*) or target id/URN", required: true },
14175
+ chat: CHAT_READ_ARG
13612
14176
  },
13613
14177
  run: async ({ args }) => {
13614
14178
  const ref = requireTarget2(args, "op");
13615
14179
  try {
13616
- const chatId = requireChatId();
14180
+ const chatId = resolveChatId(args.chat);
13617
14181
  const body = { chatId, ref };
13618
14182
  const response = await apiPost(
13619
14183
  "/api/ads/linkedin/draft/show",
@@ -13628,8 +14192,11 @@ var showCommand = defineCommand45({
13628
14192
  var linkedinDraftCommand = defineCommand45({
13629
14193
  meta: {
13630
14194
  name: "draft",
13631
- description: "Review and edit the LinkedIn write ops staged in this chat BEFORE publish. Subcommands: list (default), remove, clear, amend, show. Ops never hit LinkedIn until the chat is published."
14195
+ description: "Review and edit the LinkedIn write ops staged in this chat BEFORE publish. Subcommands: list (default), remove, clear, amend, show. Ops never hit LinkedIn until the chat is published. `list` and `show` take --chat <id> to read an earlier chat's changes instead."
13632
14196
  },
14197
+ // Declared on the parent too: `default: "list"` dispatches the bare `draft --chat <id>` form, and
14198
+ // citty prints help for a flag the parent does not know instead of forwarding it.
14199
+ args: { chat: CHAT_READ_ARG },
13633
14200
  subCommands: {
13634
14201
  list: listCommand3,
13635
14202
  remove: removeCommand2,
@@ -15011,6 +15578,17 @@ var metaDraftListResponseSchema = z19.object({
15011
15578
  /** Non-blocking cross-op quality advisories — "good campaign, not just valid". */
15012
15579
  advisories: z19.array(metaDraftAdvisorySchema)
15013
15580
  });
15581
+ var metaDraftShowRequestSchema = z19.object({
15582
+ chatId: z19.string(),
15583
+ ref: z19.string()
15584
+ });
15585
+ var metaDraftShowResponseSchema = z19.object({
15586
+ op: metaDraftOpViewSchema.extend({
15587
+ payload: z19.unknown().optional(),
15588
+ warnings: z19.array(z19.string()).optional(),
15589
+ annotations: z19.unknown().optional()
15590
+ })
15591
+ });
15014
15592
  var metaDraftRemoveRequestSchema = z19.object({
15015
15593
  chatId: z19.string(),
15016
15594
  ref: z19.string()
@@ -15598,10 +16176,10 @@ function duplicateCommand2(entity, label) {
15598
16176
  replace: { type: "boolean", description: "Pause the original once the copy publishes" }
15599
16177
  },
15600
16178
  run: async ({ args }) => {
15601
- const { apiPost: apiPost2 } = await import("./client-XRQWOADV.js");
15602
- const { requireChatId: requireChatId2 } = await import("./env-3JMYIH25.js");
15603
- const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-FL7WRIJF.js");
15604
- const { handleMetaError: handleMetaError2 } = await import("./shared-OIYLDW3G.js");
16179
+ const { apiPost: apiPost2 } = await import("./client-PJ7ID35L.js");
16180
+ const { requireChatId: requireChatId2 } = await import("./env-6QJCMTRK.js");
16181
+ const { writeJsonEnvelope: writeJsonEnvelope2 } = await import("./output-NWX3YW64.js");
16182
+ const { handleMetaError: handleMetaError2 } = await import("./shared-5ZEOG664.js");
15605
16183
  try {
15606
16184
  const accountId = bareAccountId2(args);
15607
16185
  const chatId = requireChatId2();
@@ -15990,9 +16568,9 @@ Examples:
15990
16568
 
15991
16569
  // src/commands/ads/meta/draft.ts
15992
16570
  import { defineCommand as defineCommand62 } from "citty";
15993
- async function listDraft2() {
16571
+ async function listDraft2(chat) {
15994
16572
  try {
15995
- const chatId = requireChatId();
16573
+ const chatId = resolveChatId(chat);
15996
16574
  const response = await apiPost("/api/ads/meta/draft", { chatId });
15997
16575
  writeJsonEnvelope(response);
15998
16576
  } catch (err) {
@@ -16004,7 +16582,32 @@ var listCommand9 = defineCommand62({
16004
16582
  name: "list",
16005
16583
  description: "Show every Meta write op staged in this chat, its mode (simulated = publish will NOT hit Meta), dependencies, and post-publish results. Example: baker ads meta draft"
16006
16584
  },
16007
- run: listDraft2
16585
+ args: { chat: CHAT_READ_ARG },
16586
+ run: async ({ args }) => {
16587
+ await listDraft2(args.chat);
16588
+ }
16589
+ });
16590
+ var showCommand2 = defineCommand62({
16591
+ meta: {
16592
+ name: "show",
16593
+ description: "Print the full staged payload for one op \u2014 the receipt to verify a change looks right before publish (never truncated). Example: baker ads meta draft show meta_temp_abc123"
16594
+ },
16595
+ args: {
16596
+ ref: { type: "positional", description: "Op ref (meta_temp_* for creates, target id for updates)", required: true },
16597
+ chat: CHAT_READ_ARG
16598
+ },
16599
+ run: async ({ args }) => {
16600
+ try {
16601
+ const chatId = resolveChatId(args.chat);
16602
+ const response = await apiPost("/api/ads/meta/draft/show", {
16603
+ chatId,
16604
+ ref: args.ref
16605
+ });
16606
+ writeJsonEnvelope(response);
16607
+ } catch (err) {
16608
+ handleMetaError(err);
16609
+ }
16610
+ }
16008
16611
  });
16009
16612
  var removeCommand3 = defineCommand62({
16010
16613
  meta: {
@@ -16047,9 +16650,12 @@ var clearCommand3 = defineCommand62({
16047
16650
  var metaDraftCommand = defineCommand62({
16048
16651
  meta: {
16049
16652
  name: "draft",
16050
- description: "Review and edit the Meta write ops staged in this chat BEFORE publish. Subcommands: list (default), remove, clear. Ops never hit Meta until the chat is published."
16653
+ description: "Review and edit the Meta write ops staged in this chat BEFORE publish. Subcommands: list (default), show, remove, clear. Ops never hit Meta until the chat is published. `list` and `show` take --chat <id> to read an earlier chat's changes instead."
16051
16654
  },
16052
- subCommands: { list: listCommand9, remove: removeCommand3, clear: clearCommand3 },
16655
+ // Declared on the parent too: `default: "list"` dispatches the bare `draft --chat <id>` form, and
16656
+ // citty prints help for a flag the parent does not know instead of forwarding it.
16657
+ args: { chat: CHAT_READ_ARG },
16658
+ subCommands: { list: listCommand9, show: showCommand2, remove: removeCommand3, clear: clearCommand3 },
16053
16659
  // `default` (not `run`) dispatches the bare invocation: citty falls through to `run`
16054
16660
  // after dispatching a subcommand, so a `run` here would list the draft a second time
16055
16661
  // on every `draft list` / `draft remove` / `draft clear`.
@@ -25931,7 +26537,7 @@ var listCommand11 = defineCommand104({
25931
26537
  writeJson({ ok: true, data: { flows } });
25932
26538
  }
25933
26539
  });
25934
- var showCommand2 = defineCommand104({
26540
+ var showCommand3 = defineCommand104({
25935
26541
  meta: {
25936
26542
  name: "show",
25937
26543
  description: "Show a Form's confidential fields and their configuration status (never secret values). Example: baker flows show contact"
@@ -25967,7 +26573,7 @@ Full guide: __tooling__/docs/tools/baker/flows.md`
25967
26573
  },
25968
26574
  subCommands: {
25969
26575
  list: listCommand11,
25970
- show: showCommand2
26576
+ show: showCommand3
25971
26577
  },
25972
26578
  // Bare `baker flows` lists the Forms. This must be `default`, not `run`: citty falls
25973
26579
  // through to `run` after dispatching a subcommand, so a `run` here would also print
@@ -25976,7 +26582,7 @@ Full guide: __tooling__/docs/tools/baker/flows.md`
25976
26582
  });
25977
26583
 
25978
26584
  // src/commands/ga4/index.ts
25979
- import { defineCommand as defineCommand108 } from "citty";
26585
+ import { defineCommand as defineCommand111 } from "citty";
25980
26586
 
25981
26587
  // src/commands/ga4/audit.ts
25982
26588
  import { defineCommand as defineCommand105 } from "citty";
@@ -26099,8 +26705,306 @@ Examples:
26099
26705
  }
26100
26706
  });
26101
26707
 
26102
- // src/commands/ga4/properties.ts
26708
+ // src/commands/ga4/config.ts
26103
26709
  import { defineCommand as defineCommand106 } from "citty";
26710
+
26711
+ // src/commands/ga4/shared.ts
26712
+ import { readFileSync as readFileSync10 } from "fs";
26713
+ function failValidation2(message) {
26714
+ writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
26715
+ process.exit(1);
26716
+ }
26717
+ function requireTarget4(args, entity) {
26718
+ const positional = Array.isArray(args._) ? args._[0] : void 0;
26719
+ const target = args.id ?? args.target ?? positional;
26720
+ if (typeof target !== "string" || target.length === 0) {
26721
+ failValidation2(`pass the ${entity} id as the positional argument`);
26722
+ }
26723
+ return target;
26724
+ }
26725
+ function readJsonSource(args, flag) {
26726
+ const inline = args[flag];
26727
+ const file = args.file;
26728
+ const raw = typeof file === "string" && file.length > 0 ? readFileSync10(file, "utf8") : typeof inline === "string" && inline.length > 0 ? inline : void 0;
26729
+ if (raw === void 0) {
26730
+ failValidation2(`pass --${flag} with inline JSON or --file with a path to a JSON file`);
26731
+ }
26732
+ try {
26733
+ return JSON.parse(raw);
26734
+ } catch {
26735
+ return failValidation2(`--${flag} is not valid JSON`);
26736
+ }
26737
+ }
26738
+ function asObject(value, flag, index) {
26739
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
26740
+ failValidation2(
26741
+ index === void 0 ? `--${flag} must be a JSON object` : `--${flag}[${index}] must be a JSON object`
26742
+ );
26743
+ }
26744
+ return value;
26745
+ }
26746
+ function loadJsonArg(args, flag = "json") {
26747
+ return asObject(readJsonSource(args, flag), flag);
26748
+ }
26749
+ function loadJsonPayloads(args) {
26750
+ const parsed = readJsonSource(args, "json");
26751
+ if (!Array.isArray(parsed)) {
26752
+ return [asObject(parsed, "json")];
26753
+ }
26754
+ if (parsed.length === 0) {
26755
+ failValidation2("--json is an empty list \u2014 pass at least one definition");
26756
+ }
26757
+ return parsed.map((entry, index) => asObject(entry, "json", index));
26758
+ }
26759
+ var RETRYABLE_CODES = /* @__PURE__ */ new Set(["RATE_LIMITED", "INTERNAL_ERROR", "NETWORK_ERROR", "TIMEOUT"]);
26760
+ function handleError(err) {
26761
+ if (err instanceof ApiError) {
26762
+ const readOnly = err.code === "FORBIDDEN" && /read the property but not change it/i.test(err.message);
26763
+ writeJsonEnvelope({
26764
+ ok: false,
26765
+ error: {
26766
+ code: err.code,
26767
+ message: err.message,
26768
+ ...readOnly ? {
26769
+ fix: {
26770
+ action: "reconnect",
26771
+ explanation: "The Google Analytics connection is read-only. Ask the user to reconnect Google Analytics \u2014 in the dashboard, Brain \u2192 Integrations \u2192 Tools \u2192 Google Analytics \u2014 which grants the permission to change the property. Reporting (`baker ga4 query`, `baker ga4 audit`) keeps working meanwhile, so carry on with the rest of the job and tell them what you will set up once they have reconnected. Do NOT claim anything was configured."
26772
+ }
26773
+ } : err.code === "UNAUTHORIZED" || err.code === "FORBIDDEN" && isNotConnectedError(err.code, err.message) ? {
26774
+ fix: {
26775
+ action: "request_connection",
26776
+ explanation: 'Google Analytics is not connected for this company yet, or no property has been picked. Do NOT send the user to Settings \u2014 call the `request_connection` tool with { platform: "google-analytics", reason } and they connect and pick their property from inside the chat. If `request_connection` is not available to you, say so plainly and point them at dashboard \u2192 Brain \u2192 Integrations \u2192 Tools \u2192 Google Analytics. Carry on with the rest of the task meanwhile.'
26777
+ }
26778
+ } : {},
26779
+ retryable: RETRYABLE_CODES.has(err.code)
26780
+ }
26781
+ });
26782
+ process.exit(1);
26783
+ }
26784
+ writeJsonEnvelope({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error", retryable: true } });
26785
+ process.exit(1);
26786
+ }
26787
+ var STAGE_HINTS = [
26788
+ "Staged only \u2014 nothing has changed in Google Analytics yet. These apply when the chat completes, and an applied change takes effect on the property immediately: there is no version to publish afterwards and no undo. Say the changes are ready and take effect when the user completes the chat \u2014 not that they are done already."
26789
+ ];
26790
+ var WARNING_HINT = "Read the warnings above before telling the user this is ready.";
26791
+ async function stageOp3(op) {
26792
+ const chatId = requireChatId();
26793
+ try {
26794
+ const data = await apiPost("/api/ga4/draft/stage", { chatId, op });
26795
+ writeJsonEnvelope({
26796
+ ok: true,
26797
+ data,
26798
+ hints: [...STAGE_HINTS, ...data.warnings.length > 0 ? [WARNING_HINT] : []]
26799
+ });
26800
+ } catch (err) {
26801
+ handleError(err);
26802
+ }
26803
+ }
26804
+ async function stageOps(ops) {
26805
+ const [only] = ops;
26806
+ if (ops.length === 1 && only) {
26807
+ await stageOp3(only);
26808
+ return;
26809
+ }
26810
+ const chatId = requireChatId();
26811
+ try {
26812
+ const data = await apiPost("/api/ga4/draft/stage-batch", { chatId, ops });
26813
+ writeJsonEnvelope({
26814
+ ok: true,
26815
+ data,
26816
+ hints: [...STAGE_HINTS, ...data.ops.some((op) => op.warnings.length > 0) ? [WARNING_HINT] : []]
26817
+ });
26818
+ } catch (err) {
26819
+ handleError(err);
26820
+ }
26821
+ }
26822
+ async function draftAction2(path28, body, chat) {
26823
+ const chatId = resolveChatId(chat);
26824
+ try {
26825
+ const data = await apiPost(path28, { chatId, ...body });
26826
+ writeJsonEnvelope({ ok: true, data });
26827
+ return data;
26828
+ } catch (err) {
26829
+ handleError(err);
26830
+ }
26831
+ }
26832
+ function renderDraft(response) {
26833
+ if (response.count === 0) {
26834
+ return "No Google Analytics changes staged on this chat.";
26835
+ }
26836
+ const lines = [
26837
+ `${response.count} staged Google Analytics change(s)`,
26838
+ ...response.ops.map((op) => {
26839
+ const status = op.result ? ` [${op.result.status}]` : "";
26840
+ return ` ${op.ref} ${op.summary}${status}`;
26841
+ })
26842
+ ];
26843
+ if (response.status === "applied") {
26844
+ const failed = response.ops.filter((op) => op.result?.status !== "applied");
26845
+ lines.push(
26846
+ "",
26847
+ failed.length === 0 ? "All applied \u2014 these are in effect on the property now." : `${failed.length} of ${response.count} did not apply. The rest are in effect on the property.`
26848
+ );
26849
+ }
26850
+ if (response.publishError) {
26851
+ lines.push("", response.publishError);
26852
+ }
26853
+ return lines.join("\n");
26854
+ }
26855
+ async function draftList(json, chat) {
26856
+ const chatId = resolveChatId(chat);
26857
+ try {
26858
+ const data = await apiPost("/api/ga4/draft", { chatId });
26859
+ if (json) {
26860
+ writeJsonEnvelope({ ok: true, data });
26861
+ return;
26862
+ }
26863
+ process.stdout.write(`${renderDraft(data)}
26864
+ `);
26865
+ } catch (err) {
26866
+ handleError(err);
26867
+ }
26868
+ }
26869
+
26870
+ // src/commands/ga4/config.ts
26871
+ registerSchema({
26872
+ command: "ga4.config",
26873
+ description: "Read how a Google Analytics property is configured to measure: key events (conversions), custom dimensions and metrics, custom events, data streams and the data retention window. Start here before staging any change \u2014 every id an update or removal targets comes from this, and `canWrite` says whether this connection may change anything at all. Compact by default; pass --full for the raw Analytics objects.",
26874
+ args: {
26875
+ "property-id": { type: "string", description: "GA4 property id (optional when one is connected)", required: false },
26876
+ full: { type: "boolean", description: "Include the raw Analytics object for each entity", required: false }
26877
+ }
26878
+ });
26879
+ function configHints(config) {
26880
+ const hints = [];
26881
+ if (!config.canWrite) {
26882
+ hints.push(
26883
+ "This connection can READ this property but not change it. Do not promise to configure anything \u2014 ask the user to reconnect Google Analytics in the dashboard first, and carry on with the reporting side of the job."
26884
+ );
26885
+ }
26886
+ if (config.keyEvents.length === 0) {
26887
+ hints.push(
26888
+ "This property has no key events, so nothing is being counted as a conversion and Google Ads has nothing to import. Ask what counts as a lead or sale before proposing anything else."
26889
+ );
26890
+ }
26891
+ if (config.dataRetention.eventDataRetention === "TWO_MONTHS") {
26892
+ hints.push(
26893
+ "Event data is only kept for 2 months, which makes any long-window analysis impossible. `baker ga4 data-retention set --event-data 14` stages the fix."
26894
+ );
26895
+ }
26896
+ if (config.dataStreams.filter((stream) => stream.type === "WEB_DATA_STREAM").length > 1) {
26897
+ hints.push("This property has more than one website data stream \u2014 pass --data-stream when staging a custom event.");
26898
+ }
26899
+ return hints;
26900
+ }
26901
+ var configCommand = defineCommand106({
26902
+ meta: {
26903
+ name: "config",
26904
+ description: `Read how the property is configured to measure \u2014 key events, custom definitions, custom events, retention
26905
+
26906
+ Examples:
26907
+ baker ga4 config
26908
+ baker ga4 config --property-id 123456789
26909
+ baker ga4 config --full`
26910
+ },
26911
+ args: {
26912
+ "property-id": { type: "string", description: "GA4 property id", required: false },
26913
+ full: { type: "boolean", description: "Include raw Analytics objects", required: false }
26914
+ },
26915
+ run: async ({ args }) => {
26916
+ try {
26917
+ const data = await apiPost("/api/ga4/config", {
26918
+ ...typeof args["property-id"] === "string" ? { propertyId: args["property-id"] } : {},
26919
+ ...args.full === true ? { full: true } : {}
26920
+ });
26921
+ writeJsonEnvelope({ ok: true, data, hints: configHints(data) });
26922
+ } catch (err) {
26923
+ handleError(err);
26924
+ }
26925
+ }
26926
+ });
26927
+
26928
+ // src/commands/ga4/draft.ts
26929
+ import { defineCommand as defineCommand107 } from "citty";
26930
+ registerSchema({
26931
+ command: "ga4.draft",
26932
+ description: "Review and undo the Google Analytics changes staged on this chat. Use `list` to see everything staged, `show` to inspect one change in full before the chat completes, `amend` to correct one in place, and `remove`/`clear` to drop them. `list` and `show` take --chat <id> to read an earlier chat's changes instead.",
26933
+ args: {
26934
+ json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list", required: false },
26935
+ chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
26936
+ }
26937
+ });
26938
+ var draftCommand3 = defineCommand107({
26939
+ meta: {
26940
+ name: "draft",
26941
+ description: "List, show, amend, remove or clear the Google Analytics changes staged on this chat. `list` and `show` take --chat <id> to read an earlier chat's changes instead."
26942
+ },
26943
+ subCommands: {
26944
+ list: defineCommand107({
26945
+ meta: { name: "list", description: "Review everything staged on this chat (--json for the raw envelope)" },
26946
+ args: {
26947
+ json: { type: "boolean", description: "Print the raw JSON envelope", required: false },
26948
+ chat: CHAT_READ_ARG
26949
+ },
26950
+ run: async ({ args }) => {
26951
+ await draftList(args.json === true, args.chat);
26952
+ }
26953
+ }),
26954
+ show: defineCommand107({
26955
+ meta: {
26956
+ name: "show",
26957
+ description: "Print the full staged payload for one change, alongside how the property looks today \u2014 the receipt to verify it before the chat completes (never truncated)."
26958
+ },
26959
+ args: {
26960
+ ref: { type: "positional", description: "Staged ref or target id", required: false },
26961
+ chat: CHAT_READ_ARG
26962
+ },
26963
+ run: async ({ args }) => {
26964
+ await draftAction2(
26965
+ "/api/ga4/draft/show",
26966
+ { ref: requireTarget4(args, "change") },
26967
+ args.chat
26968
+ );
26969
+ }
26970
+ }),
26971
+ amend: defineCommand107({
26972
+ meta: {
26973
+ name: "amend",
26974
+ description: "Update a staged change in place \u2014 merges a JSON patch into its payload (objects deep-merge, null deletes a key, arrays/scalars replace) and re-runs every check. Use this instead of remove + re-create."
26975
+ },
26976
+ args: {
26977
+ ref: { type: "positional", description: "Staged ref or target id", required: false },
26978
+ patch: { type: "string", description: "Inline JSON patch object", required: false },
26979
+ file: { type: "string", description: "JSON file with the patch object", required: false }
26980
+ },
26981
+ run: async ({ args }) => {
26982
+ await draftAction2("/api/ga4/draft/amend", {
26983
+ ref: requireTarget4(args, "change"),
26984
+ patch: loadJsonArg(args, "patch")
26985
+ });
26986
+ }
26987
+ }),
26988
+ remove: defineCommand107({
26989
+ meta: { name: "remove", description: "Remove one staged change" },
26990
+ args: { ref: { type: "positional", description: "Staged ref or target id", required: false } },
26991
+ run: async ({ args }) => {
26992
+ await draftAction2("/api/ga4/draft/remove", {
26993
+ ref: requireTarget4(args, "change")
26994
+ });
26995
+ }
26996
+ }),
26997
+ clear: defineCommand107({
26998
+ meta: { name: "clear", description: "Discard all Google Analytics changes staged on this chat" },
26999
+ run: async () => {
27000
+ await draftAction2("/api/ga4/draft/clear", {});
27001
+ }
27002
+ })
27003
+ }
27004
+ });
27005
+
27006
+ // src/commands/ga4/properties.ts
27007
+ import { defineCommand as defineCommand108 } from "citty";
26104
27008
  registerSchema({
26105
27009
  command: "ga4.properties",
26106
27010
  description: "List the GA4 properties this company connected \u2014 there can be several, and every one of them is yours to query. Returns the property IDs the query and audit commands take. Run this first to find property IDs.",
@@ -26116,7 +27020,7 @@ function propertyHints(properties) {
26116
27020
  resources: properties.map((property) => ({ id: property.externalId, label: property.name }))
26117
27021
  });
26118
27022
  }
26119
- var propertiesCommand = defineCommand106({
27023
+ var propertiesCommand = defineCommand108({
26120
27024
  meta: {
26121
27025
  name: "properties",
26122
27026
  description: `List accessible GA4 properties.
@@ -26164,9 +27068,9 @@ Examples:
26164
27068
  });
26165
27069
 
26166
27070
  // src/commands/ga4/query.ts
26167
- import { appendFileSync as appendFileSync2, existsSync as existsSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync3 } from "fs";
27071
+ import { appendFileSync as appendFileSync2, existsSync as existsSync5, readFileSync as readFileSync11, writeFileSync as writeFileSync3 } from "fs";
26168
27072
  import { resolve as resolve2 } from "path";
26169
- import { defineCommand as defineCommand107 } from "citty";
27073
+ import { defineCommand as defineCommand109 } from "citty";
26170
27074
 
26171
27075
  // src/commands/ga4/presets.ts
26172
27076
  var GA4_PRESETS = [
@@ -26255,7 +27159,7 @@ function writeRowsToFile2(filePath, rows, append) {
26255
27159
  writeFileSync3(filePath, content, "utf-8");
26256
27160
  }
26257
27161
  } else if (append && existsSync5(filePath)) {
26258
- const existing = JSON.parse(readFileSync10(filePath, "utf-8"));
27162
+ const existing = JSON.parse(readFileSync11(filePath, "utf-8"));
26259
27163
  writeFileSync3(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
26260
27164
  } else {
26261
27165
  writeFileSync3(filePath, JSON.stringify(rows, null, 2), "utf-8");
@@ -26287,7 +27191,7 @@ function buildRequestBody(args, propertyId, useCache) {
26287
27191
  if (!useCache) body.skipCache = true;
26288
27192
  return body;
26289
27193
  }
26290
- function handleError(err) {
27194
+ function handleError2(err) {
26291
27195
  if (err instanceof ApiError) {
26292
27196
  if (isNotConnectedError(err.code, err.message)) {
26293
27197
  handleConnectionError("ga4", err.message);
@@ -26301,7 +27205,7 @@ function handleError(err) {
26301
27205
  });
26302
27206
  process.exit(1);
26303
27207
  }
26304
- var queryCommand2 = defineCommand107({
27208
+ var queryCommand2 = defineCommand109({
26305
27209
  meta: {
26306
27210
  name: "query",
26307
27211
  description: `Run GA4 Data API reports. Preset-first with free-form escape hatch.
@@ -26366,42 +27270,421 @@ Free-form (escape hatch):
26366
27270
  }
26367
27271
  outputRows(response.data ?? [], args, response, false);
26368
27272
  } catch (err) {
26369
- handleError(err);
27273
+ handleError2(err);
27274
+ }
27275
+ }
27276
+ });
27277
+
27278
+ // src/commands/ga4/write-commands.ts
27279
+ import { defineCommand as defineCommand110 } from "citty";
27280
+ var PROPERTY_ARG_DESCRIPTION = "GA4 property id (optional only when one property is connected \u2014 run `baker ga4 properties`)";
27281
+ var propertyArg = { type: "string", description: PROPERTY_ARG_DESCRIPTION, required: false };
27282
+ function createJsonDescription(noun) {
27283
+ return `Inline JSON ${noun} definition, or a JSON array of them to stage several in one call (all or none)`;
27284
+ }
27285
+ function withProperty(args) {
27286
+ return typeof args["property-id"] === "string" ? { propertyId: args["property-id"] } : {};
27287
+ }
27288
+ registerSchema({
27289
+ command: "ga4.keyEvent",
27290
+ description: "Mark an event as a key event (what Google Analytics calls a conversion, and what Google Ads imports for bidding), change how it is counted, or stop counting it. Read `baker ga4 config` first: the event has to be one the site actually sends, and marking an automatic event like page_view poisons Smart Bidding.",
27291
+ args: {
27292
+ json: { type: "string", description: createJsonDescription("key-event"), required: false },
27293
+ file: { type: "string", description: "Path to a JSON file with the definition", required: false },
27294
+ "property-id": { type: "string", description: PROPERTY_ARG_DESCRIPTION, required: false }
27295
+ }
27296
+ });
27297
+ var keyEventCommand = defineCommand110({
27298
+ meta: {
27299
+ name: "key-event",
27300
+ description: `Stage key-event (conversion) changes
27301
+
27302
+ Examples:
27303
+ baker ga4 key-event create --json '{"eventName":"generate_lead","countingMethod":"ONCE_PER_EVENT"}'
27304
+ baker ga4 key-event create --json '{"eventName":"purchase","countingMethod":"ONCE_PER_EVENT","defaultValue":{"numericValue":50,"currencyCode":"EUR"}}'
27305
+ baker ga4 key-event create --json '[{\u2026}, {\u2026}]' \u2014 several in one call, one read of the property
27306
+ baker ga4 key-event update 4185 --json '{"countingMethod":"ONCE_PER_SESSION"}'
27307
+ baker ga4 key-event delete 4185`
27308
+ },
27309
+ subCommands: {
27310
+ create: defineCommand110({
27311
+ meta: {
27312
+ name: "create",
27313
+ description: "Stage a new key event. Needs eventName and countingMethod (ONCE_PER_EVENT or ONCE_PER_SESSION); defaultValue sets a monetary value when the event does not send one."
27314
+ },
27315
+ args: {
27316
+ json: { type: "string", description: createJsonDescription("key-event"), required: false },
27317
+ file: { type: "string", description: "Path to a JSON file", required: false },
27318
+ "property-id": propertyArg
27319
+ },
27320
+ run: async ({ args }) => {
27321
+ const input = args;
27322
+ await stageOps(
27323
+ loadJsonPayloads(input).map((payload) => ({
27324
+ kind: "ga4.keyEvent.create",
27325
+ payload,
27326
+ ...withProperty(input)
27327
+ }))
27328
+ );
27329
+ }
27330
+ }),
27331
+ update: defineCommand110({
27332
+ meta: {
27333
+ name: "update",
27334
+ description: "Stage a change to an existing key event (pass its id). Only countingMethod and defaultValue can change \u2014 Google will not rename a key event."
27335
+ },
27336
+ args: {
27337
+ id: { type: "positional", description: "Key event id", required: false },
27338
+ json: { type: "string", description: "Inline JSON with the changed fields", required: false },
27339
+ file: { type: "string", description: "Path to a JSON file", required: false },
27340
+ "property-id": propertyArg
27341
+ },
27342
+ run: async ({ args }) => {
27343
+ await stageOp3({
27344
+ kind: "ga4.keyEvent.update",
27345
+ target: requireTarget4(args, "key event"),
27346
+ payload: loadJsonArg(args),
27347
+ ...withProperty(args)
27348
+ });
27349
+ }
27350
+ }),
27351
+ delete: defineCommand110({
27352
+ meta: {
27353
+ name: "delete",
27354
+ description: "Stage removing a key event, so the event stops counting as a conversion. The event itself keeps being collected. Irreversible once the chat completes \u2014 confirm with the user first."
27355
+ },
27356
+ args: {
27357
+ id: { type: "positional", description: "Key event id", required: false },
27358
+ "property-id": propertyArg
27359
+ },
27360
+ run: async ({ args }) => {
27361
+ await stageOp3({
27362
+ kind: "ga4.keyEvent.delete",
27363
+ target: requireTarget4(args, "key event"),
27364
+ ...withProperty(args)
27365
+ });
27366
+ }
27367
+ })
27368
+ }
27369
+ });
27370
+ var DEFINITIONS = [
27371
+ {
27372
+ command: "custom-dimension",
27373
+ kind: "customDimension",
27374
+ noun: "custom dimension",
27375
+ createHint: "Needs parameterName (the event parameter the site sends), displayName, and scope (EVENT, USER or ITEM). Until a parameter has a custom dimension, it is collected but cannot be reported on.",
27376
+ example: '{"parameterName":"plan_tier","displayName":"Plan tier","scope":"EVENT"}'
27377
+ },
27378
+ {
27379
+ command: "custom-metric",
27380
+ kind: "customMetric",
27381
+ noun: "custom metric",
27382
+ createHint: "Needs parameterName, displayName, scope EVENT and measurementUnit (STANDARD, CURRENCY, SECONDS\u2026). A CURRENCY metric must also declare restrictedMetricType: COST_DATA or REVENUE_DATA.",
27383
+ example: '{"parameterName":"deal_value","displayName":"Deal value","scope":"EVENT","measurementUnit":"CURRENCY","restrictedMetricType":["REVENUE_DATA"]}'
27384
+ }
27385
+ ];
27386
+ for (const { kind, noun, createHint } of DEFINITIONS) {
27387
+ registerSchema({
27388
+ command: `ga4.${kind}`,
27389
+ description: `Create, update or archive a Google Analytics ${noun}. ${createHint} Archiving frees the slot and takes it out of reporting; historical data stays. Read \`baker ga4 config\` first \u2014 a duplicate parameter name is refused.`,
27390
+ args: {
27391
+ json: { type: "string", description: createJsonDescription(noun), required: false },
27392
+ file: { type: "string", description: "Path to a JSON file", required: false },
27393
+ "property-id": { type: "string", description: PROPERTY_ARG_DESCRIPTION, required: false }
27394
+ }
27395
+ });
27396
+ }
27397
+ function definitionCommand(definition) {
27398
+ const { command, kind, noun, example } = definition;
27399
+ return defineCommand110({
27400
+ meta: {
27401
+ name: command,
27402
+ description: `Stage ${noun} changes
27403
+
27404
+ Examples:
27405
+ baker ga4 ${command} create --json '${example}'
27406
+ baker ga4 ${command} create --json '[${example}, \u2026]' \u2014 several in one call, one read of the property
27407
+ baker ga4 ${command} update 12 --json '{"displayName":"Renamed"}'
27408
+ baker ga4 ${command} archive 12`
27409
+ },
27410
+ subCommands: {
27411
+ create: defineCommand110({
27412
+ meta: { name: "create", description: `Stage a new ${noun} (or a JSON array of them, staged together)` },
27413
+ args: {
27414
+ json: { type: "string", description: createJsonDescription(noun), required: false },
27415
+ file: { type: "string", description: "Path to a JSON file", required: false },
27416
+ "property-id": propertyArg
27417
+ },
27418
+ run: async ({ args }) => {
27419
+ const input = args;
27420
+ await stageOps(
27421
+ loadJsonPayloads(input).map((payload) => ({
27422
+ kind: `ga4.${kind}.create`,
27423
+ payload,
27424
+ ...withProperty(input)
27425
+ }))
27426
+ );
27427
+ }
27428
+ }),
27429
+ update: defineCommand110({
27430
+ meta: {
27431
+ name: "update",
27432
+ description: `Stage a change to an existing ${noun} (pass its id). The parameter name and scope cannot change \u2014 archive and recreate for that.`
27433
+ },
27434
+ args: {
27435
+ id: { type: "positional", description: `${noun} id`, required: false },
27436
+ json: { type: "string", description: "Inline JSON with the changed fields", required: false },
27437
+ file: { type: "string", description: "Path to a JSON file", required: false },
27438
+ "property-id": propertyArg
27439
+ },
27440
+ run: async ({ args }) => {
27441
+ await stageOp3({
27442
+ kind: `ga4.${kind}.update`,
27443
+ target: requireTarget4(args, noun),
27444
+ payload: loadJsonArg(args),
27445
+ ...withProperty(args)
27446
+ });
27447
+ }
27448
+ }),
27449
+ archive: defineCommand110({
27450
+ meta: {
27451
+ name: "archive",
27452
+ description: `Stage archiving a ${noun} (pass its id). It stops collecting and leaves reporting; past data stays. Irreversible once the chat completes \u2014 confirm with the user first.`
27453
+ },
27454
+ args: {
27455
+ id: { type: "positional", description: `${noun} id`, required: false },
27456
+ "property-id": propertyArg
27457
+ },
27458
+ run: async ({ args }) => {
27459
+ await stageOp3({
27460
+ kind: `ga4.${kind}.archive`,
27461
+ target: requireTarget4(args, noun),
27462
+ ...withProperty(args)
27463
+ });
27464
+ }
27465
+ })
26370
27466
  }
27467
+ });
27468
+ }
27469
+ var customDimensionCommand = definitionCommand(DEFINITIONS[0]);
27470
+ var customMetricCommand = definitionCommand(DEFINITIONS[1]);
27471
+ registerSchema({
27472
+ command: "ga4.customEvent",
27473
+ description: "Create a new Google Analytics event out of one the site already sends \u2014 the 'Create event' rule in the Analytics interface. Use it to turn a generic event into a meaningful one (a form_submit on the quote page becomes quote_request) so it can be marked a key event. Needs destinationEvent and 1-10 eventConditions; sourceCopyParameters carries the original parameters over.",
27474
+ args: {
27475
+ json: { type: "string", description: createJsonDescription("custom-event rule"), required: false },
27476
+ file: { type: "string", description: "Path to a JSON file", required: false },
27477
+ "data-stream": {
27478
+ type: "string",
27479
+ description: "Data stream id (optional when the property has one website stream)",
27480
+ required: false
27481
+ },
27482
+ "property-id": { type: "string", description: PROPERTY_ARG_DESCRIPTION, required: false }
27483
+ }
27484
+ });
27485
+ var CUSTOM_EVENT_EXAMPLE = '{"destinationEvent":"quote_request","eventConditions":[{"field":"event_name","comparisonType":"EQUALS","value":"form_submit"},{"field":"page_location","comparisonType":"CONTAINS","value":"/quote"}],"sourceCopyParameters":true}';
27486
+ var dataStreamArg = {
27487
+ type: "string",
27488
+ description: "Data stream id (optional when the property has one website stream)",
27489
+ required: false
27490
+ };
27491
+ function withStream(args) {
27492
+ return typeof args["data-stream"] === "string" ? { dataStream: args["data-stream"] } : {};
27493
+ }
27494
+ var customEventCommand = defineCommand110({
27495
+ meta: {
27496
+ name: "custom-event",
27497
+ description: `Stage custom events \u2014 new events built from events the site already sends
27498
+
27499
+ Examples:
27500
+ baker ga4 custom-event create --json '${CUSTOM_EVENT_EXAMPLE}'
27501
+ baker ga4 custom-event update 7 --json '{"sourceCopyParameters":false}'
27502
+ baker ga4 custom-event delete 7`
27503
+ },
27504
+ subCommands: {
27505
+ create: defineCommand110({
27506
+ meta: {
27507
+ name: "create",
27508
+ description: "Stage a new custom event. Conditions match the source event: use field `event_name` to match the event itself, or any parameter name to match its value."
27509
+ },
27510
+ args: {
27511
+ json: { type: "string", description: createJsonDescription("custom event"), required: false },
27512
+ file: { type: "string", description: "Path to a JSON file", required: false },
27513
+ "data-stream": dataStreamArg,
27514
+ "property-id": propertyArg
27515
+ },
27516
+ run: async ({ args }) => {
27517
+ const input = args;
27518
+ await stageOps(
27519
+ loadJsonPayloads(input).map((payload) => ({
27520
+ kind: "ga4.eventCreateRule.create",
27521
+ payload,
27522
+ ...withStream(input),
27523
+ ...withProperty(input)
27524
+ }))
27525
+ );
27526
+ }
27527
+ }),
27528
+ update: defineCommand110({
27529
+ meta: { name: "update", description: "Stage a change to an existing custom event (pass its id)" },
27530
+ args: {
27531
+ id: { type: "positional", description: "Custom event rule id", required: false },
27532
+ json: { type: "string", description: "Inline JSON with the changed fields", required: false },
27533
+ file: { type: "string", description: "Path to a JSON file", required: false },
27534
+ "data-stream": dataStreamArg,
27535
+ "property-id": propertyArg
27536
+ },
27537
+ run: async ({ args }) => {
27538
+ await stageOp3({
27539
+ kind: "ga4.eventCreateRule.update",
27540
+ target: requireTarget4(args, "custom event"),
27541
+ payload: loadJsonArg(args),
27542
+ ...withStream(args),
27543
+ ...withProperty(args)
27544
+ });
27545
+ }
27546
+ }),
27547
+ delete: defineCommand110({
27548
+ meta: {
27549
+ name: "delete",
27550
+ description: "Stage removing a custom event (pass its id). The event stops being created from then on; data already collected under it stays. Confirm with the user first."
27551
+ },
27552
+ args: {
27553
+ id: { type: "positional", description: "Custom event rule id", required: false },
27554
+ "data-stream": dataStreamArg,
27555
+ "property-id": propertyArg
27556
+ },
27557
+ run: async ({ args }) => {
27558
+ await stageOp3({
27559
+ kind: "ga4.eventCreateRule.delete",
27560
+ target: requireTarget4(args, "custom event"),
27561
+ ...withStream(args),
27562
+ ...withProperty(args)
27563
+ });
27564
+ }
27565
+ })
27566
+ }
27567
+ });
27568
+ registerSchema({
27569
+ command: "ga4.dataRetention",
27570
+ description: "Set how long Google Analytics keeps event and user data. Standard properties allow 2 or 14 months; longer windows need an Analytics 360 licence. Two months is the default on many properties and makes year-on-year and long-window attribution impossible, so 14 is almost always the right answer.",
27571
+ args: {
27572
+ "event-data": { type: "string", description: "Months to keep event data: 2, 14, 26, 38 or 50", required: false },
27573
+ "user-data": { type: "string", description: "Months to keep user data: 2, 14, 26, 38 or 50", required: false },
27574
+ "reset-on-activity": {
27575
+ type: "string",
27576
+ description: "true|false \u2014 restart a user's retention window on every new event from them",
27577
+ required: false
27578
+ },
27579
+ "property-id": { type: "string", description: PROPERTY_ARG_DESCRIPTION, required: false }
27580
+ }
27581
+ });
27582
+ var RETENTION_BY_MONTHS = {
27583
+ "2": "TWO_MONTHS",
27584
+ "14": "FOURTEEN_MONTHS",
27585
+ "26": "TWENTY_SIX_MONTHS",
27586
+ "38": "THIRTY_EIGHT_MONTHS",
27587
+ "50": "FIFTY_MONTHS"
27588
+ };
27589
+ function retentionValue(input, flag) {
27590
+ const normalized = input.trim();
27591
+ const mapped = RETENTION_BY_MONTHS[normalized] ?? (Object.values(RETENTION_BY_MONTHS).includes(normalized.toUpperCase()) ? normalized.toUpperCase() : void 0);
27592
+ if (!mapped) {
27593
+ failValidation2(`--${flag} must be one of 2, 14, 26, 38 or 50 (months)`);
27594
+ }
27595
+ return mapped;
27596
+ }
27597
+ function booleanArg(input, flag) {
27598
+ if (input === "true") return true;
27599
+ if (input === "false") return false;
27600
+ return failValidation2(`--${flag} must be true or false`);
27601
+ }
27602
+ var dataRetentionCommand = defineCommand110({
27603
+ meta: {
27604
+ name: "data-retention",
27605
+ description: `Stage a change to how long Google Analytics keeps data
27606
+
27607
+ Examples:
27608
+ baker ga4 data-retention set --event-data 14
27609
+ baker ga4 data-retention set --event-data 14 --user-data 14 --reset-on-activity true`
27610
+ },
27611
+ subCommands: {
27612
+ set: defineCommand110({
27613
+ meta: { name: "set", description: "Stage the retention window (months)" },
27614
+ args: {
27615
+ "event-data": { type: "string", description: "2, 14, 26, 38 or 50", required: false },
27616
+ "user-data": { type: "string", description: "2, 14, 26, 38 or 50", required: false },
27617
+ "reset-on-activity": { type: "string", description: "true|false", required: false },
27618
+ "property-id": propertyArg
27619
+ },
27620
+ run: async ({ args }) => {
27621
+ const payload = {};
27622
+ if (typeof args["event-data"] === "string") {
27623
+ payload.eventDataRetention = retentionValue(args["event-data"], "event-data");
27624
+ }
27625
+ if (typeof args["user-data"] === "string") {
27626
+ payload.userDataRetention = retentionValue(args["user-data"], "user-data");
27627
+ }
27628
+ if (typeof args["reset-on-activity"] === "string") {
27629
+ payload.resetUserDataOnNewActivity = booleanArg(args["reset-on-activity"], "reset-on-activity");
27630
+ }
27631
+ if (Object.keys(payload).length === 0) {
27632
+ failValidation2("pass at least one of --event-data, --user-data or --reset-on-activity");
27633
+ }
27634
+ await stageOp3({ kind: "ga4.dataRetention.update", payload, ...withProperty(args) });
27635
+ }
27636
+ })
26371
27637
  }
26372
27638
  });
26373
27639
 
26374
27640
  // src/commands/ga4/index.ts
26375
- var ga4Command = defineCommand108({
27641
+ var ga4Command = defineCommand111({
26376
27642
  meta: {
26377
27643
  name: "ga4",
26378
- description: `Google Analytics 4 commands. Audit property config, run playbook-aligned reports.
27644
+ description: `Google Analytics 4. Report on a property, audit its config, and change what it measures.
26379
27645
 
26380
27646
  Start here:
26381
27647
  baker ga4 properties \u2014 list accessible properties
27648
+ baker ga4 config \u2014 what the property measures today (and whether Baker may change it)
26382
27649
  baker ga4 query --list-presets \u2014 see available report presets
26383
27650
 
26384
- Examples:
27651
+ Report:
26385
27652
  baker ga4 audit \u2014 full property health check
26386
27653
  baker ga4 query --preset tracking-health \u2014 compare GA4 vs GAds data
26387
- baker ga4 query --preset lp-performance --days 14 \u2014 landing page UX audit
26388
27654
  baker ga4 query --dimensions "date" --metrics "sessions" --days 7 \u2014 free-form query
27655
+
27656
+ Then stage changes (nothing is sent to Google Analytics until the chat completes):
27657
+ baker ga4 key-event create --json '{"eventName":"generate_lead","countingMethod":"ONCE_PER_EVENT"}'
27658
+ baker ga4 custom-event create --json '{"destinationEvent":"quote_request","eventConditions":[...]}'
27659
+ baker ga4 custom-dimension create --json '{"parameterName":"plan_tier","displayName":"Plan tier","scope":"EVENT"}'
27660
+ baker ga4 draft list \u2014 review everything staged
27661
+
27662
+ An applied change takes effect on the property immediately \u2014 there is no version to publish afterwards
27663
+ and no undo. Agree the changes with the user before the chat completes, not after.
27664
+
26389
27665
  Full guide: __tooling__/docs/tools/baker/ga4.md`
26390
27666
  },
26391
27667
  subCommands: {
26392
27668
  properties: propertiesCommand,
27669
+ config: configCommand,
26393
27670
  audit: auditCommand2,
26394
- query: queryCommand2
27671
+ query: queryCommand2,
27672
+ "key-event": keyEventCommand,
27673
+ "custom-dimension": customDimensionCommand,
27674
+ "custom-metric": customMetricCommand,
27675
+ "custom-event": customEventCommand,
27676
+ "data-retention": dataRetentionCommand,
27677
+ draft: draftCommand3
26395
27678
  }
26396
27679
  });
26397
27680
 
26398
27681
  // src/commands/gsc/index.ts
26399
- import { defineCommand as defineCommand112 } from "citty";
27682
+ import { defineCommand as defineCommand115 } from "citty";
26400
27683
 
26401
27684
  // src/commands/gsc/query.ts
26402
- import { appendFileSync as appendFileSync3, existsSync as existsSync6, readFileSync as readFileSync11, writeFileSync as writeFileSync4 } from "fs";
27685
+ import { appendFileSync as appendFileSync3, existsSync as existsSync6, readFileSync as readFileSync12, writeFileSync as writeFileSync4 } from "fs";
26403
27686
  import { resolve as resolve3 } from "path";
26404
- import { defineCommand as defineCommand109 } from "citty";
27687
+ import { defineCommand as defineCommand112 } from "citty";
26405
27688
 
26406
27689
  // src/commands/gsc/presets.ts
26407
27690
  var GSC_PRESETS = [
@@ -26547,7 +27830,7 @@ function writeRowsToFile3(filePath, rows, append) {
26547
27830
  writeFileSync4(filePath, content, "utf-8");
26548
27831
  }
26549
27832
  } else if (append && existsSync6(filePath)) {
26550
- const existing = JSON.parse(readFileSync11(filePath, "utf-8"));
27833
+ const existing = JSON.parse(readFileSync12(filePath, "utf-8"));
26551
27834
  writeFileSync4(filePath, JSON.stringify([...existing, ...rows], null, 2), "utf-8");
26552
27835
  } else {
26553
27836
  writeFileSync4(filePath, JSON.stringify(rows, null, 2), "utf-8");
@@ -26581,7 +27864,7 @@ function buildRequestBody2(args, siteUrl, useCache) {
26581
27864
  if (!useCache) body.skipCache = true;
26582
27865
  return body;
26583
27866
  }
26584
- function handleError2(err) {
27867
+ function handleError3(err) {
26585
27868
  if (err instanceof ApiError) {
26586
27869
  if (isNotConnectedError(err.code, err.message)) {
26587
27870
  handleConnectionError("gsc", err.message);
@@ -26595,7 +27878,7 @@ function handleError2(err) {
26595
27878
  });
26596
27879
  process.exit(1);
26597
27880
  }
26598
- var queryCommand3 = defineCommand109({
27881
+ var queryCommand3 = defineCommand112({
26599
27882
  meta: {
26600
27883
  name: "query",
26601
27884
  description: `Run GSC Search Analytics queries. Preset-first with free-form escape hatch.
@@ -26667,13 +27950,13 @@ Free-form (escape hatch):
26667
27950
  }
26668
27951
  outputRows2(response.data ?? [], args, response, false);
26669
27952
  } catch (err) {
26670
- handleError2(err);
27953
+ handleError3(err);
26671
27954
  }
26672
27955
  }
26673
27956
  });
26674
27957
 
26675
27958
  // src/commands/gsc/sitemaps.ts
26676
- import { defineCommand as defineCommand110 } from "citty";
27959
+ import { defineCommand as defineCommand113 } from "citty";
26677
27960
  registerSchema({
26678
27961
  command: "gsc.sitemaps",
26679
27962
  description: "List sitemaps for a Search Console site. Check sitemap health and errors.",
@@ -26682,7 +27965,7 @@ registerSchema({
26682
27965
  "no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
26683
27966
  }
26684
27967
  });
26685
- var sitemapsCommand = defineCommand110({
27968
+ var sitemapsCommand = defineCommand113({
26686
27969
  meta: {
26687
27970
  name: "sitemaps",
26688
27971
  description: `List sitemaps for a site. Check health and errors.
@@ -26735,7 +28018,7 @@ Examples:
26735
28018
  });
26736
28019
 
26737
28020
  // src/commands/gsc/sites.ts
26738
- import { defineCommand as defineCommand111 } from "citty";
28021
+ import { defineCommand as defineCommand114 } from "citty";
26739
28022
  registerSchema({
26740
28023
  command: "gsc.sites",
26741
28024
  description: "List the Search Console sites this company connected \u2014 there can be several, and every one of them is yours to query. Returns the site URLs the query and sitemaps commands take.",
@@ -26751,7 +28034,7 @@ function siteHints(sites) {
26751
28034
  resources: sites.map((site) => ({ id: site.siteUrl, label: site.permissionLevel }))
26752
28035
  });
26753
28036
  }
26754
- var sitesCommand = defineCommand111({
28037
+ var sitesCommand = defineCommand114({
26755
28038
  meta: {
26756
28039
  name: "sites",
26757
28040
  description: `List verified Search Console sites.
@@ -26799,7 +28082,7 @@ Examples:
26799
28082
  });
26800
28083
 
26801
28084
  // src/commands/gsc/index.ts
26802
- var gscCommand = defineCommand112({
28085
+ var gscCommand = defineCommand115({
26803
28086
  meta: {
26804
28087
  name: "gsc",
26805
28088
  description: `Google Search Console commands. PPC-SEO arbitrage, brand halo analysis, negative keyword discovery.
@@ -26823,7 +28106,7 @@ Full guide: __tooling__/docs/tools/baker/gsc.md`
26823
28106
  });
26824
28107
 
26825
28108
  // src/commands/history/index.ts
26826
- import { defineCommand as defineCommand113 } from "citty";
28109
+ import { defineCommand as defineCommand116 } from "citty";
26827
28110
  registerSchema({
26828
28111
  command: "history.list",
26829
28112
  description: "Start here: unified account history (audit log) \u2014 everything that changed on this account, newest first: publishes, chat lifecycle, backlog actions, team changes, setup links, tags, schedules, ad-platform writes, followed advertisers, media, creatives, reports, domains, and integrations. Use it to see what happened recently before planning work. Compact by default; add --full for raw metadata per entry.",
@@ -26878,7 +28161,7 @@ function parseBoundedInt2(raw, name, min, max) {
26878
28161
  }
26879
28162
  return value;
26880
28163
  }
26881
- var listCommand12 = defineCommand113({
28164
+ var listCommand12 = defineCommand116({
26882
28165
  meta: {
26883
28166
  name: "list",
26884
28167
  description: "List recent account changes (unified audit log), newest first."
@@ -26924,7 +28207,7 @@ var listCommand12 = defineCommand113({
26924
28207
  }
26925
28208
  }
26926
28209
  });
26927
- var historyCommand = defineCommand113({
28210
+ var historyCommand = defineCommand116({
26928
28211
  meta: {
26929
28212
  name: "history",
26930
28213
  description: `Unified account history (audit log): what changed, who did it, and when.
@@ -26934,7 +28217,7 @@ Full guide: __tooling__/docs/tools/baker/history.md`
26934
28217
  });
26935
28218
 
26936
28219
  // src/commands/hubspot/index.ts
26937
- import { defineCommand as defineCommand114 } from "citty";
28220
+ import { defineCommand as defineCommand117 } from "citty";
26938
28221
  var EMBED_TYPES = ["legacy", "v4", "unknown"];
26939
28222
  function failNotConnected(err) {
26940
28223
  if (err instanceof ApiError && err.code === "FORBIDDEN" && err.message.includes(HUBSPOT_MISSING_GRANT_MARKER)) {
@@ -27071,7 +28354,7 @@ registerSchema({
27071
28354
  }
27072
28355
  }
27073
28356
  });
27074
- var formsListCommand = defineCommand114({
28357
+ var formsListCommand = defineCommand117({
27075
28358
  meta: {
27076
28359
  name: "list",
27077
28360
  description: "List HubSpot forms with embed type and post-submit action. Example: baker hubspot forms list --redirecting-only"
@@ -27116,7 +28399,7 @@ var formsListCommand = defineCommand114({
27116
28399
  }
27117
28400
  }
27118
28401
  });
27119
- var formsViewCommand = defineCommand114({
28402
+ var formsViewCommand = defineCommand117({
27120
28403
  meta: {
27121
28404
  name: "view",
27122
28405
  description: "Show one HubSpot form's fields and configuration. Example: baker hubspot forms view 1a2b3c"
@@ -27168,7 +28451,7 @@ var formsViewCommand = defineCommand114({
27168
28451
  }
27169
28452
  }
27170
28453
  });
27171
- var meetingsListCommand = defineCommand114({
28454
+ var meetingsListCommand = defineCommand117({
27172
28455
  meta: {
27173
28456
  name: "list",
27174
28457
  description: "List HubSpot meeting links (calendars). Example: baker hubspot meetings list"
@@ -27210,7 +28493,7 @@ var meetingsListCommand = defineCommand114({
27210
28493
  }
27211
28494
  }
27212
28495
  });
27213
- var meetingsViewCommand = defineCommand114({
28496
+ var meetingsViewCommand = defineCommand117({
27214
28497
  meta: {
27215
28498
  name: "view",
27216
28499
  description: "Show one HubSpot meeting link's booking fields. Example: baker hubspot meetings view discovery-call"
@@ -27254,7 +28537,7 @@ var meetingsViewCommand = defineCommand114({
27254
28537
  }
27255
28538
  }
27256
28539
  });
27257
- var formsSubmissionsCommand = defineCommand114({
28540
+ var formsSubmissionsCommand = defineCommand117({
27258
28541
  meta: {
27259
28542
  name: "submissions",
27260
28543
  description: "How many leads a form received, and when. Example: baker hubspot forms submissions <formId> --days 30"
@@ -27303,7 +28586,7 @@ var formsSubmissionsCommand = defineCommand114({
27303
28586
  }
27304
28587
  }
27305
28588
  });
27306
- var workflowsListCommand = defineCommand114({
28589
+ var workflowsListCommand = defineCommand117({
27307
28590
  meta: {
27308
28591
  name: "list",
27309
28592
  description: "List HubSpot workflows. Example: baker hubspot workflows list --enabled-only"
@@ -27339,7 +28622,7 @@ var workflowsListCommand = defineCommand114({
27339
28622
  }
27340
28623
  }
27341
28624
  });
27342
- var pipelinesListCommand = defineCommand114({
28625
+ var pipelinesListCommand = defineCommand117({
27343
28626
  meta: {
27344
28627
  name: "list",
27345
28628
  description: "List HubSpot deal pipelines and their stages. Example: baker hubspot pipelines list"
@@ -27356,7 +28639,7 @@ var pipelinesListCommand = defineCommand114({
27356
28639
  }
27357
28640
  }
27358
28641
  });
27359
- var contactsSummaryCommand = defineCommand114({
28642
+ var contactsSummaryCommand = defineCommand117({
27360
28643
  meta: {
27361
28644
  name: "summary",
27362
28645
  description: "Whether recent leads are being worked, as counts. Example: baker hubspot contacts summary --days 30"
@@ -27426,7 +28709,7 @@ function contactLookupHints(data) {
27426
28709
  }
27427
28710
  return hints;
27428
28711
  }
27429
- var contactsLookupCommand = defineCommand114({
28712
+ var contactsLookupCommand = defineCommand117({
27430
28713
  meta: {
27431
28714
  name: "lookup",
27432
28715
  description: "Find one contact by email and see whether it was worked. Example: baker hubspot contacts lookup a@b.com"
@@ -27450,27 +28733,27 @@ var contactsLookupCommand = defineCommand114({
27450
28733
  }
27451
28734
  }
27452
28735
  });
27453
- var contactsCommand = defineCommand114({
28736
+ var contactsCommand = defineCommand117({
27454
28737
  meta: { name: "contacts", description: "Contacts on the connected HubSpot account." },
27455
28738
  subCommands: { summary: contactsSummaryCommand, lookup: contactsLookupCommand }
27456
28739
  });
27457
- var formsCommand = defineCommand114({
28740
+ var formsCommand = defineCommand117({
27458
28741
  meta: { name: "forms", description: "HubSpot forms on the connected account." },
27459
28742
  subCommands: { list: formsListCommand, view: formsViewCommand, submissions: formsSubmissionsCommand }
27460
28743
  });
27461
- var workflowsCommand = defineCommand114({
28744
+ var workflowsCommand = defineCommand117({
27462
28745
  meta: { name: "workflows", description: "HubSpot workflows on the connected account." },
27463
28746
  subCommands: { list: workflowsListCommand }
27464
28747
  });
27465
- var pipelinesCommand = defineCommand114({
28748
+ var pipelinesCommand = defineCommand117({
27466
28749
  meta: { name: "pipelines", description: "HubSpot deal pipelines on the connected account." },
27467
28750
  subCommands: { list: pipelinesListCommand }
27468
28751
  });
27469
- var meetingsCommand = defineCommand114({
28752
+ var meetingsCommand = defineCommand117({
27470
28753
  meta: { name: "meetings", description: "HubSpot meeting links (calendars) on the connected account." },
27471
28754
  subCommands: { list: meetingsListCommand, view: meetingsViewCommand }
27472
28755
  });
27473
- var hubspotCommand = defineCommand114({
28756
+ var hubspotCommand = defineCommand117({
27474
28757
  meta: {
27475
28758
  name: "hubspot",
27476
28759
  description: `Read the connected HubSpot account \u2014 forms, the leads they received, workflows, deal pipelines and
@@ -27507,10 +28790,10 @@ Full guide: __tooling__/docs/tools/baker/hubspot.md`
27507
28790
  });
27508
28791
 
27509
28792
  // src/commands/images/index.ts
27510
- import { defineCommand as defineCommand138 } from "citty";
28793
+ import { defineCommand as defineCommand141 } from "citty";
27511
28794
 
27512
28795
  // src/commands/images/crop.ts
27513
- import { defineCommand as defineCommand115 } from "citty";
28796
+ import { defineCommand as defineCommand118 } from "citty";
27514
28797
 
27515
28798
  // src/lib/image/crop-sprite.ts
27516
28799
  import sharp from "sharp";
@@ -27635,7 +28918,7 @@ function emitError2(err) {
27635
28918
  }
27636
28919
  process.exit(1);
27637
28920
  }
27638
- var cropCommand = defineCommand115({
28921
+ var cropCommand = defineCommand118({
27639
28922
  meta: {
27640
28923
  name: "crop",
27641
28924
  description: "Crop a rectangular region from an image.\n\nExample: baker images crop sprite.png --x 0 --y 0 --width 64 --height 64 --output icon.png"
@@ -27671,7 +28954,7 @@ var cropCommand = defineCommand115({
27671
28954
  });
27672
28955
 
27673
28956
  // src/commands/images/delete.ts
27674
- import { defineCommand as defineCommand116 } from "citty";
28957
+ import { defineCommand as defineCommand119 } from "citty";
27675
28958
  registerSchema({
27676
28959
  command: "images.delete",
27677
28960
  description: "Delete an image by ID",
@@ -27685,7 +28968,7 @@ registerSchema({
27685
28968
  }
27686
28969
  }
27687
28970
  });
27688
- var deleteCommand = defineCommand116({
28971
+ var deleteCommand = defineCommand119({
27689
28972
  meta: {
27690
28973
  name: "delete",
27691
28974
  description: "Delete an image by ID. Use --dry-run to preview. Example: baker images delete j571abc123 --dry-run"
@@ -27726,7 +29009,7 @@ var deleteCommand = defineCommand116({
27726
29009
  });
27727
29010
 
27728
29011
  // src/commands/images/dimensions.ts
27729
- import { defineCommand as defineCommand117 } from "citty";
29012
+ import { defineCommand as defineCommand120 } from "citty";
27730
29013
 
27731
29014
  // src/lib/image/dimensions.ts
27732
29015
  import { imageSize } from "image-size";
@@ -27749,7 +29032,7 @@ registerSchema({
27749
29032
  target: { type: "string", description: "Local file path or remote http(s) URL", required: true }
27750
29033
  }
27751
29034
  });
27752
- var dimensionsCommand = defineCommand117({
29035
+ var dimensionsCommand = defineCommand120({
27753
29036
  meta: {
27754
29037
  name: "dimensions",
27755
29038
  description: "Read image dimensions without decoding the full file.\n\nExample: baker images dimensions ./logo.png\nExample: baker images dimensions https://acme.com/hero.png"
@@ -27793,7 +29076,7 @@ var dimensionsCommand = defineCommand117({
27793
29076
  });
27794
29077
 
27795
29078
  // src/commands/images/extract.ts
27796
- import { defineCommand as defineCommand118 } from "citty";
29079
+ import { defineCommand as defineCommand121 } from "citty";
27797
29080
  registerSchema({
27798
29081
  command: "images.extract",
27799
29082
  description: "Extract images from a URL via Firecrawl (formats: images).",
@@ -27809,7 +29092,7 @@ registerSchema({
27809
29092
  }
27810
29093
  }
27811
29094
  });
27812
- var extractCommand = defineCommand118({
29095
+ var extractCommand = defineCommand121({
27813
29096
  meta: {
27814
29097
  name: "extract",
27815
29098
  description: "Pull every image from a single URL via Firecrawl. ~$0.001/scrape. Cap auto-ingest at 20.\n\nExample: baker images extract https://stripe.com --auto-ingest 5"
@@ -27847,7 +29130,7 @@ var extractCommand = defineCommand118({
27847
29130
  });
27848
29131
 
27849
29132
  // src/commands/images/find.ts
27850
- import { defineCommand as defineCommand119 } from "citty";
29133
+ import { defineCommand as defineCommand122 } from "citty";
27851
29134
  registerSchema({
27852
29135
  command: "images.find",
27853
29136
  description: "Fanout image search: library first, then opted-in external providers.",
@@ -27879,7 +29162,7 @@ registerSchema({
27879
29162
  }
27880
29163
  }
27881
29164
  });
27882
- var findCommand = defineCommand119({
29165
+ var findCommand = defineCommand122({
27883
29166
  meta: {
27884
29167
  name: "find",
27885
29168
  description: "Library-first fanout image search. Opt in to providers with --sources. `--fallback` short-circuits to externals only when library is thin. With --auto-ingest, ingested external hits return Baker-owned URLs.\n\nExample: baker images find 'office' --sources library,magnific --limit 20"
@@ -27928,7 +29211,7 @@ var findCommand = defineCommand119({
27928
29211
 
27929
29212
  // src/commands/images/generate.ts
27930
29213
  import { readFile as readFile20 } from "fs/promises";
27931
- import { defineCommand as defineCommand120 } from "citty";
29214
+ import { defineCommand as defineCommand123 } from "citty";
27932
29215
  import sharp2 from "sharp";
27933
29216
  var GENERATE_TIMEOUT_MS = 18e4;
27934
29217
  var REFERENCE_MAX_EDGE = 1536;
@@ -28031,7 +29314,7 @@ async function resolveReferences(spec) {
28031
29314
  }
28032
29315
  return out;
28033
29316
  }
28034
- var generateCommand = defineCommand120({
29317
+ var generateCommand = defineCommand123({
28035
29318
  meta: {
28036
29319
  name: "generate",
28037
29320
  description: "Generate an image with AI and store it in the library (cost-tracked per request via OpenRouter usage). Models mirror the canvas: google/gemini-3.1-flash-image-preview (Nano Banana flash \u2014 default, fast, extreme aspect ratios), google/gemini-3-pro-image-preview (Nano Banana Pro \u2014 highest fidelity), openai/gpt-image-2 (photoreal, cleanest in-image text, best for ad/landing reproduction \u2014 no --image-size, and no 4:5 / 5:4), recraft/recraft-v4.1-pro-vector (vector/SVG-style with palette control). The result is auto-ingested (describe + embed), so the next `baker images library` query finds it. Pass --reference with image URLs and/or local file paths (Pinterest, stock, brand assets, sandbox files) to ground generation in reality.\n\nExamples:\n baker images generate 'a friendly golden retriever sitting in a bright modern living room' --aspect-ratio 16:9\n baker images generate 'hero shot of a matte black water bottle on marble' --model openai/gpt-image-2 --aspect-ratio 3:2\n baker images generate 'lifestyle photo matching this mood' --reference 'https://\u2026/ref1.jpg,https://\u2026/ref2.jpg'\n baker images generate 'put this product on a marble countertop, soft daylight' --reference './src/brand/logos/product.png,./refs/kitchen-mood.jpg'\n baker images generate 'flat geometric mascot, brand palette' --model recraft/recraft-v4.1-pro-vector --rgb-colors '[[10,10,10],[255,80,0]]'"
@@ -28083,7 +29366,7 @@ var generateCommand = defineCommand120({
28083
29366
  });
28084
29367
 
28085
29368
  // src/commands/images/get.ts
28086
- import { defineCommand as defineCommand121 } from "citty";
29369
+ import { defineCommand as defineCommand124 } from "citty";
28087
29370
  registerSchema({
28088
29371
  command: "images.get",
28089
29372
  description: "Get a single image by ID",
@@ -28091,7 +29374,7 @@ registerSchema({
28091
29374
  id: { type: "string", description: "Image ID", required: true }
28092
29375
  }
28093
29376
  });
28094
- var getCommand2 = defineCommand121({
29377
+ var getCommand2 = defineCommand124({
28095
29378
  meta: { name: "get", description: "Get a single image by ID. Example: baker images get j571abc123" },
28096
29379
  args: {
28097
29380
  id: { type: "positional", description: "Image ID", required: false },
@@ -28127,7 +29410,7 @@ var getCommand2 = defineCommand121({
28127
29410
  });
28128
29411
 
28129
29412
  // src/commands/images/gif.ts
28130
- import { defineCommand as defineCommand122 } from "citty";
29413
+ import { defineCommand as defineCommand125 } from "citty";
28131
29414
  registerSchema({
28132
29415
  command: "images.gif",
28133
29416
  description: "Search Giphy for GIFs / reaction memes (paid social creative).",
@@ -28159,7 +29442,7 @@ registerSchema({
28159
29442
  }
28160
29443
  }
28161
29444
  });
28162
- var gifCommand = defineCommand122({
29445
+ var gifCommand = defineCommand125({
28163
29446
  meta: {
28164
29447
  name: "gif",
28165
29448
  description: "Search Giphy for GIFs / reaction memes \u2014 built for paid-social creative (Meta, TikTok, LinkedIn, X). Free API. Each hit carries WebP + GIF + MP4 URLs in providerMeta so you can pick the right format per platform.\n\nExample: baker images gif 'this is fine' --limit 10\nExample: baker images gif 'office reaction' --rating pg --auto-ingest 2\nExample: baker images gif --trending --limit 25"
@@ -28206,7 +29489,7 @@ var gifCommand = defineCommand122({
28206
29489
  });
28207
29490
 
28208
29491
  // src/commands/images/google.ts
28209
- import { defineCommand as defineCommand123 } from "citty";
29492
+ import { defineCommand as defineCommand126 } from "citty";
28210
29493
 
28211
29494
  // src/commands/images/searchHints.ts
28212
29495
  var FALLBACK = {
@@ -28270,7 +29553,7 @@ registerSchema({
28270
29553
  }
28271
29554
  }
28272
29555
  });
28273
- var googleCommand2 = defineCommand123({
29556
+ var googleCommand2 = defineCommand126({
28274
29557
  meta: {
28275
29558
  name: "google",
28276
29559
  description: "Google Images via the official Custom Search JSON API ($0.005/query, free 100/day). \u26A0 Source unverified \u2014 watermarks, low-res, mislabeled results are common. Use as last resort. With --auto-ingest, ingested hits return Baker-owned URLs.\n\nExample: baker images google 'industrial workshop' --type photo --size large --limit 20"
@@ -28326,7 +29609,7 @@ var googleCommand2 = defineCommand123({
28326
29609
  });
28327
29610
 
28328
29611
  // src/commands/images/icon.ts
28329
- import { defineCommand as defineCommand124 } from "citty";
29612
+ import { defineCommand as defineCommand127 } from "citty";
28330
29613
  registerSchema({
28331
29614
  command: "images.icon",
28332
29615
  description: "Icon lookup via Iconify (200+ icon sets, free CDN).",
@@ -28352,7 +29635,7 @@ registerSchema({
28352
29635
  }
28353
29636
  }
28354
29637
  });
28355
- var iconCommand = defineCommand124({
29638
+ var iconCommand = defineCommand127({
28356
29639
  meta: {
28357
29640
  name: "icon",
28358
29641
  description: "Icon via Iconify (simple-icons, logos, lucide, devicon, heroicons, tabler, phosphor, material-symbols, \u2026). Free CDN, no API key.\n\nExample: baker images icon react --set devicon\nExample: baker images icon lucide:check --color '#0a0a0a'"
@@ -28392,7 +29675,7 @@ var iconCommand = defineCommand124({
28392
29675
  });
28393
29676
 
28394
29677
  // src/commands/images/ingest.ts
28395
- import { defineCommand as defineCommand125 } from "citty";
29678
+ import { defineCommand as defineCommand128 } from "citty";
28396
29679
  registerSchema({
28397
29680
  command: "images.ingest",
28398
29681
  description: "Ingest a remote image URL into the library (full describe + embed).",
@@ -28404,7 +29687,7 @@ registerSchema({
28404
29687
  context: { type: "string", description: "Description context hint", required: false }
28405
29688
  }
28406
29689
  });
28407
- var ingestCommand = defineCommand125({
29690
+ var ingestCommand = defineCommand128({
28408
29691
  meta: {
28409
29692
  name: "ingest",
28410
29693
  description: "Download a remote URL and store it in the library. Hash-deduped on bytes + externalId.\n\nExample: baker images ingest https://img.freepik.com/free-photo/xyz.jpg --source magnific --external-id 12345"
@@ -28446,7 +29729,7 @@ var ingestCommand = defineCommand125({
28446
29729
  });
28447
29730
 
28448
29731
  // src/commands/images/library.ts
28449
- import { defineCommand as defineCommand126 } from "citty";
29732
+ import { defineCommand as defineCommand129 } from "citty";
28450
29733
  registerSchema({
28451
29734
  command: "images.library",
28452
29735
  description: "Search the company image library. Returns only ready images.",
@@ -28472,7 +29755,7 @@ registerSchema({
28472
29755
  }
28473
29756
  }
28474
29757
  });
28475
- var libraryCommand = defineCommand126({
29758
+ var libraryCommand = defineCommand129({
28476
29759
  meta: {
28477
29760
  name: "library",
28478
29761
  description: "Search the company image library (hybrid BM25 + vector + Cohere rerank). Use this BEFORE any external provider.\n\nExample: baker images library 'hero banner' --aspect-ratio 16:9 --source magnific"
@@ -28529,7 +29812,7 @@ var libraryCommand = defineCommand126({
28529
29812
  });
28530
29813
 
28531
29814
  // src/commands/images/logo.ts
28532
- import { defineCommand as defineCommand127 } from "citty";
29815
+ import { defineCommand as defineCommand130 } from "citty";
28533
29816
  registerSchema({
28534
29817
  command: "images.logo",
28535
29818
  description: "Brand logo lookup via Brandfetch CDN (fallback/404). Auto-ingests by default.",
@@ -28554,7 +29837,7 @@ registerSchema({
28554
29837
  }
28555
29838
  }
28556
29839
  });
28557
- var logoCommand = defineCommand127({
29840
+ var logoCommand = defineCommand130({
28558
29841
  meta: {
28559
29842
  name: "logo",
28560
29843
  description: "Brand logo via Brandfetch CDN. Returns up to 5 variants (icon, light/dark logo, light/dark symbol). Auto-ingests the first variant.\n\nExample: baker images logo stripe.com --variant logo"
@@ -28592,7 +29875,7 @@ var logoCommand = defineCommand127({
28592
29875
  });
28593
29876
 
28594
29877
  // src/commands/images/normalize.ts
28595
- import { defineCommand as defineCommand128 } from "citty";
29878
+ import { defineCommand as defineCommand131 } from "citty";
28596
29879
 
28597
29880
  // src/lib/image/color-changer.ts
28598
29881
  import quantize from "quantize";
@@ -29324,7 +30607,7 @@ function coerceRawArgs(args) {
29324
30607
  "dry-run": bool(args["dry-run"])
29325
30608
  };
29326
30609
  }
29327
- var normalizeCommand = defineCommand128({
30610
+ var normalizeCommand = defineCommand131({
29328
30611
  meta: {
29329
30612
  name: "normalize",
29330
30613
  description: `Normalize logos / images: declarative recolor + bg removal + trim + resize. Operates on local files; writes in-place by default.
@@ -29379,7 +30662,7 @@ Examples:
29379
30662
  });
29380
30663
 
29381
30664
  // src/commands/images/pinterest.ts
29382
- import { defineCommand as defineCommand129 } from "citty";
30665
+ import { defineCommand as defineCommand132 } from "citty";
29383
30666
  registerSchema({
29384
30667
  command: "images.pinterest",
29385
30668
  description: "Pinterest image search via ScrapeCreators. Reference-grade real-world photography, product styling, interiors, fashion, food, and aesthetic mood boards. Inspect before placing \u2014 Pinterest is unverified, trademark-bearing web content.",
@@ -29399,7 +30682,7 @@ registerSchema({
29399
30682
  }
29400
30683
  }
29401
30684
  });
29402
- var pinterestCommand = defineCommand129({
30685
+ var pinterestCommand = defineCommand132({
29403
30686
  meta: {
29404
30687
  name: "pinterest",
29405
30688
  description: "Pinterest image search via ScrapeCreators ($0.00188/request). Best for photo-realistic reference imagery \u2014 lifestyle, interiors, fashion, food, product styling, and mood boards to brief AI generation against. \u26A0 Unverified, trademark-bearing web content \u2014 inspect and respect rights before placing on a customer page. Browse first; auto-ingest only the pins you commit to.\n\nExamples:\n baker images pinterest 'scandinavian living room'\n baker images pinterest 'minimalist skincare product photography' --limit 20\n baker images pinterest 'cozy coffee shop interior' --auto-ingest 2 --context 'Mood reference for hero photography'"
@@ -29439,7 +30722,7 @@ var pinterestCommand = defineCommand129({
29439
30722
  });
29440
30723
 
29441
30724
  // src/commands/images/screenshot.ts
29442
- import { defineCommand as defineCommand130 } from "citty";
30725
+ import { defineCommand as defineCommand133 } from "citty";
29443
30726
  registerSchema({
29444
30727
  command: "images.screenshot",
29445
30728
  description: "Capture a website screenshot via ScreenshotOne. Auto-ingests on success.",
@@ -29455,7 +30738,7 @@ registerSchema({
29455
30738
  }
29456
30739
  }
29457
30740
  });
29458
- var screenshotCommand = defineCommand130({
30741
+ var screenshotCommand = defineCommand133({
29459
30742
  meta: {
29460
30743
  name: "screenshot",
29461
30744
  description: "Screenshot a URL via ScreenshotOne. $0.009/capture. Auto-ingests to library.\n\nExample: baker images screenshot https://stripe.com --full-page"
@@ -29518,7 +30801,7 @@ var screenshotCommand = defineCommand130({
29518
30801
  });
29519
30802
 
29520
30803
  // src/commands/images/search.ts
29521
- import { defineCommand as defineCommand131 } from "citty";
30804
+ import { defineCommand as defineCommand134 } from "citty";
29522
30805
  registerSchema({
29523
30806
  command: "images.search",
29524
30807
  description: "Search images by text query. Only returns ready images.",
@@ -29534,7 +30817,7 @@ registerSchema({
29534
30817
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
29535
30818
  }
29536
30819
  });
29537
- var searchCommand = defineCommand131({
30820
+ var searchCommand = defineCommand134({
29538
30821
  meta: {
29539
30822
  name: "search",
29540
30823
  description: "Semantic search images by text query. Uses hybrid BM25 + vector + reranking. Example: baker images search 'hero banner' --aspect-ratio 16:9 --tags logo"
@@ -29594,7 +30877,7 @@ var searchCommand = defineCommand131({
29594
30877
  });
29595
30878
 
29596
30879
  // src/commands/images/sticker.ts
29597
- import { defineCommand as defineCommand132 } from "citty";
30880
+ import { defineCommand as defineCommand135 } from "citty";
29598
30881
  registerSchema({
29599
30882
  command: "images.sticker",
29600
30883
  description: "Search Giphy stickers \u2014 transparent-background overlays for ad creative.",
@@ -29626,7 +30909,7 @@ registerSchema({
29626
30909
  }
29627
30910
  }
29628
30911
  });
29629
- var stickerCommand = defineCommand132({
30912
+ var stickerCommand = defineCommand135({
29630
30913
  meta: {
29631
30914
  name: "sticker",
29632
30915
  description: "Search Giphy's sticker corpus \u2014 transparent-background WebPs / GIFs ideal for overlaying on ad creative (Meta, TikTok, Stories). Same Giphy free API as `baker images gif`; results carry WebP + GIF + MP4 URLs in providerMeta.\n\nExample: baker images sticker 'thumbs up' --limit 10\nExample: baker images sticker celebration --rating g --auto-ingest 3\nExample: baker images sticker --trending --limit 25"
@@ -29673,7 +30956,7 @@ var stickerCommand = defineCommand132({
29673
30956
  });
29674
30957
 
29675
30958
  // src/commands/images/stock.ts
29676
- import { defineCommand as defineCommand133 } from "citty";
30959
+ import { defineCommand as defineCommand136 } from "citty";
29677
30960
  var STOCK_ERROR_FIX = {
29678
30961
  action: "use_different_resource",
29679
30962
  explanation: "Switch provider instead of retrying stock search. Stock search is one of several image sources. Run `baker images find <query> --sources library,pinterest,google` (`--sources` is required \u2014 `find` alone searches the library only) or `baker images generate` to make the asset. Never sleep-and-retry this command \u2014 the CLI already backs off on rate limits. If no image can be sourced, continue the rest of the task with a placeholder rather than aborting it."
@@ -29750,7 +31033,7 @@ function buildStockRequest(query, args) {
29750
31033
  if (args.context) body.descriptionContext = args.context;
29751
31034
  return body;
29752
31035
  }
29753
- var stockCommand = defineCommand133({
31036
+ var stockCommand = defineCommand136({
29754
31037
  meta: {
29755
31038
  name: "stock",
29756
31039
  description: "Stock search via Magnific \u2014 Freepik's developer API (~250M assets: photos, vectors, illustrations, icons, PSDs). $0.002/req. With --auto-ingest, ingested hits return Baker-owned URLs.\n\nExamples:\n baker images stock 'minimalist office'\n baker images stock 'flat office workers' --type vector\n baker images stock 'hero photo of a kitchen' --type photo --orientation landscape --ai exclude\n baker images stock 'brand pattern' --color '#0a0a0a' --license freemium --auto-ingest 2"
@@ -29806,7 +31089,7 @@ var stockCommand = defineCommand133({
29806
31089
  });
29807
31090
 
29808
31091
  // src/lib/tags-command.ts
29809
- import { defineCommand as defineCommand134 } from "citty";
31092
+ import { defineCommand as defineCommand137 } from "citty";
29810
31093
  function makeTagsCommand(command, label, endpoint) {
29811
31094
  registerSchema({
29812
31095
  command: `${command}.tags`,
@@ -29815,7 +31098,7 @@ function makeTagsCommand(command, label, endpoint) {
29815
31098
  output: { type: "string", description: "Output format: md|json", required: false, default: "md" }
29816
31099
  }
29817
31100
  });
29818
- return defineCommand134({
31101
+ return defineCommand137({
29819
31102
  meta: {
29820
31103
  name: "tags",
29821
31104
  description: `List the available ${label} tag names (defaults + company custom tags). Use before filtering with --tags. Example: baker ${command} tags`
@@ -29851,7 +31134,7 @@ function makeTagsCommand(command, label, endpoint) {
29851
31134
  var tagsCommand2 = makeTagsCommand("images", "image", "/api/images/tags");
29852
31135
 
29853
31136
  // src/commands/images/upload.ts
29854
- import { defineCommand as defineCommand135 } from "citty";
31137
+ import { defineCommand as defineCommand138 } from "citty";
29855
31138
  registerSchema({
29856
31139
  command: "images.upload",
29857
31140
  description: "Upload an image to the library \u2014 local file path or remote http(s) URL.",
@@ -29889,7 +31172,7 @@ registerSchema({
29889
31172
  function isRemoteUrl2(value) {
29890
31173
  return /^https?:\/\//i.test(value);
29891
31174
  }
29892
- var uploadCommand = defineCommand135({
31175
+ var uploadCommand = defineCommand138({
29893
31176
  meta: {
29894
31177
  name: "upload",
29895
31178
  description: "Upload an image to the library \u2014 accepts a local file path OR a remote http(s) URL.\n\nLocal: reads bytes, sends to /api/images/upload, content-type auto-detected from extension.\nRemote: dispatches to /api/images/ingest with hash-dedup on bytes + externalId.\n\nExamples:\n baker images upload ./logo.png --source uploaded\n baker images upload ./cert.png --context 'ISO 27001 badge \u2014 enterprise tier'\n baker images upload https://acme.com/hero.png --source firecrawl --context 'Acme competitor pricing hero'"
@@ -29982,7 +31265,7 @@ async function uploadLocal(target, args) {
29982
31265
  }
29983
31266
 
29984
31267
  // src/commands/images/upscale.ts
29985
- import { defineCommand as defineCommand136 } from "citty";
31268
+ import { defineCommand as defineCommand139 } from "citty";
29986
31269
  registerSchema({
29987
31270
  command: "images.upscale",
29988
31271
  description: "Upscale a library image via the backend (Replicate, cost-tracked). Waits for completion by default. The image must be status 'ready' and raster (not SVG/AVIF).",
@@ -29997,7 +31280,7 @@ registerSchema({
29997
31280
  }
29998
31281
  });
29999
31282
  var POLL_INTERVAL_MS3 = 1500;
30000
- var upscaleCommand = defineCommand136({
31283
+ var upscaleCommand = defineCommand139({
30001
31284
  meta: {
30002
31285
  name: "upscale",
30003
31286
  description: "Upscale a library image via the Convex backend (Replicate, cost-tracked at $0.05/image). Waits for completion by default.\n\nExample: baker images upscale j571abc123def\nExample: baker images upscale j571abc123def --max-wait 0 # fire-and-forget"
@@ -30052,7 +31335,7 @@ var upscaleCommand = defineCommand136({
30052
31335
  });
30053
31336
 
30054
31337
  // src/commands/images/use.ts
30055
- import { defineCommand as defineCommand137 } from "citty";
31338
+ import { defineCommand as defineCommand140 } from "citty";
30056
31339
  registerSchema({
30057
31340
  command: "images.use",
30058
31341
  description: "Ingest a URL and wait for the library record to be ready.",
@@ -30068,7 +31351,7 @@ registerSchema({
30068
31351
  }
30069
31352
  });
30070
31353
  var POLL_INTERVAL_MS4 = 1500;
30071
- var useCommand = defineCommand137({
31354
+ var useCommand = defineCommand140({
30072
31355
  meta: {
30073
31356
  name: "use",
30074
31357
  description: "Sugar over `ingest`: download \u2192 store \u2192 wait until describe + embed complete \u2192 return ready library record.\n\nExample: baker images use https://cdn.example.com/hero.png --source uploaded"
@@ -30114,7 +31397,7 @@ var useCommand = defineCommand137({
30114
31397
  });
30115
31398
 
30116
31399
  // src/commands/images/index.ts
30117
- var imagesCommand = defineCommand138({
31400
+ var imagesCommand = defineCommand141({
30118
31401
  meta: {
30119
31402
  name: "images",
30120
31403
  description: `Find, source, and normalize images. Subcommands route by provider so cost + license are explicit.
@@ -30185,12 +31468,12 @@ Full guide: __tooling__/docs/tools/baker/images.md`
30185
31468
  });
30186
31469
 
30187
31470
  // src/commands/landing/index.ts
30188
- import { defineCommand as defineCommand140 } from "citty";
31471
+ import { defineCommand as defineCommand143 } from "citty";
30189
31472
 
30190
31473
  // src/commands/landing/critique.ts
30191
31474
  import { readdir as readdir8, stat as stat6 } from "fs/promises";
30192
31475
  import path27 from "path";
30193
- import { defineCommand as defineCommand139 } from "citty";
31476
+ import { defineCommand as defineCommand142 } from "citty";
30194
31477
 
30195
31478
  // src/engine/landing/lib/brand-tokens.ts
30196
31479
  import { readFile as readFile21 } from "fs/promises";
@@ -31465,7 +32748,7 @@ function fail5(code, message, fix) {
31465
32748
  );
31466
32749
  process.exit(2);
31467
32750
  }
31468
- var critiqueCommand2 = defineCommand139({
32751
+ var critiqueCommand2 = defineCommand142({
31469
32752
  meta: {
31470
32753
  name: "critique",
31471
32754
  description: "Start here: `baker landing critique <slug>` after building or editing a landing. Deterministic design-quality critic (ADVISORY \u2014 findings never fail it). Flags the known AI design tells (gradient text, overused fonts, side-tab borders, cream palettes, buzzword copy, broken images) tiered block/warn/advisory, respecting the client's BRAND.md as the allowlist. Also records the critique that publishing requires \u2014 run it before finishing a landing."
@@ -31574,7 +32857,7 @@ async function isDir(p) {
31574
32857
  }
31575
32858
 
31576
32859
  // src/commands/landing/index.ts
31577
- var landingCommand = defineCommand140({
32860
+ var landingCommand = defineCommand143({
31578
32861
  meta: {
31579
32862
  name: "landing",
31580
32863
  description: `Design-quality tools for landing pages (src/pages/<slug>/).
@@ -31590,7 +32873,7 @@ Subcommands:
31590
32873
  });
31591
32874
 
31592
32875
  // src/commands/mcp/index.ts
31593
- import { defineCommand as defineCommand141 } from "citty";
32876
+ import { defineCommand as defineCommand144 } from "citty";
31594
32877
 
31595
32878
  // src/commands/mcp/platforms.ts
31596
32879
  function readsKey(label) {
@@ -31659,7 +32942,7 @@ registerSchema({
31659
32942
  description: "List everything this chat can reach: managed integrations (Attio, Slack, Gmail, Google Sheets, \u2026), custom MCP servers, and the platforms the company signed in to (HubSpot, Google Ads, GA4, Search Console, Tag Manager) which you read through their own `baker` commands. Start here when the user mentions an external tool or platform.",
31660
32943
  args: {}
31661
32944
  });
31662
- var connectedCommand = defineCommand141({
32945
+ var connectedCommand = defineCommand144({
31663
32946
  meta: {
31664
32947
  name: "connected",
31665
32948
  description: `Everything this chat can reach \u2014 managed integrations, custom MCP servers, and connected platforms.
@@ -31718,7 +33001,7 @@ registerSchema({
31718
33001
  description: "List the custom MCP servers this company's chats see (org + company + your own user scope).",
31719
33002
  args: {}
31720
33003
  });
31721
- var listCommand13 = defineCommand141({
33004
+ var listCommand13 = defineCommand144({
31722
33005
  meta: { name: "list", description: "List custom MCP servers visible to this company's chats." },
31723
33006
  run: async () => {
31724
33007
  try {
@@ -31755,7 +33038,7 @@ registerSchema({
31755
33038
  header: { type: "string", description: 'Auth header "Key: Value" (repeatable)', required: false }
31756
33039
  }
31757
33040
  });
31758
- var addCommand = defineCommand141({
33041
+ var addCommand = defineCommand144({
31759
33042
  meta: {
31760
33043
  name: "add",
31761
33044
  description: `Register a custom MCP server. Tools appear as mcp__<name>__* on the NEXT message.
@@ -31807,7 +33090,7 @@ registerSchema({
31807
33090
  description: "Remove a company custom MCP server by name.",
31808
33091
  args: { name: { type: "string", description: "Server name to remove", required: true } }
31809
33092
  });
31810
- var removeCommand4 = defineCommand141({
33093
+ var removeCommand4 = defineCommand144({
31811
33094
  meta: {
31812
33095
  name: "remove",
31813
33096
  description: `Remove a company custom MCP server by name.
@@ -31829,7 +33112,7 @@ Example:
31829
33112
  }
31830
33113
  }
31831
33114
  });
31832
- var mcpCommand = defineCommand141({
33115
+ var mcpCommand = defineCommand144({
31833
33116
  meta: {
31834
33117
  name: "mcp",
31835
33118
  description: `Third-party tools for this company \u2014 see what's connected, register custom HTTPS MCP endpoints.
@@ -31855,10 +33138,10 @@ Full guide: __tooling__/docs/tools/baker/mcp.md`
31855
33138
  });
31856
33139
 
31857
33140
  // src/commands/research/index.ts
31858
- import { defineCommand as defineCommand152 } from "citty";
33141
+ import { defineCommand as defineCommand155 } from "citty";
31859
33142
 
31860
33143
  // src/commands/research/advertisers.ts
31861
- import { defineCommand as defineCommand142 } from "citty";
33144
+ import { defineCommand as defineCommand145 } from "citty";
31862
33145
 
31863
33146
  // src/commands/research/output.ts
31864
33147
  var RESEARCH_DATA_NOTE = "Estimates based on third-party SERP data \u2014 not exact figures. Use for directional insights, not precise measurement.";
@@ -31971,7 +33254,7 @@ var FIELDS3 = {
31971
33254
  etv: "Estimated traffic value (USD)",
31972
33255
  visibility: "SERP visibility score (0-1)"
31973
33256
  };
31974
- var advertisersCommand = defineCommand142({
33257
+ var advertisersCommand = defineCommand145({
31975
33258
  meta: {
31976
33259
  name: "advertisers",
31977
33260
  description: `Find domains competing for a keyword in Google SERPs.
@@ -32018,7 +33301,7 @@ Examples:
32018
33301
  });
32019
33302
 
32020
33303
  // src/commands/research/autocomplete.ts
32021
- import { defineCommand as defineCommand143 } from "citty";
33304
+ import { defineCommand as defineCommand146 } from "citty";
32022
33305
  registerSchema({
32023
33306
  command: "research.autocomplete",
32024
33307
  description: "Get Google Autocomplete suggestions for a seed keyword. Useful for keyword expansion and discovering what people actually search for. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en).",
@@ -32041,7 +33324,7 @@ registerSchema({
32041
33324
  var FIELDS4 = {
32042
33325
  suggestion: "Autocomplete suggestion from Google"
32043
33326
  };
32044
- var autocompleteCommand = defineCommand143({
33327
+ var autocompleteCommand = defineCommand146({
32045
33328
  meta: {
32046
33329
  name: "autocomplete",
32047
33330
  description: `Get Google Autocomplete suggestions for keyword expansion.
@@ -32087,7 +33370,7 @@ Examples:
32087
33370
  });
32088
33371
 
32089
33372
  // src/commands/research/countries.ts
32090
- import { defineCommand as defineCommand144 } from "citty";
33373
+ import { defineCommand as defineCommand147 } from "citty";
32091
33374
  registerSchema({
32092
33375
  command: "research.countries",
32093
33376
  description: "List all supported country codes for --location flag in research commands.",
@@ -32144,7 +33427,7 @@ var FIELDS5 = {
32144
33427
  code: "Country code to pass as --location",
32145
33428
  name: "Country name"
32146
33429
  };
32147
- var countriesCommand = defineCommand144({
33430
+ var countriesCommand = defineCommand147({
32148
33431
  meta: {
32149
33432
  name: "countries",
32150
33433
  description: "List all supported country codes for --location flag."
@@ -32155,7 +33438,7 @@ var countriesCommand = defineCommand144({
32155
33438
  });
32156
33439
 
32157
33440
  // src/commands/research/intent.ts
32158
- import { defineCommand as defineCommand145 } from "citty";
33441
+ import { defineCommand as defineCommand148 } from "citty";
32159
33442
  registerSchema({
32160
33443
  command: "research.intent",
32161
33444
  description: "Classify Google Search intent for keywords. Determines if someone searching is looking to buy, research, or navigate. IMPORTANT: If --language is omitted, defaults to English (en). The response includes a query_context object showing which language was used.",
@@ -32178,7 +33461,7 @@ var FIELDS6 = {
32178
33461
  intent: "Primary Google Search intent: informational, navigational, commercial, transactional",
32179
33462
  probability: "Confidence score 0.0-1.0"
32180
33463
  };
32181
- var intentCommand = defineCommand145({
33464
+ var intentCommand = defineCommand148({
32182
33465
  meta: {
32183
33466
  name: "intent",
32184
33467
  description: `Classify Google Search intent for keywords. Returns intent type and confidence.
@@ -32226,7 +33509,7 @@ Examples:
32226
33509
  });
32227
33510
 
32228
33511
  // src/commands/research/keyword-gap.ts
32229
- import { defineCommand as defineCommand146 } from "citty";
33512
+ import { defineCommand as defineCommand149 } from "citty";
32230
33513
  registerSchema({
32231
33514
  command: "research.keyword-gap",
32232
33515
  description: "Find keywords a competitor ranks for (organic or paid) that you don't. Discovers expansion opportunities. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en). The response includes a query_context object showing which location/language were used.",
@@ -32255,7 +33538,7 @@ var FIELDS7 = {
32255
33538
  cpc: "Cost per click USD",
32256
33539
  their_position: "Competitor's ranking position"
32257
33540
  };
32258
- var keywordGapCommand = defineCommand146({
33541
+ var keywordGapCommand = defineCommand149({
32259
33542
  meta: {
32260
33543
  name: "keyword-gap",
32261
33544
  description: `Find keywords a competitor has that you don't. Supports pagination via --offset.
@@ -32329,7 +33612,7 @@ Examples:
32329
33612
  });
32330
33613
 
32331
33614
  // src/commands/research/keywords-for-site.ts
32332
- import { defineCommand as defineCommand147 } from "citty";
33615
+ import { defineCommand as defineCommand150 } from "citty";
32333
33616
  registerSchema({
32334
33617
  command: "research.keywords-for-site",
32335
33618
  description: "Get keywords a competitor targets in Google. Use --type paid to see only paid keywords, --type organic for organic only. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en). The response includes a query_context object showing which location/language were used.",
@@ -32362,7 +33645,7 @@ var FIELDS8 = {
32362
33645
  competition: "LOW, MEDIUM, or HIGH",
32363
33646
  competition_index: "Competition score 0-100"
32364
33647
  };
32365
- var keywordsForSiteCommand = defineCommand147({
33648
+ var keywordsForSiteCommand = defineCommand150({
32366
33649
  meta: {
32367
33650
  name: "keywords-for-site",
32368
33651
  description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.
@@ -32415,7 +33698,7 @@ Examples:
32415
33698
  });
32416
33699
 
32417
33700
  // src/commands/research/languages.ts
32418
- import { defineCommand as defineCommand148 } from "citty";
33701
+ import { defineCommand as defineCommand151 } from "citty";
32419
33702
  registerSchema({
32420
33703
  command: "research.languages",
32421
33704
  description: "List all supported language codes for --language flag in research commands.",
@@ -32445,7 +33728,7 @@ var FIELDS9 = {
32445
33728
  code: "Language code to pass as --language",
32446
33729
  name: "Language name (also accepted by --language)"
32447
33730
  };
32448
- var languagesCommand2 = defineCommand148({
33731
+ var languagesCommand2 = defineCommand151({
32449
33732
  meta: {
32450
33733
  name: "languages",
32451
33734
  description: "List all supported language codes for --language flag."
@@ -32456,7 +33739,7 @@ var languagesCommand2 = defineCommand148({
32456
33739
  });
32457
33740
 
32458
33741
  // src/commands/research/lighthouse.ts
32459
- import { defineCommand as defineCommand149 } from "citty";
33742
+ import { defineCommand as defineCommand152 } from "citty";
32460
33743
  registerSchema({
32461
33744
  command: "research.lighthouse",
32462
33745
  description: "Landing page performance audit. Returns metrics that affect Google Ads Quality Score and CPC.",
@@ -32475,7 +33758,7 @@ var FIELDS10 = {
32475
33758
  speed_index_ms: "Speed Index in ms (good: < 3400)",
32476
33759
  interactive_ms: "Time to Interactive in ms (good: < 3800)"
32477
33760
  };
32478
- var lighthouseCommand = defineCommand149({
33761
+ var lighthouseCommand = defineCommand152({
32479
33762
  meta: {
32480
33763
  name: "lighthouse",
32481
33764
  description: `Landing page performance audit. Metrics affecting Google Ads Quality Score.
@@ -32513,7 +33796,7 @@ Examples:
32513
33796
  });
32514
33797
 
32515
33798
  // src/commands/research/relevant-pages.ts
32516
- import { defineCommand as defineCommand150 } from "citty";
33799
+ import { defineCommand as defineCommand153 } from "citty";
32517
33800
  registerSchema({
32518
33801
  command: "research.relevant-pages",
32519
33802
  description: "Get the top pages of a competitor domain with organic traffic and ranking data. Shows which pages drive the most traffic. IMPORTANT: If --location and --language are omitted, defaults to United States (us) and English (en).",
@@ -32539,7 +33822,7 @@ var FIELDS11 = {
32539
33822
  keywords: "Total organic keywords the page ranks for",
32540
33823
  top_10: "Keywords in positions 1-10"
32541
33824
  };
32542
- var relevantPagesCommand = defineCommand150({
33825
+ var relevantPagesCommand = defineCommand153({
32543
33826
  meta: {
32544
33827
  name: "relevant-pages",
32545
33828
  description: `Get the top pages of a competitor domain with traffic data.
@@ -32585,7 +33868,7 @@ Examples:
32585
33868
  });
32586
33869
 
32587
33870
  // src/commands/research/web.ts
32588
- import { defineCommand as defineCommand151 } from "citty";
33871
+ import { defineCommand as defineCommand154 } from "citty";
32589
33872
  registerSchema({
32590
33873
  command: "research.web",
32591
33874
  description: "Search the web with AI to answer marketing questions \u2014 competitors, ICP, pricing, pain points, market trends. Three depth levels: medium (quick, default), high (thorough), xhigh (exhaustive deep research).",
@@ -32636,7 +33919,7 @@ async function runDeepResearch(question) {
32636
33919
  }
32637
33920
  throw new Error("Deep research timed out");
32638
33921
  }
32639
- var webCommand = defineCommand151({
33922
+ var webCommand = defineCommand154({
32640
33923
  meta: {
32641
33924
  name: "web",
32642
33925
  description: `Search the web with AI to answer any open-ended marketing question. Uses live internet data via Google Search.
@@ -32696,7 +33979,7 @@ Examples:
32696
33979
  });
32697
33980
 
32698
33981
  // src/commands/research/index.ts
32699
- var researchCommand = defineCommand152({
33982
+ var researchCommand = defineCommand155({
32700
33983
  meta: {
32701
33984
  name: "research",
32702
33985
  description: `Competitive intelligence and AI-powered research commands.
@@ -32737,10 +34020,10 @@ Full guide: __tooling__/docs/tools/baker/research.md`
32737
34020
  });
32738
34021
 
32739
34022
  // src/commands/scheduled-actions/index.ts
32740
- import { defineCommand as defineCommand159 } from "citty";
34023
+ import { defineCommand as defineCommand162 } from "citty";
32741
34024
 
32742
34025
  // src/commands/scheduled-actions/create.ts
32743
- import { defineCommand as defineCommand153 } from "citty";
34026
+ import { defineCommand as defineCommand156 } from "citty";
32744
34027
 
32745
34028
  // src/commands/scheduled-actions/shared.ts
32746
34029
  var TEMP_SCHEDULED_ACTION_PREFIX = "temp_sched_";
@@ -32748,7 +34031,7 @@ var TEMP_ID_PREFIX = "temp_";
32748
34031
  function writeOk2(data) {
32749
34032
  writeJson({ ok: true, data: data ?? null });
32750
34033
  }
32751
- function failValidation2(message) {
34034
+ function failValidation3(message) {
32752
34035
  writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message } });
32753
34036
  process.exit(1);
32754
34037
  }
@@ -32772,7 +34055,7 @@ function isOtherTempId(id) {
32772
34055
  }
32773
34056
  function validateScheduledActionRef(ref) {
32774
34057
  if (isOtherTempId(ref)) {
32775
- failValidation2(`Scheduled action temp IDs must start with ${TEMP_SCHEDULED_ACTION_PREFIX}.`);
34058
+ failValidation3(`Scheduled action temp IDs must start with ${TEMP_SCHEDULED_ACTION_PREFIX}.`);
32776
34059
  }
32777
34060
  if (!isTempScheduledActionId(ref)) {
32778
34061
  validateConvexId(ref);
@@ -32786,7 +34069,7 @@ function isPromptWithoutAgent(args, agentDisabled) {
32786
34069
  }
32787
34070
  function failIfPromptWithoutAgent(args, agentDisabled) {
32788
34071
  if (isPromptWithoutAgent(args, agentDisabled)) {
32789
- failValidation2(
34072
+ failValidation3(
32790
34073
  "--prompt only applies when an agent is spawned; it has no effect with --no-spawn-agent or --spawn-agent false."
32791
34074
  );
32792
34075
  }
@@ -32801,21 +34084,21 @@ function parseBooleanFlag(raw, flagName) {
32801
34084
  if (raw === false || raw === "false") {
32802
34085
  return false;
32803
34086
  }
32804
- failValidation2(`${flagName} must be true or false.`);
34087
+ failValidation3(`${flagName} must be true or false.`);
32805
34088
  }
32806
34089
  function buildScheduleBody(args, options) {
32807
34090
  const cron = args.cron;
32808
34091
  const runAt = args["run-at"];
32809
34092
  const timezone = args.timezone;
32810
34093
  if (cron && runAt) {
32811
- failValidation2("--cron and --run-at are mutually exclusive.");
34094
+ failValidation3("--cron and --run-at are mutually exclusive.");
32812
34095
  }
32813
34096
  if (runAt) {
32814
34097
  if (!runAt.endsWith("Z")) {
32815
- failValidation2("--run-at must be an ISO UTC timestamp ending in Z.");
34098
+ failValidation3("--run-at must be an ISO UTC timestamp ending in Z.");
32816
34099
  }
32817
34100
  if (!Number.isFinite(Date.parse(runAt))) {
32818
- failValidation2("--run-at must be a valid ISO timestamp.");
34101
+ failValidation3("--run-at must be a valid ISO timestamp.");
32819
34102
  }
32820
34103
  return { runAt, ...timezone ? { timezone } : {} };
32821
34104
  }
@@ -32826,7 +34109,7 @@ function buildScheduleBody(args, options) {
32826
34109
  return { timezone };
32827
34110
  }
32828
34111
  if (options.required) {
32829
- failValidation2("Provide exactly one of --cron or --run-at.");
34112
+ failValidation3("Provide exactly one of --cron or --run-at.");
32830
34113
  }
32831
34114
  return void 0;
32832
34115
  }
@@ -32855,7 +34138,7 @@ registerSchema({
32855
34138
  prompt: { type: "string", description: "Additional prompt instructions for the spawned agent", required: false }
32856
34139
  }
32857
34140
  });
32858
- var createCommand2 = defineCommand153({
34141
+ var createCommand2 = defineCommand156({
32859
34142
  meta: {
32860
34143
  name: "create",
32861
34144
  description: 'Stage a scheduled action. Example: baker scheduled-actions create --name "Weekly report" --description "..." --cron "0 9 * * MON"'
@@ -32875,10 +34158,10 @@ var createCommand2 = defineCommand153({
32875
34158
  const name = args.name;
32876
34159
  const description = args.description;
32877
34160
  if (!name || name.trim().length === 0) {
32878
- failValidation2("--name is required.");
34161
+ failValidation3("--name is required.");
32879
34162
  }
32880
34163
  if (!description || description.trim().length === 0) {
32881
- failValidation2("--description is required.");
34164
+ failValidation3("--description is required.");
32882
34165
  }
32883
34166
  const schedule = buildScheduleBody(args, { required: true });
32884
34167
  const chatId = requireChatId();
@@ -32904,7 +34187,7 @@ var createCommand2 = defineCommand153({
32904
34187
  });
32905
34188
 
32906
34189
  // src/commands/scheduled-actions/delete.ts
32907
- import { defineCommand as defineCommand154 } from "citty";
34190
+ import { defineCommand as defineCommand157 } from "citty";
32908
34191
  registerSchema({
32909
34192
  command: "scheduled-actions.delete",
32910
34193
  description: "Stage deletion of a published scheduled action or cancellation of a temp_sched_* draft creation.",
@@ -32912,7 +34195,7 @@ registerSchema({
32912
34195
  id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
32913
34196
  }
32914
34197
  });
32915
- var deleteCommand2 = defineCommand154({
34198
+ var deleteCommand2 = defineCommand157({
32916
34199
  meta: {
32917
34200
  name: "delete",
32918
34201
  description: "Stage scheduled action deletion. Example: baker scheduled-actions delete <id-or-temp_sched_id>"
@@ -32929,7 +34212,7 @@ var deleteCommand2 = defineCommand154({
32929
34212
  try {
32930
34213
  const id = args.id || args["scheduled-action-id"];
32931
34214
  if (!id) {
32932
- failValidation2("Scheduled action ID is required.");
34215
+ failValidation3("Scheduled action ID is required.");
32933
34216
  }
32934
34217
  validateScheduledActionRef(id);
32935
34218
  await apiPost("/api/scheduled-actions/delete", { chatId: requireChatId(), id });
@@ -32941,15 +34224,16 @@ var deleteCommand2 = defineCommand154({
32941
34224
  });
32942
34225
 
32943
34226
  // src/commands/scheduled-actions/get.ts
32944
- import { defineCommand as defineCommand155 } from "citty";
34227
+ import { defineCommand as defineCommand158 } from "citty";
32945
34228
  registerSchema({
32946
34229
  command: "scheduled-actions.get",
32947
34230
  description: "Get a published scheduled action or a temp_sched_* draft-created scheduled action.",
32948
34231
  args: {
32949
- id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
34232
+ id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true },
34233
+ chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
32950
34234
  }
32951
34235
  });
32952
- var getCommand3 = defineCommand155({
34236
+ var getCommand3 = defineCommand158({
32953
34237
  meta: {
32954
34238
  name: "get",
32955
34239
  description: "Get a scheduled action. Example: baker scheduled-actions get <id-or-temp_sched_id>"
@@ -32960,22 +34244,24 @@ var getCommand3 = defineCommand155({
32960
34244
  type: "string",
32961
34245
  description: "Scheduled action ID (alternative to positional)",
32962
34246
  required: false
32963
- }
34247
+ },
34248
+ chat: CHAT_READ_ARG
32964
34249
  },
32965
34250
  run: async ({ args }) => {
32966
34251
  try {
32967
34252
  const id = args.id || args["scheduled-action-id"];
32968
34253
  if (!id) {
32969
- failValidation2("Scheduled action ID is required.");
34254
+ failValidation3("Scheduled action ID is required.");
32970
34255
  }
32971
34256
  validateScheduledActionRef(id);
32972
34257
  const env = getEnv();
32973
- if (isTempScheduledActionId(id) && !env.BAKER_CHAT_ID) {
32974
- failValidation2("BAKER_CHAT_ID is required to get a temp scheduled action ID.");
34258
+ const chatId = typeof args.chat === "string" && args.chat.length > 0 ? args.chat : env.BAKER_CHAT_ID;
34259
+ if (isTempScheduledActionId(id) && !chatId) {
34260
+ failValidation3("BAKER_CHAT_ID or --chat is required to get a temp scheduled action ID.");
32975
34261
  }
32976
34262
  const body = { id };
32977
- if (env.BAKER_CHAT_ID) {
32978
- body.chatId = env.BAKER_CHAT_ID;
34263
+ if (chatId) {
34264
+ body.chatId = chatId;
32979
34265
  }
32980
34266
  const response = await apiPost("/api/scheduled-actions/get", body);
32981
34267
  writeJson(response);
@@ -32986,23 +34272,27 @@ var getCommand3 = defineCommand155({
32986
34272
  });
32987
34273
 
32988
34274
  // src/commands/scheduled-actions/list.ts
32989
- import { defineCommand as defineCommand156 } from "citty";
34275
+ import { defineCommand as defineCommand159 } from "citty";
32990
34276
  registerSchema({
32991
34277
  command: "scheduled-actions.list",
32992
- description: "List published scheduled actions. Includes draft state when BAKER_CHAT_ID is set.",
32993
- args: {}
34278
+ description: "List published scheduled actions. Includes draft state when BAKER_CHAT_ID is set, or --chat <id> to read an earlier chat's staged schedules instead.",
34279
+ args: {
34280
+ chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
34281
+ }
32994
34282
  });
32995
- var listCommand14 = defineCommand156({
34283
+ var listCommand14 = defineCommand159({
32996
34284
  meta: {
32997
34285
  name: "list",
32998
- description: "List scheduled actions. Includes staged draft ops when BAKER_CHAT_ID is set."
34286
+ description: "List scheduled actions. Includes staged draft ops when BAKER_CHAT_ID is set, or --chat <id> to read an earlier chat's staged schedules instead."
32999
34287
  },
33000
- run: async () => {
34288
+ args: { chat: CHAT_READ_ARG },
34289
+ run: async ({ args }) => {
33001
34290
  try {
33002
34291
  const env = getEnv();
33003
34292
  const body = {};
33004
- if (env.BAKER_CHAT_ID) {
33005
- body.chatId = env.BAKER_CHAT_ID;
34293
+ const chatId = typeof args.chat === "string" && args.chat.length > 0 ? args.chat : env.BAKER_CHAT_ID;
34294
+ if (chatId) {
34295
+ body.chatId = chatId;
33006
34296
  }
33007
34297
  const response = await apiPost("/api/scheduled-actions/list", body);
33008
34298
  writeJson(response);
@@ -33013,7 +34303,7 @@ var listCommand14 = defineCommand156({
33013
34303
  });
33014
34304
 
33015
34305
  // src/commands/scheduled-actions/trigger.ts
33016
- import { defineCommand as defineCommand157 } from "citty";
34306
+ import { defineCommand as defineCommand160 } from "citty";
33017
34307
  registerSchema({
33018
34308
  command: "scheduled-actions.trigger",
33019
34309
  description: "Immediately trigger a published scheduled action. Does not require BAKER_CHAT_ID and rejects temp_sched_* IDs.",
@@ -33021,7 +34311,7 @@ registerSchema({
33021
34311
  id: { type: "string", description: "Published scheduled action ID", required: true }
33022
34312
  }
33023
34313
  });
33024
- var triggerCommand = defineCommand157({
34314
+ var triggerCommand = defineCommand160({
33025
34315
  meta: {
33026
34316
  name: "trigger",
33027
34317
  description: "Immediately trigger a published scheduled action. Example: baker scheduled-actions trigger <id>"
@@ -33038,10 +34328,10 @@ var triggerCommand = defineCommand157({
33038
34328
  try {
33039
34329
  const id = args.id || args["scheduled-action-id"];
33040
34330
  if (!id) {
33041
- failValidation2("Scheduled action ID is required.");
34331
+ failValidation3("Scheduled action ID is required.");
33042
34332
  }
33043
34333
  if (isTempScheduledActionId(id)) {
33044
- failValidation2("trigger requires a published scheduled action ID, not temp_sched_*.");
34334
+ failValidation3("trigger requires a published scheduled action ID, not temp_sched_*.");
33045
34335
  }
33046
34336
  validateConvexId(id);
33047
34337
  const env = getEnv();
@@ -33058,7 +34348,7 @@ var triggerCommand = defineCommand157({
33058
34348
  });
33059
34349
 
33060
34350
  // src/commands/scheduled-actions/update.ts
33061
- import { defineCommand as defineCommand158 } from "citty";
34351
+ import { defineCommand as defineCommand161 } from "citty";
33062
34352
  registerSchema({
33063
34353
  command: "scheduled-actions.update",
33064
34354
  description: "Stage an update to a published scheduled action or temp_sched_* draft-created scheduled action.",
@@ -33083,7 +34373,7 @@ registerSchema({
33083
34373
  prompt: { type: "string", description: "Replacement additional spawned-agent instructions", required: false }
33084
34374
  }
33085
34375
  });
33086
- var updateCommand2 = defineCommand158({
34376
+ var updateCommand2 = defineCommand161({
33087
34377
  meta: {
33088
34378
  name: "update",
33089
34379
  description: "Stage a scheduled action update. Example: baker scheduled-actions update <id> --enabled false"
@@ -33108,7 +34398,7 @@ var updateCommand2 = defineCommand158({
33108
34398
  try {
33109
34399
  const id = args.id || args["scheduled-action-id"];
33110
34400
  if (!id) {
33111
- failValidation2("Scheduled action ID is required.");
34401
+ failValidation3("Scheduled action ID is required.");
33112
34402
  }
33113
34403
  validateScheduledActionRef(id);
33114
34404
  const body = { id };
@@ -33140,7 +34430,7 @@ var updateCommand2 = defineCommand158({
33140
34430
  hasPatch = true;
33141
34431
  }
33142
34432
  if (!hasPatch) {
33143
- failValidation2(
34433
+ failValidation3(
33144
34434
  "Provide at least one of --name, --description, --cron, --run-at, --timezone, --enabled, --spawn-agent, --prompt."
33145
34435
  );
33146
34436
  }
@@ -33154,7 +34444,7 @@ var updateCommand2 = defineCommand158({
33154
34444
  });
33155
34445
 
33156
34446
  // src/commands/scheduled-actions/index.ts
33157
- var scheduledActionsCommand = defineCommand159({
34447
+ var scheduledActionsCommand = defineCommand162({
33158
34448
  meta: {
33159
34449
  name: "scheduled-actions",
33160
34450
  description: `Manage Scheduled Actions. Subcommands: list, get, create, update, delete, trigger.
@@ -33181,14 +34471,14 @@ Full guide: __tooling__/docs/tools/baker/scheduled-actions.md`
33181
34471
  });
33182
34472
 
33183
34473
  // src/commands/schema.ts
33184
- import { defineCommand as defineCommand160 } from "citty";
34474
+ import { defineCommand as defineCommand163 } from "citty";
33185
34475
  function narrowToFamily(commandName, available) {
33186
34476
  const segments = commandName.split(".");
33187
34477
  const prefix = segments[0] === "ads" && segments[1] ? `ads.${segments[1]}.` : `${segments[0]}.`;
33188
34478
  const siblings = available.filter((name) => name.startsWith(prefix));
33189
34479
  return siblings.length > 0 ? siblings : available;
33190
34480
  }
33191
- var schemaCommand = defineCommand160({
34481
+ var schemaCommand = defineCommand163({
33192
34482
  meta: {
33193
34483
  name: "schema",
33194
34484
  description: "Inspect command argument schemas (for AI agent introspection). Lists all commands if no argument given. Example: baker schema images.search"
@@ -33232,44 +34522,44 @@ var schemaCommand = defineCommand160({
33232
34522
  });
33233
34523
 
33234
34524
  // src/commands/tag-manager/index.ts
33235
- import { defineCommand as defineCommand164 } from "citty";
34525
+ import { defineCommand as defineCommand167 } from "citty";
33236
34526
 
33237
34527
  // src/commands/tag-manager/draft.ts
33238
- import { defineCommand as defineCommand161 } from "citty";
34528
+ import { defineCommand as defineCommand164 } from "citty";
33239
34529
 
33240
34530
  // src/commands/tag-manager/shared.ts
33241
- import { readFileSync as readFileSync12 } from "fs";
33242
- function failValidation3(message) {
34531
+ import { readFileSync as readFileSync13 } from "fs";
34532
+ function failValidation4(message) {
33243
34533
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
33244
34534
  process.exit(1);
33245
34535
  }
33246
- function requireTarget4(args, entity) {
34536
+ function requireTarget5(args, entity) {
33247
34537
  const positional = Array.isArray(args._) ? args._[0] : void 0;
33248
34538
  const target = args.id ?? args.target ?? positional;
33249
34539
  if (typeof target !== "string" || target.length === 0) {
33250
- failValidation3(`pass the ${entity} id or path as the positional argument`);
34540
+ failValidation4(`pass the ${entity} id or path as the positional argument`);
33251
34541
  }
33252
34542
  return target;
33253
34543
  }
33254
- function loadJsonArg(args, flag = "json") {
34544
+ function loadJsonArg2(args, flag = "json") {
33255
34545
  const inline = args[flag];
33256
34546
  const file = args.file;
33257
- const raw = typeof file === "string" && file.length > 0 ? readFileSync12(file, "utf8") : typeof inline === "string" && inline.length > 0 ? inline : void 0;
34547
+ const raw = typeof file === "string" && file.length > 0 ? readFileSync13(file, "utf8") : typeof inline === "string" && inline.length > 0 ? inline : void 0;
33258
34548
  if (raw === void 0) {
33259
- failValidation3(`pass --${flag} with inline JSON or --file with a path to a JSON file`);
34549
+ failValidation4(`pass --${flag} with inline JSON or --file with a path to a JSON file`);
33260
34550
  }
33261
34551
  try {
33262
34552
  const parsed = JSON.parse(raw);
33263
34553
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
33264
- failValidation3(`--${flag} must be a JSON object`);
34554
+ failValidation4(`--${flag} must be a JSON object`);
33265
34555
  }
33266
34556
  return parsed;
33267
34557
  } catch {
33268
- return failValidation3(`--${flag} is not valid JSON`);
34558
+ return failValidation4(`--${flag} is not valid JSON`);
33269
34559
  }
33270
34560
  }
33271
- var RETRYABLE_CODES = /* @__PURE__ */ new Set(["RATE_LIMITED", "INTERNAL_ERROR", "NETWORK_ERROR", "TIMEOUT"]);
33272
- function handleError3(err) {
34561
+ var RETRYABLE_CODES2 = /* @__PURE__ */ new Set(["RATE_LIMITED", "INTERNAL_ERROR", "NETWORK_ERROR", "TIMEOUT"]);
34562
+ function handleError4(err) {
33273
34563
  if (err instanceof ApiError) {
33274
34564
  writeJsonEnvelope({
33275
34565
  ok: false,
@@ -33282,7 +34572,7 @@ function handleError3(err) {
33282
34572
  explanation: 'Tag Manager is not connected for this company yet, or no container has been picked. Do NOT send the user to Settings \u2014 call the `request_connection` tool with { platform: "google-tag-manager", reason } and they connect and pick their containers (they can pick more than one) from inside the chat. `request_tag_input` is NOT the route: that form manages the container snippet on the site, not what runs inside the container, and it cannot pick a container. If `request_connection` is not available to you, say so plainly and point them at dashboard \u2192 Brain \u2192 Integrations \u2192 Tools \u2192 Google Tag Manager, where they also pick the container. Carry on with the rest of the task meanwhile.'
33283
34573
  }
33284
34574
  } : {},
33285
- retryable: RETRYABLE_CODES.has(err.code)
34575
+ retryable: RETRYABLE_CODES2.has(err.code)
33286
34576
  }
33287
34577
  });
33288
34578
  process.exit(1);
@@ -33290,29 +34580,29 @@ function handleError3(err) {
33290
34580
  writeJsonEnvelope({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error", retryable: true } });
33291
34581
  process.exit(1);
33292
34582
  }
33293
- var STAGE_HINTS = [
34583
+ var STAGE_HINTS2 = [
33294
34584
  "Staged only \u2014 nothing has changed in Tag Manager yet. These apply when the chat completes, in dependency order, and close as a Tag Manager version that is then published, so they do go live on the user's site. Say the changes are ready and go live when they publish \u2014 not that they are live already."
33295
34585
  ];
33296
- async function stageOp3(op) {
34586
+ async function stageOp4(op) {
33297
34587
  const chatId = requireChatId();
33298
34588
  try {
33299
34589
  const data = await apiPost("/api/tag-manager/draft/stage", { chatId, op });
33300
- writeJsonEnvelope({ ok: true, data, hints: STAGE_HINTS });
34590
+ writeJsonEnvelope({ ok: true, data, hints: STAGE_HINTS2 });
33301
34591
  } catch (err) {
33302
- handleError3(err);
34592
+ handleError4(err);
33303
34593
  }
33304
34594
  }
33305
- async function draftAction2(path28, body) {
33306
- const chatId = requireChatId();
34595
+ async function draftAction3(path28, body, chat) {
34596
+ const chatId = resolveChatId(chat);
33307
34597
  try {
33308
34598
  const data = await apiPost(path28, { chatId, ...body });
33309
34599
  writeJsonEnvelope({ ok: true, data });
33310
34600
  return data;
33311
34601
  } catch (err) {
33312
- handleError3(err);
34602
+ handleError4(err);
33313
34603
  }
33314
34604
  }
33315
- function renderDraft(response) {
34605
+ function renderDraft2(response) {
33316
34606
  if (response.count === 0) {
33317
34607
  return "No Tag Manager changes staged on this chat.";
33318
34608
  }
@@ -33334,58 +34624,67 @@ function renderDraft(response) {
33334
34624
  }
33335
34625
  return lines.join("\n");
33336
34626
  }
33337
- async function draftList(json) {
33338
- const chatId = requireChatId();
34627
+ async function draftList2(json, chat) {
34628
+ const chatId = resolveChatId(chat);
33339
34629
  try {
33340
34630
  const data = await apiPost("/api/tag-manager/draft", { chatId });
33341
34631
  if (json) {
33342
34632
  writeJsonEnvelope({ ok: true, data });
33343
34633
  return;
33344
34634
  }
33345
- process.stdout.write(`${renderDraft(data)}
34635
+ process.stdout.write(`${renderDraft2(data)}
33346
34636
  `);
33347
34637
  } catch (err) {
33348
- handleError3(err);
34638
+ handleError4(err);
33349
34639
  }
33350
34640
  }
33351
34641
 
33352
34642
  // src/commands/tag-manager/draft.ts
33353
34643
  registerSchema({
33354
34644
  command: "tagManager.draft",
33355
- 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.",
34645
+ 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. `list` and `show` take --chat <id> to read an earlier chat's changes instead.",
33356
34646
  args: {
33357
- json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list", required: false }
34647
+ json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list", required: false },
34648
+ chat: { type: "string", description: CHAT_READ_ARG.description, required: false }
33358
34649
  }
33359
34650
  });
33360
- var draftCommand3 = defineCommand161({
34651
+ var draftCommand4 = defineCommand164({
33361
34652
  meta: {
33362
34653
  name: "draft",
33363
- description: "List, show, amend, remove, or clear staged Tag Manager changes for this chat"
34654
+ description: "List, show, amend, remove, or clear staged Tag Manager changes for this chat. `list` and `show` take --chat <id> to read an earlier chat's changes instead."
33364
34655
  },
33365
34656
  subCommands: {
33366
- list: defineCommand161({
34657
+ list: defineCommand164({
33367
34658
  meta: {
33368
34659
  name: "list",
33369
34660
  description: "Review everything staged on this chat (--json for the raw envelope)"
33370
34661
  },
33371
- args: { json: { type: "boolean", description: "Print the raw JSON envelope", required: false } },
34662
+ args: {
34663
+ json: { type: "boolean", description: "Print the raw JSON envelope", required: false },
34664
+ chat: CHAT_READ_ARG
34665
+ },
33372
34666
  run: async ({ args }) => {
33373
- await draftList(args.json === true);
34667
+ await draftList2(args.json === true, args.chat);
33374
34668
  }
33375
34669
  }),
33376
- show: defineCommand161({
34670
+ show: defineCommand164({
33377
34671
  meta: {
33378
34672
  name: "show",
33379
34673
  description: "Print the full staged payload for one change \u2014 the receipt to verify it looks right before publish (never truncated)."
33380
34674
  },
33381
- args: { ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false } },
34675
+ args: {
34676
+ ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false },
34677
+ chat: CHAT_READ_ARG
34678
+ },
33382
34679
  run: async ({ args }) => {
33383
- await draftAction2("/api/tag-manager/draft/show", {
33384
- ref: requireTarget4(args, "change")
33385
- });
34680
+ await draftAction3(
34681
+ "/api/tag-manager/draft/show",
34682
+ { ref: requireTarget5(args, "change") },
34683
+ args.chat
34684
+ );
33386
34685
  }
33387
34686
  }),
33388
- amend: defineCommand161({
34687
+ amend: defineCommand164({
33389
34688
  meta: {
33390
34689
  name: "amend",
33391
34690
  description: "Update a staged change in place \u2014 merges a JSON patch into its payload (objects deep-merge, null deletes a key, arrays/scalars replace) and re-validates. Use this instead of remove + re-create."
@@ -33396,32 +34695,32 @@ var draftCommand3 = defineCommand161({
33396
34695
  file: { type: "string", description: "JSON file with the patch object", required: false }
33397
34696
  },
33398
34697
  run: async ({ args }) => {
33399
- await draftAction2("/api/tag-manager/draft/amend", {
33400
- ref: requireTarget4(args, "change"),
33401
- patch: loadJsonArg(args, "patch")
34698
+ await draftAction3("/api/tag-manager/draft/amend", {
34699
+ ref: requireTarget5(args, "change"),
34700
+ patch: loadJsonArg2(args, "patch")
33402
34701
  });
33403
34702
  }
33404
34703
  }),
33405
- remove: defineCommand161({
34704
+ remove: defineCommand164({
33406
34705
  meta: { name: "remove", description: "Remove one staged change (cascades to anything depending on it)" },
33407
34706
  args: { ref: { type: "positional", description: "Staged ref (gtm_temp_*) or target", required: false } },
33408
34707
  run: async ({ args }) => {
33409
- await draftAction2("/api/tag-manager/draft/remove", {
33410
- ref: requireTarget4(args, "change")
34708
+ await draftAction3("/api/tag-manager/draft/remove", {
34709
+ ref: requireTarget5(args, "change")
33411
34710
  });
33412
34711
  }
33413
34712
  }),
33414
- clear: defineCommand161({
34713
+ clear: defineCommand164({
33415
34714
  meta: { name: "clear", description: "Discard all Tag Manager changes staged on this chat" },
33416
34715
  run: async () => {
33417
- await draftAction2("/api/tag-manager/draft/clear", {});
34716
+ await draftAction3("/api/tag-manager/draft/clear", {});
33418
34717
  }
33419
34718
  })
33420
34719
  }
33421
34720
  });
33422
34721
 
33423
34722
  // src/commands/tag-manager/read.ts
33424
- import { defineCommand as defineCommand162 } from "citty";
34723
+ import { defineCommand as defineCommand165 } from "citty";
33425
34724
  registerSchema({
33426
34725
  command: "tagManager.containers",
33427
34726
  description: "List the Google Tag Manager containers this company's connection can reach. Every container the company connected is flagged `connected: true` \u2014 there can be several, and Baker may read and change all of them. Start here to confirm which containers you are managing.",
@@ -33462,7 +34761,7 @@ function containersHints(containers) {
33462
34761
  }))
33463
34762
  });
33464
34763
  }
33465
- var containersCommand = defineCommand162({
34764
+ var containersCommand = defineCommand165({
33466
34765
  meta: {
33467
34766
  name: "containers",
33468
34767
  description: `List Tag Manager containers reachable by this company's connection.
@@ -33475,11 +34774,11 @@ Start here:
33475
34774
  const data = await apiGet("/api/tag-manager/containers");
33476
34775
  writeJsonEnvelope({ ok: true, data, hints: containersHints(data.containers) });
33477
34776
  } catch (err) {
33478
- handleError3(err);
34777
+ handleError4(err);
33479
34778
  }
33480
34779
  }
33481
34780
  });
33482
- var readCommand = defineCommand162({
34781
+ var readCommand = defineCommand165({
33483
34782
  meta: {
33484
34783
  name: "read",
33485
34784
  description: `Read the current contents of the Tag Manager container \u2014 always do this before staging changes.
@@ -33515,13 +34814,13 @@ Examples:
33515
34814
  );
33516
34815
  writeJsonEnvelope({ ok: true, data, hints });
33517
34816
  } catch (err) {
33518
- handleError3(err);
34817
+ handleError4(err);
33519
34818
  }
33520
34819
  }
33521
34820
  });
33522
34821
 
33523
34822
  // src/commands/tag-manager/write-commands.ts
33524
- import { defineCommand as defineCommand163 } from "citty";
34823
+ import { defineCommand as defineCommand166 } from "citty";
33525
34824
  var CONTAINER_ARG_DESCRIPTION = "Numeric container id (optional only when one container is connected \u2014 run `baker tag-manager containers`)";
33526
34825
  var ENTITIES = [
33527
34826
  {
@@ -33577,10 +34876,10 @@ for (const { entity, noun, createHint } of ENTITIES) {
33577
34876
  });
33578
34877
  }
33579
34878
  function entityCommand(entity, noun, example) {
33580
- return defineCommand163({
34879
+ return defineCommand166({
33581
34880
  meta: { name: entity, description: `Stage ${noun} changes on this chat's Tag Manager draft` },
33582
34881
  subCommands: {
33583
- create: defineCommand163({
34882
+ create: defineCommand166({
33584
34883
  meta: {
33585
34884
  name: "create",
33586
34885
  description: `Stage a new ${noun}
@@ -33595,14 +34894,14 @@ Examples:
33595
34894
  container: { type: "string", description: CONTAINER_ARG_DESCRIPTION, required: false }
33596
34895
  },
33597
34896
  run: async ({ args }) => {
33598
- await stageOp3({
34897
+ await stageOp4({
33599
34898
  kind: `tagManager.${entity}.create`,
33600
- payload: loadJsonArg(args),
34899
+ payload: loadJsonArg2(args),
33601
34900
  ...typeof args.container === "string" ? { containerId: args.container } : {}
33602
34901
  });
33603
34902
  }
33604
34903
  }),
33605
- update: defineCommand163({
34904
+ update: defineCommand166({
33606
34905
  meta: {
33607
34906
  name: "update",
33608
34907
  description: `Stage an update to an existing ${noun} (pass its id or path)`
@@ -33614,24 +34913,24 @@ Examples:
33614
34913
  container: { type: "string", description: CONTAINER_ARG_DESCRIPTION, required: false }
33615
34914
  },
33616
34915
  run: async ({ args }) => {
33617
- await stageOp3({
34916
+ await stageOp4({
33618
34917
  kind: `tagManager.${entity}.update`,
33619
- target: requireTarget4(args, noun),
33620
- payload: loadJsonArg(args),
34918
+ target: requireTarget5(args, noun),
34919
+ payload: loadJsonArg2(args),
33621
34920
  ...typeof args.container === "string" ? { containerId: args.container } : {}
33622
34921
  });
33623
34922
  }
33624
34923
  }),
33625
- delete: defineCommand163({
34924
+ delete: defineCommand166({
33626
34925
  meta: { name: "delete", description: `Stage the deletion of a ${noun} (pass its id or path)` },
33627
34926
  args: {
33628
34927
  id: { type: "positional", description: `${noun} id or path`, required: false },
33629
34928
  container: { type: "string", description: CONTAINER_ARG_DESCRIPTION, required: false }
33630
34929
  },
33631
34930
  run: async ({ args }) => {
33632
- await stageOp3({
34931
+ await stageOp4({
33633
34932
  kind: `tagManager.${entity}.delete`,
33634
- target: requireTarget4(args, noun),
34933
+ target: requireTarget5(args, noun),
33635
34934
  ...typeof args.container === "string" ? { containerId: args.container } : {}
33636
34935
  });
33637
34936
  }
@@ -33663,7 +34962,7 @@ function builtinTypes(args) {
33663
34962
  }
33664
34963
  return raw.split(",").map((entry) => entry.trim());
33665
34964
  }
33666
- var builtinCommand = defineCommand163({
34965
+ var builtinCommand = defineCommand166({
33667
34966
  meta: {
33668
34967
  name: "builtin",
33669
34968
  description: `Enable or disable built-in variables
@@ -33673,28 +34972,28 @@ Examples:
33673
34972
  baker tag-manager builtin disable --types formId`
33674
34973
  },
33675
34974
  subCommands: {
33676
- enable: defineCommand163({
34975
+ enable: defineCommand166({
33677
34976
  meta: { name: "enable", description: "Stage enabling built-in variables" },
33678
34977
  args: {
33679
34978
  types: { type: "string", description: "Comma-separated types", required: false },
33680
34979
  container: { type: "string", description: CONTAINER_ARG_DESCRIPTION, required: false }
33681
34980
  },
33682
34981
  run: async ({ args }) => {
33683
- await stageOp3({
34982
+ await stageOp4({
33684
34983
  kind: "tagManager.builtInVariable.enable",
33685
34984
  payload: { type: builtinTypes(args) },
33686
34985
  ...typeof args.container === "string" ? { containerId: args.container } : {}
33687
34986
  });
33688
34987
  }
33689
34988
  }),
33690
- disable: defineCommand163({
34989
+ disable: defineCommand166({
33691
34990
  meta: { name: "disable", description: "Stage disabling built-in variables" },
33692
34991
  args: {
33693
34992
  types: { type: "string", description: "Comma-separated types", required: false },
33694
34993
  container: { type: "string", description: CONTAINER_ARG_DESCRIPTION, required: false }
33695
34994
  },
33696
34995
  run: async ({ args }) => {
33697
- await stageOp3({
34996
+ await stageOp4({
33698
34997
  kind: "tagManager.builtInVariable.disable",
33699
34998
  payload: { type: builtinTypes(args) },
33700
34999
  ...typeof args.container === "string" ? { containerId: args.container } : {}
@@ -33705,7 +35004,7 @@ Examples:
33705
35004
  });
33706
35005
 
33707
35006
  // src/commands/tag-manager/index.ts
33708
- var tagManagerCommand = defineCommand164({
35007
+ var tagManagerCommand = defineCommand167({
33709
35008
  meta: {
33710
35009
  name: "tag-manager",
33711
35010
  description: `Read and change what lives inside the client's Google Tag Manager container \u2014 tags, triggers, variables, folders and built-in variables.
@@ -33734,12 +35033,12 @@ Full guide: __tooling__/docs/tools/baker/tag-manager.md`
33734
35033
  variable: variableCommand,
33735
35034
  folder: folderCommand,
33736
35035
  builtin: builtinCommand,
33737
- draft: draftCommand3
35036
+ draft: draftCommand4
33738
35037
  }
33739
35038
  });
33740
35039
 
33741
35040
  // src/commands/tags/index.ts
33742
- import { defineCommand as defineCommand165 } from "citty";
35041
+ import { defineCommand as defineCommand168 } from "citty";
33743
35042
 
33744
35043
  // src/commands/tags/shared.ts
33745
35044
  function failApi3(err) {
@@ -33808,7 +35107,7 @@ async function listTags(json) {
33808
35107
  var listArgs9 = {
33809
35108
  json: { type: "boolean", description: "Print the raw JSON envelope instead of the readable list" }
33810
35109
  };
33811
- var listCommand15 = defineCommand165({
35110
+ var listCommand15 = defineCommand168({
33812
35111
  meta: {
33813
35112
  name: "list",
33814
35113
  description: "Effective tags for this chat (production + staged), with each tag's full readable config (secrets excluded) \u2014 reuse a stored value to pre-fill a change rather than asking the user. Refs printed here are what flow side-effect tagIds should use. Example: baker tags list"
@@ -33818,25 +35117,26 @@ var listCommand15 = defineCommand165({
33818
35117
  await listTags(args.json === true);
33819
35118
  }
33820
35119
  });
33821
- async function listDraft3() {
35120
+ async function listDraft3(chat) {
33822
35121
  try {
33823
- const chatId = requireChatId();
35122
+ const chatId = resolveChatId(chat);
33824
35123
  const response = await apiPost("/api/tags/draft", { chatId });
33825
35124
  writeJson({ ok: true, data: response });
33826
35125
  } catch (err) {
33827
35126
  failApi3(err);
33828
35127
  }
33829
35128
  }
33830
- var draftCommand4 = defineCommand165({
35129
+ var draftCommand5 = defineCommand168({
33831
35130
  meta: {
33832
35131
  name: "draft",
33833
- 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)."
35132
+ description: "Review the tag changes staged in this chat (read-only). Staged changes were approved via request_tag_input and apply when the chat is published; to amend or drop one, propose a follow-up change through the same tool (a delete on a tag_temp_* ref drops the staged create). Takes --chat <id> to read an earlier chat's staged changes instead."
33834
35133
  },
33835
- run: async () => {
33836
- await listDraft3();
35134
+ args: { chat: CHAT_READ_ARG },
35135
+ run: async ({ args }) => {
35136
+ await listDraft3(args.chat);
33837
35137
  }
33838
35138
  });
33839
- var tagsCommand3 = defineCommand165({
35139
+ var tagsCommand3 = defineCommand168({
33840
35140
  meta: {
33841
35141
  name: "tags",
33842
35142
  description: `Read the client's marketing/analytics tags (Meta pixel, GA4, Google Ads, GTM, Clarity, Hotjar, \u2026) \u2014 production tags plus the changes staged in this chat.
@@ -33854,7 +35154,7 @@ Full guide: __tooling__/docs/tools/baker/tags.md`
33854
35154
  },
33855
35155
  subCommands: {
33856
35156
  list: listCommand15,
33857
- draft: draftCommand4
35157
+ draft: draftCommand5
33858
35158
  },
33859
35159
  // Bare `baker tags` lists the effective tags. `args` stays so citty knows this
33860
35160
  // command's flags when it scans rawArgs for a subcommand name, and `default` (not
@@ -33865,10 +35165,10 @@ Full guide: __tooling__/docs/tools/baker/tags.md`
33865
35165
  });
33866
35166
 
33867
35167
  // src/commands/testimonials/index.ts
33868
- import { defineCommand as defineCommand169 } from "citty";
35168
+ import { defineCommand as defineCommand172 } from "citty";
33869
35169
 
33870
35170
  // src/commands/testimonials/get.ts
33871
- import { defineCommand as defineCommand166 } from "citty";
35171
+ import { defineCommand as defineCommand169 } from "citty";
33872
35172
  registerSchema({
33873
35173
  command: "testimonials.get",
33874
35174
  description: "Get a single testimonial by ID",
@@ -33876,7 +35176,7 @@ registerSchema({
33876
35176
  id: { type: "string", description: "Testimonial ID", required: true }
33877
35177
  }
33878
35178
  });
33879
- var getCommand4 = defineCommand166({
35179
+ var getCommand4 = defineCommand169({
33880
35180
  meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
33881
35181
  args: {
33882
35182
  id: { type: "positional", description: "Testimonial ID", required: false },
@@ -33913,7 +35213,7 @@ var getCommand4 = defineCommand166({
33913
35213
  });
33914
35214
 
33915
35215
  // src/commands/testimonials/list.ts
33916
- import { defineCommand as defineCommand167 } from "citty";
35216
+ import { defineCommand as defineCommand170 } from "citty";
33917
35217
  registerSchema({
33918
35218
  command: "testimonials.list",
33919
35219
  description: "List testimonials with optional filters.",
@@ -33943,7 +35243,7 @@ registerSchema({
33943
35243
  limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
33944
35244
  }
33945
35245
  });
33946
- var listCommand16 = defineCommand167({
35246
+ var listCommand16 = defineCommand170({
33947
35247
  meta: {
33948
35248
  name: "list",
33949
35249
  description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
@@ -33992,7 +35292,7 @@ var listCommand16 = defineCommand167({
33992
35292
  });
33993
35293
 
33994
35294
  // src/commands/testimonials/search.ts
33995
- import { defineCommand as defineCommand168 } from "citty";
35295
+ import { defineCommand as defineCommand171 } from "citty";
33996
35296
  function languageBiasHint(results, requestedLanguage) {
33997
35297
  if (requestedLanguage) {
33998
35298
  return null;
@@ -34070,7 +35370,7 @@ function buildSearchRequest(query, args) {
34070
35370
  }
34071
35371
  return body;
34072
35372
  }
34073
- var searchCommand2 = defineCommand168({
35373
+ var searchCommand2 = defineCommand171({
34074
35374
  meta: {
34075
35375
  name: "search",
34076
35376
  description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
@@ -34126,7 +35426,7 @@ var searchCommand2 = defineCommand168({
34126
35426
  var tagsCommand4 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
34127
35427
 
34128
35428
  // src/commands/testimonials/index.ts
34129
- var testimonialsCommand = defineCommand169({
35429
+ var testimonialsCommand = defineCommand172({
34130
35430
  meta: {
34131
35431
  name: "testimonials",
34132
35432
  description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
@@ -34148,10 +35448,10 @@ Full guide: __tooling__/docs/tools/baker/testimonials.md`
34148
35448
  });
34149
35449
 
34150
35450
  // src/commands/videos/index.ts
34151
- import { defineCommand as defineCommand174 } from "citty";
35451
+ import { defineCommand as defineCommand177 } from "citty";
34152
35452
 
34153
35453
  // src/commands/videos/delete.ts
34154
- import { defineCommand as defineCommand170 } from "citty";
35454
+ import { defineCommand as defineCommand173 } from "citty";
34155
35455
  registerSchema({
34156
35456
  command: "videos.delete",
34157
35457
  description: "Delete a video by ID",
@@ -34165,7 +35465,7 @@ registerSchema({
34165
35465
  }
34166
35466
  }
34167
35467
  });
34168
- var deleteCommand3 = defineCommand170({
35468
+ var deleteCommand3 = defineCommand173({
34169
35469
  meta: {
34170
35470
  name: "delete",
34171
35471
  description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
@@ -34206,7 +35506,7 @@ var deleteCommand3 = defineCommand170({
34206
35506
  });
34207
35507
 
34208
35508
  // src/commands/videos/get.ts
34209
- import { defineCommand as defineCommand171 } from "citty";
35509
+ import { defineCommand as defineCommand174 } from "citty";
34210
35510
  registerSchema({
34211
35511
  command: "videos.get",
34212
35512
  description: "Get a single video by ID",
@@ -34214,7 +35514,7 @@ registerSchema({
34214
35514
  id: { type: "string", description: "Video ID", required: true }
34215
35515
  }
34216
35516
  });
34217
- var getCommand5 = defineCommand171({
35517
+ var getCommand5 = defineCommand174({
34218
35518
  meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
34219
35519
  args: {
34220
35520
  id: { type: "positional", description: "Video ID", required: false },
@@ -34251,7 +35551,7 @@ var getCommand5 = defineCommand171({
34251
35551
  });
34252
35552
 
34253
35553
  // src/commands/videos/search.ts
34254
- import { defineCommand as defineCommand172 } from "citty";
35554
+ import { defineCommand as defineCommand175 } from "citty";
34255
35555
  registerSchema({
34256
35556
  command: "videos.search",
34257
35557
  description: "Search videos by text query. Only returns ready videos.",
@@ -34261,7 +35561,7 @@ registerSchema({
34261
35561
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
34262
35562
  }
34263
35563
  });
34264
- var searchCommand3 = defineCommand172({
35564
+ var searchCommand3 = defineCommand175({
34265
35565
  meta: {
34266
35566
  name: "search",
34267
35567
  description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
@@ -34313,7 +35613,7 @@ var tagsCommand5 = makeTagsCommand("videos", "video", "/api/videos/tags");
34313
35613
  // src/commands/videos/upload.ts
34314
35614
  import { readFile as readFile23, stat as stat7 } from "fs/promises";
34315
35615
  import { extname as extname3 } from "path";
34316
- import { defineCommand as defineCommand173 } from "citty";
35616
+ import { defineCommand as defineCommand176 } from "citty";
34317
35617
  var MIME_MAP = {
34318
35618
  ".mp4": "video/mp4",
34319
35619
  ".mov": "video/quicktime",
@@ -34347,7 +35647,7 @@ function detectContentType(filePath) {
34347
35647
  }
34348
35648
  return mime;
34349
35649
  }
34350
- var uploadCommand2 = defineCommand173({
35650
+ var uploadCommand2 = defineCommand176({
34351
35651
  meta: {
34352
35652
  name: "upload",
34353
35653
  description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
@@ -34401,7 +35701,7 @@ var uploadCommand2 = defineCommand173({
34401
35701
  });
34402
35702
 
34403
35703
  // src/commands/videos/index.ts
34404
- var videosCommand = defineCommand174({
35704
+ var videosCommand = defineCommand177({
34405
35705
  meta: {
34406
35706
  name: "videos",
34407
35707
  description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
@@ -34425,10 +35725,10 @@ Full guide: __tooling__/docs/tools/baker/videos.md`
34425
35725
  });
34426
35726
 
34427
35727
  // src/commands/winning-ads/index.ts
34428
- import { defineCommand as defineCommand187 } from "citty";
35728
+ import { defineCommand as defineCommand190 } from "citty";
34429
35729
 
34430
35730
  // src/commands/winning-ads/advertisers.ts
34431
- import { defineCommand as defineCommand175 } from "citty";
35731
+ import { defineCommand as defineCommand178 } from "citty";
34432
35732
 
34433
35733
  // src/commands/winning-ads/shared.ts
34434
35734
  function splitList(value) {
@@ -34481,7 +35781,7 @@ function advertiserNormalizer(record, full) {
34481
35781
  last_synced_at: record.last_synced_at ?? null
34482
35782
  };
34483
35783
  }
34484
- var advertisersCommand2 = defineCommand175({
35784
+ var advertisersCommand2 = defineCommand178({
34485
35785
  meta: {
34486
35786
  name: "advertisers",
34487
35787
  description: 'List corpus advertisers by name or domain. Find your own advertiser for --exclude-advertiser, or a competitor for --advertiser-id / winners. Example: baker winning-ads advertisers "Deel" --output md'
@@ -34539,7 +35839,7 @@ var advertisersCommand2 = defineCommand175({
34539
35839
  });
34540
35840
 
34541
35841
  // src/commands/winning-ads/brief.ts
34542
- import { defineCommand as defineCommand176 } from "citty";
35842
+ import { defineCommand as defineCommand179 } from "citty";
34543
35843
  registerSchema({
34544
35844
  command: "winning-ads.brief",
34545
35845
  description: "Generate a creative brief grounded in strategically-similar winning ads. Optionally describe the target creative with --dna (JSON) and steer with --notes.",
@@ -34585,7 +35885,7 @@ function parseDna(raw) {
34585
35885
  }
34586
35886
  return parsed;
34587
35887
  }
34588
- var briefCommand = defineCommand176({
35888
+ var briefCommand = defineCommand179({
34589
35889
  meta: {
34590
35890
  name: "brief",
34591
35891
  description: `Generate a creative brief from winning references. Example: baker winning-ads brief --dna '{"angle":"cost savings"}' --notes "B2B, LinkedIn video" --k 8`
@@ -34621,7 +35921,7 @@ var briefCommand = defineCommand176({
34621
35921
  });
34622
35922
 
34623
35923
  // src/commands/winning-ads/content.ts
34624
- import { defineCommand as defineCommand177 } from "citty";
35924
+ import { defineCommand as defineCommand180 } from "citty";
34625
35925
  registerSchema({
34626
35926
  command: "winning-ads.content",
34627
35927
  description: "Read what's INSIDE one winning ad: the spoken transcript, the on-screen text, and the ad copy. Use this after `search`/`winners`/`feed` return a shortlist \u2014 pass an ad_id to understand a reference before reproducing it. Add --full for speech, pacing, and soundtrack detail. Video ads carry the transcript/on-screen text; static ads carry only the copy.",
@@ -34634,7 +35934,7 @@ registerSchema({
34634
35934
  }
34635
35935
  }
34636
35936
  });
34637
- var contentCommand = defineCommand177({
35937
+ var contentCommand = defineCommand180({
34638
35938
  meta: {
34639
35939
  name: "content",
34640
35940
  description: "Read the transcript + on-screen text + copy of one winning ad. Example: baker winning-ads content adg_123 --platform meta --full --output md"
@@ -34683,7 +35983,7 @@ var contentCommand = defineCommand177({
34683
35983
  });
34684
35984
 
34685
35985
  // src/commands/winning-ads/feed.ts
34686
- import { defineCommand as defineCommand178 } from "citty";
35986
+ import { defineCommand as defineCommand181 } from "citty";
34687
35987
  function buildFeedParams(input) {
34688
35988
  const params = {};
34689
35989
  const advertiser = splitList(input.advertiser);
@@ -34735,7 +36035,7 @@ registerSchema({
34735
36035
  format: { type: "string", description: "Comma-separated formats to include (e.g. static,video)", required: false }
34736
36036
  }
34737
36037
  });
34738
- var feedCommand = defineCommand178({
36038
+ var feedCommand = defineCommand181({
34739
36039
  meta: {
34740
36040
  name: "feed",
34741
36041
  description: "Winners across every brand you follow (browse, then trim per advertiser). Example: baker winning-ads feed --per-advertiser 5 --output md"
@@ -34820,7 +36120,7 @@ var feedCommand = defineCommand178({
34820
36120
  });
34821
36121
 
34822
36122
  // src/commands/winning-ads/follow.ts
34823
- import { defineCommand as defineCommand179 } from "citty";
36123
+ import { defineCommand as defineCommand182 } from "citty";
34824
36124
  var PLATFORMS = ["meta", "linkedin"];
34825
36125
  registerSchema({
34826
36126
  command: "winning-ads.follow",
@@ -34835,7 +36135,7 @@ registerSchema({
34835
36135
  label: { type: "string", description: "Optional display label (defaults to the resolved name)", required: false }
34836
36136
  }
34837
36137
  });
34838
- var followCommand = defineCommand179({
36138
+ var followCommand = defineCommand182({
34839
36139
  meta: {
34840
36140
  name: "follow",
34841
36141
  description: 'Follow a brand to track ALL its ads \u2014 every platform and country. --platform is how we read your input, not a limit. A domain tracks both Meta + LinkedIn. Example: baker winning-ads follow "deel.com" --platform meta'
@@ -34882,7 +36182,7 @@ var followCommand = defineCommand179({
34882
36182
  });
34883
36183
 
34884
36184
  // src/commands/winning-ads/follow-competitors.ts
34885
- import { defineCommand as defineCommand180 } from "citty";
36185
+ import { defineCommand as defineCommand183 } from "citty";
34886
36186
  var PLATFORMS2 = ["meta", "linkedin"];
34887
36187
  var BATCH_TIMEOUT_MS = 3e5;
34888
36188
  function buildFollowBatchBody(input) {
@@ -34915,7 +36215,7 @@ registerSchema({
34915
36215
  }
34916
36216
  }
34917
36217
  });
34918
- var followCompetitorsCommand = defineCommand180({
36218
+ var followCompetitorsCommand = defineCommand183({
34919
36219
  meta: {
34920
36220
  name: "follow-competitors",
34921
36221
  description: 'Follow many brands at once by domain \u2014 add every competitor in one call. Example: baker winning-ads follow-competitors "deel.com,notion.so,hubspot.com"'
@@ -34990,7 +36290,7 @@ var followCompetitorsCommand = defineCommand180({
34990
36290
  });
34991
36291
 
34992
36292
  // src/commands/winning-ads/following.ts
34993
- import { defineCommand as defineCommand181 } from "citty";
36293
+ import { defineCommand as defineCommand184 } from "citty";
34994
36294
  registerSchema({
34995
36295
  command: "winning-ads.following",
34996
36296
  description: "List the brands you follow in your ad-dna library, with each one's status (ready vs still adding) and cached ad counts.",
@@ -35023,7 +36323,7 @@ function followingNormalizer(record, full) {
35023
36323
  platforms: Array.isArray(record.platforms) ? record.platforms : []
35024
36324
  };
35025
36325
  }
35026
- var followingCommand = defineCommand181({
36326
+ var followingCommand = defineCommand184({
35027
36327
  meta: {
35028
36328
  name: "following",
35029
36329
  description: "List brands you follow, with status (ready / adding\u2026) and cached counts. Example: baker winning-ads following --output md"
@@ -35058,7 +36358,7 @@ var followingCommand = defineCommand181({
35058
36358
  });
35059
36359
 
35060
36360
  // src/commands/winning-ads/patterns.ts
35061
- import { defineCommand as defineCommand182 } from "citty";
36361
+ import { defineCommand as defineCommand185 } from "citty";
35062
36362
  registerSchema({
35063
36363
  command: "winning-ads.patterns",
35064
36364
  description: "Mine what separates two cohorts of ads: pass a comma-list of winning ad ids (--winners) and a comma-list of weaker ad ids (--duds). Returns the discriminating DNA fields.",
@@ -35097,7 +36397,7 @@ function discriminatorRow(record) {
35097
36397
  top_values_duds: Array.isArray(record.top_values_b) ? record.top_values_b.join(", ") : ""
35098
36398
  };
35099
36399
  }
35100
- var patternsCommand = defineCommand182({
36400
+ var patternsCommand = defineCommand185({
35101
36401
  meta: {
35102
36402
  name: "patterns",
35103
36403
  description: "Discover what separates winning ads from weak ones. Example: baker winning-ads patterns --winners a_1,a_2,a_3 --duds a_9,a_8 --output md"
@@ -35153,7 +36453,7 @@ var patternsCommand = defineCommand182({
35153
36453
  });
35154
36454
 
35155
36455
  // src/commands/winning-ads/search.ts
35156
- import { defineCommand as defineCommand183 } from "citty";
36456
+ import { defineCommand as defineCommand186 } from "citty";
35157
36457
  registerSchema({
35158
36458
  command: "winning-ads.search",
35159
36459
  description: "Search the ad-dna corpus of scored winning ads. Returns a lean shortlist (advertiser, summary, scores, media_url) to pick a reference to reproduce.",
@@ -35261,7 +36561,7 @@ function buildSearchBody(args) {
35261
36561
  }
35262
36562
  return body;
35263
36563
  }
35264
- var searchCommand4 = defineCommand183({
36564
+ var searchCommand4 = defineCommand186({
35265
36565
  meta: {
35266
36566
  name: "search",
35267
36567
  description: "Search winning reference ads. Example: baker winning-ads search 'B2B SaaS before/after AI automation' --platform meta --format static --winner-category winner --exclude-advertiser adv_123 --output md"
@@ -35376,7 +36676,7 @@ var searchCommand4 = defineCommand183({
35376
36676
  });
35377
36677
 
35378
36678
  // src/commands/winning-ads/seeds.ts
35379
- import { defineCommand as defineCommand184 } from "citty";
36679
+ import { defineCommand as defineCommand187 } from "citty";
35380
36680
  function leanRow(r) {
35381
36681
  return {
35382
36682
  key: r.key,
@@ -35404,7 +36704,7 @@ function makeSeedCommand(opts) {
35404
36704
  limit: { type: "number", description: "Max keys 1-100 (default 20)", required: false, default: 20 }
35405
36705
  }
35406
36706
  });
35407
- return defineCommand184({
36707
+ return defineCommand187({
35408
36708
  meta: { name: opts.name, description: opts.description },
35409
36709
  args: {
35410
36710
  platform: { type: "string", description: "Single platform to segment on", required: false },
@@ -35453,7 +36753,7 @@ var formatsCommand = makeSeedCommand({
35453
36753
  });
35454
36754
 
35455
36755
  // src/commands/winning-ads/unfollow.ts
35456
- import { defineCommand as defineCommand185 } from "citty";
36756
+ import { defineCommand as defineCommand188 } from "citty";
35457
36757
  registerSchema({
35458
36758
  command: "winning-ads.unfollow",
35459
36759
  description: "Stop following a brand \u2014 removes it from your ad-dna library by advertiser id.",
@@ -35461,7 +36761,7 @@ registerSchema({
35461
36761
  advertiser: { type: "string", description: "Advertiser id to unfollow", required: true }
35462
36762
  }
35463
36763
  });
35464
- var unfollowCommand = defineCommand185({
36764
+ var unfollowCommand = defineCommand188({
35465
36765
  meta: {
35466
36766
  name: "unfollow",
35467
36767
  description: "Stop following a brand by advertiser id. Example: baker winning-ads unfollow adv_123"
@@ -35482,7 +36782,7 @@ var unfollowCommand = defineCommand185({
35482
36782
  });
35483
36783
 
35484
36784
  // src/commands/winning-ads/winners.ts
35485
- import { defineCommand as defineCommand186 } from "citty";
36785
+ import { defineCommand as defineCommand189 } from "citty";
35486
36786
  registerSchema({
35487
36787
  command: "winning-ads.winners",
35488
36788
  description: "Top winning ads for one advertiser id (from `advertisers` or `following`). Returns lean winner cards; add --full for DNA + longevity.",
@@ -35492,7 +36792,7 @@ registerSchema({
35492
36792
  platform: { type: "string", description: "Filter to a single platform: meta|linkedin", required: false }
35493
36793
  }
35494
36794
  });
35495
- var winnersCommand = defineCommand186({
36795
+ var winnersCommand = defineCommand189({
35496
36796
  meta: {
35497
36797
  name: "winners",
35498
36798
  description: "Top winning ads for a specific advertiser id. Example: baker winning-ads winners adv_123 --top 15 --output md"
@@ -35542,7 +36842,7 @@ var winnersCommand = defineCommand186({
35542
36842
  });
35543
36843
 
35544
36844
  // src/commands/winning-ads/index.ts
35545
- var winningAdsCommand = defineCommand187({
36845
+ var winningAdsCommand = defineCommand190({
35546
36846
  meta: {
35547
36847
  name: "winning-ads",
35548
36848
  description: `Search the ad-dna corpus of scored "winning" ads for reference creatives to reproduce, and manage the brands your library tracks. Proxied through the Baker backend (BAKER_API_KEY) \u2014 no separate token needed.
@@ -35598,7 +36898,7 @@ Full guide: __tooling__/docs/tools/baker/winning-ads.md`
35598
36898
  });
35599
36899
 
35600
36900
  // src/version.ts
35601
- import { readFileSync as readFileSync13 } from "fs";
36901
+ import { readFileSync as readFileSync14 } from "fs";
35602
36902
  function packageJsonUrl() {
35603
36903
  return new URL("../package.json", import.meta.url);
35604
36904
  }
@@ -35610,11 +36910,11 @@ function parsePackageVersion(raw) {
35610
36910
  throw new Error("Invalid CLI package.json: missing version");
35611
36911
  }
35612
36912
  function getCliVersion() {
35613
- return parsePackageVersion(readFileSync13(packageJsonUrl(), "utf8"));
36913
+ return parsePackageVersion(readFileSync14(packageJsonUrl(), "utf8"));
35614
36914
  }
35615
36915
 
35616
36916
  // src/cli.ts
35617
- var main = defineCommand188({
36917
+ var main = defineCommand191({
35618
36918
  meta: {
35619
36919
  name: "baker",
35620
36920
  version: getCliVersion(),