@koda-sl/baker-cli 0.93.0 → 0.94.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -9,13 +9,13 @@ import {
9
9
  defaultRegistry,
10
10
  generateCatalog,
11
11
  validateCanvasDeep
12
- } from "./chunk-LMVDA3EZ.js";
12
+ } from "./chunk-RCPMJKI7.js";
13
13
 
14
14
  // src/cli.ts
15
- import { defineCommand as defineCommand148, runMain } from "citty";
15
+ import { defineCommand as defineCommand143, runMain } from "citty";
16
16
 
17
17
  // src/commands/actions/index.ts
18
- import { defineCommand as defineCommand12 } from "citty";
18
+ import { defineCommand as defineCommand13 } from "citty";
19
19
 
20
20
  // src/commands/actions/claim.ts
21
21
  import { defineCommand } from "citty";
@@ -465,6 +465,22 @@ function generateTempId() {
465
465
  function isTempId(id) {
466
466
  return id.startsWith("temp_");
467
467
  }
468
+ var SCHEDULE_SIGNALS = [
469
+ /\brecurr(?:ing|ence)\b/i,
470
+ /\bcadence\b/i,
471
+ /\bcron\b/i,
472
+ /\bschedule[ds]?\b/i,
473
+ /\b(?:daily|weekly|monthly|quarterly|annual(?:ly)?|biweekly|nightly)\b/i,
474
+ /\bevery\s+(?:day|week|month|quarter|year|morning|monday|tuesday|wednesday|thursday|friday|saturday|sunday|\d)/i,
475
+ /\beach\s+(?:day|week|month|monday|tuesday|wednesday|thursday|friday|saturday|sunday)\b/i,
476
+ /\bremind(?:er|s)?\b/i,
477
+ /\brun\s+at\b/i
478
+ ];
479
+ function looksScheduled(name, description) {
480
+ const haystack = `${name}
481
+ ${description}`;
482
+ return SCHEDULE_SIGNALS.some((re) => re.test(haystack));
483
+ }
468
484
 
469
485
  // src/commands/actions/claim.ts
470
486
  registerSchema({
@@ -509,7 +525,7 @@ var claimCommand = defineCommand({
509
525
  import { defineCommand as defineCommand2 } from "citty";
510
526
  registerSchema({
511
527
  command: "actions.complete",
512
- description: "Stage completion of an action. Accepts a real action ID (must be claimed) or a temp ID from the same draft. The action becomes completed when the chat is published.",
528
+ description: "Stage completion of an action (it was DONE). Accepts a real action ID (must be claimed) or a temp ID from the same draft. The action becomes completed when the chat is published. Do NOT use this to drop an action you no longer want \u2014 to remove a staged op use `actions draft remove`, to close an unwanted published action use `actions discard`.",
513
529
  args: {
514
530
  id: { type: "string", description: "Action ID or temp ID", required: true },
515
531
  note: { type: "string", description: "What was done \u2014 context for the team and AI", required: false }
@@ -547,7 +563,7 @@ var completeCommand = defineCommand2({
547
563
  import { defineCommand as defineCommand3 } from "citty";
548
564
  registerSchema({
549
565
  command: "actions.create",
550
- description: "Stage creation of a new action (applies when the chat is published). Returns a tempId you can use to link in the same draft. After creating, check if this action blocks or is blocked by other actions and wire dependencies with `baker actions link`. To make this action a mission step, pass --mission and --order \u2014 it attaches atomically, so the step never flickers as a loose action.",
566
+ description: "Stage creation of a new action (applies when the chat is published). Returns a tempId you can use to link in the same draft. After creating, check if this action blocks or is blocked by other actions and wire dependencies with `baker actions link`.",
551
567
  args: {
552
568
  name: { type: "string", description: "Action name (short, action-verb, \u22646 words)", required: true },
553
569
  description: {
@@ -555,17 +571,7 @@ registerSchema({
555
571
  description: "Context-complete description: what / why / where / done-when",
556
572
  required: false
557
573
  },
558
- "temp-id": { type: "string", description: "Custom tempId (auto-generated if omitted)", required: false },
559
- mission: {
560
- type: "string",
561
- description: "Attach the new action to this mission (id or missionTempId) as a step, in one atomic op",
562
- required: false
563
- },
564
- order: {
565
- type: "string",
566
- description: "0-based position of the step within the mission (required when --mission is set)",
567
- required: false
568
- }
574
+ "temp-id": { type: "string", description: "Custom tempId (auto-generated if omitted)", required: false }
569
575
  }
570
576
  });
571
577
  var createCommand = defineCommand3({
@@ -576,9 +582,7 @@ var createCommand = defineCommand3({
576
582
  args: {
577
583
  name: { type: "string", description: "Action name", required: false },
578
584
  description: { type: "string", description: "Description", required: false, default: "" },
579
- "temp-id": { type: "string", description: "Optional custom tempId", required: false },
580
- mission: { type: "string", description: "Mission ref to attach this step to", required: false },
581
- order: { type: "string", description: "0-based step position (required with --mission)", required: false }
585
+ "temp-id": { type: "string", description: "Optional custom tempId", required: false }
582
586
  },
583
587
  run: async ({ args }) => {
584
588
  try {
@@ -586,31 +590,24 @@ var createCommand = defineCommand3({
586
590
  if (!name || name.trim().length === 0) {
587
591
  failValidation("--name is required.");
588
592
  }
589
- const mission = args.mission;
590
- let order;
591
- if (mission) {
592
- order = Number.parseInt(args.order ?? "", 10);
593
- if (Number.isNaN(order) || order < 0) {
594
- failValidation("--order must be a non-negative integer when --mission is set.");
595
- }
596
- }
597
593
  const chatId = requireChatId();
598
594
  const tempId = args["temp-id"] || generateTempId();
599
595
  const response = await apiPost("/api/actions/create", {
600
596
  chatId,
601
597
  tempId,
602
598
  name,
603
- description: args.description ?? "",
604
- ...mission ? { missionRef: mission, order } : {}
599
+ description: args.description ?? ""
605
600
  });
606
601
  const hints = [];
602
+ if (looksScheduled(name, args.description ?? "")) {
603
+ hints.push(
604
+ 'This reads as recurring/scheduled work. If it should run on a cadence or a future date, create a Scheduled Action instead \u2014 baker scheduled-actions create --cron "0 9 * * MON" (or --run-at). Do NOT capture "set up a scheduled action" as a Work Action.'
605
+ );
606
+ }
607
607
  hints.push(`Link dependencies: baker actions link --blocker <id> --blocked ${tempId}`);
608
608
  if (!args.description) {
609
609
  hints.push("Add description: baker actions update <tempId> --description '...' (what/why/where/done-when)");
610
610
  }
611
- if (mission) {
612
- hints.push(`Attached to mission ${mission} at order ${order}.`);
613
- }
614
611
  writeJson({ ...response, hints });
615
612
  } catch (err) {
616
613
  failApi(err);
@@ -658,8 +655,133 @@ var discardCommand = defineCommand4({
658
655
  }
659
656
  });
660
657
 
661
- // src/commands/actions/get.ts
658
+ // src/commands/actions/draft.ts
662
659
  import { defineCommand as defineCommand5 } from "citty";
660
+ var REMOVE_OP_KINDS = ["update", "complete", "discard", "tagAdd", "tagRemove"];
661
+ registerSchema({
662
+ command: "actions.draft.list",
663
+ 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.",
664
+ args: {}
665
+ });
666
+ registerSchema({
667
+ command: "actions.draft.remove",
668
+ description: "Drop a single staged action op from this chat's draft before publish. For a tempId, removing the create cascades into its complete/link/tagAdd ops. For a real action ID, pass --op to say which op to drop. Use this to UNDO a staged op \u2014 never stage `complete` to delete an action.",
669
+ args: {
670
+ ref: { type: "string", description: "tempId (temp_*) or real action ID to drop from the draft", required: true },
671
+ op: {
672
+ type: "string",
673
+ description: "Required for real action IDs: which op to drop (update|complete|discard|tagAdd|tagRemove)",
674
+ required: false
675
+ },
676
+ "tag-slug": { type: "string", description: "Tag slug (only for --op tagAdd|tagRemove)", required: false }
677
+ }
678
+ });
679
+ registerSchema({
680
+ command: "actions.draft.clear",
681
+ description: "Discard ALL staged action ops in this chat's draft before publish. Nothing applies on publish. Does not touch already-published actions.",
682
+ args: {}
683
+ });
684
+ var listCommand = defineCommand5({
685
+ meta: {
686
+ name: "list",
687
+ description: "Show every action op staged in this chat's draft, with footgun warnings. Example: baker actions draft"
688
+ },
689
+ run: async () => {
690
+ try {
691
+ const chatId = requireChatId();
692
+ const response = await apiPost("/api/actions/draft", { chatId });
693
+ writeJson(response);
694
+ } catch (err) {
695
+ failApi(err);
696
+ }
697
+ }
698
+ });
699
+ var removeCommand = defineCommand5({
700
+ meta: {
701
+ name: "remove",
702
+ description: "Drop one staged op from the draft. Example: baker actions draft remove temp_abc123 | baker actions draft remove jx7... --op complete"
703
+ },
704
+ args: {
705
+ ref: { type: "positional", description: "tempId or real action ID", required: false },
706
+ op: {
707
+ type: "string",
708
+ description: "Op kind for real IDs: update|complete|discard|tagAdd|tagRemove",
709
+ required: false
710
+ },
711
+ "tag-slug": { type: "string", description: "Tag slug (for tagAdd|tagRemove)", required: false }
712
+ },
713
+ run: async ({ args }) => {
714
+ try {
715
+ const ref = args.ref;
716
+ if (!ref) {
717
+ failValidation("A tempId or action ID is required.");
718
+ }
719
+ const chatId = requireChatId();
720
+ if (isTempId(ref)) {
721
+ await apiPost("/api/actions/draft-op/remove", {
722
+ chatId,
723
+ target: { kind: "tempId", tempId: ref }
724
+ });
725
+ writeJson({ ok: true, data: { removed: ref, kind: "tempId" } });
726
+ return;
727
+ }
728
+ validateConvexId(ref);
729
+ const op = args.op;
730
+ if (!op || !REMOVE_OP_KINDS.includes(op)) {
731
+ failValidation(
732
+ `Removing a staged op for a real action ID requires --op (one of: ${REMOVE_OP_KINDS.join("|")}).`
733
+ );
734
+ }
735
+ const tagSlug = args["tag-slug"];
736
+ await apiPost("/api/actions/draft-op/remove", {
737
+ chatId,
738
+ target: { kind: "actionId", actionId: ref, opKind: op, ...tagSlug ? { tagSlug } : {} }
739
+ });
740
+ writeJson({ ok: true, data: { removed: ref, kind: "actionId", op } });
741
+ } catch (err) {
742
+ failApi(err);
743
+ }
744
+ }
745
+ });
746
+ var clearCommand = defineCommand5({
747
+ meta: {
748
+ name: "clear",
749
+ description: "Discard every staged op in this chat's draft. Example: baker actions draft clear"
750
+ },
751
+ run: async () => {
752
+ try {
753
+ const chatId = requireChatId();
754
+ await apiPost("/api/actions/draft/clear", { chatId });
755
+ writeJson({ ok: true, data: { cleared: true } });
756
+ } catch (err) {
757
+ failApi(err);
758
+ }
759
+ }
760
+ });
761
+ var draftCommand = defineCommand5({
762
+ meta: {
763
+ name: "draft",
764
+ 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."
765
+ },
766
+ subCommands: {
767
+ list: listCommand,
768
+ remove: removeCommand,
769
+ clear: clearCommand
770
+ },
771
+ // Bare `baker actions draft` (no subcommand) shows the staged ops.
772
+ run: async () => {
773
+ try {
774
+ const chatId = requireChatId();
775
+ const response = await apiPost("/api/actions/draft", { chatId });
776
+ writeJson(response);
777
+ } catch (err) {
778
+ failApi(err);
779
+ }
780
+ }
781
+ });
782
+
783
+ // src/commands/actions/get.ts
784
+ import { defineCommand as defineCommand6 } from "citty";
663
785
  registerSchema({
664
786
  command: "actions.get",
665
787
  description: "Get a single action with tags, blockers, blocked-by, and active-chat info.",
@@ -667,7 +789,7 @@ registerSchema({
667
789
  id: { type: "string", description: "Action ID", required: true }
668
790
  }
669
791
  });
670
- var getCommand = defineCommand5({
792
+ var getCommand = defineCommand6({
671
793
  meta: { name: "get", description: "Get a single action by ID. Example: baker actions get <action-id>" },
672
794
  args: {
673
795
  id: { type: "positional", description: "Action ID", required: false },
@@ -689,7 +811,7 @@ var getCommand = defineCommand5({
689
811
  });
690
812
 
691
813
  // src/commands/actions/link.ts
692
- import { defineCommand as defineCommand6 } from "citty";
814
+ import { defineCommand as defineCommand7 } from "citty";
693
815
  registerSchema({
694
816
  command: "actions.link",
695
817
  description: "Stage a 'blocker -> blocked' dependency. Refs can be either action IDs or tempIds from create ops in the same draft.",
@@ -698,7 +820,7 @@ registerSchema({
698
820
  blocked: { type: "string", description: "Blocked action ID or tempId", required: true }
699
821
  }
700
822
  });
701
- var linkCommand = defineCommand6({
823
+ var linkCommand = defineCommand7({
702
824
  meta: {
703
825
  name: "link",
704
826
  description: "Stage a dependency link. Example: baker actions link --blocker <id> --blocked <id>"
@@ -728,7 +850,7 @@ var linkCommand = defineCommand6({
728
850
  });
729
851
 
730
852
  // src/commands/actions/list.ts
731
- import { defineCommand as defineCommand7 } from "citty";
853
+ import { defineCommand as defineCommand8 } from "citty";
732
854
  registerSchema({
733
855
  command: "actions.list",
734
856
  description: "List actions for the current company. Default: pre-bucketed (claimable/myClaims/blocked/claimedByOthers/completed/discarded). Set --bucketed=false for a flat list filterable by --status.",
@@ -746,7 +868,7 @@ registerSchema({
746
868
  }
747
869
  }
748
870
  });
749
- var listCommand = defineCommand7({
871
+ var listCommand2 = defineCommand8({
750
872
  meta: {
751
873
  name: "list",
752
874
  description: "List actions. Default: bucketed view (claimable, myClaims, blocked, claimedByOthers). Use --bucketed=false for raw filter by --status."
@@ -777,7 +899,7 @@ var listCommand = defineCommand7({
777
899
  });
778
900
 
779
901
  // src/commands/actions/release.ts
780
- import { defineCommand as defineCommand8 } from "citty";
902
+ import { defineCommand as defineCommand9 } from "citty";
781
903
  registerSchema({
782
904
  command: "actions.release",
783
905
  description: "Release an action you previously claimed (no-op if you don't own the claim).",
@@ -785,7 +907,7 @@ registerSchema({
785
907
  id: { type: "string", description: "Action ID", required: true }
786
908
  }
787
909
  });
788
- var releaseCommand = defineCommand8({
910
+ var releaseCommand = defineCommand9({
789
911
  meta: {
790
912
  name: "release",
791
913
  description: "Release a claim you made on an action. Example: baker actions release <action-id>"
@@ -811,15 +933,15 @@ var releaseCommand = defineCommand8({
811
933
  });
812
934
 
813
935
  // src/commands/actions/status.ts
814
- import { defineCommand as defineCommand9 } from "citty";
936
+ import { defineCommand as defineCommand10 } from "citty";
815
937
  registerSchema({
816
938
  command: "actions.status",
817
- description: "Resolve one or more Work Action refs by real action ID or temp_* ref in a single batch call.",
939
+ description: "Resolve one or more Work Action refs by real action ID or temp_* ref in a single batch call. When BAKER_CHAT_ID is set, a temp_* ref still staged in THIS chat resolves to status 'draft' (not 'not_found') \u2014 staged ops only become published actions on chat publish.",
818
940
  args: {
819
941
  refs: { type: "string", description: "One or more action refs: real action IDs or temp_* refs", required: true }
820
942
  }
821
943
  });
822
- var statusCommand = defineCommand9({
944
+ var statusCommand = defineCommand10({
823
945
  meta: {
824
946
  name: "status",
825
947
  description: "Resolve Work Action refs by real ID or temp_* ref. Example: baker actions status temp_hero jx123"
@@ -833,7 +955,9 @@ var statusCommand = defineCommand9({
833
955
  if (refs.length === 0) {
834
956
  failValidation("At least one action ref is required.");
835
957
  }
836
- const response = await apiPost("/api/actions/status", { refs });
958
+ const { BAKER_CHAT_ID } = getEnv();
959
+ const body = BAKER_CHAT_ID ? { refs, chatId: BAKER_CHAT_ID } : { refs };
960
+ const response = await apiPost("/api/actions/status", body);
837
961
  writeJson(response);
838
962
  } catch (err) {
839
963
  failApi(err);
@@ -842,7 +966,7 @@ var statusCommand = defineCommand9({
842
966
  });
843
967
 
844
968
  // src/commands/actions/unlink.ts
845
- import { defineCommand as defineCommand10 } from "citty";
969
+ import { defineCommand as defineCommand11 } from "citty";
846
970
  registerSchema({
847
971
  command: "actions.unlink",
848
972
  description: "Stage removal of a 'blocker -> blocked' dependency. The blocked action must be claimed by current chat.",
@@ -851,7 +975,7 @@ registerSchema({
851
975
  blocked: { type: "string", description: "Blocked action ID (must be claimed by current chat)", required: true }
852
976
  }
853
977
  });
854
- var unlinkCommand = defineCommand10({
978
+ var unlinkCommand = defineCommand11({
855
979
  meta: {
856
980
  name: "unlink",
857
981
  description: "Stage removal of a dependency. Example: baker actions unlink --blocker <id> --blocked <id>"
@@ -883,7 +1007,7 @@ var unlinkCommand = defineCommand10({
883
1007
  });
884
1008
 
885
1009
  // src/commands/actions/update.ts
886
- import { defineCommand as defineCommand11 } from "citty";
1010
+ import { defineCommand as defineCommand12 } from "citty";
887
1011
  registerSchema({
888
1012
  command: "actions.update",
889
1013
  description: "Stage an update on a claimed action (name and/or description). Applies on publish.",
@@ -893,7 +1017,7 @@ registerSchema({
893
1017
  description: { type: "string", description: "New description", required: false }
894
1018
  }
895
1019
  });
896
- var updateCommand = defineCommand11({
1020
+ var updateCommand = defineCommand12({
897
1021
  meta: {
898
1022
  name: "update",
899
1023
  description: 'Stage an update on a claimed action. Example: baker actions update <id> --name "New name"'
@@ -929,15 +1053,20 @@ var updateCommand = defineCommand11({
929
1053
  });
930
1054
 
931
1055
  // src/commands/actions/index.ts
932
- var actionsCommand = defineCommand12({
1056
+ var actionsCommand = defineCommand13({
933
1057
  meta: {
934
1058
  name: "actions",
935
- description: `Manage action items for the current chat. Subcommands: list, get, status, claim, release, create, update, complete, discard, link, unlink.
1059
+ description: `Manage action items for the current chat. Subcommands: list, draft, get, status, claim, release, create, update, complete, discard, link, unlink.
1060
+
1061
+ Lifecycle: claim an action before working on it. Stage create/update/complete/discard/link via this CLI; they apply when the chat is published. Release if you decide not to work on it after all.
936
1062
 
937
- Lifecycle: claim an action before working on it. Stage create/complete/discard via this CLI; they apply when the chat is published. Release if you decide not to work on it after all.
1063
+ Staged vs published: create/update/complete/discard/link are STAGED in this chat's draft and are invisible to \`list\`/\`status\` until the chat publishes. Review them with \`actions draft\` before finishing. To drop a staged op, use \`actions draft remove <ref>\` \u2014 never stage \`complete\` to delete a staged action (that publishes it as already-completed, leaving a duplicate).
938
1064
 
939
1065
  Examples:
940
- baker actions list # bucketed view: claimable, myClaims, blocked, claimedByOthers
1066
+ baker actions list # bucketed view of PUBLISHED actions
1067
+ baker actions draft # review what THIS chat has staged (pre-publish)
1068
+ baker actions draft remove temp_hero # drop a staged create (cascades its complete/link ops)
1069
+ baker actions draft clear # drop everything staged in this chat
941
1070
  baker actions status temp_hero jx123 # batch resolve real IDs and temp_* refs
942
1071
  baker actions claim <id>
943
1072
  baker actions create --name "Build hero" --description "..."
@@ -945,7 +1074,8 @@ Examples:
945
1074
  baker actions discard <id> --reason "obsolete"`
946
1075
  },
947
1076
  subCommands: {
948
- list: listCommand,
1077
+ list: listCommand2,
1078
+ draft: draftCommand,
949
1079
  get: getCommand,
950
1080
  status: statusCommand,
951
1081
  claim: claimCommand,
@@ -960,13 +1090,13 @@ Examples:
960
1090
  });
961
1091
 
962
1092
  // src/commands/ads/index.ts
963
- import { defineCommand as defineCommand71 } from "citty";
1093
+ import { defineCommand as defineCommand73 } from "citty";
964
1094
 
965
1095
  // src/commands/ads/google/index.ts
966
- import { defineCommand as defineCommand23 } from "citty";
1096
+ import { defineCommand as defineCommand24 } from "citty";
967
1097
 
968
1098
  // src/commands/ads/google/accounts.ts
969
- import { defineCommand as defineCommand13 } from "citty";
1099
+ import { defineCommand as defineCommand14 } from "citty";
970
1100
 
971
1101
  // src/commands/ads/cache.ts
972
1102
  import { createHash } from "crypto";
@@ -1242,7 +1372,7 @@ function handleAccountsError(err) {
1242
1372
  writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
1243
1373
  process.exit(1);
1244
1374
  }
1245
- var accountsCommand = defineCommand13({
1375
+ var accountsCommand = defineCommand14({
1246
1376
  meta: {
1247
1377
  name: "accounts",
1248
1378
  description: `List accessible Google Ads accounts. Returns customer IDs needed for all other commands.
@@ -1282,7 +1412,7 @@ Examples:
1282
1412
  });
1283
1413
 
1284
1414
  // src/commands/ads/google/changes.ts
1285
- import { defineCommand as defineCommand14 } from "citty";
1415
+ import { defineCommand as defineCommand15 } from "citty";
1286
1416
 
1287
1417
  // src/commands/ads/field-descriptions.ts
1288
1418
  var FIELD_DESCRIPTIONS = {
@@ -1834,7 +1964,7 @@ registerSchema({
1834
1964
  output: { type: "string", description: "Format: json|csv|jsonl|md", required: false, default: "json" }
1835
1965
  }
1836
1966
  });
1837
- var changesCommand = defineCommand14({
1967
+ var changesCommand = defineCommand15({
1838
1968
  meta: {
1839
1969
  name: "changes",
1840
1970
  description: `Get recent changes in a Google Ads account with performance data.
@@ -1885,7 +2015,7 @@ Examples:
1885
2015
  });
1886
2016
 
1887
2017
  // src/commands/ads/google/currency.ts
1888
- import { defineCommand as defineCommand15 } from "citty";
2018
+ import { defineCommand as defineCommand16 } from "citty";
1889
2019
  registerSchema({
1890
2020
  command: "ads.google.currency",
1891
2021
  description: "Get the currency code for a Google Ads account. Returns currency_code, customer_id, account_name, and access_type. Call this before interpreting cost_micros values.",
@@ -1897,7 +2027,7 @@ registerSchema({
1897
2027
  }
1898
2028
  }
1899
2029
  });
1900
- var currencyCommand = defineCommand15({
2030
+ var currencyCommand = defineCommand16({
1901
2031
  meta: {
1902
2032
  name: "currency",
1903
2033
  description: `Get account currency code. Use this to interpret metrics.cost_micros values.
@@ -1946,10 +2076,10 @@ Examples:
1946
2076
  });
1947
2077
 
1948
2078
  // src/commands/ads/google/keywords/index.ts
1949
- import { defineCommand as defineCommand20 } from "citty";
2079
+ import { defineCommand as defineCommand21 } from "citty";
1950
2080
 
1951
2081
  // src/commands/ads/google/keywords/discover.ts
1952
- import { defineCommand as defineCommand16 } from "citty";
2082
+ import { defineCommand as defineCommand17 } from "citty";
1953
2083
 
1954
2084
  // src/geo-context.ts
1955
2085
  var GOOGLE_ADS_LOCATIONS = [
@@ -2224,7 +2354,7 @@ function handleKeywordError(err) {
2224
2354
  writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
2225
2355
  process.exit(1);
2226
2356
  }
2227
- var discoverCommand = defineCommand16({
2357
+ var discoverCommand = defineCommand17({
2228
2358
  meta: {
2229
2359
  name: "discover",
2230
2360
  description: `Discover new keyword ideas from seed keywords or competitor URLs.
@@ -2286,7 +2416,7 @@ Examples:
2286
2416
  });
2287
2417
 
2288
2418
  // src/commands/ads/google/keywords/languages.ts
2289
- import { defineCommand as defineCommand17 } from "citty";
2419
+ import { defineCommand as defineCommand18 } from "citty";
2290
2420
  registerSchema({
2291
2421
  command: "ads.google.keywords.languages",
2292
2422
  description: "List all supported language IDs for --language flag in Google Ads keyword commands.",
@@ -2296,7 +2426,7 @@ var FIELDS = {
2296
2426
  id: "Language ID to pass as --language",
2297
2427
  name: "Language name"
2298
2428
  };
2299
- var languagesCommand = defineCommand17({
2429
+ var languagesCommand = defineCommand18({
2300
2430
  meta: {
2301
2431
  name: "languages",
2302
2432
  description: "List all supported language IDs for --language flag."
@@ -2307,7 +2437,7 @@ var languagesCommand = defineCommand17({
2307
2437
  });
2308
2438
 
2309
2439
  // src/commands/ads/google/keywords/locations.ts
2310
- import { defineCommand as defineCommand18 } from "citty";
2440
+ import { defineCommand as defineCommand19 } from "citty";
2311
2441
  registerSchema({
2312
2442
  command: "ads.google.keywords.locations",
2313
2443
  description: "List all supported geo target IDs for --location flag in Google Ads keyword commands.",
@@ -2317,7 +2447,7 @@ var FIELDS2 = {
2317
2447
  id: "Geo target ID to pass as --location",
2318
2448
  name: "Country/region name"
2319
2449
  };
2320
- var locationsCommand = defineCommand18({
2450
+ var locationsCommand = defineCommand19({
2321
2451
  meta: {
2322
2452
  name: "locations",
2323
2453
  description: "List all supported geo target IDs for --location flag."
@@ -2328,7 +2458,7 @@ var locationsCommand = defineCommand18({
2328
2458
  });
2329
2459
 
2330
2460
  // src/commands/ads/google/keywords/metrics.ts
2331
- import { defineCommand as defineCommand19 } from "citty";
2461
+ import { defineCommand as defineCommand20 } from "citty";
2332
2462
  registerSchema({
2333
2463
  command: "ads.google.keywords.metrics",
2334
2464
  description: "Get historical metrics for specific keywords. Returns { historical_metrics: [...] } with snake_case fields matching the Google Ads API. IMPORTANT: If --location and --language are omitted, defaults to United States (2840) and English (1000). The response includes a query_context object showing which location/language were used.",
@@ -2352,7 +2482,7 @@ registerSchema({
2352
2482
  output: { type: "string", description: "Format: json|csv|jsonl|md", required: false, default: "json" }
2353
2483
  }
2354
2484
  });
2355
- var metricsCommand = defineCommand19({
2485
+ var metricsCommand = defineCommand20({
2356
2486
  meta: {
2357
2487
  name: "metrics",
2358
2488
  description: `Get historical search metrics for specific keywords.
@@ -2439,7 +2569,7 @@ Examples:
2439
2569
  });
2440
2570
 
2441
2571
  // src/commands/ads/google/keywords/index.ts
2442
- var keywordsCommand = defineCommand20({
2572
+ var keywordsCommand = defineCommand21({
2443
2573
  meta: {
2444
2574
  name: "keywords",
2445
2575
  description: `Keyword research tools. Subcommands: discover, metrics, locations, languages.
@@ -2459,8 +2589,8 @@ Examples:
2459
2589
  });
2460
2590
 
2461
2591
  // src/commands/ads/google/library/index.ts
2462
- import { defineCommand as defineCommand21 } from "citty";
2463
- var listAdvertisers = defineCommand21({
2592
+ import { defineCommand as defineCommand22 } from "citty";
2593
+ var listAdvertisers = defineCommand22({
2464
2594
  meta: {
2465
2595
  name: "list-advertisers",
2466
2596
  description: "List tracked Google advertisers and their accounts"
@@ -2477,7 +2607,7 @@ var listAdvertisers = defineCommand21({
2477
2607
  }
2478
2608
  }
2479
2609
  });
2480
- var syncStatus = defineCommand21({
2610
+ var syncStatus = defineCommand22({
2481
2611
  meta: {
2482
2612
  name: "sync-status",
2483
2613
  description: "Check the sync status and ad counts of a Google account"
@@ -2497,7 +2627,7 @@ var syncStatus = defineCommand21({
2497
2627
  writeAdsJson({ ok: true, data });
2498
2628
  }
2499
2629
  });
2500
- var searchAds = defineCommand21({
2630
+ var searchAds = defineCommand22({
2501
2631
  meta: {
2502
2632
  name: "search-ads",
2503
2633
  description: "Search and filter Google ads for an account"
@@ -2554,7 +2684,7 @@ var searchAds = defineCommand21({
2554
2684
  }
2555
2685
  }
2556
2686
  });
2557
- var searchAdvertiser = defineCommand21({
2687
+ var searchAdvertiser = defineCommand22({
2558
2688
  meta: {
2559
2689
  name: "search-advertiser",
2560
2690
  description: "Search for an advertiser on the Google Ads Transparency Center"
@@ -2589,7 +2719,7 @@ var searchAdvertiser = defineCommand21({
2589
2719
  function sleep(ms) {
2590
2720
  return new Promise((resolve5) => setTimeout(resolve5, ms));
2591
2721
  }
2592
- var track = defineCommand21({
2722
+ var track = defineCommand22({
2593
2723
  meta: {
2594
2724
  name: "track",
2595
2725
  description: "Track a new Google advertiser (from search results). Waits for initial sync to complete before returning."
@@ -2647,7 +2777,7 @@ var track = defineCommand21({
2647
2777
  process.exit(1);
2648
2778
  }
2649
2779
  });
2650
- var sync = defineCommand21({
2780
+ var sync = defineCommand22({
2651
2781
  meta: {
2652
2782
  name: "sync",
2653
2783
  description: "Trigger an immediate sync for a Google account. Waits for completion before returning."
@@ -2691,7 +2821,7 @@ var sync = defineCommand21({
2691
2821
  process.exit(1);
2692
2822
  }
2693
2823
  });
2694
- var searchCompetitors = defineCommand21({
2824
+ var searchCompetitors = defineCommand22({
2695
2825
  meta: {
2696
2826
  name: "search-competitors",
2697
2827
  description: "Search for competitors running Google ads for a keyword (DataForSEO)"
@@ -2723,7 +2853,7 @@ var searchCompetitors = defineCommand21({
2723
2853
  }
2724
2854
  }
2725
2855
  });
2726
- var library = defineCommand21({
2856
+ var library = defineCommand22({
2727
2857
  meta: {
2728
2858
  name: "library",
2729
2859
  description: "Manage and search the Google Ads Library"
@@ -2742,7 +2872,7 @@ var library = defineCommand21({
2742
2872
  // src/commands/ads/google/query.ts
2743
2873
  import { appendFileSync, existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
2744
2874
  import { resolve } from "path";
2745
- import { defineCommand as defineCommand22 } from "citty";
2875
+ import { defineCommand as defineCommand23 } from "citty";
2746
2876
 
2747
2877
  // src/commands/ads/google/preflight.ts
2748
2878
  function buildCommand2(query, customerId) {
@@ -3198,7 +3328,7 @@ function handleQueryError(err, finalQuery, customerId) {
3198
3328
  });
3199
3329
  process.exit(1);
3200
3330
  }
3201
- var queryCommand = defineCommand22({
3331
+ var queryCommand = defineCommand23({
3202
3332
  meta: {
3203
3333
  name: "query",
3204
3334
  description: `Run GAQL queries against Google Ads. Supports raw GAQL, presets, pagination, file export, and caching.
@@ -3256,7 +3386,7 @@ Examples:
3256
3386
  });
3257
3387
 
3258
3388
  // src/commands/ads/google/index.ts
3259
- var googleCommand = defineCommand23({
3389
+ var googleCommand = defineCommand24({
3260
3390
  meta: {
3261
3391
  name: "google",
3262
3392
  description: `Google Ads commands. Query campaigns, keywords, search terms, and more via GAQL.
@@ -3284,7 +3414,7 @@ Examples:
3284
3414
  });
3285
3415
 
3286
3416
  // src/commands/ads/linkedin/index.ts
3287
- import { defineCommand as defineCommand40 } from "citty";
3417
+ import { defineCommand as defineCommand42 } from "citty";
3288
3418
 
3289
3419
  // src/commands/ads/linkedin/schemas.ts
3290
3420
  registerSchema({
@@ -3584,7 +3714,7 @@ registerSchema({
3584
3714
  });
3585
3715
 
3586
3716
  // src/commands/ads/linkedin/account.ts
3587
- import { defineCommand as defineCommand24 } from "citty";
3717
+ import { defineCommand as defineCommand25 } from "citty";
3588
3718
 
3589
3719
  // src/commands/ads/linkedin/shared.ts
3590
3720
  var DAY_MS = 864e5;
@@ -3687,7 +3817,7 @@ function resolveStatusFilter(args) {
3687
3817
  }
3688
3818
 
3689
3819
  // src/commands/ads/linkedin/account.ts
3690
- var accountCommand = defineCommand24({
3820
+ var accountCommand = defineCommand25({
3691
3821
  meta: {
3692
3822
  name: "account",
3693
3823
  description: `Single LinkedIn ad account detail (currency, status, type).
@@ -3721,9 +3851,9 @@ Examples:
3721
3851
  });
3722
3852
 
3723
3853
  // src/commands/ads/linkedin/accounts.ts
3724
- import { defineCommand as defineCommand25 } from "citty";
3854
+ import { defineCommand as defineCommand26 } from "citty";
3725
3855
  var ACCOUNTS_TTL_MS = 60 * 60 * 1e3;
3726
- var accountsCommand2 = defineCommand25({
3856
+ var accountsCommand2 = defineCommand26({
3727
3857
  meta: {
3728
3858
  name: "accounts",
3729
3859
  description: `List LinkedIn ad accounts in this company's connected scope.
@@ -3771,7 +3901,7 @@ Examples:
3771
3901
  });
3772
3902
 
3773
3903
  // src/commands/ads/linkedin/analytics.ts
3774
- import { defineCommand as defineCommand26 } from "citty";
3904
+ import { defineCommand as defineCommand27 } from "citty";
3775
3905
 
3776
3906
  // src/commands/ads/linkedin/presets.ts
3777
3907
  var INTENTS = {
@@ -4043,7 +4173,7 @@ function numberOf(v) {
4043
4173
  }
4044
4174
  return 0;
4045
4175
  }
4046
- var analyticsCommand = defineCommand26({
4176
+ var analyticsCommand = defineCommand27({
4047
4177
  meta: {
4048
4178
  name: "analytics",
4049
4179
  description: `Performance reporting \u2014 the workhorse for AI agents.
@@ -4171,7 +4301,7 @@ Examples \u2014 common AI questions:
4171
4301
 
4172
4302
  // src/commands/ads/linkedin/audience-size.ts
4173
4303
  import { readFileSync as readFileSync3 } from "fs";
4174
- import { defineCommand as defineCommand27 } from "citty";
4304
+ import { defineCommand as defineCommand28 } from "citty";
4175
4305
  function loadTargeting(args) {
4176
4306
  const inline = args.targeting;
4177
4307
  if (inline) {
@@ -4193,7 +4323,7 @@ function loadTargeting(args) {
4193
4323
  }
4194
4324
  handleLinkedinError(new Error("Pass --targeting-file <path> or --targeting '{...JSON...}'"));
4195
4325
  }
4196
- var audienceSizeCommand = defineCommand27({
4326
+ var audienceSizeCommand = defineCommand28({
4197
4327
  meta: {
4198
4328
  name: "audience-size",
4199
4329
  description: `Estimate audience size for a targeting payload \u2014 pre-launch sanity check.
@@ -4238,7 +4368,7 @@ Examples:
4238
4368
  });
4239
4369
 
4240
4370
  // src/commands/ads/linkedin/audit.ts
4241
- import { defineCommand as defineCommand28 } from "citty";
4371
+ import { defineCommand as defineCommand29 } from "citty";
4242
4372
  var SEVERITY_RANK = {
4243
4373
  critical: 0,
4244
4374
  high: 1,
@@ -4297,7 +4427,7 @@ function noteOf(f) {
4297
4427
  const fix = f.fix?.explanation ?? "";
4298
4428
  return [fix, ev].filter(Boolean).join(" \u2014 ");
4299
4429
  }
4300
- var auditCommand = defineCommand28({
4430
+ var auditCommand = defineCommand29({
4301
4431
  meta: {
4302
4432
  name: "audit",
4303
4433
  description: `Run a LinkedIn Ads playbook audit \u2014 30+ checks across Settings, Tracking,
@@ -4364,7 +4494,7 @@ Examples:
4364
4494
 
4365
4495
  // src/commands/ads/linkedin/bid-pricing.ts
4366
4496
  import { readFileSync as readFileSync4 } from "fs";
4367
- import { defineCommand as defineCommand29 } from "citty";
4497
+ import { defineCommand as defineCommand30 } from "citty";
4368
4498
  function loadTargeting2(args) {
4369
4499
  const inline = args.targeting;
4370
4500
  if (inline) {
@@ -4386,7 +4516,7 @@ function loadTargeting2(args) {
4386
4516
  }
4387
4517
  handleLinkedinError(new Error("Pass --targeting-file <path> or --targeting '{...JSON...}'"));
4388
4518
  }
4389
- var bidPricingCommand = defineCommand29({
4519
+ var bidPricingCommand = defineCommand30({
4390
4520
  meta: {
4391
4521
  name: "bid-pricing",
4392
4522
  description: `Get LinkedIn's suggested bid range for a targeting + objective + cost type.
@@ -4436,8 +4566,8 @@ Examples:
4436
4566
  });
4437
4567
 
4438
4568
  // src/commands/ads/linkedin/campaign-groups.ts
4439
- import { defineCommand as defineCommand30 } from "citty";
4440
- var campaignGroupsCommand = defineCommand30({
4569
+ import { defineCommand as defineCommand31 } from "citty";
4570
+ var campaignGroupsCommand = defineCommand31({
4441
4571
  meta: {
4442
4572
  name: "campaign-groups",
4443
4573
  description: `List LinkedIn campaign groups.
@@ -4480,8 +4610,8 @@ Examples:
4480
4610
  });
4481
4611
 
4482
4612
  // src/commands/ads/linkedin/campaigns.ts
4483
- import { defineCommand as defineCommand31 } from "citty";
4484
- var campaignsCommand = defineCommand31({
4613
+ import { defineCommand as defineCommand32 } from "citty";
4614
+ var campaignsCommand = defineCommand32({
4485
4615
  meta: {
4486
4616
  name: "campaigns",
4487
4617
  description: `List LinkedIn campaigns.
@@ -4530,8 +4660,8 @@ Examples:
4530
4660
  });
4531
4661
 
4532
4662
  // src/commands/ads/linkedin/conversation.ts
4533
- import { defineCommand as defineCommand32 } from "citty";
4534
- var conversationCommand = defineCommand32({
4663
+ import { defineCommand as defineCommand33 } from "citty";
4664
+ var conversationCommand = defineCommand33({
4535
4665
  meta: {
4536
4666
  name: "conversation",
4537
4667
  description: `Per-button click rates inside Sponsored Messaging / Conversation Ads.
@@ -4594,7 +4724,7 @@ Examples:
4594
4724
  });
4595
4725
 
4596
4726
  // src/commands/ads/linkedin/conversions.ts
4597
- import { defineCommand as defineCommand33 } from "citty";
4727
+ import { defineCommand as defineCommand34 } from "citty";
4598
4728
  var DAY_MS2 = 864e5;
4599
4729
  function healthOf(rules) {
4600
4730
  const enabled = rules.filter((r) => r.enabled !== false);
@@ -4620,7 +4750,7 @@ function healthOf(rules) {
4620
4750
  wrongLeadDedup: wrongDedup
4621
4751
  };
4622
4752
  }
4623
- var listCmd = defineCommand33({
4753
+ var listCmd = defineCommand34({
4624
4754
  meta: {
4625
4755
  name: "list",
4626
4756
  description: `List conversion rules on the account.`
@@ -4648,7 +4778,7 @@ var listCmd = defineCommand33({
4648
4778
  }
4649
4779
  }
4650
4780
  });
4651
- var healthCmd = defineCommand33({
4781
+ var healthCmd = defineCommand34({
4652
4782
  meta: {
4653
4783
  name: "health",
4654
4784
  description: `5-point Insight Tag / CAPI health check (playbook \xA707).
@@ -4678,7 +4808,7 @@ Surfaces:
4678
4808
  }
4679
4809
  }
4680
4810
  });
4681
- var conversionsCommand = defineCommand33({
4811
+ var conversionsCommand = defineCommand34({
4682
4812
  meta: {
4683
4813
  name: "conversions",
4684
4814
  description: `Conversion rules \u2014 Insight Tag and Conversions API.
@@ -4694,8 +4824,8 @@ Subcommands:
4694
4824
  });
4695
4825
 
4696
4826
  // src/commands/ads/linkedin/creatives.ts
4697
- import { defineCommand as defineCommand34 } from "citty";
4698
- var creativesCommand = defineCommand34({
4827
+ import { defineCommand as defineCommand35 } from "citty";
4828
+ var creativesCommand = defineCommand35({
4699
4829
  meta: {
4700
4830
  name: "creatives",
4701
4831
  description: `List LinkedIn creatives (ads).
@@ -4744,7 +4874,7 @@ Examples:
4744
4874
  });
4745
4875
 
4746
4876
  // src/commands/ads/linkedin/demographics.ts
4747
- import { defineCommand as defineCommand35 } from "citty";
4877
+ import { defineCommand as defineCommand36 } from "citty";
4748
4878
  var DEFAULT_PIVOTS = ["job-title", "company", "industry", "seniority", "job-function", "company-size"];
4749
4879
  function numberOf2(v) {
4750
4880
  if (typeof v === "number") return Number.isFinite(v) ? v : 0;
@@ -4757,7 +4887,7 @@ function numberOf2(v) {
4757
4887
  function topByImpressions(rows, limit) {
4758
4888
  return [...rows].sort((a, b) => numberOf2(b.impressions) - numberOf2(a.impressions)).slice(0, limit);
4759
4889
  }
4760
- var demographicsCommand = defineCommand35({
4890
+ var demographicsCommand = defineCommand36({
4761
4891
  meta: {
4762
4892
  name: "demographics",
4763
4893
  description: `Sweep all firmographic pivots in one command \u2014 LinkedIn's superpower.
@@ -4854,8 +4984,8 @@ function resolveRange(args) {
4854
4984
  }
4855
4985
 
4856
4986
  // src/commands/ads/linkedin/facets.ts
4857
- import { defineCommand as defineCommand36 } from "citty";
4858
- var listCmd2 = defineCommand36({
4987
+ import { defineCommand as defineCommand37 } from "citty";
4988
+ var listCmd2 = defineCommand37({
4859
4989
  meta: {
4860
4990
  name: "list",
4861
4991
  description: `List every targeting facet LinkedIn supports.
@@ -4883,7 +5013,7 @@ seniorities, titles, employers, growthRate, companyCategory, skills, etc.).`
4883
5013
  }
4884
5014
  }
4885
5015
  });
4886
- var valuesCmd = defineCommand36({
5016
+ var valuesCmd = defineCommand37({
4887
5017
  meta: {
4888
5018
  name: "values",
4889
5019
  description: `Look up entity values for a single facet \u2014 full list or typeahead search.
@@ -4924,7 +5054,7 @@ or the full URN (urn:li:adTargetingFacet:industries).`
4924
5054
  }
4925
5055
  }
4926
5056
  });
4927
- var facetsCommand = defineCommand36({
5057
+ var facetsCommand = defineCommand37({
4928
5058
  meta: {
4929
5059
  name: "facets",
4930
5060
  description: `LinkedIn targeting facets and entity lookup.
@@ -4942,7 +5072,7 @@ Subcommands:
4942
5072
 
4943
5073
  // src/commands/ads/linkedin/forecast.ts
4944
5074
  import { readFileSync as readFileSync5 } from "fs";
4945
- import { defineCommand as defineCommand37 } from "citty";
5075
+ import { defineCommand as defineCommand38 } from "citty";
4946
5076
  function loadTargeting3(args) {
4947
5077
  const inline = args.targeting;
4948
5078
  if (inline) {
@@ -4972,7 +5102,7 @@ function parseMoney(raw) {
4972
5102
  }
4973
5103
  return { amount: m[1] ?? "0", currencyCode: m[2] ?? "USD" };
4974
5104
  }
4975
- var forecastCommand = defineCommand37({
5105
+ var forecastCommand = defineCommand38({
4976
5106
  meta: {
4977
5107
  name: "forecast",
4978
5108
  description: `Forecast reach + impressions + clicks + spend for a hypothetical campaign.
@@ -5019,9 +5149,9 @@ Examples:
5019
5149
  });
5020
5150
 
5021
5151
  // src/commands/ads/linkedin/leads.ts
5022
- import { defineCommand as defineCommand38 } from "citty";
5152
+ import { defineCommand as defineCommand39 } from "citty";
5023
5153
  var DAY_MS3 = 864e5;
5024
- var leadsCommand = defineCommand38({
5154
+ var leadsCommand = defineCommand39({
5025
5155
  meta: {
5026
5156
  name: "leads",
5027
5157
  description: `List Lead Gen Form responses (playbook \xA707).
@@ -5080,16 +5210,69 @@ Examples:
5080
5210
  }
5081
5211
  });
5082
5212
 
5213
+ // src/commands/ads/linkedin/resolve.ts
5214
+ import { defineCommand as defineCommand40 } from "citty";
5215
+ function toOrgUrn(raw) {
5216
+ const trimmed = raw.trim();
5217
+ if (trimmed.length === 0) {
5218
+ return null;
5219
+ }
5220
+ if (trimmed.startsWith("urn:li:")) {
5221
+ return trimmed;
5222
+ }
5223
+ return /^\d+$/.test(trimmed) ? `urn:li:organization:${trimmed}` : null;
5224
+ }
5225
+ var resolveCommand = defineCommand40({
5226
+ meta: {
5227
+ name: "resolve",
5228
+ description: `Resolve organization URNs to company names.
5229
+
5230
+ Examples:
5231
+ baker ads linkedin resolve --urns urn:li:organization:17719,urn:li:organization:19022
5232
+ baker ads linkedin resolve --ids 17719,19022 --output csv
5233
+
5234
+ Accepts --urns (full URNs) and/or --ids (bare numeric ids). Rows with no name
5235
+ couldn't be resolved \u2014 typically an org outside LinkedIn's targetable set.`
5236
+ },
5237
+ args: {
5238
+ urns: { type: "string", description: "Comma-separated org URNs (urn:li:organization:NNN)" },
5239
+ ids: { type: "string", description: "Comma-separated bare org ids (17719,19022)" },
5240
+ "skip-cache": { type: "boolean", description: "Bypass server-side cache" },
5241
+ output: { type: "string", description: "json|csv|jsonl|md", default: "json" }
5242
+ },
5243
+ run: async ({ args }) => {
5244
+ const raw = [args.urns, args.ids].filter(Boolean).join(",").split(",");
5245
+ const urns = [...new Set(raw.map(toOrgUrn).filter((u) => u !== null))];
5246
+ if (urns.length === 0) {
5247
+ handleLinkedinError(new Error("Provide --urns or --ids (org URNs or bare numeric ids)."));
5248
+ }
5249
+ try {
5250
+ const data = await apiPost("/api/ads/linkedin/resolve-orgs", {
5251
+ urns,
5252
+ skipCache: Boolean(args["skip-cache"])
5253
+ });
5254
+ const fmt = csvOrJson(args);
5255
+ if (fmt !== "json") {
5256
+ writeAdsOutput(data, fmt);
5257
+ return;
5258
+ }
5259
+ writeAdsJson({ ok: true, data });
5260
+ } catch (err) {
5261
+ handleLinkedinError(err);
5262
+ }
5263
+ }
5264
+ });
5265
+
5083
5266
  // src/commands/ads/linkedin/top-companies.ts
5084
- import { defineCommand as defineCommand39 } from "citty";
5085
- var topCompaniesCommand = defineCommand39({
5267
+ import { defineCommand as defineCommand41 } from "citty";
5268
+ var topCompaniesCommand = defineCommand41({
5086
5269
  meta: {
5087
5270
  name: "top-companies",
5088
5271
  description: `Top companies whose employees saw / clicked / converted on a campaign.
5089
5272
 
5090
5273
  Wrapper for: analytics --pivot company. Returns rows sorted by impressions desc.
5091
- Each row's pivot[] contains an urn:li:organization:NNN \u2014 that's the URN you
5092
- join against the Company Engagement Report or LinkedIn's Sales Navigator.
5274
+ Each row's pivot[] contains { urn, id, name } \u2014 org names are resolved automatically.
5275
+ Cross-reference names against your target account list to spot audience leakage.
5093
5276
 
5094
5277
  Demographic data is delayed 12-24h with a \u22653-event privacy floor.
5095
5278
 
@@ -5153,7 +5336,7 @@ Examples:
5153
5336
  });
5154
5337
 
5155
5338
  // src/commands/ads/linkedin/index.ts
5156
- var linkedinCommand = defineCommand40({
5339
+ var linkedinCommand = defineCommand42({
5157
5340
  meta: {
5158
5341
  name: "linkedin",
5159
5342
  description: `LinkedIn Marketing API \u2014 AI-first command surface for B2B ad insights.
@@ -5173,7 +5356,8 @@ Performance \u2014 the workhorse (3 axes):
5173
5356
  baker ads linkedin analytics \u2014 defaults: level=account, intent=baseline, last_7d, DAILY
5174
5357
  baker ads linkedin analytics --intent revenue --last-days 28
5175
5358
  baker ads linkedin analytics --level campaign --campaign-id 1234 --pivot job-title \u2014 LinkedIn's superpower (per-title perf)
5176
- baker ads linkedin analytics --level campaign --campaign-id 1234 --pivot company \u2014 top companies seeing the ad (ABM gold)
5359
+ baker ads linkedin analytics --level campaign --campaign-id 1234 --pivot company \u2014 top companies seeing the ad (ABM gold; names auto-resolved)
5360
+ baker ads linkedin resolve --urns urn:li:organization:17719 \u2014 resolve org URNs to company names
5177
5361
  baker ads linkedin analytics --level campaign --campaign-id 1234 --intent ranking \u2014 fatigue: derives frequency
5178
5362
  baker ads linkedin analytics --list-intents
5179
5363
  baker ads linkedin analytics --list-pivots
@@ -5191,6 +5375,7 @@ Account ID format:
5191
5375
  analytics: analyticsCommand,
5192
5376
  demographics: demographicsCommand,
5193
5377
  "top-companies": topCompaniesCommand,
5378
+ resolve: resolveCommand,
5194
5379
  facets: facetsCommand,
5195
5380
  "audience-size": audienceSizeCommand,
5196
5381
  "bid-pricing": bidPricingCommand,
@@ -5203,10 +5388,10 @@ Account ID format:
5203
5388
  });
5204
5389
 
5205
5390
  // src/commands/ads/meta/index.ts
5206
- import { defineCommand as defineCommand53 } from "citty";
5391
+ import { defineCommand as defineCommand55 } from "citty";
5207
5392
 
5208
5393
  // src/commands/ads/meta/account.ts
5209
- import { defineCommand as defineCommand41 } from "citty";
5394
+ import { defineCommand as defineCommand43 } from "citty";
5210
5395
 
5211
5396
  // src/commands/ads/meta/shared.ts
5212
5397
  var DAY_MS4 = 864e5;
@@ -5285,7 +5470,7 @@ function resolveEffectiveStatus(args) {
5285
5470
  }
5286
5471
 
5287
5472
  // src/commands/ads/meta/account.ts
5288
- var accountCommand2 = defineCommand41({
5473
+ var accountCommand2 = defineCommand43({
5289
5474
  meta: {
5290
5475
  name: "account",
5291
5476
  description: `Show single Meta ad account detail (currency, timezone, balance, business).
@@ -5312,8 +5497,8 @@ Examples:
5312
5497
  });
5313
5498
 
5314
5499
  // src/commands/ads/meta/accounts.ts
5315
- import { defineCommand as defineCommand42 } from "citty";
5316
- var accountsCommand3 = defineCommand42({
5500
+ import { defineCommand as defineCommand44 } from "citty";
5501
+ var accountsCommand3 = defineCommand44({
5317
5502
  meta: {
5318
5503
  name: "accounts",
5319
5504
  description: `List Meta ad accounts in this company's connected scope.
@@ -5361,8 +5546,8 @@ Examples:
5361
5546
  });
5362
5547
 
5363
5548
  // src/commands/ads/meta/activities.ts
5364
- import { defineCommand as defineCommand43 } from "citty";
5365
- var activitiesCommand = defineCommand43({
5549
+ import { defineCommand as defineCommand45 } from "citty";
5550
+ var activitiesCommand = defineCommand45({
5366
5551
  meta: {
5367
5552
  name: "activities",
5368
5553
  description: `Audit log of recent ad-account changes (created, paused, edited). Default lookback 7 days,
@@ -5399,8 +5584,8 @@ Examples:
5399
5584
  });
5400
5585
 
5401
5586
  // src/commands/ads/meta/ads.ts
5402
- import { defineCommand as defineCommand44 } from "citty";
5403
- var adsListCommand = defineCommand44({
5587
+ import { defineCommand as defineCommand46 } from "citty";
5588
+ var adsListCommand = defineCommand46({
5404
5589
  meta: {
5405
5590
  name: "ads",
5406
5591
  description: `List ads in a Meta ad account. Defaults to ACTIVE only \u2014 pass --all-statuses to widen.
@@ -5448,8 +5633,8 @@ Examples:
5448
5633
  });
5449
5634
 
5450
5635
  // src/commands/ads/meta/adsets.ts
5451
- import { defineCommand as defineCommand45 } from "citty";
5452
- var adsetsCommand = defineCommand45({
5636
+ import { defineCommand as defineCommand47 } from "citty";
5637
+ var adsetsCommand = defineCommand47({
5453
5638
  meta: {
5454
5639
  name: "adsets",
5455
5640
  description: `List ad sets in a Meta ad account, optionally scoped to one campaign. Defaults to ACTIVE only.
@@ -5491,8 +5676,8 @@ Examples:
5491
5676
  });
5492
5677
 
5493
5678
  // src/commands/ads/meta/audiences.ts
5494
- import { defineCommand as defineCommand46 } from "citty";
5495
- var audiencesCommand = defineCommand46({
5679
+ import { defineCommand as defineCommand48 } from "citty";
5680
+ var audiencesCommand = defineCommand48({
5496
5681
  meta: {
5497
5682
  name: "audiences",
5498
5683
  description: `List custom audiences for a Meta ad account. Includes lookalikes, website-pixel audiences,
@@ -5527,8 +5712,8 @@ Examples:
5527
5712
  });
5528
5713
 
5529
5714
  // src/commands/ads/meta/businesses.ts
5530
- import { defineCommand as defineCommand47 } from "citty";
5531
- var businessesCommand = defineCommand47({
5715
+ import { defineCommand as defineCommand49 } from "citty";
5716
+ var businessesCommand = defineCommand49({
5532
5717
  meta: {
5533
5718
  name: "businesses",
5534
5719
  description: `List Meta Business Manager accounts the connected user has access to. Required for ad-studies and product-catalogs commands.
@@ -5558,8 +5743,8 @@ Examples:
5558
5743
  });
5559
5744
 
5560
5745
  // src/commands/ads/meta/campaigns.ts
5561
- import { defineCommand as defineCommand48 } from "citty";
5562
- var campaignsCommand2 = defineCommand48({
5746
+ import { defineCommand as defineCommand50 } from "citty";
5747
+ var campaignsCommand2 = defineCommand50({
5563
5748
  meta: {
5564
5749
  name: "campaigns",
5565
5750
  description: `List campaigns for a Meta ad account. Defaults to ACTIVE only \u2014 pass --all-statuses to widen.
@@ -5603,8 +5788,8 @@ Examples:
5603
5788
  });
5604
5789
 
5605
5790
  // src/commands/ads/meta/creatives.ts
5606
- import { defineCommand as defineCommand49 } from "citty";
5607
- var creativesCommand2 = defineCommand49({
5791
+ import { defineCommand as defineCommand51 } from "citty";
5792
+ var creativesCommand2 = defineCommand51({
5608
5793
  meta: {
5609
5794
  name: "creatives",
5610
5795
  description: `List ad creatives in an account, or fetch a single creative by ID.
@@ -5648,7 +5833,7 @@ Examples:
5648
5833
  });
5649
5834
 
5650
5835
  // src/commands/ads/meta/insights.ts
5651
- import { defineCommand as defineCommand50 } from "citty";
5836
+ import { defineCommand as defineCommand52 } from "citty";
5652
5837
 
5653
5838
  // src/commands/ads/meta/presets.ts
5654
5839
  var INSIGHTS_INTENTS = {
@@ -5853,7 +6038,7 @@ function sortRowsBySpendDesc(rows) {
5853
6038
  return sb - sa;
5854
6039
  });
5855
6040
  }
5856
- var insightsCommand = defineCommand50({
6041
+ var insightsCommand = defineCommand52({
5857
6042
  meta: {
5858
6043
  name: "insights",
5859
6044
  description: `Performance reporting \u2014 the main Meta tool for AI agents.
@@ -5954,8 +6139,8 @@ Async is automatic for heavy queries; pass --async to force it, or --no-async to
5954
6139
  });
5955
6140
 
5956
6141
  // src/commands/ads/meta/pixels.ts
5957
- import { defineCommand as defineCommand51 } from "citty";
5958
- var pixelsCommand = defineCommand51({
6142
+ import { defineCommand as defineCommand53 } from "citty";
6143
+ var pixelsCommand = defineCommand53({
5959
6144
  meta: {
5960
6145
  name: "pixels",
5961
6146
  description: `List Meta Pixels for an ad account, or fetch firing stats for one pixel.
@@ -6026,7 +6211,7 @@ function emit(data, args) {
6026
6211
 
6027
6212
  // src/commands/ads/meta/preview.ts
6028
6213
  import { writeFileSync as writeFileSync3 } from "fs";
6029
- import { defineCommand as defineCommand52 } from "citty";
6214
+ import { defineCommand as defineCommand54 } from "citty";
6030
6215
  var VALID_AD_FORMATS = [
6031
6216
  "DESKTOP_FEED_STANDARD",
6032
6217
  "MOBILE_FEED_STANDARD",
@@ -6060,7 +6245,7 @@ var VALID_AD_FORMATS = [
6060
6245
  "MARKETPLACE_MOBILE",
6061
6246
  "BIZ_DISCO_FEED_MOBILE"
6062
6247
  ];
6063
- var previewCommand = defineCommand52({
6248
+ var previewCommand = defineCommand54({
6064
6249
  meta: {
6065
6250
  name: "preview",
6066
6251
  description: `Generate a Meta-hosted preview iframe for a creative or ad. Returns iframe HTML which you
@@ -6107,7 +6292,7 @@ Examples:
6107
6292
  });
6108
6293
 
6109
6294
  // src/commands/ads/meta/index.ts
6110
- var metaCommand = defineCommand53({
6295
+ var metaCommand = defineCommand55({
6111
6296
  meta: {
6112
6297
  name: "meta",
6113
6298
  description: `Meta Marketing API \u2014 AI-first command surface (Facebook + Instagram ads).
@@ -6159,10 +6344,10 @@ Audit & review:
6159
6344
  });
6160
6345
 
6161
6346
  // src/commands/ads/x/index.ts
6162
- import { defineCommand as defineCommand70 } from "citty";
6347
+ import { defineCommand as defineCommand72 } from "citty";
6163
6348
 
6164
6349
  // src/commands/ads/x/accounts.ts
6165
- import { defineCommand as defineCommand54 } from "citty";
6350
+ import { defineCommand as defineCommand56 } from "citty";
6166
6351
  registerSchema({
6167
6352
  command: "ads.x.accounts",
6168
6353
  description: "List all accessible X Ads accounts. Returns accounts with id (base36), name, approval_status, timezone, currency. Run this first to find account IDs for other commands.",
@@ -6190,7 +6375,7 @@ function handleAccountsError2(err) {
6190
6375
  writeAdsJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
6191
6376
  process.exit(1);
6192
6377
  }
6193
- var accountsCommand4 = defineCommand54({
6378
+ var accountsCommand4 = defineCommand56({
6194
6379
  meta: {
6195
6380
  name: "accounts",
6196
6381
  description: `List accessible X Ads accounts. Returns account IDs needed for all other commands.
@@ -6230,7 +6415,7 @@ Examples:
6230
6415
  });
6231
6416
 
6232
6417
  // src/commands/ads/x/active-entities.ts
6233
- import { defineCommand as defineCommand55 } from "citty";
6418
+ import { defineCommand as defineCommand57 } from "citty";
6234
6419
 
6235
6420
  // src/commands/ads/x/error-parser.ts
6236
6421
  function mapXErrorCode(message) {
@@ -6381,7 +6566,7 @@ function parseCsv(v) {
6381
6566
  const parts = v.split(",").map((s) => s.trim()).filter(Boolean);
6382
6567
  return parts.length > 0 ? parts : void 0;
6383
6568
  }
6384
- var activeEntitiesCommand = defineCommand55({
6569
+ var activeEntitiesCommand = defineCommand57({
6385
6570
  meta: {
6386
6571
  name: "active-entities",
6387
6572
  description: `List entities with metric activity in a time range.
@@ -6439,7 +6624,7 @@ Examples:
6439
6624
  });
6440
6625
 
6441
6626
  // src/commands/ads/x/audiences.ts
6442
- import { defineCommand as defineCommand56 } from "citty";
6627
+ import { defineCommand as defineCommand58 } from "citty";
6443
6628
  registerSchema({
6444
6629
  command: "ads.x.audiences",
6445
6630
  description: "List custom audiences for an X Ads account. Returns id, name, audience_size, audience_type, targetable status. Audiences need 100+ active users in the past 90 days to be targetable.",
@@ -6448,7 +6633,7 @@ registerSchema({
6448
6633
  "no-cache": { type: "boolean", description: "Skip cache", required: false }
6449
6634
  }
6450
6635
  });
6451
- var audiencesCommand2 = defineCommand56({
6636
+ var audiencesCommand2 = defineCommand58({
6452
6637
  meta: {
6453
6638
  name: "audiences",
6454
6639
  description: `List X Ads custom audiences.
@@ -6497,7 +6682,7 @@ Examples:
6497
6682
  });
6498
6683
 
6499
6684
  // src/commands/ads/x/campaigns.ts
6500
- import { defineCommand as defineCommand57 } from "citty";
6685
+ import { defineCommand as defineCommand59 } from "citty";
6501
6686
 
6502
6687
  // src/commands/ads/x/run-list.ts
6503
6688
  function buildCleanParams(opts) {
@@ -6560,7 +6745,7 @@ registerSchema({
6560
6745
  "no-cache": { type: "boolean", description: "Skip cache", required: false }
6561
6746
  }
6562
6747
  });
6563
- var campaignsCommand3 = defineCommand57({
6748
+ var campaignsCommand3 = defineCommand59({
6564
6749
  meta: {
6565
6750
  name: "campaigns",
6566
6751
  description: `List X Ads campaigns. Returns budget, schedule, funding instrument, status.
@@ -6602,7 +6787,7 @@ Examples:
6602
6787
  });
6603
6788
 
6604
6789
  // src/commands/ads/x/cards.ts
6605
- import { defineCommand as defineCommand58 } from "citty";
6790
+ import { defineCommand as defineCommand60 } from "citty";
6606
6791
  registerSchema({
6607
6792
  command: "ads.x.cards",
6608
6793
  description: "List website cards, video cards, and carousels for an X Ads account.",
@@ -6611,7 +6796,7 @@ registerSchema({
6611
6796
  "no-cache": { type: "boolean", description: "Skip cache", required: false }
6612
6797
  }
6613
6798
  });
6614
- var cardsCommand = defineCommand58({
6799
+ var cardsCommand = defineCommand60({
6615
6800
  meta: {
6616
6801
  name: "cards",
6617
6802
  description: `List X Ads cards (rich creatives).
@@ -6660,7 +6845,7 @@ Examples:
6660
6845
  });
6661
6846
 
6662
6847
  // src/commands/ads/x/funding.ts
6663
- import { defineCommand as defineCommand59 } from "citty";
6848
+ import { defineCommand as defineCommand61 } from "citty";
6664
6849
  registerSchema({
6665
6850
  command: "ads.x.funding",
6666
6851
  description: "List funding instruments for an X Ads account. Returns id, type, currency, credit_limit_local_micro, funded_amount_local_micro, status. Falls back to BAKER_X_ADS_ACCOUNT_ID env var.",
@@ -6669,7 +6854,7 @@ registerSchema({
6669
6854
  "no-cache": { type: "boolean", description: "Skip cache", required: false }
6670
6855
  }
6671
6856
  });
6672
- var fundingCommand = defineCommand59({
6857
+ var fundingCommand = defineCommand61({
6673
6858
  meta: {
6674
6859
  name: "funding",
6675
6860
  description: `List funding instruments for an X Ads account.
@@ -6718,7 +6903,7 @@ Examples:
6718
6903
  });
6719
6904
 
6720
6905
  // src/commands/ads/x/line-items.ts
6721
- import { defineCommand as defineCommand60 } from "citty";
6906
+ import { defineCommand as defineCommand62 } from "citty";
6722
6907
  registerSchema({
6723
6908
  command: "ads.x.lineItems",
6724
6909
  description: "List line items (ad groups) for an X Ads account. Returns bid, product_type, objective, placements, schedule. Filter by campaign-ids or line-item-ids (CSV).",
@@ -6730,7 +6915,7 @@ registerSchema({
6730
6915
  "no-cache": { type: "boolean", description: "Skip cache", required: false }
6731
6916
  }
6732
6917
  });
6733
- var lineItemsCommand = defineCommand60({
6918
+ var lineItemsCommand = defineCommand62({
6734
6919
  meta: {
6735
6920
  name: "line-items",
6736
6921
  description: `List X Ads line items (ad groups).
@@ -6771,7 +6956,7 @@ Examples:
6771
6956
  });
6772
6957
 
6773
6958
  // src/commands/ads/x/media.ts
6774
- import { defineCommand as defineCommand61 } from "citty";
6959
+ import { defineCommand as defineCommand63 } from "citty";
6775
6960
  registerSchema({
6776
6961
  command: "ads.x.media",
6777
6962
  description: "List media assets in the X Ads media library (images, GIFs, videos). Filter by media-type (IMAGE, GIF, VIDEO).",
@@ -6781,7 +6966,7 @@ registerSchema({
6781
6966
  "no-cache": { type: "boolean", description: "Skip cache", required: false }
6782
6967
  }
6783
6968
  });
6784
- var mediaCommand = defineCommand61({
6969
+ var mediaCommand = defineCommand63({
6785
6970
  meta: {
6786
6971
  name: "media",
6787
6972
  description: `List media assets in the X Ads media library.
@@ -6833,7 +7018,7 @@ Examples:
6833
7018
  });
6834
7019
 
6835
7020
  // src/commands/ads/x/promoted-tweets.ts
6836
- import { defineCommand as defineCommand62 } from "citty";
7021
+ import { defineCommand as defineCommand64 } from "citty";
6837
7022
  registerSchema({
6838
7023
  command: "ads.x.promotedTweets",
6839
7024
  description: "List promoted tweets for an X Ads account. Returns id, line_item_id, tweet_id, approval_status. Filter by line-item-ids (CSV).",
@@ -6844,7 +7029,7 @@ registerSchema({
6844
7029
  "no-cache": { type: "boolean", description: "Skip cache", required: false }
6845
7030
  }
6846
7031
  });
6847
- var promotedTweetsCommand = defineCommand62({
7032
+ var promotedTweetsCommand = defineCommand64({
6848
7033
  meta: {
6849
7034
  name: "promoted-tweets",
6850
7035
  description: `List X Ads promoted tweets.
@@ -6898,11 +7083,11 @@ Examples:
6898
7083
  });
6899
7084
 
6900
7085
  // src/commands/ads/x/stats/index.ts
6901
- import { defineCommand as defineCommand67 } from "citty";
7086
+ import { defineCommand as defineCommand69 } from "citty";
6902
7087
 
6903
7088
  // src/commands/ads/x/stats/job.ts
6904
7089
  import { gunzipSync } from "zlib";
6905
- import { defineCommand as defineCommand63 } from "citty";
7090
+ import { defineCommand as defineCommand65 } from "citty";
6906
7091
  var POLL_INTERVAL_MS2 = 1e4;
6907
7092
  var DEADLINE_MS = 12 * 60 * 1e3;
6908
7093
  var RESULT_CACHE_TTL_MS = 6 * 60 * 60 * 1e3;
@@ -6972,7 +7157,7 @@ async function pollUntilDone(accountId, jobId) {
6972
7157
  function buildCacheKey(body) {
6973
7158
  return `stats-job:${JSON.stringify(body)}`;
6974
7159
  }
6975
- var statsJobCommand = defineCommand63({
7160
+ var statsJobCommand = defineCommand65({
6976
7161
  meta: {
6977
7162
  name: "job",
6978
7163
  description: `Async X Ads stats job, sync from the CLI's perspective. Creates \u2192 polls \u2192 downloads \u2192 returns.
@@ -7077,7 +7262,7 @@ For fine-grained control (don't wait, poll yourself), use:
7077
7262
  });
7078
7263
 
7079
7264
  // src/commands/ads/x/stats/job-create.ts
7080
- import { defineCommand as defineCommand64 } from "citty";
7265
+ import { defineCommand as defineCommand66 } from "citty";
7081
7266
  registerSchema({
7082
7267
  command: "ads.x.statsJobCreate",
7083
7268
  description: "Create an asynchronous X Ads stats job (range up to 90 days non-segmented, 45 days segmented). Returns a job id; poll with `stats job-status`. Times must be ISO 8601 hour-aligned.",
@@ -7100,7 +7285,7 @@ function parseCsv3(v) {
7100
7285
  const parts = v.split(",").map((s) => s.trim()).filter(Boolean);
7101
7286
  return parts.length > 0 ? parts : void 0;
7102
7287
  }
7103
- var statsJobCreateCommand = defineCommand64({
7288
+ var statsJobCreateCommand = defineCommand66({
7104
7289
  meta: {
7105
7290
  name: "job-create",
7106
7291
  description: `Create an async X Ads stats job (up to 90 days, supports segmentation).
@@ -7163,7 +7348,7 @@ Examples:
7163
7348
  });
7164
7349
 
7165
7350
  // src/commands/ads/x/stats/job-status.ts
7166
- import { defineCommand as defineCommand65 } from "citty";
7351
+ import { defineCommand as defineCommand67 } from "citty";
7167
7352
  registerSchema({
7168
7353
  command: "ads.x.statsJobStatus",
7169
7354
  description: "Check the status of one or more X Ads stats jobs. Returns status (PROCESSING|SUCCESS|FAILED) and a downloadable url when SUCCESS. Pass --job-id or --job-ids (CSV).",
@@ -7173,7 +7358,7 @@ registerSchema({
7173
7358
  "job-ids": { type: "string", description: "CSV of job IDs", required: false }
7174
7359
  }
7175
7360
  });
7176
- var statsJobStatusCommand = defineCommand65({
7361
+ var statsJobStatusCommand = defineCommand67({
7177
7362
  meta: {
7178
7363
  name: "job-status",
7179
7364
  description: `Poll the status of an async X Ads stats job.
@@ -7214,7 +7399,7 @@ Examples:
7214
7399
  });
7215
7400
 
7216
7401
  // src/commands/ads/x/stats/sync.ts
7217
- import { defineCommand as defineCommand66 } from "citty";
7402
+ import { defineCommand as defineCommand68 } from "citty";
7218
7403
 
7219
7404
  // src/commands/ads/x/presets.ts
7220
7405
  var X_STATS_PRESETS = [
@@ -7373,7 +7558,7 @@ async function runSync(args, q) {
7373
7558
  process.exit(1);
7374
7559
  }
7375
7560
  }
7376
- var statsSyncCommand = defineCommand66({
7561
+ var statsSyncCommand = defineCommand68({
7377
7562
  meta: {
7378
7563
  name: "sync",
7379
7564
  description: `Synchronous X Ads analytics (max 7-day window).
@@ -7416,7 +7601,7 @@ Examples:
7416
7601
  });
7417
7602
 
7418
7603
  // src/commands/ads/x/stats/index.ts
7419
- var statsCommand = defineCommand67({
7604
+ var statsCommand = defineCommand69({
7420
7605
  meta: {
7421
7606
  name: "stats",
7422
7607
  description: `X Ads analytics. Sync (\u22647 days, no segmentation) or async jobs (\u226490 days, segmentable).
@@ -7444,7 +7629,7 @@ Examples:
7444
7629
  });
7445
7630
 
7446
7631
  // src/commands/ads/x/targeting-constants.ts
7447
- import { defineCommand as defineCommand68 } from "citty";
7632
+ import { defineCommand as defineCommand70 } from "citty";
7448
7633
  var ALLOWED_CONSTANTS = [
7449
7634
  "locations",
7450
7635
  "interests",
@@ -7472,7 +7657,7 @@ registerSchema({
7472
7657
  "no-cache": { type: "boolean", description: "Skip cache", required: false }
7473
7658
  }
7474
7659
  });
7475
- var targetingConstantsCommand = defineCommand68({
7660
+ var targetingConstantsCommand = defineCommand70({
7476
7661
  meta: {
7477
7662
  name: "targeting-constants",
7478
7663
  description: `Lookup X Ads targeting constants.
@@ -7522,7 +7707,7 @@ Examples:
7522
7707
  });
7523
7708
 
7524
7709
  // src/commands/ads/x/targeting-criteria.ts
7525
- import { defineCommand as defineCommand69 } from "citty";
7710
+ import { defineCommand as defineCommand71 } from "citty";
7526
7711
  registerSchema({
7527
7712
  command: "ads.x.targetingCriteria",
7528
7713
  description: "List targeting criteria attached to line items in an X Ads account. Returns targeting_type, targeting_value, name, operator_type per criterion. Filter by line-item-ids.",
@@ -7532,7 +7717,7 @@ registerSchema({
7532
7717
  "no-cache": { type: "boolean", description: "Skip cache", required: false }
7533
7718
  }
7534
7719
  });
7535
- var targetingCriteriaCommand = defineCommand69({
7720
+ var targetingCriteriaCommand = defineCommand71({
7536
7721
  meta: {
7537
7722
  name: "targeting-criteria",
7538
7723
  description: `List targeting criteria attached to line items.
@@ -7583,7 +7768,7 @@ Examples:
7583
7768
  });
7584
7769
 
7585
7770
  // src/commands/ads/x/index.ts
7586
- var xCommand = defineCommand70({
7771
+ var xCommand = defineCommand72({
7587
7772
  meta: {
7588
7773
  name: "x",
7589
7774
  description: `X (Twitter) Ads commands. Read campaigns, line items, promoted tweets, creatives, audiences, and analytics.
@@ -7621,7 +7806,7 @@ The CLI auto-detects --account-id when exactly one X Ads account is connected, o
7621
7806
  });
7622
7807
 
7623
7808
  // src/commands/ads/index.ts
7624
- var adsCommand = defineCommand71({
7809
+ var adsCommand = defineCommand73({
7625
7810
  meta: {
7626
7811
  name: "ads",
7627
7812
  description: `Ad platform commands. Each platform exposes its own native command surface \u2014 no forced parity.
@@ -7651,11 +7836,11 @@ Examples:
7651
7836
  });
7652
7837
 
7653
7838
  // src/commands/canvas/index.ts
7654
- import { defineCommand as defineCommand78 } from "citty";
7839
+ import { defineCommand as defineCommand80 } from "citty";
7655
7840
 
7656
7841
  // src/commands/canvas/catalog.ts
7657
- import { defineCommand as defineCommand72 } from "citty";
7658
- var catalogCommand = defineCommand72({
7842
+ import { defineCommand as defineCommand74 } from "citty";
7843
+ var catalogCommand = defineCommand74({
7659
7844
  meta: {
7660
7845
  name: "catalog",
7661
7846
  description: "Print the agent-facing node catalog (JSON Schema). Includes every registered node grouped by category."
@@ -7672,9 +7857,9 @@ import { execFile } from "child_process";
7672
7857
  import { readdir, readFile, stat } from "fs/promises";
7673
7858
  import path from "path";
7674
7859
  import { promisify } from "util";
7675
- import { defineCommand as defineCommand73 } from "citty";
7860
+ import { defineCommand as defineCommand75 } from "citty";
7676
7861
  var execFileAsync = promisify(execFile);
7677
- var inspectCommand = defineCommand73({
7862
+ var inspectCommand = defineCommand75({
7678
7863
  meta: {
7679
7864
  name: "inspect",
7680
7865
  description: "Dump a one-page summary of a canvas run: per-node duration + cache status, list of output files in the run dir, and optionally three thumbnail frames per video output. Pass either a run_id (resolved against --outputs-dir) or an absolute run directory."
@@ -7783,7 +7968,7 @@ async function probeDuration(filePath) {
7783
7968
  // src/commands/canvas/run.ts
7784
7969
  import { readFile as readFile2 } from "fs/promises";
7785
7970
  import path2 from "path";
7786
- import { defineCommand as defineCommand74 } from "citty";
7971
+ import { defineCommand as defineCommand76 } from "citty";
7787
7972
 
7788
7973
  // src/commands/canvas/placeholders.ts
7789
7974
  function unsuppliedPlaceholderAssets(canvas) {
@@ -7802,7 +7987,7 @@ function unsuppliedPlaceholderAssets(canvas) {
7802
7987
  }
7803
7988
 
7804
7989
  // src/commands/canvas/run.ts
7805
- var runCommand = defineCommand74({
7990
+ var runCommand = defineCommand76({
7806
7991
  meta: { name: "run", description: "Validate and execute a canvas JSON file." },
7807
7992
  args: {
7808
7993
  file: { type: "positional", required: true, description: "Path to canvas JSON" },
@@ -7887,7 +8072,7 @@ var runCommand = defineCommand74({
7887
8072
  // src/commands/canvas/scaffold-static-ad.ts
7888
8073
  import { readFile as readFile3, writeFile } from "fs/promises";
7889
8074
  import path3 from "path";
7890
- import { defineCommand as defineCommand75 } from "citty";
8075
+ import { defineCommand as defineCommand77 } from "citty";
7891
8076
 
7892
8077
  // src/engine/scaffold/staticAd.ts
7893
8078
  import { z as z2 } from "zod";
@@ -8206,7 +8391,7 @@ async function runVisionPasses(canvas) {
8206
8391
  return fail("read_outputs", e instanceof Error ? e.message : String(e));
8207
8392
  }
8208
8393
  }
8209
- var scaffoldStaticAdCommand = defineCommand75({
8394
+ var scaffoldStaticAdCommand = defineCommand77({
8210
8395
  meta: {
8211
8396
  name: "scaffold-static-ad",
8212
8397
  description: "Turn a source/inspiration image into a runnable static-ad canvas. Runs billed passes \u2014 image_describe (the blueprint, baked to prompt.json as the editable 'prompt'), an AI selection of the image's MAIN identity elements, and a structured global-layout pass (the column/row grid with per-region bounds and text sizes) \u2014 then scaffolds a canvas that wires one [TODO] ingest slot per element (logo/product/subject/badge + brand font) into image_generate. Edit prompt.json and drop the real assets, then `baker canvas run` it."
@@ -8300,7 +8485,7 @@ var scaffoldStaticAdCommand = defineCommand75({
8300
8485
  // src/commands/canvas/scaffold-video.ts
8301
8486
  import { cp, mkdir, readFile as readFile5, writeFile as writeFile2 } from "fs/promises";
8302
8487
  import path5 from "path";
8303
- import { defineCommand as defineCommand76 } from "citty";
8488
+ import { defineCommand as defineCommand78 } from "citty";
8304
8489
 
8305
8490
  // src/engine/nodes/local/lib/sceneDetect.ts
8306
8491
  import { execFile as execFile2 } from "child_process";
@@ -8393,6 +8578,18 @@ async function detectSceneCutsPySceneDetect(filePath, opts = {}) {
8393
8578
  }
8394
8579
 
8395
8580
  // src/engine/scaffold/video.ts
8581
+ import { toCardinal as nwAr } from "n2words/ar-SA";
8582
+ import { toCardinal as nwDe } from "n2words/de-DE";
8583
+ import { toCardinal as nwEn } from "n2words/en-US";
8584
+ import { toCardinal as nwEs } from "n2words/es-ES";
8585
+ import { toCardinal as nwFr } from "n2words/fr-FR";
8586
+ import { toCardinal as nwHi } from "n2words/hi-IN";
8587
+ import { toCardinal as nwIt } from "n2words/it-IT";
8588
+ import { toCardinal as nwJa } from "n2words/ja-JP";
8589
+ import { toCardinal as nwKo } from "n2words/ko-KR";
8590
+ import { toCardinal as nwNl } from "n2words/nl-NL";
8591
+ import { toCardinal as nwPl } from "n2words/pl-PL";
8592
+ import { toCardinal as nwPt } from "n2words/pt-PT";
8396
8593
  import { z as z3 } from "zod";
8397
8594
 
8398
8595
  // src/engine/scaffold/lib/shoot-modes.ts
@@ -8504,6 +8701,14 @@ var XFADE_BY_TYPE = {
8504
8701
  swipe: "wipeleft",
8505
8702
  zoom: "zoomin"
8506
8703
  };
8704
+ var DEFAULT_VIDEO_RESOLUTION = "1080p";
8705
+ var VIDEO_MODELS_WITH_RESOLUTION = new Set(
8706
+ Object.entries(MODEL_REGISTRY.video_generate).filter(([, spec]) => "resolution" in spec.params).map(([id]) => id)
8707
+ );
8708
+ function videoResolutionParam(videoModel, resolution) {
8709
+ if (!VIDEO_MODELS_WITH_RESOLUTION.has(videoModel)) return {};
8710
+ return { resolution: resolution ?? DEFAULT_VIDEO_RESOLUTION };
8711
+ }
8507
8712
  var WORDS_PER_SECOND = 2.5;
8508
8713
  function estSpeechS(text) {
8509
8714
  const words = text.trim().split(/\s+/).filter(Boolean).length;
@@ -8721,12 +8926,21 @@ var VideoBlueprint = z3.object({
8721
8926
  // reference track. We never reuse it — only style the regenerated bed.
8722
8927
  identified_track: z3.object({ title: z3.string().optional(), artist: z3.string().optional() }).loose().nullish()
8723
8928
  }).loose().optional(),
8724
- cast: z3.array(z3.object({ id: z3.string().optional(), description: z3.string().optional() }).loose()).optional(),
8929
+ cast: z3.array(
8930
+ z3.object({
8931
+ id: z3.string().optional(),
8932
+ description: z3.string().optional(),
8933
+ // The deconstruct's note on the target-market localization (e.g. "native
8934
+ // French speaker") — read to derive the spoken-track language code.
8935
+ market_localization_note: z3.string().optional()
8936
+ }).loose()
8937
+ ).optional(),
8725
8938
  voiceover: z3.object({
8726
8939
  // on_camera | mixed → mouths are on screen (lip-sync candidates);
8727
8940
  // voiceover | none → narration over the picture (no lip-sync).
8728
8941
  mode: z3.string().optional(),
8729
- voice_description: z3.string().optional()
8942
+ voice_description: z3.string().optional(),
8943
+ persona: z3.string().optional()
8730
8944
  }).loose().optional()
8731
8945
  }).loose().optional(),
8732
8946
  scenes: z3.array(Scene).min(1)
@@ -8909,11 +9123,18 @@ function slotsForFrame(slots, sceneIndex, edge) {
8909
9123
  return slots.filter((s) => s.presence.get(sceneIndex)?.has(edge));
8910
9124
  }
8911
9125
  var ACTOR_SHEET_MODEL = "google/gemini-3-pro-image-preview";
8912
- function applyActorSheets(slots, nodes) {
9126
+ var SHEET_SUBJECT_TYPE = {
9127
+ person: "person",
9128
+ animal: "character",
9129
+ product: "product",
9130
+ location: "location"
9131
+ };
9132
+ function buildElementSheets(slots, nodes) {
8913
9133
  for (const slot of slots) {
8914
- const t = slot.type.toLowerCase();
8915
- if (t !== "person" && t !== "animal") continue;
8916
- if (slot.presence.size < 2) continue;
9134
+ const subjectType = SHEET_SUBJECT_TYPE[slot.type.toLowerCase()];
9135
+ if (!subjectType) continue;
9136
+ if (slot.sameAs) continue;
9137
+ if (slot.presence.size < 1) continue;
8917
9138
  const sheetId = `${slot.id}_sheet`;
8918
9139
  nodes.push({
8919
9140
  id: sheetId,
@@ -8923,11 +9144,15 @@ function applyActorSheets(slots, nodes) {
8923
9144
  params: {
8924
9145
  model: ACTOR_SHEET_MODEL,
8925
9146
  subject_description: slot.description ?? `the ${slot.type}`,
8926
- subject_type: t === "person" ? "person" : "character",
8927
- image_size: "2K"
9147
+ subject_type: subjectType,
9148
+ // 4K: the sheet packs up to 8 cells (angles + tight face/detail close-ups), and
9149
+ // it's the ONE reference every frame grounds on — per-cell sharpness here
9150
+ // propagates to every clip, so it's worth the highest tier on this single asset.
9151
+ image_size: "4K"
8928
9152
  }
8929
9153
  });
8930
9154
  slot.ref = `$ref:${sheetId}.sheet`;
9155
+ slot.sheetBacked = true;
8931
9156
  }
8932
9157
  }
8933
9158
  function slotsForScene(slots, sceneIndex) {
@@ -8938,7 +9163,7 @@ function buildFramePrompt(edge, sceneIndex, framePrompt, present, hasAnchor, mod
8938
9163
  const legend = [
8939
9164
  ...present.map((s) => `- ${s.label} \u2014 ${roleForSlot(s)}`),
8940
9165
  ...hasAnchor ? [
8941
- "- ORIGINAL_FRAME \u2014 use ONLY for composition, framing, pose, and proportions. IGNORE its text, its logo, its brand name, and its colors entirely \u2014 it is a DIFFERENT brand's footage, here only to anchor layout/pose, never identity or palette."
9166
+ "- ORIGINAL_FRAME \u2014 use ONLY for composition: framing, camera angle, shot size, subject placement, pose, and proportions. IGNORE its text, logo, brand name, colors, AND the identity of every person/animal/object in it \u2014 those come from the labeled reference images above, never from this frame. It is a DIFFERENT brand's footage with DIFFERENT actors, here ONLY to anchor where things sit and how the shot is framed (e.g. a profile/side angle stays a profile/side angle), never who they are or what palette to use."
8942
9167
  ] : []
8943
9168
  ].join("\n");
8944
9169
  const description = framePrompt?.trim() || `the ${edge} frame of scene ${sceneIndex + 1} \u2014 describe the full composition, subjects, setting, action, lighting, and palette here. (Edit this line to change ONLY this frame.)`;
@@ -9027,11 +9252,12 @@ function ingestFrameRef(url, edge, ctx, nodes) {
9027
9252
  function buildFrameRef(edge, url, framePrompt, present, ctx, nodes) {
9028
9253
  const tag = ctx.tag ?? "";
9029
9254
  if (ctx.reuse && url) return ingestFrameRef(url, edge, ctx, nodes);
9030
- const hasPersonOrAnimal = present.some((s) => {
9255
+ const castSlots = present.filter((s) => {
9031
9256
  const t = s.type.toLowerCase();
9032
9257
  return t === "person" || t === "animal";
9033
9258
  });
9034
- const useOriginalAnchor = Boolean(url) && !hasPersonOrAnimal;
9259
+ const castIdentityLocked = castSlots.every((s) => s.sheetBacked);
9260
+ const useOriginalAnchor = Boolean(url) && (castSlots.length === 0 || castIdentityLocked);
9035
9261
  const hasOriginal = useOriginalAnchor;
9036
9262
  const originalRef = useOriginalAnchor && url ? ingestFrameRef(url, edge, ctx, nodes) : void 0;
9037
9263
  const reference = [...present.map((s) => s.ref), ...originalRef ? [originalRef] : []];
@@ -9063,17 +9289,18 @@ function seedanceAudioLine(scene, mode, audio, nativeLine) {
9063
9289
  }
9064
9290
  return null;
9065
9291
  }
9066
- function buildSeedancePrompt(scene, sceneIndex, present, mode, audio, nativeLine) {
9292
+ function buildSeedancePrompt(scene, sceneIndex, present, mode, audio, nativeLine, nativeLang) {
9293
+ const loc = (s) => nativeLine ? localizeNumeralsForNative(s, nativeLang) : s;
9067
9294
  const parts = [];
9068
9295
  const summary = scene.summary?.trim();
9069
- parts.push(summary ? `Scene ${sceneIndex + 1}: ${summary}` : `Scene ${sceneIndex + 1}`);
9070
- if (scene.action_detail) parts.push(`Action: ${scene.action_detail}`);
9296
+ parts.push(summary ? `Scene ${sceneIndex + 1}: ${loc(summary)}` : `Scene ${sceneIndex + 1}`);
9297
+ if (scene.action_detail) parts.push(`Action: ${loc(scene.action_detail)}`);
9071
9298
  const cm = scene.camera_motion;
9072
9299
  if (cm) {
9073
9300
  const camera = [cm.movement, cm.detail].filter(Boolean).join(" \u2014 ");
9074
9301
  if (camera) parts.push(`Camera: ${camera}`);
9075
9302
  }
9076
- if (scene.motion_prompt) parts.push(`Motion: ${scene.motion_prompt}`);
9303
+ if (scene.motion_prompt) parts.push(`Motion: ${loc(scene.motion_prompt)}`);
9077
9304
  if (present.length > 0) {
9078
9305
  parts.push(
9079
9306
  `Keep these consistent with their references: ${present.map((s) => `${s.label} (${s.description ?? s.type})`).join("; ")}`
@@ -9081,7 +9308,7 @@ function buildSeedancePrompt(scene, sceneIndex, present, mode, audio, nativeLine
9081
9308
  }
9082
9309
  if (nativeLine) {
9083
9310
  parts.push(
9084
- `The person speaks to camera. Lip-sync follows the dialogue verbatim; put delivery/emotion cues in [brackets]. Dialogue: "${nativeLine}"`
9311
+ `The person speaks to camera. Lip-sync follows the dialogue verbatim; put delivery/emotion cues in [brackets]. Dialogue: "${loc(nativeLine)}"`
9085
9312
  );
9086
9313
  } else {
9087
9314
  const lines = (scene.dialogue ?? []).map((d) => d.line?.trim()).filter((l) => Boolean(l));
@@ -9089,7 +9316,7 @@ function buildSeedancePrompt(scene, sceneIndex, present, mode, audio, nativeLine
9089
9316
  parts.push(`Spoken context (do not render as audio): ${lines.map((l) => `"${l}"`).join(" ")}`);
9090
9317
  }
9091
9318
  const transcript = (scene.transcript_slice ?? []).map((w) => w.text?.trim()).filter(Boolean).join(" ").trim();
9092
- if (transcript) parts.push(`Transcript: ${transcript}`);
9319
+ if (transcript) parts.push(`Transcript: ${loc(transcript)}`);
9093
9320
  const audioLine = seedanceAudioLine(scene, mode, audio, nativeLine);
9094
9321
  if (audioLine) parts.push(audioLine);
9095
9322
  parts.push(
@@ -9200,8 +9427,17 @@ function buildPerSpeakerVoiceConversion(segments, totalMs, nodes) {
9200
9427
  function emitSceneClip(i, scene, present, mode, nativeTurn, ambientBroll, frames, lengths, out, opts, nodes, tag = "") {
9201
9428
  const clipParams = {
9202
9429
  model: opts.videoModel,
9203
- prompt: buildSeedancePrompt(scene, i, present, mode, Boolean(nativeTurn) || ambientBroll, nativeTurn?.text),
9430
+ prompt: buildSeedancePrompt(
9431
+ scene,
9432
+ i,
9433
+ present,
9434
+ mode,
9435
+ Boolean(nativeTurn) || ambientBroll,
9436
+ nativeTurn?.text,
9437
+ opts.nativeLang
9438
+ ),
9204
9439
  duration: lengths.genDur,
9440
+ ...videoResolutionParam(opts.videoModel, opts.resolution),
9205
9441
  // Native talking scene → Seedance generates the spoken audio + lip-sync; an opt-in
9206
9442
  // ambient b-roll beat generates diegetic ambient only; otherwise the clip is silent.
9207
9443
  generate_audio: Boolean(nativeTurn) || ambientBroll
@@ -9305,7 +9541,7 @@ function buildCompositeScene(layout, regions, comp, scene, i, present, mode, nat
9305
9541
  { first, last },
9306
9542
  lengths,
9307
9543
  null,
9308
- { ar: opts.ar, videoModel: opts.videoModel },
9544
+ { ar: opts.ar, videoModel: opts.videoModel, resolution: opts.resolution, nativeLang: opts.nativeLang },
9309
9545
  nodes,
9310
9546
  tag
9311
9547
  );
@@ -9437,6 +9673,65 @@ var LANGUAGE_WORDS = [
9437
9673
  [/\b(hindi)\b/, "hindi"],
9438
9674
  [/\b(polish)\b/, "polish"]
9439
9675
  ];
9676
+ var LANGUAGE_ISO = {
9677
+ french: "fr",
9678
+ spanish: "es",
9679
+ english: "en",
9680
+ german: "de",
9681
+ italian: "it",
9682
+ portuguese: "pt",
9683
+ dutch: "nl",
9684
+ arabic: "ar",
9685
+ japanese: "ja",
9686
+ korean: "ko",
9687
+ hindi: "hi",
9688
+ polish: "pl"
9689
+ };
9690
+ function languageHaystacks(blueprint) {
9691
+ const vo = blueprint.global?.voiceover;
9692
+ const cast = blueprint.global?.cast ?? [];
9693
+ const dialogue = blueprint.scenes.flatMap((s) => s.dialogue ?? []);
9694
+ return [
9695
+ vo?.voice_description,
9696
+ vo?.persona,
9697
+ ...cast.flatMap((c) => [c.market_localization_note, c.description]),
9698
+ ...dialogue.map((l) => l.voice_description)
9699
+ ].filter((s) => Boolean(s));
9700
+ }
9701
+ function deriveTtsLanguageCode(blueprint) {
9702
+ for (const text of languageHaystacks(blueprint)) {
9703
+ const name = parseVoiceTraits(text).language;
9704
+ if (name && LANGUAGE_ISO[name]) return LANGUAGE_ISO[name];
9705
+ }
9706
+ return void 0;
9707
+ }
9708
+ var INTEGER_SPELLERS = {
9709
+ fr: nwFr,
9710
+ es: nwEs,
9711
+ en: nwEn,
9712
+ de: nwDe,
9713
+ it: nwIt,
9714
+ pt: nwPt,
9715
+ nl: nwNl,
9716
+ pl: nwPl,
9717
+ ar: nwAr,
9718
+ ja: nwJa,
9719
+ ko: nwKo,
9720
+ hi: nwHi
9721
+ };
9722
+ function spellNumber(langCode, n) {
9723
+ const spell = langCode ? INTEGER_SPELLERS[langCode] : void 0;
9724
+ if (!spell || !Number.isFinite(n)) return String(n);
9725
+ try {
9726
+ return spell(n);
9727
+ } catch {
9728
+ return String(n);
9729
+ }
9730
+ }
9731
+ function localizeNumeralsForNative(text, langCode) {
9732
+ if (!langCode || !INTEGER_SPELLERS[langCode]) return text;
9733
+ return text.replace(/(?<![\w.,-])\d{1,9}(?![\w.,-])/g, (m) => spellNumber(langCode, Number.parseInt(m, 10)));
9734
+ }
9440
9735
  function parseVoiceTraits(description) {
9441
9736
  const d = description.toLowerCase();
9442
9737
  const out = {};
@@ -9455,14 +9750,14 @@ function isOnCameraSpeaker(speaker, casts, cameraOn) {
9455
9750
  if (NARRATOR_SPEAKERS.has(speaker.toLowerCase())) return false;
9456
9751
  return casts.has(speaker);
9457
9752
  }
9458
- function makePresenterPresent(slots, canonical) {
9753
+ function makePresenterPresent(slots, canonical, opts = {}) {
9459
9754
  const personSlots = slots.filter((s) => s.type.toLowerCase() === "person");
9460
9755
  const bySpeaker = /* @__PURE__ */ new Map();
9461
9756
  for (const slot of personSlots) if (slot.castId) bySpeaker.set(canonical(slot.castId), slot.presence);
9462
- const solePerson = personSlots.length === 1 ? personSlots[0].presence : null;
9757
+ const solePerson = !opts.strict && personSlots.length === 1 ? personSlots[0].presence : null;
9463
9758
  return (speaker, sceneIndex) => {
9464
9759
  const presence = bySpeaker.get(speaker) ?? solePerson;
9465
- if (!presence) return true;
9760
+ if (!presence) return opts.strict ? false : true;
9466
9761
  return presence.has(sceneIndex);
9467
9762
  };
9468
9763
  }
@@ -9481,16 +9776,18 @@ function collapseVoiceover(blueprint) {
9481
9776
  const presenter = [...presenters][0];
9482
9777
  return (speaker) => NARRATOR_SPEAKERS.has(speaker.toLowerCase()) ? presenter : speaker;
9483
9778
  }
9484
- function buildPhrases(blueprint, canonical, compositeScenes, presenterPresent) {
9779
+ function buildPhrases(blueprint, canonical, compositeScenes, presenterPresent, presentStrict) {
9485
9780
  const casts = castIdSet(blueprint);
9486
9781
  const cameraOn = onCameraDialogue(blueprint);
9487
9782
  const sceneEndS = (i) => blueprint.scenes[i]?.end_s ?? blueprint.scenes[i]?.start_s ?? 0;
9488
9783
  const multiSpeaker = /* @__PURE__ */ new Set();
9489
9784
  blueprint.scenes.forEach((scene, i) => {
9490
- const onCam = new Set(
9785
+ const onCamAll = new Set(
9491
9786
  (scene.dialogue ?? []).map((l) => l.speaker ?? "voiceover").filter((sp) => isOnCameraSpeaker(sp, casts, cameraOn))
9492
9787
  );
9493
- if (onCam.size >= 2) multiSpeaker.add(i);
9788
+ const onCamPresent = [...onCamAll].filter((sp) => presentStrict(canonical(sp), i));
9789
+ const effective = onCamPresent.length > 0 ? new Set(onCamPresent) : onCamAll;
9790
+ if (effective.size >= 2) multiSpeaker.add(i);
9494
9791
  });
9495
9792
  const lines = blueprint.scenes.flatMap(
9496
9793
  (scene, sceneIndex) => compositeScenes.has(sceneIndex) ? [] : (scene.dialogue ?? []).filter((l) => Boolean(l.line?.trim())).map((l) => {
@@ -9629,8 +9926,9 @@ function emitPhraseClip(phrase, voiceNode, env, nodes, out) {
9629
9926
  const genDur = ceilToSeedance(phraseLen);
9630
9927
  const clipParams = {
9631
9928
  model: env.opts.videoModel,
9632
- prompt: buildSeedancePrompt(anchorScene, anchor, present, mode, true, phrase.text),
9929
+ prompt: buildSeedancePrompt(anchorScene, anchor, present, mode, true, phrase.text, env.ttsLanguageCode),
9633
9930
  duration: genDur,
9931
+ ...videoResolutionParam(env.opts.videoModel, env.opts.resolution),
9634
9932
  generate_audio: true
9635
9933
  };
9636
9934
  if (env.ar) clipParams.aspect_ratio = env.ar;
@@ -9690,7 +9988,7 @@ function emitPhraseClip(phrase, voiceNode, env, nodes, out) {
9690
9988
  });
9691
9989
  }
9692
9990
  }
9693
- function emitPhraseTts(phrase, voiceNode, idx, used, nodes, out) {
9991
+ function emitPhraseTts(phrase, voiceNode, idx, used, nodes, out, languageCode) {
9694
9992
  let id = sanitizeId2(`vo_ph${idx}_${phrase.speaker}`, `vo_ph${idx}`);
9695
9993
  while (used.has(id)) id = `${id}_x`;
9696
9994
  used.add(id);
@@ -9698,7 +9996,12 @@ function emitPhraseTts(phrase, voiceNode, idx, used, nodes, out) {
9698
9996
  id,
9699
9997
  type: "tts",
9700
9998
  inputs: { voice_ref: `$ref:${voiceNode}.voice_id` },
9701
- params: { model: FIXED_TTS_MODEL, text: phrase.text, voice: "{{voice_ref}}" }
9999
+ params: {
10000
+ model: FIXED_TTS_MODEL,
10001
+ text: phrase.text,
10002
+ voice: "{{voice_ref}}",
10003
+ ...languageCode ? { language_code: languageCode } : {}
10004
+ }
9702
10005
  });
9703
10006
  out.voTracks.push({ slot: id, ref: `$ref:${id}.audio`, start_s: phrase.start_s, end_s: phrase.end_s, kind: "vo" });
9704
10007
  out.voSegments.push({
@@ -9741,17 +10044,34 @@ function emitCompositeInTimeline(composite, scene, i, isLast, env, canonical, en
9741
10044
  nativeTurn,
9742
10045
  lengths,
9743
10046
  lengths.out,
9744
- { ar: env.ar, reuse: env.reuse, imageModel: env.opts.imageModel, videoModel: env.opts.videoModel },
10047
+ {
10048
+ ar: env.ar,
10049
+ reuse: env.reuse,
10050
+ imageModel: env.opts.imageModel,
10051
+ videoModel: env.opts.videoModel,
10052
+ resolution: env.opts.resolution,
10053
+ nativeLang: env.ttsLanguageCode
10054
+ },
9745
10055
  nodes,
9746
10056
  out.voTracks,
9747
10057
  out.nativeSegments,
9748
10058
  out.clips
9749
10059
  );
9750
10060
  if (!nativeTurn && distinctSpeakers.size >= 2) {
9751
- emitCompositeMultiSpeakerVoice(onCam, scene, i, canonical, ensureVoiceNode, usedVoIds, nodes, out);
10061
+ emitCompositeMultiSpeakerVoice(
10062
+ onCam,
10063
+ scene,
10064
+ i,
10065
+ canonical,
10066
+ ensureVoiceNode,
10067
+ usedVoIds,
10068
+ nodes,
10069
+ out,
10070
+ env.ttsLanguageCode
10071
+ );
9752
10072
  }
9753
10073
  }
9754
- function emitCompositeMultiSpeakerVoice(onCam, scene, i, canonical, ensureVoiceNode, usedVoIds, nodes, out) {
10074
+ function emitCompositeMultiSpeakerVoice(onCam, scene, i, canonical, ensureVoiceNode, usedVoIds, nodes, out, languageCode) {
9755
10075
  const bySpeaker = /* @__PURE__ */ new Map();
9756
10076
  for (const l of onCam) {
9757
10077
  const speaker = canonical(l.speaker ?? "voiceover");
@@ -9783,7 +10103,8 @@ function emitCompositeMultiSpeakerVoice(onCam, scene, i, canonical, ensureVoiceN
9783
10103
  i,
9784
10104
  usedVoIds,
9785
10105
  nodes,
9786
- out
10106
+ out,
10107
+ languageCode
9787
10108
  );
9788
10109
  }
9789
10110
  }
@@ -9830,7 +10151,7 @@ function emitBrollScene(scene, i, isLast, env, nodes, out, prevEndFrame) {
9830
10151
  { first, last },
9831
10152
  { dur: lengths.dur, trimTarget: lengths.trimTarget, genDur: lengths.genDur },
9832
10153
  lengths.out,
9833
- { ar: env.ar, videoModel: env.opts.videoModel },
10154
+ { ar: env.ar, videoModel: env.opts.videoModel, resolution: env.opts.resolution, nativeLang: env.ttsLanguageCode },
9834
10155
  nodes
9835
10156
  );
9836
10157
  if (ambientBroll) {
@@ -9866,7 +10187,8 @@ function buildTimeline(blueprint, slots, opts, nodes) {
9866
10187
  reuse,
9867
10188
  cameraOn: onCameraDialogue(blueprint),
9868
10189
  casts: castIdSet(blueprint),
9869
- ingestCache: /* @__PURE__ */ new Map()
10190
+ ingestCache: /* @__PURE__ */ new Map(),
10191
+ ttsLanguageCode: deriveTtsLanguageCode(blueprint)
9870
10192
  };
9871
10193
  const out = {
9872
10194
  clips: [],
@@ -9877,7 +10199,8 @@ function buildTimeline(blueprint, slots, opts, nodes) {
9877
10199
  sceneSlice: /* @__PURE__ */ new Map()
9878
10200
  };
9879
10201
  const presenterPresent = makePresenterPresent(slots, canonical);
9880
- const phrases = buildPhrases(blueprint, canonical, compositeScenes, presenterPresent);
10202
+ const presentStrict = makePresenterPresent(slots, canonical, { strict: true });
10203
+ const phrases = buildPhrases(blueprint, canonical, compositeScenes, presenterPresent, presentStrict);
9881
10204
  const usedVoIds = /* @__PURE__ */ new Set();
9882
10205
  const claimed = /* @__PURE__ */ new Set();
9883
10206
  phrases.forEach((phrase, k) => {
@@ -9887,7 +10210,7 @@ function buildTimeline(blueprint, slots, opts, nodes) {
9887
10210
  for (const s of available) claimed.add(s);
9888
10211
  emitPhraseClip({ ...phrase, shownScenes: available }, voiceNode, env, nodes, out);
9889
10212
  } else {
9890
- emitPhraseTts(phrase, voiceNode, k, usedVoIds, nodes, out);
10213
+ emitPhraseTts(phrase, voiceNode, k, usedVoIds, nodes, out, env.ttsLanguageCode);
9891
10214
  }
9892
10215
  });
9893
10216
  const lastIndex = blueprint.scenes.length - 1;
@@ -10224,7 +10547,7 @@ function scaffoldVideoCanvas(input, elementsInput, opts) {
10224
10547
  params: { source: "path", path: todoPath2(elements[i], slot.label), expect: "image" }
10225
10548
  });
10226
10549
  });
10227
- applyActorSheets(slots, nodes);
10550
+ buildElementSheets(slots, nodes);
10228
10551
  const { clips, voTracks, vo_segments, talking_scenes } = buildTimeline(blueprint, slots, opts, nodes);
10229
10552
  let videoRef = buildSpine(clips, nodes);
10230
10553
  let videoNode = "spine";
@@ -10333,9 +10656,27 @@ function buildVideoMeta(blueprint, meta) {
10333
10656
  duration_s: blueprint.source?.duration_s ?? lastSceneEnd(blueprint),
10334
10657
  vo_segments: [...meta.vo_segments].sort((a, b) => a.start_s - b.start_s),
10335
10658
  talking_scenes: meta.talking_scenes,
10659
+ lip_sync_caution: buildLipSyncCaution(meta.vo_segments),
10336
10660
  motion_board: buildMotionBoard(blueprint)
10337
10661
  };
10338
10662
  }
10663
+ function buildLipSyncCaution(segments) {
10664
+ const out = [];
10665
+ const byScene = /* @__PURE__ */ new Map();
10666
+ for (const s of segments) {
10667
+ const arr = byScene.get(s.scene) ?? [];
10668
+ arr.push(s);
10669
+ byScene.set(s.scene, arr);
10670
+ }
10671
+ for (const [scene, segs] of [...byScene.entries()].sort((a, b) => a[0] - b[0])) {
10672
+ const nativeSpeakers = new Set(segs.filter((s) => s.slot.endsWith("_conv")).map((s) => s.speaker));
10673
+ for (const speaker of nativeSpeakers) {
10674
+ const ttsOver = segs.filter((s) => !s.slot.endsWith("_conv") && s.speaker === speaker).map((s) => s.slot);
10675
+ if (ttsOver.length > 0) out.push({ scene, speaker, tts_over_native: ttsOver });
10676
+ }
10677
+ }
10678
+ return out;
10679
+ }
10339
10680
  function sceneSpokenText(scene) {
10340
10681
  return (scene.dialogue ?? []).map((d) => d.line?.trim()).filter((l) => Boolean(l)).join(" ") || null;
10341
10682
  }
@@ -10744,7 +11085,7 @@ async function runAnalysisPasses(deconstructCanvas, selectModel) {
10744
11085
  return fail2("deconstruct", e instanceof Error ? e.message : String(e));
10745
11086
  }
10746
11087
  }
10747
- var scaffoldVideoCommand = defineCommand76({
11088
+ var scaffoldVideoCommand = defineCommand78({
10748
11089
  meta: {
10749
11090
  name: "scaffold-video",
10750
11091
  description: "Turn a reference video into a runnable reproduction canvas in one command. Runs billed passes \u2014 video_deconstruct (the full scene-by-scene blueprint + transcript, baked to prompt.json as the editable 'prompt') and an AI selection of the video's RECURRING identity elements (person/animal/product/logo) \u2014 then scaffolds a pipeline where every scene boundary is a static-ad-grade frame (the blueprint as target_blueprint, a reference legend, the real frame as anchor) and each recurring element gets ONE shared [TODO] ingest slot wired into every frame it appears in. The clips feed Seedance an ultra-detailed motion brief (action, camera, dialogue, transcript). Edit prompt.json, drop the real source images, then `baker canvas run`."
@@ -10767,7 +11108,11 @@ var scaffoldVideoCommand = defineCommand76({
10767
11108
  "deconstruct-model": { type: "string", description: "Override the video_deconstruct model id" },
10768
11109
  "select-model": { type: "string", description: "Override the text_generate model id for element selection" },
10769
11110
  "image-model": { type: "string", description: "Override the image_generate model id for frames" },
10770
- "video-model": { type: "string", description: "Override the video_generate model id for clips" }
11111
+ "video-model": { type: "string", description: "Override the video_generate model id for clips" },
11112
+ resolution: {
11113
+ type: "string",
11114
+ description: `Output resolution for generated clips (e.g. "1080p"). Default 1080p \u2014 the highest the video model supports \u2014 so clips keep the keyframe sharpness instead of the model's low default.`
11115
+ }
10771
11116
  },
10772
11117
  async run({ args }) {
10773
11118
  const videoPath = path5.resolve(String(args.file));
@@ -10819,7 +11164,8 @@ var scaffoldVideoCommand = defineCommand76({
10819
11164
  transcriptPath: captions.transcriptPath,
10820
11165
  blueprintPath,
10821
11166
  frames,
10822
- ambient: Boolean(args.ambient)
11167
+ ambient: Boolean(args.ambient),
11168
+ ...args.resolution ? { resolution: String(args.resolution) } : {}
10823
11169
  };
10824
11170
  let canvas;
10825
11171
  let report;
@@ -10882,8 +11228,8 @@ var scaffoldVideoCommand = defineCommand76({
10882
11228
  // src/commands/canvas/validate.ts
10883
11229
  import { readFile as readFile6 } from "fs/promises";
10884
11230
  import path6 from "path";
10885
- import { defineCommand as defineCommand77 } from "citty";
10886
- var validateCommand = defineCommand77({
11231
+ import { defineCommand as defineCommand79 } from "citty";
11232
+ var validateCommand = defineCommand79({
10887
11233
  meta: {
10888
11234
  name: "validate",
10889
11235
  description: "Validate a canvas JSON file (no execution). Includes a per-node cost preview and runs each node's deep validators (composition meta checks for hyperframe_render/_snapshot)."
@@ -10925,7 +11271,7 @@ var validateCommand = defineCommand77({
10925
11271
  });
10926
11272
 
10927
11273
  // src/commands/canvas/index.ts
10928
- var canvasCommand = defineCommand78({
11274
+ var canvasCommand = defineCommand80({
10929
11275
  meta: {
10930
11276
  name: "canvas",
10931
11277
  description: `Run Baker creative canvas JSON files locally. Local nodes execute in-process; remote nodes POST to the Convex backend gateway.
@@ -10951,10 +11297,10 @@ Subcommands:
10951
11297
  });
10952
11298
 
10953
11299
  // src/commands/ga4/index.ts
10954
- import { defineCommand as defineCommand82 } from "citty";
11300
+ import { defineCommand as defineCommand84 } from "citty";
10955
11301
 
10956
11302
  // src/commands/ga4/audit.ts
10957
- import { defineCommand as defineCommand79 } from "citty";
11303
+ import { defineCommand as defineCommand81 } from "citty";
10958
11304
 
10959
11305
  // src/commands/ga4/resolve.ts
10960
11306
  async function fetchProperties(useCache = true) {
@@ -11017,7 +11363,7 @@ registerSchema({
11017
11363
  "no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
11018
11364
  }
11019
11365
  });
11020
- var auditCommand2 = defineCommand79({
11366
+ var auditCommand2 = defineCommand81({
11021
11367
  meta: {
11022
11368
  name: "audit",
11023
11369
  description: `Run all GA4 admin health checks. Returns property config with playbook warnings.
@@ -11069,7 +11415,7 @@ Examples:
11069
11415
  });
11070
11416
 
11071
11417
  // src/commands/ga4/properties.ts
11072
- import { defineCommand as defineCommand80 } from "citty";
11418
+ import { defineCommand as defineCommand82 } from "citty";
11073
11419
  registerSchema({
11074
11420
  command: "ga4.properties",
11075
11421
  description: "List all accessible GA4 properties. Returns property IDs needed for query and audit commands. Run this first to find property IDs.",
@@ -11077,7 +11423,7 @@ registerSchema({
11077
11423
  "no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
11078
11424
  }
11079
11425
  });
11080
- var propertiesCommand = defineCommand80({
11426
+ var propertiesCommand = defineCommand82({
11081
11427
  meta: {
11082
11428
  name: "properties",
11083
11429
  description: `List accessible GA4 properties.
@@ -11127,7 +11473,7 @@ Examples:
11127
11473
  // src/commands/ga4/query.ts
11128
11474
  import { appendFileSync as appendFileSync2, existsSync as existsSync4, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "fs";
11129
11475
  import { resolve as resolve2 } from "path";
11130
- import { defineCommand as defineCommand81 } from "citty";
11476
+ import { defineCommand as defineCommand83 } from "citty";
11131
11477
 
11132
11478
  // src/commands/ga4/presets.ts
11133
11479
  var GA4_PRESETS = [
@@ -11259,7 +11605,7 @@ function handleError(err) {
11259
11605
  });
11260
11606
  process.exit(1);
11261
11607
  }
11262
- var queryCommand2 = defineCommand81({
11608
+ var queryCommand2 = defineCommand83({
11263
11609
  meta: {
11264
11610
  name: "query",
11265
11611
  description: `Run GA4 Data API reports. Preset-first with free-form escape hatch.
@@ -11330,7 +11676,7 @@ Free-form (escape hatch):
11330
11676
  });
11331
11677
 
11332
11678
  // src/commands/ga4/index.ts
11333
- var ga4Command = defineCommand82({
11679
+ var ga4Command = defineCommand84({
11334
11680
  meta: {
11335
11681
  name: "ga4",
11336
11682
  description: `Google Analytics 4 commands. Audit property config, run playbook-aligned reports.
@@ -11353,12 +11699,12 @@ Examples:
11353
11699
  });
11354
11700
 
11355
11701
  // src/commands/gsc/index.ts
11356
- import { defineCommand as defineCommand86 } from "citty";
11702
+ import { defineCommand as defineCommand88 } from "citty";
11357
11703
 
11358
11704
  // src/commands/gsc/query.ts
11359
11705
  import { appendFileSync as appendFileSync3, existsSync as existsSync5, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "fs";
11360
11706
  import { resolve as resolve3 } from "path";
11361
- import { defineCommand as defineCommand83 } from "citty";
11707
+ import { defineCommand as defineCommand85 } from "citty";
11362
11708
 
11363
11709
  // src/commands/gsc/presets.ts
11364
11710
  var GSC_PRESETS = [
@@ -11546,7 +11892,7 @@ function handleError2(err) {
11546
11892
  });
11547
11893
  process.exit(1);
11548
11894
  }
11549
- var queryCommand3 = defineCommand83({
11895
+ var queryCommand3 = defineCommand85({
11550
11896
  meta: {
11551
11897
  name: "query",
11552
11898
  description: `Run GSC Search Analytics queries. Preset-first with free-form escape hatch.
@@ -11624,7 +11970,7 @@ Free-form (escape hatch):
11624
11970
  });
11625
11971
 
11626
11972
  // src/commands/gsc/sitemaps.ts
11627
- import { defineCommand as defineCommand84 } from "citty";
11973
+ import { defineCommand as defineCommand86 } from "citty";
11628
11974
  registerSchema({
11629
11975
  command: "gsc.sitemaps",
11630
11976
  description: "List sitemaps for a Search Console site. Check sitemap health and errors.",
@@ -11633,7 +11979,7 @@ registerSchema({
11633
11979
  "no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
11634
11980
  }
11635
11981
  });
11636
- var sitemapsCommand = defineCommand84({
11982
+ var sitemapsCommand = defineCommand86({
11637
11983
  meta: {
11638
11984
  name: "sitemaps",
11639
11985
  description: `List sitemaps for a site. Check health and errors.
@@ -11683,7 +12029,7 @@ Examples:
11683
12029
  });
11684
12030
 
11685
12031
  // src/commands/gsc/sites.ts
11686
- import { defineCommand as defineCommand85 } from "citty";
12032
+ import { defineCommand as defineCommand87 } from "citty";
11687
12033
  registerSchema({
11688
12034
  command: "gsc.sites",
11689
12035
  description: "List all verified Google Search Console sites. Returns site URLs needed for query and sitemaps commands.",
@@ -11691,7 +12037,7 @@ registerSchema({
11691
12037
  "no-cache": { type: "boolean", description: "Skip cache, hit API directly", required: false }
11692
12038
  }
11693
12039
  });
11694
- var sitesCommand = defineCommand85({
12040
+ var sitesCommand = defineCommand87({
11695
12041
  meta: {
11696
12042
  name: "sites",
11697
12043
  description: `List verified Search Console sites.
@@ -11739,7 +12085,7 @@ Examples:
11739
12085
  });
11740
12086
 
11741
12087
  // src/commands/gsc/index.ts
11742
- var gscCommand = defineCommand86({
12088
+ var gscCommand = defineCommand88({
11743
12089
  meta: {
11744
12090
  name: "gsc",
11745
12091
  description: `Google Search Console commands. PPC-SEO arbitrage, brand halo analysis, negative keyword discovery.
@@ -11762,10 +12108,10 @@ Examples:
11762
12108
  });
11763
12109
 
11764
12110
  // src/commands/images/index.ts
11765
- import { defineCommand as defineCommand109 } from "citty";
12111
+ import { defineCommand as defineCommand111 } from "citty";
11766
12112
 
11767
12113
  // src/commands/images/crop.ts
11768
- import { defineCommand as defineCommand87 } from "citty";
12114
+ import { defineCommand as defineCommand89 } from "citty";
11769
12115
 
11770
12116
  // src/lib/image/crop-sprite.ts
11771
12117
  import sharp from "sharp";
@@ -11890,7 +12236,7 @@ function emitError2(err) {
11890
12236
  }
11891
12237
  process.exit(1);
11892
12238
  }
11893
- var cropCommand = defineCommand87({
12239
+ var cropCommand = defineCommand89({
11894
12240
  meta: {
11895
12241
  name: "crop",
11896
12242
  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"
@@ -11926,7 +12272,7 @@ var cropCommand = defineCommand87({
11926
12272
  });
11927
12273
 
11928
12274
  // src/commands/images/delete.ts
11929
- import { defineCommand as defineCommand88 } from "citty";
12275
+ import { defineCommand as defineCommand90 } from "citty";
11930
12276
  registerSchema({
11931
12277
  command: "images.delete",
11932
12278
  description: "Delete an image by ID",
@@ -11940,7 +12286,7 @@ registerSchema({
11940
12286
  }
11941
12287
  }
11942
12288
  });
11943
- var deleteCommand = defineCommand88({
12289
+ var deleteCommand = defineCommand90({
11944
12290
  meta: {
11945
12291
  name: "delete",
11946
12292
  description: "Delete an image by ID. Use --dry-run to preview. Example: baker images delete j571abc123 --dry-run"
@@ -11981,7 +12327,7 @@ var deleteCommand = defineCommand88({
11981
12327
  });
11982
12328
 
11983
12329
  // src/commands/images/dimensions.ts
11984
- import { defineCommand as defineCommand89 } from "citty";
12330
+ import { defineCommand as defineCommand91 } from "citty";
11985
12331
 
11986
12332
  // src/lib/image/dimensions.ts
11987
12333
  import { imageSize } from "image-size";
@@ -12004,7 +12350,7 @@ registerSchema({
12004
12350
  target: { type: "string", description: "Local file path or remote http(s) URL", required: true }
12005
12351
  }
12006
12352
  });
12007
- var dimensionsCommand = defineCommand89({
12353
+ var dimensionsCommand = defineCommand91({
12008
12354
  meta: {
12009
12355
  name: "dimensions",
12010
12356
  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"
@@ -12048,7 +12394,7 @@ var dimensionsCommand = defineCommand89({
12048
12394
  });
12049
12395
 
12050
12396
  // src/commands/images/extract.ts
12051
- import { defineCommand as defineCommand90 } from "citty";
12397
+ import { defineCommand as defineCommand92 } from "citty";
12052
12398
  registerSchema({
12053
12399
  command: "images.extract",
12054
12400
  description: "Extract images from a URL via Firecrawl (formats: images).",
@@ -12064,7 +12410,7 @@ registerSchema({
12064
12410
  }
12065
12411
  }
12066
12412
  });
12067
- var extractCommand = defineCommand90({
12413
+ var extractCommand = defineCommand92({
12068
12414
  meta: {
12069
12415
  name: "extract",
12070
12416
  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"
@@ -12102,7 +12448,7 @@ var extractCommand = defineCommand90({
12102
12448
  });
12103
12449
 
12104
12450
  // src/commands/images/find.ts
12105
- import { defineCommand as defineCommand91 } from "citty";
12451
+ import { defineCommand as defineCommand93 } from "citty";
12106
12452
  registerSchema({
12107
12453
  command: "images.find",
12108
12454
  description: "Fanout image search: library first, then opted-in external providers.",
@@ -12134,7 +12480,7 @@ registerSchema({
12134
12480
  }
12135
12481
  }
12136
12482
  });
12137
- var findCommand = defineCommand91({
12483
+ var findCommand = defineCommand93({
12138
12484
  meta: {
12139
12485
  name: "find",
12140
12486
  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"
@@ -12181,7 +12527,7 @@ var findCommand = defineCommand91({
12181
12527
 
12182
12528
  // src/commands/images/generate.ts
12183
12529
  import { readFile as readFile8 } from "fs/promises";
12184
- import { defineCommand as defineCommand92 } from "citty";
12530
+ import { defineCommand as defineCommand94 } from "citty";
12185
12531
  import sharp2 from "sharp";
12186
12532
  var GENERATE_TIMEOUT_MS = 18e4;
12187
12533
  var REFERENCE_MAX_EDGE = 1536;
@@ -12277,7 +12623,7 @@ async function resolveReferences(spec) {
12277
12623
  }
12278
12624
  return out;
12279
12625
  }
12280
- var generateCommand = defineCommand92({
12626
+ var generateCommand = defineCommand94({
12281
12627
  meta: {
12282
12628
  name: "generate",
12283
12629
  description: "Generate an image with AI and store it in the library (cost-tracked per request via OpenRouter usage). Models mirror the canvas: openai/gpt-5.4-image-2 (default \u2014 photoreal, cleanest text, best for ad/landing reproduction), google/gemini-3-pro-image-preview (Nano Banana Pro), google/gemini-3.5-flash & google/gemini-3.1-flash-image-preview (fast, extreme aspect ratios), 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 google/gemini-3-pro-image-preview --image-size 2K\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]]'"
@@ -12329,7 +12675,7 @@ var generateCommand = defineCommand92({
12329
12675
  });
12330
12676
 
12331
12677
  // src/commands/images/get.ts
12332
- import { defineCommand as defineCommand93 } from "citty";
12678
+ import { defineCommand as defineCommand95 } from "citty";
12333
12679
  registerSchema({
12334
12680
  command: "images.get",
12335
12681
  description: "Get a single image by ID",
@@ -12337,7 +12683,7 @@ registerSchema({
12337
12683
  id: { type: "string", description: "Image ID", required: true }
12338
12684
  }
12339
12685
  });
12340
- var getCommand2 = defineCommand93({
12686
+ var getCommand2 = defineCommand95({
12341
12687
  meta: { name: "get", description: "Get a single image by ID. Example: baker images get j571abc123" },
12342
12688
  args: {
12343
12689
  id: { type: "positional", description: "Image ID", required: false },
@@ -12373,7 +12719,7 @@ var getCommand2 = defineCommand93({
12373
12719
  });
12374
12720
 
12375
12721
  // src/commands/images/gif.ts
12376
- import { defineCommand as defineCommand94 } from "citty";
12722
+ import { defineCommand as defineCommand96 } from "citty";
12377
12723
  registerSchema({
12378
12724
  command: "images.gif",
12379
12725
  description: "Search Giphy for GIFs / reaction memes (paid social creative).",
@@ -12405,7 +12751,7 @@ registerSchema({
12405
12751
  }
12406
12752
  }
12407
12753
  });
12408
- var gifCommand = defineCommand94({
12754
+ var gifCommand = defineCommand96({
12409
12755
  meta: {
12410
12756
  name: "gif",
12411
12757
  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"
@@ -12452,7 +12798,7 @@ var gifCommand = defineCommand94({
12452
12798
  });
12453
12799
 
12454
12800
  // src/commands/images/google.ts
12455
- import { defineCommand as defineCommand95 } from "citty";
12801
+ import { defineCommand as defineCommand97 } from "citty";
12456
12802
  registerSchema({
12457
12803
  command: "images.google",
12458
12804
  description: "Google Images search via the official Custom Search JSON API. Unverified source \u2014 inspect before placing.",
@@ -12488,7 +12834,7 @@ registerSchema({
12488
12834
  }
12489
12835
  }
12490
12836
  });
12491
- var googleCommand2 = defineCommand95({
12837
+ var googleCommand2 = defineCommand97({
12492
12838
  meta: {
12493
12839
  name: "google",
12494
12840
  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"
@@ -12536,7 +12882,7 @@ var googleCommand2 = defineCommand95({
12536
12882
  });
12537
12883
 
12538
12884
  // src/commands/images/icon.ts
12539
- import { defineCommand as defineCommand96 } from "citty";
12885
+ import { defineCommand as defineCommand98 } from "citty";
12540
12886
  registerSchema({
12541
12887
  command: "images.icon",
12542
12888
  description: "Icon lookup via Iconify (200+ icon sets, free CDN).",
@@ -12562,7 +12908,7 @@ registerSchema({
12562
12908
  }
12563
12909
  }
12564
12910
  });
12565
- var iconCommand = defineCommand96({
12911
+ var iconCommand = defineCommand98({
12566
12912
  meta: {
12567
12913
  name: "icon",
12568
12914
  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'"
@@ -12602,7 +12948,7 @@ var iconCommand = defineCommand96({
12602
12948
  });
12603
12949
 
12604
12950
  // src/commands/images/ingest.ts
12605
- import { defineCommand as defineCommand97 } from "citty";
12951
+ import { defineCommand as defineCommand99 } from "citty";
12606
12952
  registerSchema({
12607
12953
  command: "images.ingest",
12608
12954
  description: "Ingest a remote image URL into the library (full describe + embed).",
@@ -12614,7 +12960,7 @@ registerSchema({
12614
12960
  context: { type: "string", description: "Description context hint", required: false }
12615
12961
  }
12616
12962
  });
12617
- var ingestCommand = defineCommand97({
12963
+ var ingestCommand = defineCommand99({
12618
12964
  meta: {
12619
12965
  name: "ingest",
12620
12966
  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"
@@ -12656,7 +13002,7 @@ var ingestCommand = defineCommand97({
12656
13002
  });
12657
13003
 
12658
13004
  // src/commands/images/library.ts
12659
- import { defineCommand as defineCommand98 } from "citty";
13005
+ import { defineCommand as defineCommand100 } from "citty";
12660
13006
  registerSchema({
12661
13007
  command: "images.library",
12662
13008
  description: "Search the company image library. Returns only ready images.",
@@ -12682,7 +13028,7 @@ registerSchema({
12682
13028
  }
12683
13029
  }
12684
13030
  });
12685
- var libraryCommand = defineCommand98({
13031
+ var libraryCommand = defineCommand100({
12686
13032
  meta: {
12687
13033
  name: "library",
12688
13034
  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"
@@ -12739,7 +13085,7 @@ var libraryCommand = defineCommand98({
12739
13085
  });
12740
13086
 
12741
13087
  // src/commands/images/logo.ts
12742
- import { defineCommand as defineCommand99 } from "citty";
13088
+ import { defineCommand as defineCommand101 } from "citty";
12743
13089
  registerSchema({
12744
13090
  command: "images.logo",
12745
13091
  description: "Brand logo lookup via Brandfetch CDN (fallback/404). Auto-ingests by default.",
@@ -12764,7 +13110,7 @@ registerSchema({
12764
13110
  }
12765
13111
  }
12766
13112
  });
12767
- var logoCommand = defineCommand99({
13113
+ var logoCommand = defineCommand101({
12768
13114
  meta: {
12769
13115
  name: "logo",
12770
13116
  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"
@@ -12802,7 +13148,7 @@ var logoCommand = defineCommand99({
12802
13148
  });
12803
13149
 
12804
13150
  // src/commands/images/normalize.ts
12805
- import { defineCommand as defineCommand100 } from "citty";
13151
+ import { defineCommand as defineCommand102 } from "citty";
12806
13152
 
12807
13153
  // src/lib/image/color-changer.ts
12808
13154
  import quantize from "quantize";
@@ -13534,7 +13880,7 @@ function coerceRawArgs(args) {
13534
13880
  "dry-run": bool(args["dry-run"])
13535
13881
  };
13536
13882
  }
13537
- var normalizeCommand = defineCommand100({
13883
+ var normalizeCommand = defineCommand102({
13538
13884
  meta: {
13539
13885
  name: "normalize",
13540
13886
  description: `Normalize logos / images: declarative recolor + bg removal + trim + resize. Operates on local files; writes in-place by default.
@@ -13589,7 +13935,7 @@ Examples:
13589
13935
  });
13590
13936
 
13591
13937
  // src/commands/images/pinterest.ts
13592
- import { defineCommand as defineCommand101 } from "citty";
13938
+ import { defineCommand as defineCommand103 } from "citty";
13593
13939
  registerSchema({
13594
13940
  command: "images.pinterest",
13595
13941
  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.",
@@ -13609,7 +13955,7 @@ registerSchema({
13609
13955
  }
13610
13956
  }
13611
13957
  });
13612
- var pinterestCommand = defineCommand101({
13958
+ var pinterestCommand = defineCommand103({
13613
13959
  meta: {
13614
13960
  name: "pinterest",
13615
13961
  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'"
@@ -13649,7 +13995,7 @@ var pinterestCommand = defineCommand101({
13649
13995
  });
13650
13996
 
13651
13997
  // src/commands/images/screenshot.ts
13652
- import { defineCommand as defineCommand102 } from "citty";
13998
+ import { defineCommand as defineCommand104 } from "citty";
13653
13999
  registerSchema({
13654
14000
  command: "images.screenshot",
13655
14001
  description: "Capture a website screenshot via ScreenshotOne. Auto-ingests on success.",
@@ -13665,7 +14011,7 @@ registerSchema({
13665
14011
  }
13666
14012
  }
13667
14013
  });
13668
- var screenshotCommand = defineCommand102({
14014
+ var screenshotCommand = defineCommand104({
13669
14015
  meta: {
13670
14016
  name: "screenshot",
13671
14017
  description: "Screenshot a URL via ScreenshotOne. $0.009/capture. Auto-ingests to library.\n\nExample: baker images screenshot https://stripe.com --full-page"
@@ -13715,7 +14061,7 @@ var screenshotCommand = defineCommand102({
13715
14061
  });
13716
14062
 
13717
14063
  // src/commands/images/search.ts
13718
- import { defineCommand as defineCommand103 } from "citty";
14064
+ import { defineCommand as defineCommand105 } from "citty";
13719
14065
  registerSchema({
13720
14066
  command: "images.search",
13721
14067
  description: "Search images by text query. Only returns ready images.",
@@ -13731,7 +14077,7 @@ registerSchema({
13731
14077
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
13732
14078
  }
13733
14079
  });
13734
- var searchCommand = defineCommand103({
14080
+ var searchCommand = defineCommand105({
13735
14081
  meta: {
13736
14082
  name: "search",
13737
14083
  description: "Semantic search images by text query. Uses hybrid BM25 + vector + reranking. Example: baker images search 'hero banner' --aspect-ratio 16:9 --tags logo"
@@ -13791,7 +14137,7 @@ var searchCommand = defineCommand103({
13791
14137
  });
13792
14138
 
13793
14139
  // src/commands/images/sticker.ts
13794
- import { defineCommand as defineCommand104 } from "citty";
14140
+ import { defineCommand as defineCommand106 } from "citty";
13795
14141
  registerSchema({
13796
14142
  command: "images.sticker",
13797
14143
  description: "Search Giphy stickers \u2014 transparent-background overlays for ad creative.",
@@ -13823,7 +14169,7 @@ registerSchema({
13823
14169
  }
13824
14170
  }
13825
14171
  });
13826
- var stickerCommand = defineCommand104({
14172
+ var stickerCommand = defineCommand106({
13827
14173
  meta: {
13828
14174
  name: "sticker",
13829
14175
  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"
@@ -13870,7 +14216,7 @@ var stickerCommand = defineCommand104({
13870
14216
  });
13871
14217
 
13872
14218
  // src/commands/images/stock.ts
13873
- import { defineCommand as defineCommand105 } from "citty";
14219
+ import { defineCommand as defineCommand107 } from "citty";
13874
14220
  registerSchema({
13875
14221
  command: "images.stock",
13876
14222
  description: "Stock photo, vector illustration, icon-set, and PSD search via Magnific (Freepik's developer API).",
@@ -13928,7 +14274,7 @@ registerSchema({
13928
14274
  }
13929
14275
  }
13930
14276
  });
13931
- var stockCommand = defineCommand105({
14277
+ var stockCommand = defineCommand107({
13932
14278
  meta: {
13933
14279
  name: "stock",
13934
14280
  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"
@@ -13986,7 +14332,7 @@ var stockCommand = defineCommand105({
13986
14332
  // src/commands/images/upload.ts
13987
14333
  import { readFile as readFile9 } from "fs/promises";
13988
14334
  import { extname as extname2 } from "path";
13989
- import { defineCommand as defineCommand106 } from "citty";
14335
+ import { defineCommand as defineCommand108 } from "citty";
13990
14336
  var MIME_MAP = {
13991
14337
  ".png": "image/png",
13992
14338
  ".jpg": "image/jpeg",
@@ -14041,7 +14387,7 @@ function detectContentType(filePath) {
14041
14387
  }
14042
14388
  return mime;
14043
14389
  }
14044
- var uploadCommand = defineCommand106({
14390
+ var uploadCommand = defineCommand108({
14045
14391
  meta: {
14046
14392
  name: "upload",
14047
14393
  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'"
@@ -14134,7 +14480,7 @@ async function uploadLocal(target, args) {
14134
14480
  }
14135
14481
 
14136
14482
  // src/commands/images/upscale.ts
14137
- import { defineCommand as defineCommand107 } from "citty";
14483
+ import { defineCommand as defineCommand109 } from "citty";
14138
14484
  registerSchema({
14139
14485
  command: "images.upscale",
14140
14486
  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).",
@@ -14149,7 +14495,7 @@ registerSchema({
14149
14495
  }
14150
14496
  });
14151
14497
  var POLL_INTERVAL_MS3 = 1500;
14152
- var upscaleCommand = defineCommand107({
14498
+ var upscaleCommand = defineCommand109({
14153
14499
  meta: {
14154
14500
  name: "upscale",
14155
14501
  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"
@@ -14204,7 +14550,7 @@ var upscaleCommand = defineCommand107({
14204
14550
  });
14205
14551
 
14206
14552
  // src/commands/images/use.ts
14207
- import { defineCommand as defineCommand108 } from "citty";
14553
+ import { defineCommand as defineCommand110 } from "citty";
14208
14554
  registerSchema({
14209
14555
  command: "images.use",
14210
14556
  description: "Ingest a URL and wait for the library record to be ready.",
@@ -14220,7 +14566,7 @@ registerSchema({
14220
14566
  }
14221
14567
  });
14222
14568
  var POLL_INTERVAL_MS4 = 1500;
14223
- var useCommand = defineCommand108({
14569
+ var useCommand = defineCommand110({
14224
14570
  meta: {
14225
14571
  name: "use",
14226
14572
  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"
@@ -14266,7 +14612,7 @@ var useCommand = defineCommand108({
14266
14612
  });
14267
14613
 
14268
14614
  // src/commands/images/index.ts
14269
- var imagesCommand = defineCommand109({
14615
+ var imagesCommand = defineCommand111({
14270
14616
  meta: {
14271
14617
  name: "images",
14272
14618
  description: `Find, source, and normalize images. Subcommands route by provider so cost + license are explicit.
@@ -14331,292 +14677,11 @@ Paid transforms (run on the Convex backend, cost-tracked):
14331
14677
  }
14332
14678
  });
14333
14679
 
14334
- // src/commands/missions/index.ts
14335
- import { defineCommand as defineCommand116 } from "citty";
14336
-
14337
- // src/commands/missions/add-action.ts
14338
- import { defineCommand as defineCommand110 } from "citty";
14339
- registerSchema({
14340
- command: "missions.add-action",
14341
- description: "Attach an action to a mission as an ordered step. Both --mission and --action accept a real id or a temp_* ref from a create op in the same draft. --order is the 0-based position in the plan. Applies on chat publish.",
14342
- args: {
14343
- mission: { type: "string", description: "Mission id or missionTempId", required: true },
14344
- action: { type: "string", description: "Action id or tempId", required: true },
14345
- order: { type: "string", description: "0-based position within the mission", required: true }
14346
- }
14347
- });
14348
- var addActionCommand = defineCommand110({
14349
- meta: {
14350
- name: "add-action",
14351
- description: "Attach an action to a mission as an ordered step. Example: baker missions add-action --mission <ref> --action <ref> --order 0"
14352
- },
14353
- args: {
14354
- mission: { type: "string", description: "Mission ref", required: false },
14355
- action: { type: "string", description: "Action ref", required: false },
14356
- order: { type: "string", description: "0-based order", required: false }
14357
- },
14358
- run: async ({ args }) => {
14359
- try {
14360
- const mission = args.mission;
14361
- const action = args.action;
14362
- if (!mission || !action) {
14363
- failValidation("--mission and --action are required.");
14364
- }
14365
- const order = Number.parseInt(args.order ?? "", 10);
14366
- if (Number.isNaN(order) || order < 0) {
14367
- failValidation("--order must be a non-negative integer.");
14368
- }
14369
- const chatId = requireChatId();
14370
- await apiPost("/api/missions/add-action", {
14371
- chatId,
14372
- missionRef: mission,
14373
- actionRef: action,
14374
- order
14375
- });
14376
- writeOk();
14377
- } catch (err) {
14378
- failApi(err);
14379
- }
14380
- }
14381
- });
14382
-
14383
- // src/commands/missions/create.ts
14384
- import { defineCommand as defineCommand111 } from "citty";
14385
- registerSchema({
14386
- command: "missions.create",
14387
- description: "Open a Mission to group the ordered steps of a multi-step request. A Mission has a title and a markdown overview (what you're doing and why \u2014 the human-readable plan, written as numbered Phases with NO dates and NO effort sizing). Returns a missionTempId. Next: create the action steps with `baker actions create`, then attach each in order with `baker missions add-action`. Applies when the chat is published \u2014 publishing = the user approving the plan.",
14388
- args: {
14389
- title: { type: "string", description: "Mission title \u2014 the goal, short", required: true },
14390
- overview: {
14391
- type: "string",
14392
- description: "Markdown overview: the plan as numbered Phases (goal / what it produces / what unlocks next). No calendar or effort framing.",
14393
- required: false
14394
- },
14395
- "temp-id": { type: "string", description: "Custom missionTempId (auto-generated if omitted)", required: false }
14396
- }
14397
- });
14398
- var createCommand2 = defineCommand111({
14399
- meta: {
14400
- name: "create",
14401
- description: 'Open a Mission to group ordered steps. Example: baker missions create --title "Audit Google Ads" --overview "..."'
14402
- },
14403
- args: {
14404
- title: { type: "string", description: "Mission title", required: false },
14405
- overview: { type: "string", description: "Markdown overview (numbered Phases)", required: false, default: "" },
14406
- "temp-id": { type: "string", description: "Optional custom missionTempId", required: false }
14407
- },
14408
- run: async ({ args }) => {
14409
- try {
14410
- const title = args.title;
14411
- if (!title || title.trim().length === 0) {
14412
- failValidation("--title is required.");
14413
- }
14414
- const chatId = requireChatId();
14415
- const missionTempId = args["temp-id"] || generateTempId();
14416
- const response = await apiPost("/api/missions/create", {
14417
- chatId,
14418
- missionTempId,
14419
- title,
14420
- overview: args.overview ?? ""
14421
- });
14422
- const hints = [
14423
- `Add ordered steps: create each action, then baker missions add-action --mission ${missionTempId} --action <tempId> --order 0`
14424
- ];
14425
- if (!args.overview) {
14426
- hints.push(
14427
- "Tip: pass --overview with the plan as numbered Phases (goal / produces / unlocks; no dates or effort sizing)."
14428
- );
14429
- }
14430
- writeJson({ ...response, hints });
14431
- } catch (err) {
14432
- failApi(err);
14433
- }
14434
- }
14435
- });
14436
-
14437
- // src/commands/missions/get.ts
14438
- import { defineCommand as defineCommand112 } from "citty";
14439
- registerSchema({
14440
- command: "missions.get",
14441
- description: "Get one mission with its overview, progress, and ordered steps.",
14442
- args: {
14443
- id: { type: "string", description: "Mission ID", required: true }
14444
- }
14445
- });
14446
- var getCommand3 = defineCommand112({
14447
- meta: { name: "get", description: "Get a mission by ID. Example: baker missions get <mission-id>" },
14448
- args: {
14449
- id: { type: "positional", description: "Mission ID", required: false },
14450
- "mission-id": { type: "string", description: "Mission ID (alternative to positional)", required: false }
14451
- },
14452
- run: async ({ args }) => {
14453
- try {
14454
- const id = args.id || args["mission-id"];
14455
- if (!id) {
14456
- failValidation("Mission ID is required.");
14457
- }
14458
- validateConvexId(id);
14459
- const response = await apiPost("/api/missions/get", { missionId: id });
14460
- writeJson(response);
14461
- } catch (err) {
14462
- failApi(err);
14463
- }
14464
- }
14465
- });
14466
-
14467
- // src/commands/missions/list.ts
14468
- import { defineCommand as defineCommand113 } from "citty";
14469
- registerSchema({
14470
- command: "missions.list",
14471
- description: "List the company's missions with per-mission progress (done/total) and ordered steps. Aborted missions are hidden unless --include-aborted.",
14472
- args: {
14473
- "include-aborted": {
14474
- type: "boolean",
14475
- description: "Include aborted missions (default: false)",
14476
- required: false,
14477
- default: false
14478
- }
14479
- }
14480
- });
14481
- var listCommand2 = defineCommand113({
14482
- meta: {
14483
- name: "list",
14484
- description: "List missions with progress and ordered steps. Example: baker missions list"
14485
- },
14486
- args: {
14487
- "include-aborted": { type: "boolean", description: "Include aborted missions", required: false, default: false }
14488
- },
14489
- run: async ({ args }) => {
14490
- try {
14491
- const body = {};
14492
- if (args["include-aborted"] === true) {
14493
- body.includeAborted = true;
14494
- }
14495
- const response = await apiPost("/api/missions/list", body);
14496
- writeJson(response);
14497
- } catch (err) {
14498
- failApi(err);
14499
- }
14500
- }
14501
- });
14502
-
14503
- // src/commands/missions/set-status.ts
14504
- import { defineCommand as defineCommand114 } from "citty";
14505
- registerSchema({
14506
- command: "missions.set-status",
14507
- description: "Set a mission's status: accomplished (the goal is genuinely met), aborted (abandoned), or active (reopen). Do NOT mark accomplished just because all steps are closed \u2014 only when the goal is done. Applies on chat publish.",
14508
- args: {
14509
- id: { type: "string", description: "Mission ID", required: true },
14510
- status: { type: "string", description: "active | accomplished | aborted", required: true }
14511
- }
14512
- });
14513
- var setStatusCommand = defineCommand114({
14514
- meta: {
14515
- name: "set-status",
14516
- description: "Set mission status. Example: baker missions set-status <id> --status accomplished"
14517
- },
14518
- args: {
14519
- id: { type: "positional", description: "Mission ID", required: false },
14520
- "mission-id": { type: "string", description: "Mission ID", required: false },
14521
- status: { type: "string", description: "active | accomplished | aborted", required: false }
14522
- },
14523
- run: async ({ args }) => {
14524
- try {
14525
- const id = args.id || args["mission-id"];
14526
- if (!id) {
14527
- failValidation("Mission ID is required.");
14528
- }
14529
- validateConvexId(id);
14530
- const status = args.status;
14531
- if (status !== "active" && status !== "accomplished" && status !== "aborted") {
14532
- failValidation("--status must be one of: active, accomplished, aborted.");
14533
- }
14534
- const chatId = requireChatId();
14535
- await apiPost("/api/missions/set-status", { chatId, missionId: id, status });
14536
- writeOk();
14537
- } catch (err) {
14538
- failApi(err);
14539
- }
14540
- }
14541
- });
14542
-
14543
- // src/commands/missions/update.ts
14544
- import { defineCommand as defineCommand115 } from "citty";
14545
- registerSchema({
14546
- command: "missions.update",
14547
- description: "Stage an update to a mission's title and/or overview (real mission id only). Applies on chat publish.",
14548
- args: {
14549
- id: { type: "string", description: "Mission ID", required: true },
14550
- title: { type: "string", description: "New title", required: false },
14551
- overview: { type: "string", description: "New markdown overview (numbered Phases)", required: false }
14552
- }
14553
- });
14554
- var updateCommand2 = defineCommand115({
14555
- meta: {
14556
- name: "update",
14557
- description: 'Stage a mission update. Example: baker missions update <id> --overview "..."'
14558
- },
14559
- args: {
14560
- id: { type: "positional", description: "Mission ID", required: false },
14561
- "mission-id": { type: "string", description: "Mission ID", required: false },
14562
- title: { type: "string", description: "New title", required: false },
14563
- overview: { type: "string", description: "New markdown overview", required: false }
14564
- },
14565
- run: async ({ args }) => {
14566
- try {
14567
- const id = args.id || args["mission-id"];
14568
- if (!id) {
14569
- failValidation("Mission ID is required.");
14570
- }
14571
- validateConvexId(id);
14572
- if (args.title === void 0 && args.overview === void 0) {
14573
- failValidation("Provide at least one of --title, --overview.");
14574
- }
14575
- const chatId = requireChatId();
14576
- await apiPost("/api/missions/update", {
14577
- chatId,
14578
- missionId: id,
14579
- title: args.title,
14580
- overview: args.overview
14581
- });
14582
- writeOk();
14583
- } catch (err) {
14584
- failApi(err);
14585
- }
14586
- }
14587
- });
14588
-
14589
- // src/commands/missions/index.ts
14590
- var missionsCommand = defineCommand116({
14591
- meta: {
14592
- name: "missions",
14593
- description: `Group ordered actions into a Mission \u2014 one goal with a markdown overview (the plan) and ordered action "steps". Subcommands: list, get, create, add-action, update, set-status.
14594
-
14595
- Use a mission whenever a request decomposes into 2+ ordered actions (audits, campaigns, multi-step plans). A single one-off capture stays a loose action.
14596
-
14597
- Flow: create the mission \u2192 create each action step in order \u2192 attach each with add-action \u2192 wire hard dependencies with 'baker actions link' \u2192 publish the chat (= the user approving the plan). The overview is forward planning: write it as numbered Phases, no dates, no effort sizing. Mark accomplished/aborted explicitly \u2014 never auto-conclude from step status.
14598
-
14599
- Examples:
14600
- baker missions create --title "Audit Google Ads" --overview "..."
14601
- baker missions add-action --mission <ref> --action <ref> --order 0
14602
- baker missions list
14603
- baker missions set-status <id> --status accomplished`
14604
- },
14605
- subCommands: {
14606
- list: listCommand2,
14607
- get: getCommand3,
14608
- create: createCommand2,
14609
- "add-action": addActionCommand,
14610
- update: updateCommand2,
14611
- "set-status": setStatusCommand
14612
- }
14613
- });
14614
-
14615
14680
  // src/commands/research/index.ts
14616
- import { defineCommand as defineCommand127 } from "citty";
14681
+ import { defineCommand as defineCommand122 } from "citty";
14617
14682
 
14618
14683
  // src/commands/research/advertisers.ts
14619
- import { defineCommand as defineCommand117 } from "citty";
14684
+ import { defineCommand as defineCommand112 } from "citty";
14620
14685
 
14621
14686
  // src/commands/research/output.ts
14622
14687
  var RESEARCH_DATA_NOTE = "Estimates based on third-party SERP data \u2014 not exact figures. Use for directional insights, not precise measurement.";
@@ -14729,7 +14794,7 @@ var FIELDS3 = {
14729
14794
  etv: "Estimated traffic value (USD)",
14730
14795
  visibility: "SERP visibility score (0-1)"
14731
14796
  };
14732
- var advertisersCommand = defineCommand117({
14797
+ var advertisersCommand = defineCommand112({
14733
14798
  meta: {
14734
14799
  name: "advertisers",
14735
14800
  description: `Find domains competing for a keyword in Google SERPs.
@@ -14776,7 +14841,7 @@ Examples:
14776
14841
  });
14777
14842
 
14778
14843
  // src/commands/research/autocomplete.ts
14779
- import { defineCommand as defineCommand118 } from "citty";
14844
+ import { defineCommand as defineCommand113 } from "citty";
14780
14845
  registerSchema({
14781
14846
  command: "research.autocomplete",
14782
14847
  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).",
@@ -14799,7 +14864,7 @@ registerSchema({
14799
14864
  var FIELDS4 = {
14800
14865
  suggestion: "Autocomplete suggestion from Google"
14801
14866
  };
14802
- var autocompleteCommand = defineCommand118({
14867
+ var autocompleteCommand = defineCommand113({
14803
14868
  meta: {
14804
14869
  name: "autocomplete",
14805
14870
  description: `Get Google Autocomplete suggestions for keyword expansion.
@@ -14845,7 +14910,7 @@ Examples:
14845
14910
  });
14846
14911
 
14847
14912
  // src/commands/research/countries.ts
14848
- import { defineCommand as defineCommand119 } from "citty";
14913
+ import { defineCommand as defineCommand114 } from "citty";
14849
14914
  registerSchema({
14850
14915
  command: "research.countries",
14851
14916
  description: "List all supported country codes for --location flag in research commands.",
@@ -14902,7 +14967,7 @@ var FIELDS5 = {
14902
14967
  code: "Country code to pass as --location",
14903
14968
  name: "Country name"
14904
14969
  };
14905
- var countriesCommand = defineCommand119({
14970
+ var countriesCommand = defineCommand114({
14906
14971
  meta: {
14907
14972
  name: "countries",
14908
14973
  description: "List all supported country codes for --location flag."
@@ -14913,7 +14978,7 @@ var countriesCommand = defineCommand119({
14913
14978
  });
14914
14979
 
14915
14980
  // src/commands/research/intent.ts
14916
- import { defineCommand as defineCommand120 } from "citty";
14981
+ import { defineCommand as defineCommand115 } from "citty";
14917
14982
  registerSchema({
14918
14983
  command: "research.intent",
14919
14984
  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.",
@@ -14936,7 +15001,7 @@ var FIELDS6 = {
14936
15001
  intent: "Primary Google Search intent: informational, navigational, commercial, transactional",
14937
15002
  probability: "Confidence score 0.0-1.0"
14938
15003
  };
14939
- var intentCommand = defineCommand120({
15004
+ var intentCommand = defineCommand115({
14940
15005
  meta: {
14941
15006
  name: "intent",
14942
15007
  description: `Classify Google Search intent for keywords. Returns intent type and confidence.
@@ -14984,7 +15049,7 @@ Examples:
14984
15049
  });
14985
15050
 
14986
15051
  // src/commands/research/keyword-gap.ts
14987
- import { defineCommand as defineCommand121 } from "citty";
15052
+ import { defineCommand as defineCommand116 } from "citty";
14988
15053
  registerSchema({
14989
15054
  command: "research.keyword-gap",
14990
15055
  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.",
@@ -15013,7 +15078,7 @@ var FIELDS7 = {
15013
15078
  cpc: "Cost per click USD",
15014
15079
  their_position: "Competitor's ranking position"
15015
15080
  };
15016
- var keywordGapCommand = defineCommand121({
15081
+ var keywordGapCommand = defineCommand116({
15017
15082
  meta: {
15018
15083
  name: "keyword-gap",
15019
15084
  description: `Find keywords a competitor has that you don't. Supports pagination via --offset.
@@ -15087,7 +15152,7 @@ Examples:
15087
15152
  });
15088
15153
 
15089
15154
  // src/commands/research/keywords-for-site.ts
15090
- import { defineCommand as defineCommand122 } from "citty";
15155
+ import { defineCommand as defineCommand117 } from "citty";
15091
15156
  registerSchema({
15092
15157
  command: "research.keywords-for-site",
15093
15158
  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.",
@@ -15120,7 +15185,7 @@ var FIELDS8 = {
15120
15185
  competition: "LOW, MEDIUM, or HIGH",
15121
15186
  competition_index: "Competition score 0-100"
15122
15187
  };
15123
- var keywordsForSiteCommand = defineCommand122({
15188
+ var keywordsForSiteCommand = defineCommand117({
15124
15189
  meta: {
15125
15190
  name: "keywords-for-site",
15126
15191
  description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.
@@ -15173,7 +15238,7 @@ Examples:
15173
15238
  });
15174
15239
 
15175
15240
  // src/commands/research/languages.ts
15176
- import { defineCommand as defineCommand123 } from "citty";
15241
+ import { defineCommand as defineCommand118 } from "citty";
15177
15242
  registerSchema({
15178
15243
  command: "research.languages",
15179
15244
  description: "List all supported language codes for --language flag in research commands.",
@@ -15203,7 +15268,7 @@ var FIELDS9 = {
15203
15268
  code: "Language code to pass as --language",
15204
15269
  name: "Language name (also accepted by --language)"
15205
15270
  };
15206
- var languagesCommand2 = defineCommand123({
15271
+ var languagesCommand2 = defineCommand118({
15207
15272
  meta: {
15208
15273
  name: "languages",
15209
15274
  description: "List all supported language codes for --language flag."
@@ -15214,7 +15279,7 @@ var languagesCommand2 = defineCommand123({
15214
15279
  });
15215
15280
 
15216
15281
  // src/commands/research/lighthouse.ts
15217
- import { defineCommand as defineCommand124 } from "citty";
15282
+ import { defineCommand as defineCommand119 } from "citty";
15218
15283
  registerSchema({
15219
15284
  command: "research.lighthouse",
15220
15285
  description: "Landing page performance audit. Returns metrics that affect Google Ads Quality Score and CPC.",
@@ -15233,7 +15298,7 @@ var FIELDS10 = {
15233
15298
  speed_index_ms: "Speed Index in ms (good: < 3400)",
15234
15299
  interactive_ms: "Time to Interactive in ms (good: < 3800)"
15235
15300
  };
15236
- var lighthouseCommand = defineCommand124({
15301
+ var lighthouseCommand = defineCommand119({
15237
15302
  meta: {
15238
15303
  name: "lighthouse",
15239
15304
  description: `Landing page performance audit. Metrics affecting Google Ads Quality Score.
@@ -15271,7 +15336,7 @@ Examples:
15271
15336
  });
15272
15337
 
15273
15338
  // src/commands/research/relevant-pages.ts
15274
- import { defineCommand as defineCommand125 } from "citty";
15339
+ import { defineCommand as defineCommand120 } from "citty";
15275
15340
  registerSchema({
15276
15341
  command: "research.relevant-pages",
15277
15342
  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).",
@@ -15297,7 +15362,7 @@ var FIELDS11 = {
15297
15362
  keywords: "Total organic keywords the page ranks for",
15298
15363
  top_10: "Keywords in positions 1-10"
15299
15364
  };
15300
- var relevantPagesCommand = defineCommand125({
15365
+ var relevantPagesCommand = defineCommand120({
15301
15366
  meta: {
15302
15367
  name: "relevant-pages",
15303
15368
  description: `Get the top pages of a competitor domain with traffic data.
@@ -15343,7 +15408,7 @@ Examples:
15343
15408
  });
15344
15409
 
15345
15410
  // src/commands/research/web.ts
15346
- import { defineCommand as defineCommand126 } from "citty";
15411
+ import { defineCommand as defineCommand121 } from "citty";
15347
15412
  registerSchema({
15348
15413
  command: "research.web",
15349
15414
  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).",
@@ -15394,7 +15459,7 @@ async function runDeepResearch(question) {
15394
15459
  }
15395
15460
  throw new Error("Deep research timed out");
15396
15461
  }
15397
- var webCommand = defineCommand126({
15462
+ var webCommand = defineCommand121({
15398
15463
  meta: {
15399
15464
  name: "web",
15400
15465
  description: `Search the web with AI to answer any open-ended marketing question. Uses live internet data via Google Search.
@@ -15454,7 +15519,7 @@ Examples:
15454
15519
  });
15455
15520
 
15456
15521
  // src/commands/research/index.ts
15457
- var researchCommand = defineCommand127({
15522
+ var researchCommand = defineCommand122({
15458
15523
  meta: {
15459
15524
  name: "research",
15460
15525
  description: `Competitive intelligence and AI-powered research commands.
@@ -15494,10 +15559,10 @@ Examples:
15494
15559
  });
15495
15560
 
15496
15561
  // src/commands/scheduled-actions/index.ts
15497
- import { defineCommand as defineCommand134 } from "citty";
15562
+ import { defineCommand as defineCommand129 } from "citty";
15498
15563
 
15499
15564
  // src/commands/scheduled-actions/create.ts
15500
- import { defineCommand as defineCommand128 } from "citty";
15565
+ import { defineCommand as defineCommand123 } from "citty";
15501
15566
 
15502
15567
  // src/commands/scheduled-actions/shared.ts
15503
15568
  var TEMP_SCHEDULED_ACTION_PREFIX = "temp_sched_";
@@ -15602,7 +15667,7 @@ registerSchema({
15602
15667
  prompt: { type: "string", description: "Additional prompt instructions for the spawned agent", required: false }
15603
15668
  }
15604
15669
  });
15605
- var createCommand3 = defineCommand128({
15670
+ var createCommand2 = defineCommand123({
15606
15671
  meta: {
15607
15672
  name: "create",
15608
15673
  description: 'Stage a scheduled action. Example: baker scheduled-actions create --name "Weekly report" --description "..." --cron "0 9 * * MON"'
@@ -15650,7 +15715,7 @@ var createCommand3 = defineCommand128({
15650
15715
  });
15651
15716
 
15652
15717
  // src/commands/scheduled-actions/delete.ts
15653
- import { defineCommand as defineCommand129 } from "citty";
15718
+ import { defineCommand as defineCommand124 } from "citty";
15654
15719
  registerSchema({
15655
15720
  command: "scheduled-actions.delete",
15656
15721
  description: "Stage deletion of a published scheduled action or cancellation of a temp_sched_* draft creation.",
@@ -15658,7 +15723,7 @@ registerSchema({
15658
15723
  id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
15659
15724
  }
15660
15725
  });
15661
- var deleteCommand2 = defineCommand129({
15726
+ var deleteCommand2 = defineCommand124({
15662
15727
  meta: {
15663
15728
  name: "delete",
15664
15729
  description: "Stage scheduled action deletion. Example: baker scheduled-actions delete <id-or-temp_sched_id>"
@@ -15687,7 +15752,7 @@ var deleteCommand2 = defineCommand129({
15687
15752
  });
15688
15753
 
15689
15754
  // src/commands/scheduled-actions/get.ts
15690
- import { defineCommand as defineCommand130 } from "citty";
15755
+ import { defineCommand as defineCommand125 } from "citty";
15691
15756
  registerSchema({
15692
15757
  command: "scheduled-actions.get",
15693
15758
  description: "Get a published scheduled action or a temp_sched_* draft-created scheduled action.",
@@ -15695,7 +15760,7 @@ registerSchema({
15695
15760
  id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
15696
15761
  }
15697
15762
  });
15698
- var getCommand4 = defineCommand130({
15763
+ var getCommand3 = defineCommand125({
15699
15764
  meta: {
15700
15765
  name: "get",
15701
15766
  description: "Get a scheduled action. Example: baker scheduled-actions get <id-or-temp_sched_id>"
@@ -15732,13 +15797,13 @@ var getCommand4 = defineCommand130({
15732
15797
  });
15733
15798
 
15734
15799
  // src/commands/scheduled-actions/list.ts
15735
- import { defineCommand as defineCommand131 } from "citty";
15800
+ import { defineCommand as defineCommand126 } from "citty";
15736
15801
  registerSchema({
15737
15802
  command: "scheduled-actions.list",
15738
15803
  description: "List published scheduled actions. Includes draft state when BAKER_CHAT_ID is set.",
15739
15804
  args: {}
15740
15805
  });
15741
- var listCommand3 = defineCommand131({
15806
+ var listCommand3 = defineCommand126({
15742
15807
  meta: {
15743
15808
  name: "list",
15744
15809
  description: "List scheduled actions. Includes staged draft ops when BAKER_CHAT_ID is set."
@@ -15759,7 +15824,7 @@ var listCommand3 = defineCommand131({
15759
15824
  });
15760
15825
 
15761
15826
  // src/commands/scheduled-actions/trigger.ts
15762
- import { defineCommand as defineCommand132 } from "citty";
15827
+ import { defineCommand as defineCommand127 } from "citty";
15763
15828
  registerSchema({
15764
15829
  command: "scheduled-actions.trigger",
15765
15830
  description: "Immediately trigger a published scheduled action. Does not require BAKER_CHAT_ID and rejects temp_sched_* IDs.",
@@ -15767,7 +15832,7 @@ registerSchema({
15767
15832
  id: { type: "string", description: "Published scheduled action ID", required: true }
15768
15833
  }
15769
15834
  });
15770
- var triggerCommand = defineCommand132({
15835
+ var triggerCommand = defineCommand127({
15771
15836
  meta: {
15772
15837
  name: "trigger",
15773
15838
  description: "Immediately trigger a published scheduled action. Example: baker scheduled-actions trigger <id>"
@@ -15804,7 +15869,7 @@ var triggerCommand = defineCommand132({
15804
15869
  });
15805
15870
 
15806
15871
  // src/commands/scheduled-actions/update.ts
15807
- import { defineCommand as defineCommand133 } from "citty";
15872
+ import { defineCommand as defineCommand128 } from "citty";
15808
15873
  registerSchema({
15809
15874
  command: "scheduled-actions.update",
15810
15875
  description: "Stage an update to a published scheduled action or temp_sched_* draft-created scheduled action.",
@@ -15829,7 +15894,7 @@ registerSchema({
15829
15894
  prompt: { type: "string", description: "Replacement additional spawned-agent instructions", required: false }
15830
15895
  }
15831
15896
  });
15832
- var updateCommand3 = defineCommand133({
15897
+ var updateCommand2 = defineCommand128({
15833
15898
  meta: {
15834
15899
  name: "update",
15835
15900
  description: "Stage a scheduled action update. Example: baker scheduled-actions update <id> --enabled false"
@@ -15899,7 +15964,7 @@ var updateCommand3 = defineCommand133({
15899
15964
  });
15900
15965
 
15901
15966
  // src/commands/scheduled-actions/index.ts
15902
- var scheduledActionsCommand = defineCommand134({
15967
+ var scheduledActionsCommand = defineCommand129({
15903
15968
  meta: {
15904
15969
  name: "scheduled-actions",
15905
15970
  description: `Manage Scheduled Actions. Subcommands: list, get, create, update, delete, trigger.
@@ -15916,17 +15981,17 @@ Examples:
15916
15981
  },
15917
15982
  subCommands: {
15918
15983
  list: listCommand3,
15919
- get: getCommand4,
15920
- create: createCommand3,
15921
- update: updateCommand3,
15984
+ get: getCommand3,
15985
+ create: createCommand2,
15986
+ update: updateCommand2,
15922
15987
  delete: deleteCommand2,
15923
15988
  trigger: triggerCommand
15924
15989
  }
15925
15990
  });
15926
15991
 
15927
15992
  // src/commands/schema.ts
15928
- import { defineCommand as defineCommand135 } from "citty";
15929
- var schemaCommand = defineCommand135({
15993
+ import { defineCommand as defineCommand130 } from "citty";
15994
+ var schemaCommand = defineCommand130({
15930
15995
  meta: {
15931
15996
  name: "schema",
15932
15997
  description: "Inspect command argument schemas (for AI agent introspection). Lists all commands if no argument given. Example: baker schema images.search"
@@ -15962,10 +16027,10 @@ var schemaCommand = defineCommand135({
15962
16027
  });
15963
16028
 
15964
16029
  // src/commands/testimonials/index.ts
15965
- import { defineCommand as defineCommand139 } from "citty";
16030
+ import { defineCommand as defineCommand134 } from "citty";
15966
16031
 
15967
16032
  // src/commands/testimonials/get.ts
15968
- import { defineCommand as defineCommand136 } from "citty";
16033
+ import { defineCommand as defineCommand131 } from "citty";
15969
16034
  registerSchema({
15970
16035
  command: "testimonials.get",
15971
16036
  description: "Get a single testimonial by ID",
@@ -15973,7 +16038,7 @@ registerSchema({
15973
16038
  id: { type: "string", description: "Testimonial ID", required: true }
15974
16039
  }
15975
16040
  });
15976
- var getCommand5 = defineCommand136({
16041
+ var getCommand4 = defineCommand131({
15977
16042
  meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
15978
16043
  args: {
15979
16044
  id: { type: "positional", description: "Testimonial ID", required: false },
@@ -16010,7 +16075,7 @@ var getCommand5 = defineCommand136({
16010
16075
  });
16011
16076
 
16012
16077
  // src/commands/testimonials/list.ts
16013
- import { defineCommand as defineCommand137 } from "citty";
16078
+ import { defineCommand as defineCommand132 } from "citty";
16014
16079
  registerSchema({
16015
16080
  command: "testimonials.list",
16016
16081
  description: "List testimonials with optional filters.",
@@ -16040,7 +16105,7 @@ registerSchema({
16040
16105
  limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
16041
16106
  }
16042
16107
  });
16043
- var listCommand4 = defineCommand137({
16108
+ var listCommand4 = defineCommand132({
16044
16109
  meta: {
16045
16110
  name: "list",
16046
16111
  description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
@@ -16089,7 +16154,7 @@ var listCommand4 = defineCommand137({
16089
16154
  });
16090
16155
 
16091
16156
  // src/commands/testimonials/search.ts
16092
- import { defineCommand as defineCommand138 } from "citty";
16157
+ import { defineCommand as defineCommand133 } from "citty";
16093
16158
  registerSchema({
16094
16159
  command: "testimonials.search",
16095
16160
  description: "Search testimonials by text query. Uses hybrid BM25 + vector + reranking.",
@@ -16120,7 +16185,7 @@ registerSchema({
16120
16185
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
16121
16186
  }
16122
16187
  });
16123
- var searchCommand2 = defineCommand138({
16188
+ var searchCommand2 = defineCommand133({
16124
16189
  meta: {
16125
16190
  name: "search",
16126
16191
  description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
@@ -16191,7 +16256,7 @@ var searchCommand2 = defineCommand138({
16191
16256
  });
16192
16257
 
16193
16258
  // src/commands/testimonials/index.ts
16194
- var testimonialsCommand = defineCommand139({
16259
+ var testimonialsCommand = defineCommand134({
16195
16260
  meta: {
16196
16261
  name: "testimonials",
16197
16262
  description: `Find and browse testimonials in Baker. Subcommands: search, get, list.
@@ -16203,17 +16268,17 @@ Examples:
16203
16268
  baker testimonials list --source google --sentiment positive`
16204
16269
  },
16205
16270
  subCommands: {
16206
- get: getCommand5,
16271
+ get: getCommand4,
16207
16272
  search: searchCommand2,
16208
16273
  list: listCommand4
16209
16274
  }
16210
16275
  });
16211
16276
 
16212
16277
  // src/commands/videos/index.ts
16213
- import { defineCommand as defineCommand144 } from "citty";
16278
+ import { defineCommand as defineCommand139 } from "citty";
16214
16279
 
16215
16280
  // src/commands/videos/delete.ts
16216
- import { defineCommand as defineCommand140 } from "citty";
16281
+ import { defineCommand as defineCommand135 } from "citty";
16217
16282
  registerSchema({
16218
16283
  command: "videos.delete",
16219
16284
  description: "Delete a video by ID",
@@ -16227,7 +16292,7 @@ registerSchema({
16227
16292
  }
16228
16293
  }
16229
16294
  });
16230
- var deleteCommand3 = defineCommand140({
16295
+ var deleteCommand3 = defineCommand135({
16231
16296
  meta: {
16232
16297
  name: "delete",
16233
16298
  description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
@@ -16268,7 +16333,7 @@ var deleteCommand3 = defineCommand140({
16268
16333
  });
16269
16334
 
16270
16335
  // src/commands/videos/get.ts
16271
- import { defineCommand as defineCommand141 } from "citty";
16336
+ import { defineCommand as defineCommand136 } from "citty";
16272
16337
  registerSchema({
16273
16338
  command: "videos.get",
16274
16339
  description: "Get a single video by ID",
@@ -16276,7 +16341,7 @@ registerSchema({
16276
16341
  id: { type: "string", description: "Video ID", required: true }
16277
16342
  }
16278
16343
  });
16279
- var getCommand6 = defineCommand141({
16344
+ var getCommand5 = defineCommand136({
16280
16345
  meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
16281
16346
  args: {
16282
16347
  id: { type: "positional", description: "Video ID", required: false },
@@ -16313,7 +16378,7 @@ var getCommand6 = defineCommand141({
16313
16378
  });
16314
16379
 
16315
16380
  // src/commands/videos/search.ts
16316
- import { defineCommand as defineCommand142 } from "citty";
16381
+ import { defineCommand as defineCommand137 } from "citty";
16317
16382
  registerSchema({
16318
16383
  command: "videos.search",
16319
16384
  description: "Search videos by text query. Only returns ready videos.",
@@ -16323,7 +16388,7 @@ registerSchema({
16323
16388
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
16324
16389
  }
16325
16390
  });
16326
- var searchCommand3 = defineCommand142({
16391
+ var searchCommand3 = defineCommand137({
16327
16392
  meta: {
16328
16393
  name: "search",
16329
16394
  description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
@@ -16372,7 +16437,7 @@ var searchCommand3 = defineCommand142({
16372
16437
  // src/commands/videos/upload.ts
16373
16438
  import { readFile as readFile10, stat as stat3 } from "fs/promises";
16374
16439
  import { extname as extname3 } from "path";
16375
- import { defineCommand as defineCommand143 } from "citty";
16440
+ import { defineCommand as defineCommand138 } from "citty";
16376
16441
  var MIME_MAP2 = {
16377
16442
  ".mp4": "video/mp4",
16378
16443
  ".mov": "video/quicktime",
@@ -16406,7 +16471,7 @@ function detectContentType2(filePath) {
16406
16471
  }
16407
16472
  return mime;
16408
16473
  }
16409
- var uploadCommand2 = defineCommand143({
16474
+ var uploadCommand2 = defineCommand138({
16410
16475
  meta: {
16411
16476
  name: "upload",
16412
16477
  description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
@@ -16460,7 +16525,7 @@ var uploadCommand2 = defineCommand143({
16460
16525
  });
16461
16526
 
16462
16527
  // src/commands/videos/index.ts
16463
- var videosCommand = defineCommand144({
16528
+ var videosCommand = defineCommand139({
16464
16529
  meta: {
16465
16530
  name: "videos",
16466
16531
  description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete.
@@ -16473,7 +16538,7 @@ Examples:
16473
16538
  baker videos delete <video-id> --dry-run`
16474
16539
  },
16475
16540
  subCommands: {
16476
- get: getCommand6,
16541
+ get: getCommand5,
16477
16542
  search: searchCommand3,
16478
16543
  upload: uploadCommand2,
16479
16544
  delete: deleteCommand3
@@ -16481,10 +16546,10 @@ Examples:
16481
16546
  });
16482
16547
 
16483
16548
  // src/commands/winning-ads/index.ts
16484
- import { defineCommand as defineCommand147 } from "citty";
16549
+ import { defineCommand as defineCommand142 } from "citty";
16485
16550
 
16486
16551
  // src/commands/winning-ads/advertisers.ts
16487
- import { defineCommand as defineCommand145 } from "citty";
16552
+ import { defineCommand as defineCommand140 } from "citty";
16488
16553
  registerSchema({
16489
16554
  command: "winning-ads.advertisers",
16490
16555
  description: "Resolve a brand name to advertiser_id(s) in the ad-dna corpus \u2014 to find your OWN advertiser (to --exclude-advertiser) or a competitor (to --advertiser-id).",
@@ -16497,7 +16562,7 @@ registerSchema({
16497
16562
  function identity(record) {
16498
16563
  return record;
16499
16564
  }
16500
- var advertisersCommand2 = defineCommand145({
16565
+ var advertisersCommand2 = defineCommand140({
16501
16566
  meta: {
16502
16567
  name: "advertisers",
16503
16568
  description: 'Resolve a brand name to advertiser_id(s). Use it to find your own advertiser for --exclude-advertiser, or a competitor for --advertiser-id. Example: baker winning-ads advertisers "Deel" --output md'
@@ -16548,7 +16613,7 @@ var advertisersCommand2 = defineCommand145({
16548
16613
  });
16549
16614
 
16550
16615
  // src/commands/winning-ads/search.ts
16551
- import { defineCommand as defineCommand146 } from "citty";
16616
+ import { defineCommand as defineCommand141 } from "citty";
16552
16617
  registerSchema({
16553
16618
  command: "winning-ads.search",
16554
16619
  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.",
@@ -16656,7 +16721,7 @@ function buildSearchBody(args) {
16656
16721
  }
16657
16722
  return body;
16658
16723
  }
16659
- var searchCommand4 = defineCommand146({
16724
+ var searchCommand4 = defineCommand141({
16660
16725
  meta: {
16661
16726
  name: "search",
16662
16727
  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"
@@ -16768,7 +16833,7 @@ var searchCommand4 = defineCommand146({
16768
16833
  });
16769
16834
 
16770
16835
  // src/commands/winning-ads/index.ts
16771
- var winningAdsCommand = defineCommand147({
16836
+ var winningAdsCommand = defineCommand142({
16772
16837
  meta: {
16773
16838
  name: "winning-ads",
16774
16839
  description: `Search the ad-dna corpus of scored "winning" ads for reference creatives to reproduce. Proxied through the Baker backend (BAKER_API_KEY) \u2014 no separate token needed.
@@ -16808,7 +16873,7 @@ function getCliVersion() {
16808
16873
  }
16809
16874
 
16810
16875
  // src/cli.ts
16811
- var main = defineCommand148({
16876
+ var main = defineCommand143({
16812
16877
  meta: {
16813
16878
  name: "baker",
16814
16879
  version: getCliVersion(),
@@ -16822,7 +16887,6 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
16822
16887
  },
16823
16888
  subCommands: {
16824
16889
  actions: actionsCommand,
16825
- missions: missionsCommand,
16826
16890
  "scheduled-actions": scheduledActionsCommand,
16827
16891
  ads: adsCommand,
16828
16892
  ga4: ga4Command,