@koda-sl/baker-cli 0.111.0 → 0.112.1

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
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-3JVYU72O.js";
13
13
 
14
14
  // src/cli.ts
15
- import { defineCommand as defineCommand154, runMain } from "citty";
15
+ import { defineCommand as defineCommand155, runMain } from "citty";
16
16
 
17
17
  // src/commands/actions/index.ts
18
18
  import { defineCommand as defineCommand18 } from "citty";
@@ -31,6 +31,7 @@ function getEnv() {
31
31
  BAKER_API_KEY: z.string().startsWith("bk_", "API key must start with 'bk_'"),
32
32
  BAKER_API_URL: z.url("BAKER_API_URL must be a valid URL"),
33
33
  BAKER_CHAT_ID: z.string().optional(),
34
+ BAKER_ACTING_USER_ID: z.string().optional(),
34
35
  BAKER_GOOGLE_ADS_CUSTOMER_ID: z.string().regex(/^\d{10}$/).optional(),
35
36
  BAKER_GA4_PROPERTY_ID: z.string().optional(),
36
37
  BAKER_GSC_SITE_URL: z.string().optional(),
@@ -147,9 +148,9 @@ async function handleResponse(response) {
147
148
  throw new ApiError("INTERNAL_ERROR", "Failed to parse API response as JSON");
148
149
  }
149
150
  }
150
- async function apiGet(path11, params) {
151
+ async function apiGet(path12, params) {
151
152
  const env = getEnv();
152
- const url = new URL(path11, env.BAKER_API_URL);
153
+ const url = new URL(path12, env.BAKER_API_URL);
153
154
  if (params) {
154
155
  const clean = sanitizeParams(params);
155
156
  for (const [key, value] of Object.entries(clean)) {
@@ -174,12 +175,12 @@ async function apiGet(path11, params) {
174
175
  }
175
176
  return handleResponse(response);
176
177
  }
177
- async function apiPost(path11, body, opts) {
178
+ async function apiPost(path12, body, opts) {
178
179
  const env = getEnv();
179
180
  const timeoutMs = opts?.timeoutMs ?? 6e4;
180
181
  let response;
181
182
  try {
182
- response = await fetchWithRateLimitRetry(new URL(path11, env.BAKER_API_URL).toString(), {
183
+ response = await fetchWithRateLimitRetry(new URL(path12, env.BAKER_API_URL).toString(), {
183
184
  method: "POST",
184
185
  headers: {
185
186
  Authorization: `Bearer ${env.BAKER_API_KEY}`,
@@ -2871,31 +2872,31 @@ function cachePath(category, key) {
2871
2872
  return join2(dir, `${hashKey(key)}.json`);
2872
2873
  }
2873
2874
  function cacheGet(category, key) {
2874
- const path11 = cachePath(category, key);
2875
- if (!existsSync2(path11)) {
2875
+ const path12 = cachePath(category, key);
2876
+ if (!existsSync2(path12)) {
2876
2877
  return null;
2877
2878
  }
2878
2879
  try {
2879
- const raw = readFileSync2(path11, "utf-8");
2880
+ const raw = readFileSync2(path12, "utf-8");
2880
2881
  const entry = JSON.parse(raw);
2881
2882
  if (entry.expiresAt < Date.now()) {
2882
- rmSync(path11, { force: true });
2883
+ rmSync(path12, { force: true });
2883
2884
  return null;
2884
2885
  }
2885
2886
  return entry;
2886
2887
  } catch {
2887
- rmSync(path11, { force: true });
2888
+ rmSync(path12, { force: true });
2888
2889
  return null;
2889
2890
  }
2890
2891
  }
2891
2892
  function cacheSet(category, key, data, ttlMs, fields) {
2892
- const path11 = cachePath(category, key);
2893
+ const path12 = cachePath(category, key);
2893
2894
  const entry = {
2894
2895
  expiresAt: Date.now() + ttlMs,
2895
2896
  data,
2896
2897
  fields
2897
2898
  };
2898
- writeFileSync(path11, JSON.stringify(entry), "utf-8");
2899
+ writeFileSync(path12, JSON.stringify(entry), "utf-8");
2899
2900
  }
2900
2901
  var HOUR = 60 * 60 * 1e3;
2901
2902
  var MINUTE = 60 * 1e3;
@@ -6699,19 +6700,19 @@ function failWriteValidation(message) {
6699
6700
  writeJsonEnvelope({ ok: false, error: { code: "VALIDATION_ERROR", message } });
6700
6701
  process.exit(1);
6701
6702
  }
6702
- function loadJsonFileArg(path11) {
6703
- if (typeof path11 !== "string" || path11.length === 0) {
6703
+ function loadJsonFileArg(path12) {
6704
+ if (typeof path12 !== "string" || path12.length === 0) {
6704
6705
  return {};
6705
6706
  }
6706
6707
  try {
6707
- const parsed = JSON.parse(readFileSync6(path11, "utf8"));
6708
+ const parsed = JSON.parse(readFileSync6(path12, "utf8"));
6708
6709
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
6709
- failWriteValidation(`${path11} must contain a JSON object`);
6710
+ failWriteValidation(`${path12} must contain a JSON object`);
6710
6711
  }
6711
6712
  return parsed;
6712
6713
  } catch (err) {
6713
6714
  if (err instanceof SyntaxError) {
6714
- failWriteValidation(`${path11} is not valid JSON: ${err.message}`);
6715
+ failWriteValidation(`${path12} is not valid JSON: ${err.message}`);
6715
6716
  }
6716
6717
  throw err;
6717
6718
  }
@@ -6774,15 +6775,15 @@ function parseLocaleFlag(value) {
6774
6775
  }
6775
6776
  return { language: match[1], country: match[2].toUpperCase() };
6776
6777
  }
6777
- function loadTargetingFileArg(path11) {
6778
- if (typeof path11 !== "string" || path11.length === 0) {
6778
+ function loadTargetingFileArg(path12) {
6779
+ if (typeof path12 !== "string" || path12.length === 0) {
6779
6780
  return void 0;
6780
6781
  }
6781
- const parsed = loadJsonFileArg(path11);
6782
+ const parsed = loadJsonFileArg(path12);
6782
6783
  const criteria = parsed.targetingCriteria ?? parsed;
6783
6784
  if (!criteria.include) {
6784
6785
  failWriteValidation(
6785
- `${path11} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
6786
+ `${path12} must contain targeting criteria with an "include" block (see baker schema ads.linkedin.campaigns.create)`
6786
6787
  );
6787
6788
  }
6788
6789
  return criteria;
@@ -6817,14 +6818,14 @@ function parseCsvLine(line) {
6817
6818
  cells.push(current);
6818
6819
  return cells.map((cell) => cell.trim());
6819
6820
  }
6820
- function parseListFileArg(path11, maxRows) {
6821
- if (typeof path11 !== "string" || path11.length === 0) {
6821
+ function parseListFileArg(path12, maxRows) {
6822
+ if (typeof path12 !== "string" || path12.length === 0) {
6822
6823
  return void 0;
6823
6824
  }
6824
- const raw = readFileSync6(path11, "utf8");
6825
+ const raw = readFileSync6(path12, "utf8");
6825
6826
  const lines = raw.split(/\r?\n/).filter((line) => line.trim().length > 0);
6826
6827
  if (lines.length < 2) {
6827
- failWriteValidation(`${path11} needs a header row and at least one data row`);
6828
+ failWriteValidation(`${path12} needs a header row and at least one data row`);
6828
6829
  }
6829
6830
  const columns = parseCsvLine(lines[0]).map((column) => column.trim());
6830
6831
  const rows = [];
@@ -6843,7 +6844,7 @@ function parseListFileArg(path11, maxRows) {
6843
6844
  }
6844
6845
  }
6845
6846
  if (rows.length > maxRows) {
6846
- failWriteValidation(`${path11} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
6847
+ failWriteValidation(`${path12} has ${rows.length} rows \u2014 the inline limit is ${maxRows}. Split the list.`);
6847
6848
  }
6848
6849
  return { columns, rows };
6849
6850
  }
@@ -11212,7 +11213,7 @@ var runCommand = defineCommand83({
11212
11213
 
11213
11214
  // src/commands/canvas/scaffold-static-ad.ts
11214
11215
  import { readFile as readFile3, writeFile } from "fs/promises";
11215
- import path5 from "path";
11216
+ import path6 from "path";
11216
11217
  import { defineCommand as defineCommand84 } from "citty";
11217
11218
 
11218
11219
  // src/engine/scaffold/staticAd.ts
@@ -11311,7 +11312,7 @@ function scaffoldStaticAd(input, elementsInput, opts) {
11311
11312
  nodes.push({
11312
11313
  id: "original",
11313
11314
  type: "ingest",
11314
- params: { source: "path", path: opts.imagePath, expect: "image" }
11315
+ params: opts.imageIsUrl ? { source: "url", url: opts.imagePath, expect: "image" } : { source: "path", path: opts.imagePath, expect: "image" }
11315
11316
  });
11316
11317
  const usedIds = /* @__PURE__ */ new Set(["prompt", "original", "gen", "brandfont", "type_ref"]);
11317
11318
  const elementSlots = [];
@@ -11398,6 +11399,17 @@ function staticAdReport(input, elementsInput, opts) {
11398
11399
  };
11399
11400
  }
11400
11401
 
11402
+ // src/commands/canvas/scaffold-static-ad-paths.ts
11403
+ import path5 from "path";
11404
+ function resolveScaffoldStaticAdPaths(rawFile, out, cwd = process.cwd()) {
11405
+ const file = rawFile.trim();
11406
+ const imageIsUrl = /^https?:\/\//i.test(file);
11407
+ const imageSource = imageIsUrl ? file : path5.resolve(cwd, file);
11408
+ const outPath = out ? path5.resolve(cwd, out) : imageIsUrl ? path5.join(cwd, "static-ad.canvas.json") : path5.join(path5.dirname(imageSource), "static-ad.canvas.json");
11409
+ const blueprintPath = path5.join(path5.dirname(outPath), "prompt.json");
11410
+ return { imageIsUrl, imageSource, outPath, blueprintPath };
11411
+ }
11412
+
11401
11413
  // src/commands/canvas/scaffold-static-ad.ts
11402
11414
  function resolveModel(kind, preferred) {
11403
11415
  const ids = Object.keys(MODEL_REGISTRY[kind]);
@@ -11483,12 +11495,13 @@ function regionCount(layout) {
11483
11495
  const regions = layout?.regions;
11484
11496
  return Array.isArray(regions) ? regions.length : 0;
11485
11497
  }
11486
- function buildDescribeCanvas(imagePath, describeModel, selectModel, layoutModel, context) {
11498
+ function buildDescribeCanvas(imageSource, imageIsUrl, describeModel, selectModel, layoutModel, context) {
11499
+ const originalParams = imageIsUrl ? { source: "url", url: imageSource, expect: "image" } : { source: "path", path: imageSource, expect: "image" };
11487
11500
  return {
11488
11501
  schema: "baker-canvas/1",
11489
11502
  metadata: { name: "static-ad describe pass" },
11490
11503
  nodes: [
11491
- { id: "original", type: "ingest", params: { source: "path", path: imagePath, expect: "image" } },
11504
+ { id: "original", type: "ingest", params: originalParams },
11492
11505
  {
11493
11506
  id: "describe",
11494
11507
  type: "image_describe",
@@ -11553,7 +11566,7 @@ var scaffoldStaticAdCommand = defineCommand84({
11553
11566
  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."
11554
11567
  },
11555
11568
  args: {
11556
- file: { type: "positional", required: true, description: "Path to the source/inspiration image" },
11569
+ file: { type: "positional", required: true, description: "Path or http(s) URL to the source/inspiration image" },
11557
11570
  context: { type: "string", description: "Known provenance (advertiser, category, market) to ground the describe" },
11558
11571
  out: { type: "string", description: "Output canvas path (default <image-dir>/static-ad.canvas.json)" },
11559
11572
  "describe-model": { type: "string", description: "Override the image_describe model id" },
@@ -11564,13 +11577,14 @@ var scaffoldStaticAdCommand = defineCommand84({
11564
11577
  "skip-font": { type: "boolean", description: "Skip the brand-font \u2192 type-specimen slot" }
11565
11578
  },
11566
11579
  async run({ args }) {
11567
- const imagePath = path5.resolve(String(args.file));
11568
- const outPath = args.out ? path5.resolve(String(args.out)) : path5.join(path5.dirname(imagePath), "static-ad.canvas.json");
11569
- const outDir = path5.dirname(outPath);
11570
- const blueprintPath = path5.join(outDir, "prompt.json");
11580
+ const { imageIsUrl, imageSource, outPath, blueprintPath } = resolveScaffoldStaticAdPaths(
11581
+ String(args.file),
11582
+ args.out ? String(args.out) : void 0
11583
+ );
11571
11584
  const { describeModel, selectModel, layoutModel, genModel } = resolveModels(args);
11572
11585
  const describeCanvas = buildDescribeCanvas(
11573
- imagePath,
11586
+ imageSource,
11587
+ imageIsUrl,
11574
11588
  describeModel,
11575
11589
  selectModel,
11576
11590
  layoutModel,
@@ -11585,7 +11599,8 @@ var scaffoldStaticAdCommand = defineCommand84({
11585
11599
  `, "utf8");
11586
11600
  const opts = {
11587
11601
  genModel,
11588
- imagePath,
11602
+ imagePath: imageSource,
11603
+ imageIsUrl,
11589
11604
  blueprintPath,
11590
11605
  aspectRatio: args.aspect ? String(args.aspect) : void 0,
11591
11606
  includeFont: !args["skip-font"]
@@ -11624,7 +11639,7 @@ var scaffoldStaticAdCommand = defineCommand84({
11624
11639
  run_estimated_credits: validation.estimatedCredits
11625
11640
  },
11626
11641
  checklist: {
11627
- edit_prompt: `Edit ${path5.basename(blueprintPath)} \u2014 it is the blueprint generated from your image; rewrite it into the ad you want (palette, copy, claims, subjects). It feeds the generator directly.`,
11642
+ edit_prompt: `Edit ${path6.basename(blueprintPath)} \u2014 it is the blueprint generated from your image; rewrite it into the ad you want (palette, copy, claims, subjects). It feeds the generator directly.`,
11628
11643
  assets_to_supply: report.elements,
11629
11644
  font_slot: report.includes_font ? "Drop a brand font at the [TODO] brandfont path, or delete the brandfont + type_ref nodes to skip it." : "skipped (--skip-font)",
11630
11645
  note: "Replace every [TODO] ingest path with a real file, then `baker canvas validate` and `baker canvas run`. Running generates a billed image \u2014 it is not free."
@@ -11640,7 +11655,7 @@ var scaffoldStaticAdCommand = defineCommand84({
11640
11655
 
11641
11656
  // src/commands/canvas/scaffold-video.ts
11642
11657
  import { cp, mkdir, readFile as readFile6, writeFile as writeFile2 } from "fs/promises";
11643
- import path8 from "path";
11658
+ import path9 from "path";
11644
11659
  import { defineCommand as defineCommand85 } from "citty";
11645
11660
 
11646
11661
  // src/engine/nodes/local/lib/sceneDetect.ts
@@ -14256,23 +14271,23 @@ function videoReport(input, elementsInput) {
14256
14271
 
14257
14272
  // src/commands/canvas/composition-path.ts
14258
14273
  import { existsSync as existsSync4 } from "fs";
14259
- import path6 from "path";
14274
+ import path7 from "path";
14260
14275
  function resolveShippedCanvasDir(name, startDir, exists = existsSync4, maxDepth = 8) {
14261
- const rel = path6.join("canvas", name);
14276
+ const rel = path7.join("canvas", name);
14262
14277
  let dir = startDir;
14263
14278
  for (let i = 0; i < maxDepth; i++) {
14264
- const candidate = path6.join(dir, rel);
14265
- if (exists(path6.join(candidate, "meta.json"))) return candidate;
14266
- const parent = path6.dirname(dir);
14279
+ const candidate = path7.join(dir, rel);
14280
+ if (exists(path7.join(candidate, "meta.json"))) return candidate;
14281
+ const parent = path7.dirname(dir);
14267
14282
  if (parent === dir) break;
14268
14283
  dir = parent;
14269
14284
  }
14270
- return path6.resolve(startDir, "../../../", rel);
14285
+ return path7.resolve(startDir, "../../../", rel);
14271
14286
  }
14272
14287
 
14273
14288
  // src/commands/canvas/gitignore.ts
14274
14289
  import { appendFile, readFile as readFile5 } from "fs/promises";
14275
- import path7 from "path";
14290
+ import path8 from "path";
14276
14291
  function missingGitignoreEntries(existing, entries) {
14277
14292
  const present = new Set(
14278
14293
  existing.split("\n").map((l) => l.trim().replace(/\/+$/, "")).filter((l) => l.length > 0 && !l.startsWith("#"))
@@ -14280,7 +14295,7 @@ function missingGitignoreEntries(existing, entries) {
14280
14295
  return entries.filter((e) => !present.has(e.trim().replace(/\/+$/, "")));
14281
14296
  }
14282
14297
  async function ensureGitignore(dir, entries) {
14283
- const file = path7.join(dir, ".gitignore");
14298
+ const file = path8.join(dir, ".gitignore");
14284
14299
  let existing;
14285
14300
  try {
14286
14301
  existing = await readFile5(file, "utf8");
@@ -14341,7 +14356,7 @@ async function loadTranscriptBestEffort(ref) {
14341
14356
  async function stageCaptions(outDir, transcript) {
14342
14357
  const text = transcript?.trim();
14343
14358
  if (!text || text === "[]") return {};
14344
- const compositionPath = path8.join(outDir, "tiktok-captions-composition");
14359
+ const compositionPath = path9.join(outDir, "tiktok-captions-composition");
14345
14360
  await cp(SHIPPED_CAPTIONS_DIR, compositionPath, { recursive: true });
14346
14361
  return { compositionPath };
14347
14362
  }
@@ -14503,11 +14518,11 @@ var scaffoldVideoCommand = defineCommand85({
14503
14518
  }
14504
14519
  },
14505
14520
  async run({ args }) {
14506
- const videoPath = path8.resolve(String(args.file));
14507
- const base = path8.basename(videoPath, path8.extname(videoPath));
14508
- const outPath = args.out ? path8.resolve(String(args.out)) : path8.join(path8.dirname(videoPath), `${base}.video.canvas.json`);
14509
- const outDir = path8.dirname(outPath);
14510
- const blueprintPath = path8.join(outDir, "prompt.json");
14521
+ const videoPath = path9.resolve(String(args.file));
14522
+ const base = path9.basename(videoPath, path9.extname(videoPath));
14523
+ const outPath = args.out ? path9.resolve(String(args.out)) : path9.join(path9.dirname(videoPath), `${base}.video.canvas.json`);
14524
+ const outDir = path9.dirname(outPath);
14525
+ const blueprintPath = path9.join(outDir, "prompt.json");
14511
14526
  const frames = args.frames === "reuse" ? "reuse" : "generate";
14512
14527
  const maxScenes = args["max-scenes"] ? Number(args["max-scenes"]) : void 0;
14513
14528
  if (Number.isFinite(maxScenes)) {
@@ -14530,9 +14545,9 @@ var scaffoldVideoCommand = defineCommand85({
14530
14545
  const annotated = annotateBlueprintWithElements(blueprint, elements);
14531
14546
  await writeFile2(blueprintPath, `${JSON.stringify(annotated, null, 2)}
14532
14547
  `, "utf8");
14533
- const compositionDest = path8.join(outDir, "video-overlay-composition");
14548
+ const compositionDest = path9.join(outDir, "video-overlay-composition");
14534
14549
  await cp(SHIPPED_COMPOSITION_DIR, compositionDest, { recursive: true });
14535
- const indexPath = path8.join(compositionDest, "index.html");
14550
+ const indexPath = path9.join(compositionDest, "index.html");
14536
14551
  const overlayHtml = buildOverlayHtml(blueprint);
14537
14552
  const indexHtml = await readFile6(indexPath, "utf8");
14538
14553
  const injected = indexHtml.replace("<!--OVERLAYS-->", () => overlayHtml);
@@ -14547,9 +14562,9 @@ var scaffoldVideoCommand = defineCommand85({
14547
14562
  const opts = {
14548
14563
  imageModel,
14549
14564
  videoModel,
14550
- overlayCompositionPath: path8.relative(outDir, compositionDest),
14551
- captionsCompositionPath: captions.compositionPath ? path8.relative(outDir, captions.compositionPath) : void 0,
14552
- blueprintPath: path8.relative(outDir, blueprintPath),
14565
+ overlayCompositionPath: path9.relative(outDir, compositionDest),
14566
+ captionsCompositionPath: captions.compositionPath ? path9.relative(outDir, captions.compositionPath) : void 0,
14567
+ blueprintPath: path9.relative(outDir, blueprintPath),
14553
14568
  frames,
14554
14569
  ambient: Boolean(args.ambient),
14555
14570
  ...args.resolution ? { resolution: String(args.resolution) } : {}
@@ -14590,7 +14605,7 @@ var scaffoldVideoCommand = defineCommand85({
14590
14605
  run_estimated_credits: validation.estimatedCredits
14591
14606
  },
14592
14607
  checklist: {
14593
- edit_prompt: `Edit ${path8.basename(blueprintPath)} \u2014 the blueprint deconstructed from your video; rewrite it into the ad you want (cast, palette, copy, claims). Every scene frame reads it via target_blueprint.`,
14608
+ edit_prompt: `Edit ${path9.basename(blueprintPath)} \u2014 the blueprint deconstructed from your video; rewrite it into the ad you want (cast, palette, copy, claims). Every scene frame reads it via target_blueprint.`,
14594
14609
  recurring_elements_to_supply: report.elements,
14595
14610
  voices_to_confirm: report.dialogue.map((d) => ({
14596
14611
  scene: d.scene,
@@ -14617,7 +14632,7 @@ var scaffoldVideoCommand = defineCommand85({
14617
14632
 
14618
14633
  // src/commands/canvas/set-prompt.ts
14619
14634
  import { readFile as readFile7, writeFile as writeFile3 } from "fs/promises";
14620
- import path9 from "path";
14635
+ import path10 from "path";
14621
14636
  import { defineCommand as defineCommand86 } from "citty";
14622
14637
  function setNodePrompt(canvas, nodeId, text) {
14623
14638
  const nodes = canvas?.nodes;
@@ -14645,7 +14660,7 @@ var setPromptCommand = defineCommand86({
14645
14660
  "text-file": { type: "string", description: "Read the new prompt from a UTF-8 file (preserves accents/newlines)" }
14646
14661
  },
14647
14662
  async run({ args }) {
14648
- const filePath = path9.resolve(String(args.file));
14663
+ const filePath = path10.resolve(String(args.file));
14649
14664
  let canvas;
14650
14665
  try {
14651
14666
  canvas = JSON.parse(await readFile7(filePath, "utf8"));
@@ -14655,7 +14670,7 @@ var setPromptCommand = defineCommand86({
14655
14670
  process.exit(2);
14656
14671
  }
14657
14672
  let text;
14658
- if (args["text-file"]) text = await readFile7(path9.resolve(String(args["text-file"])), "utf8");
14673
+ if (args["text-file"]) text = await readFile7(path10.resolve(String(args["text-file"])), "utf8");
14659
14674
  else if (args.text !== void 0) text = String(args.text);
14660
14675
  else {
14661
14676
  process.stderr.write(
@@ -14676,7 +14691,7 @@ var setPromptCommand = defineCommand86({
14676
14691
  process.exit(2);
14677
14692
  return;
14678
14693
  }
14679
- const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated, path9.dirname(filePath)), defaultRegistry());
14694
+ const validation = await validateCanvasDeep(resolveRelativeCanvasPaths(updated, path10.dirname(filePath)), defaultRegistry());
14680
14695
  if (!validation.ok) {
14681
14696
  process.stderr.write(`${JSON.stringify({ ok: false, error: { code: "validation", issues: validation.issues } }, null, 2)}
14682
14697
  `);
@@ -14692,7 +14707,7 @@ var setPromptCommand = defineCommand86({
14692
14707
 
14693
14708
  // src/commands/canvas/validate.ts
14694
14709
  import { readFile as readFile8 } from "fs/promises";
14695
- import path10 from "path";
14710
+ import path11 from "path";
14696
14711
  import { defineCommand as defineCommand87 } from "citty";
14697
14712
  var validateCommand = defineCommand87({
14698
14713
  meta: {
@@ -14701,7 +14716,7 @@ var validateCommand = defineCommand87({
14701
14716
  },
14702
14717
  args: { file: { type: "positional", required: true, description: "Path to canvas JSON" } },
14703
14718
  async run({ args }) {
14704
- const filePath = path10.resolve(String(args.file));
14719
+ const filePath = path11.resolve(String(args.file));
14705
14720
  const raw = await readFile8(filePath, "utf8");
14706
14721
  let parsed;
14707
14722
  try {
@@ -14712,7 +14727,7 @@ var validateCommand = defineCommand87({
14712
14727
  `);
14713
14728
  process.exit(2);
14714
14729
  }
14715
- parsed = resolveRelativeCanvasPaths(parsed, path10.dirname(filePath));
14730
+ parsed = resolveRelativeCanvasPaths(parsed, path11.dirname(filePath));
14716
14731
  const result = await validateCanvasDeep(parsed, defaultRegistry());
14717
14732
  if (!result.ok) {
14718
14733
  process.stderr.write(`${JSON.stringify({ ok: false, issues: result.issues }, null, 2)}
@@ -15819,9 +15834,9 @@ async function readImageBuffer(pathOrUrl) {
15819
15834
  }
15820
15835
  return readFile10(pathOrUrl);
15821
15836
  }
15822
- async function isDirectory(path11) {
15837
+ async function isDirectory(path12) {
15823
15838
  try {
15824
- const s = await stat2(path11);
15839
+ const s = await stat2(path12);
15825
15840
  return s.isDirectory();
15826
15841
  } catch {
15827
15842
  return false;
@@ -18371,11 +18386,162 @@ Paid transforms (run on the Convex backend, cost-tracked):
18371
18386
  }
18372
18387
  });
18373
18388
 
18389
+ // src/commands/mcp/index.ts
18390
+ import { defineCommand as defineCommand123 } from "citty";
18391
+ var SCOPES = ["user", "company", "org"];
18392
+ function parseScope(raw) {
18393
+ const scope = raw === void 0 ? "company" : String(raw);
18394
+ if (!SCOPES.includes(scope)) {
18395
+ throw new ApiError("VALIDATION_ERROR", `Invalid --scope "${scope}". Use user | company | org.`);
18396
+ }
18397
+ return scope;
18398
+ }
18399
+ function actingUserId() {
18400
+ return getEnv().BAKER_ACTING_USER_ID;
18401
+ }
18402
+ function parseHeaders(raw) {
18403
+ const list = raw === void 0 ? [] : Array.isArray(raw) ? raw : [raw];
18404
+ const headers = {};
18405
+ for (const entry of list) {
18406
+ const text = String(entry);
18407
+ const sep = text.indexOf(":") >= 0 && (text.indexOf(":") < text.indexOf("=") || text.indexOf("=") < 0) ? ":" : "=";
18408
+ const at = text.indexOf(sep);
18409
+ if (at <= 0) {
18410
+ throw new ApiError("VALIDATION_ERROR", `Invalid header "${text}". Use "Key: Value".`);
18411
+ }
18412
+ headers[text.slice(0, at).trim()] = text.slice(at + 1).trim();
18413
+ }
18414
+ return Object.keys(headers).length > 0 ? headers : void 0;
18415
+ }
18416
+ function fail3(err) {
18417
+ if (err instanceof ApiError) {
18418
+ writeJson({ ok: false, error: { code: err.code, message: err.message } });
18419
+ process.exit(1);
18420
+ }
18421
+ writeJson({ ok: false, error: { code: "NETWORK_ERROR", message: "Unexpected error" } });
18422
+ process.exit(1);
18423
+ }
18424
+ registerSchema({
18425
+ command: "mcp.list",
18426
+ description: "List the custom MCP servers this company's chats see (org + company + your own user scope).",
18427
+ args: {}
18428
+ });
18429
+ var listCommand4 = defineCommand123({
18430
+ meta: { name: "list", description: "List custom MCP servers visible to this company's chats." },
18431
+ run: async () => {
18432
+ try {
18433
+ const user = actingUserId();
18434
+ const data = await apiGet(
18435
+ "/api/mcp/custom",
18436
+ user ? { actingUserId: user } : void 0
18437
+ );
18438
+ writeJson({ ok: true, data: data.servers });
18439
+ } catch (err) {
18440
+ fail3(err);
18441
+ }
18442
+ }
18443
+ });
18444
+ registerSchema({
18445
+ command: "mcp.add",
18446
+ description: "Register a custom MCP server. Tools appear as mcp__<name>__* on the next message. URL must be HTTPS. Scope: company (default, all chats) | org (org admin key) | user (only the current sender).",
18447
+ args: {
18448
+ name: { type: "string", description: "Server name \u2192 tools appear as mcp__<name>__*", required: true },
18449
+ url: { type: "string", description: "HTTPS MCP endpoint", required: true },
18450
+ scope: { type: "string", description: "user | company | org (default company)", required: false },
18451
+ header: { type: "string", description: 'Auth header "Key: Value" (repeatable)', required: false }
18452
+ }
18453
+ });
18454
+ var addCommand = defineCommand123({
18455
+ meta: {
18456
+ name: "add",
18457
+ description: `Register a custom MCP server. Tools appear as mcp__<name>__* on the NEXT message.
18458
+
18459
+ Scope: company (default \u2014 every chat in the company) | org (all companies in the org; needs an admin key) | user (only the current message sender).
18460
+
18461
+ Examples:
18462
+ baker mcp add --name weather --url https://mcp.example.com/mcp
18463
+ baker mcp add --name acme --url https://acme.dev/mcp --header "Authorization: Bearer sk-\u2026"
18464
+ baker mcp add --name mine --url https://my.dev/mcp --scope user`
18465
+ },
18466
+ args: {
18467
+ name: { type: "string", description: "Server name (mcp__<name>__*)", required: true },
18468
+ url: { type: "string", description: "HTTPS MCP endpoint", required: true },
18469
+ scope: { type: "string", description: "user | company | org (default company)", required: false },
18470
+ header: { type: "string", description: 'Auth header "Key: Value" (repeatable)', required: false }
18471
+ },
18472
+ run: async ({ args }) => {
18473
+ try {
18474
+ const scope = parseScope(args.scope);
18475
+ const user = actingUserId();
18476
+ const headers = parseHeaders(args.header);
18477
+ const data = await apiPost("/api/mcp/custom", {
18478
+ name: args.name,
18479
+ url: args.url,
18480
+ scope,
18481
+ ...user ? { actingUserId: user } : {},
18482
+ ...headers ? { headers } : {}
18483
+ });
18484
+ writeJson({ ok: true, data });
18485
+ } catch (err) {
18486
+ fail3(err);
18487
+ }
18488
+ }
18489
+ });
18490
+ registerSchema({
18491
+ command: "mcp.remove",
18492
+ description: "Remove a company custom MCP server by name.",
18493
+ args: { name: { type: "string", description: "Server name to remove", required: true } }
18494
+ });
18495
+ var removeCommand3 = defineCommand123({
18496
+ meta: {
18497
+ name: "remove",
18498
+ description: `Remove a company custom MCP server by name.
18499
+
18500
+ Example:
18501
+ baker mcp remove --name weather`
18502
+ },
18503
+ args: { name: { type: "string", description: "Server name to remove", required: true } },
18504
+ run: async ({ args }) => {
18505
+ try {
18506
+ const user = actingUserId();
18507
+ const data = await apiPost("/api/mcp/custom/remove", {
18508
+ name: args.name,
18509
+ ...user ? { actingUserId: user } : {}
18510
+ });
18511
+ writeJson({ ok: true, data });
18512
+ } catch (err) {
18513
+ fail3(err);
18514
+ }
18515
+ }
18516
+ });
18517
+ var mcpCommand = defineCommand123({
18518
+ meta: {
18519
+ name: "mcp",
18520
+ description: `Custom MCP servers for this company \u2014 point the agent at any HTTPS MCP endpoint.
18521
+
18522
+ Tools from a registered server appear as mcp__<name>__* on the next message.
18523
+ Managed here are **company-scoped** servers; user- and org-scoped servers are managed in the dashboard.
18524
+
18525
+ Start here:
18526
+ baker mcp list
18527
+
18528
+ Examples:
18529
+ baker mcp add --name weather --url https://mcp.example.com/mcp
18530
+ baker mcp add --name acme --url https://acme.dev/mcp --header "Authorization: Bearer sk-\u2026"
18531
+ baker mcp remove --name weather`
18532
+ },
18533
+ subCommands: {
18534
+ list: listCommand4,
18535
+ add: addCommand,
18536
+ remove: removeCommand3
18537
+ }
18538
+ });
18539
+
18374
18540
  // src/commands/research/index.ts
18375
- import { defineCommand as defineCommand133 } from "citty";
18541
+ import { defineCommand as defineCommand134 } from "citty";
18376
18542
 
18377
18543
  // src/commands/research/advertisers.ts
18378
- import { defineCommand as defineCommand123 } from "citty";
18544
+ import { defineCommand as defineCommand124 } from "citty";
18379
18545
 
18380
18546
  // src/commands/research/output.ts
18381
18547
  var RESEARCH_DATA_NOTE = "Estimates based on third-party SERP data \u2014 not exact figures. Use for directional insights, not precise measurement.";
@@ -18488,7 +18654,7 @@ var FIELDS3 = {
18488
18654
  etv: "Estimated traffic value (USD)",
18489
18655
  visibility: "SERP visibility score (0-1)"
18490
18656
  };
18491
- var advertisersCommand = defineCommand123({
18657
+ var advertisersCommand = defineCommand124({
18492
18658
  meta: {
18493
18659
  name: "advertisers",
18494
18660
  description: `Find domains competing for a keyword in Google SERPs.
@@ -18535,7 +18701,7 @@ Examples:
18535
18701
  });
18536
18702
 
18537
18703
  // src/commands/research/autocomplete.ts
18538
- import { defineCommand as defineCommand124 } from "citty";
18704
+ import { defineCommand as defineCommand125 } from "citty";
18539
18705
  registerSchema({
18540
18706
  command: "research.autocomplete",
18541
18707
  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).",
@@ -18558,7 +18724,7 @@ registerSchema({
18558
18724
  var FIELDS4 = {
18559
18725
  suggestion: "Autocomplete suggestion from Google"
18560
18726
  };
18561
- var autocompleteCommand = defineCommand124({
18727
+ var autocompleteCommand = defineCommand125({
18562
18728
  meta: {
18563
18729
  name: "autocomplete",
18564
18730
  description: `Get Google Autocomplete suggestions for keyword expansion.
@@ -18604,7 +18770,7 @@ Examples:
18604
18770
  });
18605
18771
 
18606
18772
  // src/commands/research/countries.ts
18607
- import { defineCommand as defineCommand125 } from "citty";
18773
+ import { defineCommand as defineCommand126 } from "citty";
18608
18774
  registerSchema({
18609
18775
  command: "research.countries",
18610
18776
  description: "List all supported country codes for --location flag in research commands.",
@@ -18661,7 +18827,7 @@ var FIELDS5 = {
18661
18827
  code: "Country code to pass as --location",
18662
18828
  name: "Country name"
18663
18829
  };
18664
- var countriesCommand = defineCommand125({
18830
+ var countriesCommand = defineCommand126({
18665
18831
  meta: {
18666
18832
  name: "countries",
18667
18833
  description: "List all supported country codes for --location flag."
@@ -18672,7 +18838,7 @@ var countriesCommand = defineCommand125({
18672
18838
  });
18673
18839
 
18674
18840
  // src/commands/research/intent.ts
18675
- import { defineCommand as defineCommand126 } from "citty";
18841
+ import { defineCommand as defineCommand127 } from "citty";
18676
18842
  registerSchema({
18677
18843
  command: "research.intent",
18678
18844
  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.",
@@ -18695,7 +18861,7 @@ var FIELDS6 = {
18695
18861
  intent: "Primary Google Search intent: informational, navigational, commercial, transactional",
18696
18862
  probability: "Confidence score 0.0-1.0"
18697
18863
  };
18698
- var intentCommand = defineCommand126({
18864
+ var intentCommand = defineCommand127({
18699
18865
  meta: {
18700
18866
  name: "intent",
18701
18867
  description: `Classify Google Search intent for keywords. Returns intent type and confidence.
@@ -18743,7 +18909,7 @@ Examples:
18743
18909
  });
18744
18910
 
18745
18911
  // src/commands/research/keyword-gap.ts
18746
- import { defineCommand as defineCommand127 } from "citty";
18912
+ import { defineCommand as defineCommand128 } from "citty";
18747
18913
  registerSchema({
18748
18914
  command: "research.keyword-gap",
18749
18915
  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.",
@@ -18772,7 +18938,7 @@ var FIELDS7 = {
18772
18938
  cpc: "Cost per click USD",
18773
18939
  their_position: "Competitor's ranking position"
18774
18940
  };
18775
- var keywordGapCommand = defineCommand127({
18941
+ var keywordGapCommand = defineCommand128({
18776
18942
  meta: {
18777
18943
  name: "keyword-gap",
18778
18944
  description: `Find keywords a competitor has that you don't. Supports pagination via --offset.
@@ -18846,7 +19012,7 @@ Examples:
18846
19012
  });
18847
19013
 
18848
19014
  // src/commands/research/keywords-for-site.ts
18849
- import { defineCommand as defineCommand128 } from "citty";
19015
+ import { defineCommand as defineCommand129 } from "citty";
18850
19016
  registerSchema({
18851
19017
  command: "research.keywords-for-site",
18852
19018
  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.",
@@ -18879,7 +19045,7 @@ var FIELDS8 = {
18879
19045
  competition: "LOW, MEDIUM, or HIGH",
18880
19046
  competition_index: "Competition score 0-100"
18881
19047
  };
18882
- var keywordsForSiteCommand = defineCommand128({
19048
+ var keywordsForSiteCommand = defineCommand129({
18883
19049
  meta: {
18884
19050
  name: "keywords-for-site",
18885
19051
  description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.
@@ -18932,7 +19098,7 @@ Examples:
18932
19098
  });
18933
19099
 
18934
19100
  // src/commands/research/languages.ts
18935
- import { defineCommand as defineCommand129 } from "citty";
19101
+ import { defineCommand as defineCommand130 } from "citty";
18936
19102
  registerSchema({
18937
19103
  command: "research.languages",
18938
19104
  description: "List all supported language codes for --language flag in research commands.",
@@ -18962,7 +19128,7 @@ var FIELDS9 = {
18962
19128
  code: "Language code to pass as --language",
18963
19129
  name: "Language name (also accepted by --language)"
18964
19130
  };
18965
- var languagesCommand2 = defineCommand129({
19131
+ var languagesCommand2 = defineCommand130({
18966
19132
  meta: {
18967
19133
  name: "languages",
18968
19134
  description: "List all supported language codes for --language flag."
@@ -18973,7 +19139,7 @@ var languagesCommand2 = defineCommand129({
18973
19139
  });
18974
19140
 
18975
19141
  // src/commands/research/lighthouse.ts
18976
- import { defineCommand as defineCommand130 } from "citty";
19142
+ import { defineCommand as defineCommand131 } from "citty";
18977
19143
  registerSchema({
18978
19144
  command: "research.lighthouse",
18979
19145
  description: "Landing page performance audit. Returns metrics that affect Google Ads Quality Score and CPC.",
@@ -18992,7 +19158,7 @@ var FIELDS10 = {
18992
19158
  speed_index_ms: "Speed Index in ms (good: < 3400)",
18993
19159
  interactive_ms: "Time to Interactive in ms (good: < 3800)"
18994
19160
  };
18995
- var lighthouseCommand = defineCommand130({
19161
+ var lighthouseCommand = defineCommand131({
18996
19162
  meta: {
18997
19163
  name: "lighthouse",
18998
19164
  description: `Landing page performance audit. Metrics affecting Google Ads Quality Score.
@@ -19030,7 +19196,7 @@ Examples:
19030
19196
  });
19031
19197
 
19032
19198
  // src/commands/research/relevant-pages.ts
19033
- import { defineCommand as defineCommand131 } from "citty";
19199
+ import { defineCommand as defineCommand132 } from "citty";
19034
19200
  registerSchema({
19035
19201
  command: "research.relevant-pages",
19036
19202
  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).",
@@ -19056,7 +19222,7 @@ var FIELDS11 = {
19056
19222
  keywords: "Total organic keywords the page ranks for",
19057
19223
  top_10: "Keywords in positions 1-10"
19058
19224
  };
19059
- var relevantPagesCommand = defineCommand131({
19225
+ var relevantPagesCommand = defineCommand132({
19060
19226
  meta: {
19061
19227
  name: "relevant-pages",
19062
19228
  description: `Get the top pages of a competitor domain with traffic data.
@@ -19102,7 +19268,7 @@ Examples:
19102
19268
  });
19103
19269
 
19104
19270
  // src/commands/research/web.ts
19105
- import { defineCommand as defineCommand132 } from "citty";
19271
+ import { defineCommand as defineCommand133 } from "citty";
19106
19272
  registerSchema({
19107
19273
  command: "research.web",
19108
19274
  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).",
@@ -19153,7 +19319,7 @@ async function runDeepResearch(question) {
19153
19319
  }
19154
19320
  throw new Error("Deep research timed out");
19155
19321
  }
19156
- var webCommand = defineCommand132({
19322
+ var webCommand = defineCommand133({
19157
19323
  meta: {
19158
19324
  name: "web",
19159
19325
  description: `Search the web with AI to answer any open-ended marketing question. Uses live internet data via Google Search.
@@ -19213,7 +19379,7 @@ Examples:
19213
19379
  });
19214
19380
 
19215
19381
  // src/commands/research/index.ts
19216
- var researchCommand = defineCommand133({
19382
+ var researchCommand = defineCommand134({
19217
19383
  meta: {
19218
19384
  name: "research",
19219
19385
  description: `Competitive intelligence and AI-powered research commands.
@@ -19253,10 +19419,10 @@ Examples:
19253
19419
  });
19254
19420
 
19255
19421
  // src/commands/scheduled-actions/index.ts
19256
- import { defineCommand as defineCommand140 } from "citty";
19422
+ import { defineCommand as defineCommand141 } from "citty";
19257
19423
 
19258
19424
  // src/commands/scheduled-actions/create.ts
19259
- import { defineCommand as defineCommand134 } from "citty";
19425
+ import { defineCommand as defineCommand135 } from "citty";
19260
19426
 
19261
19427
  // src/commands/scheduled-actions/shared.ts
19262
19428
  var TEMP_SCHEDULED_ACTION_PREFIX = "temp_sched_";
@@ -19371,7 +19537,7 @@ registerSchema({
19371
19537
  prompt: { type: "string", description: "Additional prompt instructions for the spawned agent", required: false }
19372
19538
  }
19373
19539
  });
19374
- var createCommand2 = defineCommand134({
19540
+ var createCommand2 = defineCommand135({
19375
19541
  meta: {
19376
19542
  name: "create",
19377
19543
  description: 'Stage a scheduled action. Example: baker scheduled-actions create --name "Weekly report" --description "..." --cron "0 9 * * MON"'
@@ -19420,7 +19586,7 @@ var createCommand2 = defineCommand134({
19420
19586
  });
19421
19587
 
19422
19588
  // src/commands/scheduled-actions/delete.ts
19423
- import { defineCommand as defineCommand135 } from "citty";
19589
+ import { defineCommand as defineCommand136 } from "citty";
19424
19590
  registerSchema({
19425
19591
  command: "scheduled-actions.delete",
19426
19592
  description: "Stage deletion of a published scheduled action or cancellation of a temp_sched_* draft creation.",
@@ -19428,7 +19594,7 @@ registerSchema({
19428
19594
  id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
19429
19595
  }
19430
19596
  });
19431
- var deleteCommand2 = defineCommand135({
19597
+ var deleteCommand2 = defineCommand136({
19432
19598
  meta: {
19433
19599
  name: "delete",
19434
19600
  description: "Stage scheduled action deletion. Example: baker scheduled-actions delete <id-or-temp_sched_id>"
@@ -19457,7 +19623,7 @@ var deleteCommand2 = defineCommand135({
19457
19623
  });
19458
19624
 
19459
19625
  // src/commands/scheduled-actions/get.ts
19460
- import { defineCommand as defineCommand136 } from "citty";
19626
+ import { defineCommand as defineCommand137 } from "citty";
19461
19627
  registerSchema({
19462
19628
  command: "scheduled-actions.get",
19463
19629
  description: "Get a published scheduled action or a temp_sched_* draft-created scheduled action.",
@@ -19465,7 +19631,7 @@ registerSchema({
19465
19631
  id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
19466
19632
  }
19467
19633
  });
19468
- var getCommand3 = defineCommand136({
19634
+ var getCommand3 = defineCommand137({
19469
19635
  meta: {
19470
19636
  name: "get",
19471
19637
  description: "Get a scheduled action. Example: baker scheduled-actions get <id-or-temp_sched_id>"
@@ -19502,13 +19668,13 @@ var getCommand3 = defineCommand136({
19502
19668
  });
19503
19669
 
19504
19670
  // src/commands/scheduled-actions/list.ts
19505
- import { defineCommand as defineCommand137 } from "citty";
19671
+ import { defineCommand as defineCommand138 } from "citty";
19506
19672
  registerSchema({
19507
19673
  command: "scheduled-actions.list",
19508
19674
  description: "List published scheduled actions. Includes draft state when BAKER_CHAT_ID is set.",
19509
19675
  args: {}
19510
19676
  });
19511
- var listCommand4 = defineCommand137({
19677
+ var listCommand5 = defineCommand138({
19512
19678
  meta: {
19513
19679
  name: "list",
19514
19680
  description: "List scheduled actions. Includes staged draft ops when BAKER_CHAT_ID is set."
@@ -19529,7 +19695,7 @@ var listCommand4 = defineCommand137({
19529
19695
  });
19530
19696
 
19531
19697
  // src/commands/scheduled-actions/trigger.ts
19532
- import { defineCommand as defineCommand138 } from "citty";
19698
+ import { defineCommand as defineCommand139 } from "citty";
19533
19699
  registerSchema({
19534
19700
  command: "scheduled-actions.trigger",
19535
19701
  description: "Immediately trigger a published scheduled action. Does not require BAKER_CHAT_ID and rejects temp_sched_* IDs.",
@@ -19537,7 +19703,7 @@ registerSchema({
19537
19703
  id: { type: "string", description: "Published scheduled action ID", required: true }
19538
19704
  }
19539
19705
  });
19540
- var triggerCommand = defineCommand138({
19706
+ var triggerCommand = defineCommand139({
19541
19707
  meta: {
19542
19708
  name: "trigger",
19543
19709
  description: "Immediately trigger a published scheduled action. Example: baker scheduled-actions trigger <id>"
@@ -19574,7 +19740,7 @@ var triggerCommand = defineCommand138({
19574
19740
  });
19575
19741
 
19576
19742
  // src/commands/scheduled-actions/update.ts
19577
- import { defineCommand as defineCommand139 } from "citty";
19743
+ import { defineCommand as defineCommand140 } from "citty";
19578
19744
  registerSchema({
19579
19745
  command: "scheduled-actions.update",
19580
19746
  description: "Stage an update to a published scheduled action or temp_sched_* draft-created scheduled action.",
@@ -19599,7 +19765,7 @@ registerSchema({
19599
19765
  prompt: { type: "string", description: "Replacement additional spawned-agent instructions", required: false }
19600
19766
  }
19601
19767
  });
19602
- var updateCommand2 = defineCommand139({
19768
+ var updateCommand2 = defineCommand140({
19603
19769
  meta: {
19604
19770
  name: "update",
19605
19771
  description: "Stage a scheduled action update. Example: baker scheduled-actions update <id> --enabled false"
@@ -19670,7 +19836,7 @@ var updateCommand2 = defineCommand139({
19670
19836
  });
19671
19837
 
19672
19838
  // src/commands/scheduled-actions/index.ts
19673
- var scheduledActionsCommand = defineCommand140({
19839
+ var scheduledActionsCommand = defineCommand141({
19674
19840
  meta: {
19675
19841
  name: "scheduled-actions",
19676
19842
  description: `Manage Scheduled Actions. Subcommands: list, get, create, update, delete, trigger.
@@ -19686,7 +19852,7 @@ Examples:
19686
19852
  baker scheduled-actions trigger <id>`
19687
19853
  },
19688
19854
  subCommands: {
19689
- list: listCommand4,
19855
+ list: listCommand5,
19690
19856
  get: getCommand3,
19691
19857
  create: createCommand2,
19692
19858
  update: updateCommand2,
@@ -19696,8 +19862,8 @@ Examples:
19696
19862
  });
19697
19863
 
19698
19864
  // src/commands/schema.ts
19699
- import { defineCommand as defineCommand141 } from "citty";
19700
- var schemaCommand = defineCommand141({
19865
+ import { defineCommand as defineCommand142 } from "citty";
19866
+ var schemaCommand = defineCommand142({
19701
19867
  meta: {
19702
19868
  name: "schema",
19703
19869
  description: "Inspect command argument schemas (for AI agent introspection). Lists all commands if no argument given. Example: baker schema images.search"
@@ -19733,10 +19899,10 @@ var schemaCommand = defineCommand141({
19733
19899
  });
19734
19900
 
19735
19901
  // src/commands/testimonials/index.ts
19736
- import { defineCommand as defineCommand145 } from "citty";
19902
+ import { defineCommand as defineCommand146 } from "citty";
19737
19903
 
19738
19904
  // src/commands/testimonials/get.ts
19739
- import { defineCommand as defineCommand142 } from "citty";
19905
+ import { defineCommand as defineCommand143 } from "citty";
19740
19906
  registerSchema({
19741
19907
  command: "testimonials.get",
19742
19908
  description: "Get a single testimonial by ID",
@@ -19744,7 +19910,7 @@ registerSchema({
19744
19910
  id: { type: "string", description: "Testimonial ID", required: true }
19745
19911
  }
19746
19912
  });
19747
- var getCommand4 = defineCommand142({
19913
+ var getCommand4 = defineCommand143({
19748
19914
  meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
19749
19915
  args: {
19750
19916
  id: { type: "positional", description: "Testimonial ID", required: false },
@@ -19781,7 +19947,7 @@ var getCommand4 = defineCommand142({
19781
19947
  });
19782
19948
 
19783
19949
  // src/commands/testimonials/list.ts
19784
- import { defineCommand as defineCommand143 } from "citty";
19950
+ import { defineCommand as defineCommand144 } from "citty";
19785
19951
  registerSchema({
19786
19952
  command: "testimonials.list",
19787
19953
  description: "List testimonials with optional filters.",
@@ -19811,7 +19977,7 @@ registerSchema({
19811
19977
  limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
19812
19978
  }
19813
19979
  });
19814
- var listCommand5 = defineCommand143({
19980
+ var listCommand6 = defineCommand144({
19815
19981
  meta: {
19816
19982
  name: "list",
19817
19983
  description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
@@ -19860,7 +20026,7 @@ var listCommand5 = defineCommand143({
19860
20026
  });
19861
20027
 
19862
20028
  // src/commands/testimonials/search.ts
19863
- import { defineCommand as defineCommand144 } from "citty";
20029
+ import { defineCommand as defineCommand145 } from "citty";
19864
20030
  registerSchema({
19865
20031
  command: "testimonials.search",
19866
20032
  description: "Search testimonials by text query. Uses hybrid BM25 + vector + reranking.",
@@ -19891,7 +20057,7 @@ registerSchema({
19891
20057
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
19892
20058
  }
19893
20059
  });
19894
- var searchCommand2 = defineCommand144({
20060
+ var searchCommand2 = defineCommand145({
19895
20061
  meta: {
19896
20062
  name: "search",
19897
20063
  description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
@@ -19965,7 +20131,7 @@ var searchCommand2 = defineCommand144({
19965
20131
  var tagsCommand3 = makeTagsCommand("testimonials", "testimonial", "/api/testimonials/tags");
19966
20132
 
19967
20133
  // src/commands/testimonials/index.ts
19968
- var testimonialsCommand = defineCommand145({
20134
+ var testimonialsCommand = defineCommand146({
19969
20135
  meta: {
19970
20136
  name: "testimonials",
19971
20137
  description: `Find and browse testimonials in Baker. Subcommands: search, get, list, tags.
@@ -19980,16 +20146,16 @@ Examples:
19980
20146
  subCommands: {
19981
20147
  get: getCommand4,
19982
20148
  search: searchCommand2,
19983
- list: listCommand5,
20149
+ list: listCommand6,
19984
20150
  tags: tagsCommand3
19985
20151
  }
19986
20152
  });
19987
20153
 
19988
20154
  // src/commands/videos/index.ts
19989
- import { defineCommand as defineCommand150 } from "citty";
20155
+ import { defineCommand as defineCommand151 } from "citty";
19990
20156
 
19991
20157
  // src/commands/videos/delete.ts
19992
- import { defineCommand as defineCommand146 } from "citty";
20158
+ import { defineCommand as defineCommand147 } from "citty";
19993
20159
  registerSchema({
19994
20160
  command: "videos.delete",
19995
20161
  description: "Delete a video by ID",
@@ -20003,7 +20169,7 @@ registerSchema({
20003
20169
  }
20004
20170
  }
20005
20171
  });
20006
- var deleteCommand3 = defineCommand146({
20172
+ var deleteCommand3 = defineCommand147({
20007
20173
  meta: {
20008
20174
  name: "delete",
20009
20175
  description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
@@ -20044,7 +20210,7 @@ var deleteCommand3 = defineCommand146({
20044
20210
  });
20045
20211
 
20046
20212
  // src/commands/videos/get.ts
20047
- import { defineCommand as defineCommand147 } from "citty";
20213
+ import { defineCommand as defineCommand148 } from "citty";
20048
20214
  registerSchema({
20049
20215
  command: "videos.get",
20050
20216
  description: "Get a single video by ID",
@@ -20052,7 +20218,7 @@ registerSchema({
20052
20218
  id: { type: "string", description: "Video ID", required: true }
20053
20219
  }
20054
20220
  });
20055
- var getCommand5 = defineCommand147({
20221
+ var getCommand5 = defineCommand148({
20056
20222
  meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
20057
20223
  args: {
20058
20224
  id: { type: "positional", description: "Video ID", required: false },
@@ -20089,7 +20255,7 @@ var getCommand5 = defineCommand147({
20089
20255
  });
20090
20256
 
20091
20257
  // src/commands/videos/search.ts
20092
- import { defineCommand as defineCommand148 } from "citty";
20258
+ import { defineCommand as defineCommand149 } from "citty";
20093
20259
  registerSchema({
20094
20260
  command: "videos.search",
20095
20261
  description: "Search videos by text query. Only returns ready videos.",
@@ -20099,7 +20265,7 @@ registerSchema({
20099
20265
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
20100
20266
  }
20101
20267
  });
20102
- var searchCommand3 = defineCommand148({
20268
+ var searchCommand3 = defineCommand149({
20103
20269
  meta: {
20104
20270
  name: "search",
20105
20271
  description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
@@ -20151,7 +20317,7 @@ var tagsCommand4 = makeTagsCommand("videos", "video", "/api/videos/tags");
20151
20317
  // src/commands/videos/upload.ts
20152
20318
  import { readFile as readFile12, stat as stat3 } from "fs/promises";
20153
20319
  import { extname as extname3 } from "path";
20154
- import { defineCommand as defineCommand149 } from "citty";
20320
+ import { defineCommand as defineCommand150 } from "citty";
20155
20321
  var MIME_MAP = {
20156
20322
  ".mp4": "video/mp4",
20157
20323
  ".mov": "video/quicktime",
@@ -20185,7 +20351,7 @@ function detectContentType(filePath) {
20185
20351
  }
20186
20352
  return mime;
20187
20353
  }
20188
- var uploadCommand2 = defineCommand149({
20354
+ var uploadCommand2 = defineCommand150({
20189
20355
  meta: {
20190
20356
  name: "upload",
20191
20357
  description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
@@ -20239,7 +20405,7 @@ var uploadCommand2 = defineCommand149({
20239
20405
  });
20240
20406
 
20241
20407
  // src/commands/videos/index.ts
20242
- var videosCommand = defineCommand150({
20408
+ var videosCommand = defineCommand151({
20243
20409
  meta: {
20244
20410
  name: "videos",
20245
20411
  description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete, tags.
@@ -20262,10 +20428,10 @@ Examples:
20262
20428
  });
20263
20429
 
20264
20430
  // src/commands/winning-ads/index.ts
20265
- import { defineCommand as defineCommand153 } from "citty";
20431
+ import { defineCommand as defineCommand154 } from "citty";
20266
20432
 
20267
20433
  // src/commands/winning-ads/advertisers.ts
20268
- import { defineCommand as defineCommand151 } from "citty";
20434
+ import { defineCommand as defineCommand152 } from "citty";
20269
20435
  registerSchema({
20270
20436
  command: "winning-ads.advertisers",
20271
20437
  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).",
@@ -20278,7 +20444,7 @@ registerSchema({
20278
20444
  function identity(record) {
20279
20445
  return record;
20280
20446
  }
20281
- var advertisersCommand2 = defineCommand151({
20447
+ var advertisersCommand2 = defineCommand152({
20282
20448
  meta: {
20283
20449
  name: "advertisers",
20284
20450
  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'
@@ -20329,7 +20495,7 @@ var advertisersCommand2 = defineCommand151({
20329
20495
  });
20330
20496
 
20331
20497
  // src/commands/winning-ads/search.ts
20332
- import { defineCommand as defineCommand152 } from "citty";
20498
+ import { defineCommand as defineCommand153 } from "citty";
20333
20499
  registerSchema({
20334
20500
  command: "winning-ads.search",
20335
20501
  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.",
@@ -20437,7 +20603,7 @@ function buildSearchBody(args) {
20437
20603
  }
20438
20604
  return body;
20439
20605
  }
20440
- var searchCommand4 = defineCommand152({
20606
+ var searchCommand4 = defineCommand153({
20441
20607
  meta: {
20442
20608
  name: "search",
20443
20609
  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"
@@ -20549,7 +20715,7 @@ var searchCommand4 = defineCommand152({
20549
20715
  });
20550
20716
 
20551
20717
  // src/commands/winning-ads/index.ts
20552
- var winningAdsCommand = defineCommand153({
20718
+ var winningAdsCommand = defineCommand154({
20553
20719
  meta: {
20554
20720
  name: "winning-ads",
20555
20721
  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.
@@ -20589,7 +20755,7 @@ function getCliVersion() {
20589
20755
  }
20590
20756
 
20591
20757
  // src/cli.ts
20592
- var main = defineCommand154({
20758
+ var main = defineCommand155({
20593
20759
  meta: {
20594
20760
  name: "baker",
20595
20761
  version: getCliVersion(),
@@ -20614,6 +20780,7 @@ Introspection: Run 'baker schema <command>' to inspect argument schemas.`
20614
20780
  testimonials: testimonialsCommand,
20615
20781
  canvas: canvasCommand,
20616
20782
  "winning-ads": winningAdsCommand,
20783
+ mcp: mcpCommand,
20617
20784
  schema: schemaCommand
20618
20785
  }
20619
20786
  });