@koda-sl/baker-cli 0.68.0 → 0.70.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
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ELEVENLABS_MAX_MUSIC_LENGTH_MS,
4
+ IMAGE_GENERATE_MODELS,
4
5
  MODEL_REGISTRY,
5
6
  SEEDANCE_DURATIONS,
6
7
  ValidationError,
@@ -8,10 +9,10 @@ import {
8
9
  defaultRegistry,
9
10
  generateCatalog,
10
11
  validateCanvasDeep
11
- } from "./chunk-K6LHXCKD.js";
12
+ } from "./chunk-XFDZVKLF.js";
12
13
 
13
14
  // src/cli.ts
14
- import { defineCommand as defineCommand136, runMain } from "citty";
15
+ import { defineCommand as defineCommand138, runMain } from "citty";
15
16
 
16
17
  // src/commands/actions/index.ts
17
18
  import { defineCommand as defineCommand12 } from "citty";
@@ -9858,7 +9859,7 @@ Examples:
9858
9859
  });
9859
9860
 
9860
9861
  // src/commands/images/index.ts
9861
- import { defineCommand as defineCommand107 } from "citty";
9862
+ import { defineCommand as defineCommand109 } from "citty";
9862
9863
 
9863
9864
  // src/commands/images/crop.ts
9864
9865
  import { defineCommand as defineCommand87 } from "citty";
@@ -10275,8 +10276,157 @@ var findCommand = defineCommand91({
10275
10276
  }
10276
10277
  });
10277
10278
 
10278
- // src/commands/images/get.ts
10279
+ // src/commands/images/generate.ts
10280
+ import { readFile as readFile7 } from "fs/promises";
10279
10281
  import { defineCommand as defineCommand92 } from "citty";
10282
+ import sharp2 from "sharp";
10283
+ var GENERATE_TIMEOUT_MS = 18e4;
10284
+ var REFERENCE_MAX_EDGE = 1536;
10285
+ var MODEL_LIST = [...IMAGE_GENERATE_MODELS];
10286
+ registerSchema({
10287
+ command: "images.generate",
10288
+ description: "Generate an image with AI (OpenRouter image models) and ingest it into the library. Default model openai/gpt-5.4-image-2 \u2014 photo-realistic, cleanest text rendering. Pass --reference with image URLs AND/OR local file paths (brand logo, product shot, Pinterest pin, cropped photo) to ground the generation on real imagery for on-brand, realistic output.",
10289
+ args: {
10290
+ prompt: { type: "string", description: "What to generate", required: true },
10291
+ model: {
10292
+ type: "string",
10293
+ description: `Model (default openai/gpt-5.4-image-2). One of: ${MODEL_LIST.join(", ")}`,
10294
+ required: false,
10295
+ enum: MODEL_LIST
10296
+ },
10297
+ "aspect-ratio": {
10298
+ type: "string",
10299
+ description: "Aspect ratio, e.g. 1:1 (default), 16:9, 9:16, 4:5, 3:2 (Gemini flash also supports 1:4/8:1)",
10300
+ required: false
10301
+ },
10302
+ "image-size": {
10303
+ type: "string",
10304
+ description: "Output resolution: 1K (default) | 2K | 4K (Gemini flash also 0.5K)",
10305
+ required: false
10306
+ },
10307
+ reference: {
10308
+ type: "string",
10309
+ description: "Comma-separated visual references \u2014 each is a public image URL OR a local file path (a sandbox image: brand logo, cropped photo, screenshot). Local files are downscaled and inlined automatically. Grounds output in real imagery; applied in order.",
10310
+ required: false
10311
+ },
10312
+ strength: {
10313
+ type: "number",
10314
+ description: "Recraft v4.1 Pro Vector only: vectorization strength 0-1",
10315
+ required: false
10316
+ },
10317
+ "rgb-colors": {
10318
+ type: "string",
10319
+ description: 'Recraft only: JSON array of [r,g,b] palette triples, e.g. "[[10,10,10],[255,80,0]]"',
10320
+ required: false
10321
+ },
10322
+ "bg-rgb": {
10323
+ type: "string",
10324
+ description: 'Recraft only: JSON [r,g,b] background color, e.g. "[255,255,255]"',
10325
+ required: false
10326
+ },
10327
+ context: {
10328
+ type: "string",
10329
+ description: "Description context hint for the ingested row (overrides the prompt as the describe hint)",
10330
+ required: false
10331
+ }
10332
+ }
10333
+ });
10334
+ function parseJsonArg(raw, flag) {
10335
+ try {
10336
+ return JSON.parse(raw);
10337
+ } catch {
10338
+ throw new ApiError("VALIDATION_ERROR", `--${flag} must be valid JSON (got: ${raw})`);
10339
+ }
10340
+ }
10341
+ function buildGenerateBody(args, prompt) {
10342
+ const body = { prompt };
10343
+ if (args.model) body.model = args.model;
10344
+ if (args["aspect-ratio"]) body.aspectRatio = args["aspect-ratio"];
10345
+ if (args["image-size"]) body.imageSize = args["image-size"];
10346
+ if (args.strength !== void 0) body.strength = Number(args.strength);
10347
+ if (args["rgb-colors"]) body.rgbColors = parseJsonArg(args["rgb-colors"], "rgb-colors");
10348
+ if (args["bg-rgb"]) body.backgroundRgbColor = parseJsonArg(args["bg-rgb"], "bg-rgb");
10349
+ if (args.context) body.descriptionContext = args.context;
10350
+ return body;
10351
+ }
10352
+ async function resolveReferences(spec) {
10353
+ const trimmed = spec.trim();
10354
+ const entries = trimmed.startsWith("data:") ? [trimmed] : trimmed.split(",").map((s) => s.trim()).filter(Boolean);
10355
+ const out = [];
10356
+ for (const entry of entries) {
10357
+ if (isRemoteUrl(entry) || entry.startsWith("data:")) {
10358
+ out.push(entry);
10359
+ continue;
10360
+ }
10361
+ let raw;
10362
+ try {
10363
+ raw = await readFile7(entry);
10364
+ } catch {
10365
+ throw new ApiError("VALIDATION_ERROR", `Reference file not found: ${entry}`);
10366
+ }
10367
+ let webp;
10368
+ try {
10369
+ webp = await sharp2(raw).resize({ width: REFERENCE_MAX_EDGE, height: REFERENCE_MAX_EDGE, fit: "inside", withoutEnlargement: true }).webp({ quality: 82 }).toBuffer();
10370
+ } catch {
10371
+ throw new ApiError("VALIDATION_ERROR", `Reference is not a readable image: ${entry}`);
10372
+ }
10373
+ out.push(`data:image/webp;base64,${webp.toString("base64")}`);
10374
+ }
10375
+ return out;
10376
+ }
10377
+ var generateCommand = defineCommand92({
10378
+ meta: {
10379
+ name: "generate",
10380
+ 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]]'"
10381
+ },
10382
+ args: {
10383
+ prompt: { type: "positional", description: "What to generate", required: false },
10384
+ model: { type: "string", description: "Model id (default openai/gpt-5.4-image-2)", required: false },
10385
+ "aspect-ratio": { type: "string", description: "Aspect ratio (default 1:1)", required: false },
10386
+ "image-size": { type: "string", description: "1K (default) | 2K | 4K | 0.5K", required: false },
10387
+ reference: {
10388
+ type: "string",
10389
+ description: "Comma-separated reference image URLs and/or local file paths",
10390
+ required: false
10391
+ },
10392
+ strength: { type: "string", description: "Recraft vectorization strength 0-1", required: false },
10393
+ "rgb-colors": {
10394
+ type: "string",
10395
+ description: "Recraft palette JSON, e.g. [[10,10,10],[255,80,0]]",
10396
+ required: false
10397
+ },
10398
+ "bg-rgb": { type: "string", description: "Recraft background JSON, e.g. [255,255,255]", required: false },
10399
+ context: { type: "string", description: "Describe-hint override for the ingested row", required: false }
10400
+ },
10401
+ run: async ({ args }) => {
10402
+ try {
10403
+ const prompt = args.prompt;
10404
+ if (!prompt) {
10405
+ writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: "Prompt is required" } });
10406
+ process.exit(1);
10407
+ }
10408
+ const body = buildGenerateBody(args, prompt);
10409
+ if (args.reference) {
10410
+ const refs = await resolveReferences(args.reference);
10411
+ if (refs.length > 0) body.referenceUrls = refs;
10412
+ }
10413
+ const data = await apiPost("/api/images/generate", body, {
10414
+ timeoutMs: GENERATE_TIMEOUT_MS
10415
+ });
10416
+ writeJson({ ok: true, data });
10417
+ } catch (err) {
10418
+ if (err instanceof ApiError) {
10419
+ writeJson({ ok: false, error: { code: err.code, message: err.message } });
10420
+ process.exit(1);
10421
+ }
10422
+ writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
10423
+ process.exit(1);
10424
+ }
10425
+ }
10426
+ });
10427
+
10428
+ // src/commands/images/get.ts
10429
+ import { defineCommand as defineCommand93 } from "citty";
10280
10430
  registerSchema({
10281
10431
  command: "images.get",
10282
10432
  description: "Get a single image by ID",
@@ -10284,7 +10434,7 @@ registerSchema({
10284
10434
  id: { type: "string", description: "Image ID", required: true }
10285
10435
  }
10286
10436
  });
10287
- var getCommand2 = defineCommand92({
10437
+ var getCommand2 = defineCommand93({
10288
10438
  meta: { name: "get", description: "Get a single image by ID. Example: baker images get j571abc123" },
10289
10439
  args: {
10290
10440
  id: { type: "positional", description: "Image ID", required: false },
@@ -10320,7 +10470,7 @@ var getCommand2 = defineCommand92({
10320
10470
  });
10321
10471
 
10322
10472
  // src/commands/images/gif.ts
10323
- import { defineCommand as defineCommand93 } from "citty";
10473
+ import { defineCommand as defineCommand94 } from "citty";
10324
10474
  registerSchema({
10325
10475
  command: "images.gif",
10326
10476
  description: "Search Giphy for GIFs / reaction memes (paid social creative).",
@@ -10352,7 +10502,7 @@ registerSchema({
10352
10502
  }
10353
10503
  }
10354
10504
  });
10355
- var gifCommand = defineCommand93({
10505
+ var gifCommand = defineCommand94({
10356
10506
  meta: {
10357
10507
  name: "gif",
10358
10508
  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"
@@ -10399,7 +10549,7 @@ var gifCommand = defineCommand93({
10399
10549
  });
10400
10550
 
10401
10551
  // src/commands/images/google.ts
10402
- import { defineCommand as defineCommand94 } from "citty";
10552
+ import { defineCommand as defineCommand95 } from "citty";
10403
10553
  registerSchema({
10404
10554
  command: "images.google",
10405
10555
  description: "Google Images search via the official Custom Search JSON API. Unverified source \u2014 inspect before placing.",
@@ -10435,7 +10585,7 @@ registerSchema({
10435
10585
  }
10436
10586
  }
10437
10587
  });
10438
- var googleCommand2 = defineCommand94({
10588
+ var googleCommand2 = defineCommand95({
10439
10589
  meta: {
10440
10590
  name: "google",
10441
10591
  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"
@@ -10483,7 +10633,7 @@ var googleCommand2 = defineCommand94({
10483
10633
  });
10484
10634
 
10485
10635
  // src/commands/images/icon.ts
10486
- import { defineCommand as defineCommand95 } from "citty";
10636
+ import { defineCommand as defineCommand96 } from "citty";
10487
10637
  registerSchema({
10488
10638
  command: "images.icon",
10489
10639
  description: "Icon lookup via Iconify (200+ icon sets, free CDN).",
@@ -10509,7 +10659,7 @@ registerSchema({
10509
10659
  }
10510
10660
  }
10511
10661
  });
10512
- var iconCommand = defineCommand95({
10662
+ var iconCommand = defineCommand96({
10513
10663
  meta: {
10514
10664
  name: "icon",
10515
10665
  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'"
@@ -10549,7 +10699,7 @@ var iconCommand = defineCommand95({
10549
10699
  });
10550
10700
 
10551
10701
  // src/commands/images/ingest.ts
10552
- import { defineCommand as defineCommand96 } from "citty";
10702
+ import { defineCommand as defineCommand97 } from "citty";
10553
10703
  registerSchema({
10554
10704
  command: "images.ingest",
10555
10705
  description: "Ingest a remote image URL into the library (full describe + embed).",
@@ -10561,7 +10711,7 @@ registerSchema({
10561
10711
  context: { type: "string", description: "Description context hint", required: false }
10562
10712
  }
10563
10713
  });
10564
- var ingestCommand = defineCommand96({
10714
+ var ingestCommand = defineCommand97({
10565
10715
  meta: {
10566
10716
  name: "ingest",
10567
10717
  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"
@@ -10603,7 +10753,7 @@ var ingestCommand = defineCommand96({
10603
10753
  });
10604
10754
 
10605
10755
  // src/commands/images/library.ts
10606
- import { defineCommand as defineCommand97 } from "citty";
10756
+ import { defineCommand as defineCommand98 } from "citty";
10607
10757
  registerSchema({
10608
10758
  command: "images.library",
10609
10759
  description: "Search the company image library. Returns only ready images.",
@@ -10629,7 +10779,7 @@ registerSchema({
10629
10779
  }
10630
10780
  }
10631
10781
  });
10632
- var libraryCommand = defineCommand97({
10782
+ var libraryCommand = defineCommand98({
10633
10783
  meta: {
10634
10784
  name: "library",
10635
10785
  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"
@@ -10686,7 +10836,7 @@ var libraryCommand = defineCommand97({
10686
10836
  });
10687
10837
 
10688
10838
  // src/commands/images/logo.ts
10689
- import { defineCommand as defineCommand98 } from "citty";
10839
+ import { defineCommand as defineCommand99 } from "citty";
10690
10840
  registerSchema({
10691
10841
  command: "images.logo",
10692
10842
  description: "Brand logo lookup via Brandfetch CDN (fallback/404). Auto-ingests by default.",
@@ -10711,7 +10861,7 @@ registerSchema({
10711
10861
  }
10712
10862
  }
10713
10863
  });
10714
- var logoCommand = defineCommand98({
10864
+ var logoCommand = defineCommand99({
10715
10865
  meta: {
10716
10866
  name: "logo",
10717
10867
  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"
@@ -10749,7 +10899,7 @@ var logoCommand = defineCommand98({
10749
10899
  });
10750
10900
 
10751
10901
  // src/commands/images/normalize.ts
10752
- import { defineCommand as defineCommand99 } from "citty";
10902
+ import { defineCommand as defineCommand100 } from "citty";
10753
10903
 
10754
10904
  // src/lib/image/color-changer.ts
10755
10905
  import quantize from "quantize";
@@ -11097,7 +11247,7 @@ function solidifyEdges(data, saturationBoost = 0.25) {
11097
11247
  }
11098
11248
 
11099
11249
  // src/lib/image/image-processor.ts
11100
- import sharp2 from "sharp";
11250
+ import sharp3 from "sharp";
11101
11251
  function hasGradient(data) {
11102
11252
  const uniqueColors = /* @__PURE__ */ new Set();
11103
11253
  for (let i = 0; i < data.length; i += 4) {
@@ -11129,10 +11279,10 @@ function createSvgRecolorer(target, palette) {
11129
11279
  async function processGradient(data, info) {
11130
11280
  if (!hasGradient(data)) return { data, info };
11131
11281
  const solidified = solidifyEdges(data, 0.1);
11132
- const blurred = await sharp2(solidified, {
11282
+ const blurred = await sharp3(solidified, {
11133
11283
  raw: { channels: 4, width: info.width, height: info.height }
11134
11284
  }).png().blur(0.3).toBuffer();
11135
- const result = await sharp2(blurred).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
11285
+ const result = await sharp3(blurred).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
11136
11286
  return { data: result.data, info: result.info };
11137
11287
  }
11138
11288
  function isSvgBuffer(buffer) {
@@ -11141,13 +11291,13 @@ function isSvgBuffer(buffer) {
11141
11291
  }
11142
11292
  async function processInternal(inputBuffer, isSVG, options) {
11143
11293
  const stages = [];
11144
- const metadata = await sharp2(inputBuffer).metadata();
11294
+ const metadata = await sharp3(inputBuffer).metadata();
11145
11295
  let alreadyTransparent = false;
11146
11296
  if (metadata.hasAlpha) {
11147
- const { data: alphaData } = await sharp2(inputBuffer).raw().toBuffer({ resolveWithObject: true });
11297
+ const { data: alphaData } = await sharp3(inputBuffer).raw().toBuffer({ resolveWithObject: true });
11148
11298
  alreadyTransparent = hasTransparency(alphaData, 0.05);
11149
11299
  }
11150
- let { data: processedData, info } = await sharp2(inputBuffer).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
11300
+ let { data: processedData, info } = await sharp3(inputBuffer).ensureAlpha().raw().toBuffer({ resolveWithObject: true });
11151
11301
  if (options.color) {
11152
11302
  stages.push("recolor");
11153
11303
  processedData = applyQuantization(processedData, 8);
@@ -11218,7 +11368,7 @@ async function processInternal(inputBuffer, isSVG, options) {
11218
11368
  processedData = result.data;
11219
11369
  info = result.info;
11220
11370
  }
11221
- let pipeline = sharp2(processedData, {
11371
+ let pipeline = sharp3(processedData, {
11222
11372
  raw: { channels: 4, width: info.width, height: info.height }
11223
11373
  }).png();
11224
11374
  if (options.shrinkToContent) {
@@ -11231,12 +11381,12 @@ async function processInternal(inputBuffer, isSVG, options) {
11231
11381
  function applyResize(buffer, resize) {
11232
11382
  const transparent = { r: 0, g: 0, b: 0, alpha: 0 };
11233
11383
  if (resize.size) {
11234
- return sharp2(buffer).resize(resize.size.width, resize.size.height, {
11384
+ return sharp3(buffer).resize(resize.size.width, resize.size.height, {
11235
11385
  fit: resize.fit ?? "contain",
11236
11386
  background: transparent
11237
11387
  }).toBuffer();
11238
11388
  }
11239
- return sharp2(buffer).resize(resize.width ?? null, resize.height ?? null, { fit: "inside", withoutEnlargement: false }).toBuffer();
11389
+ return sharp3(buffer).resize(resize.width ?? null, resize.height ?? null, { fit: "inside", withoutEnlargement: false }).toBuffer();
11240
11390
  }
11241
11391
  async function processImage(inputBuffer, options = {}) {
11242
11392
  const stages = [];
@@ -11245,7 +11395,7 @@ async function processImage(inputBuffer, options = {}) {
11245
11395
  if (options.resize) {
11246
11396
  stages.push("resize");
11247
11397
  const resized = await applyResize(inputBuffer, options.resize);
11248
- const meta3 = await sharp2(resized).metadata();
11398
+ const meta3 = await sharp3(resized).metadata();
11249
11399
  return {
11250
11400
  buffer: resized,
11251
11401
  format: "png",
@@ -11254,7 +11404,7 @@ async function processImage(inputBuffer, options = {}) {
11254
11404
  stages
11255
11405
  };
11256
11406
  }
11257
- const meta2 = await sharp2(inputBuffer).metadata();
11407
+ const meta2 = await sharp3(inputBuffer).metadata();
11258
11408
  return {
11259
11409
  buffer: inputBuffer,
11260
11410
  format: "svg",
@@ -11266,7 +11416,7 @@ async function processImage(inputBuffer, options = {}) {
11266
11416
  let workingBuffer = inputBuffer;
11267
11417
  if (isSVG) {
11268
11418
  stages.push("rasterize-svg");
11269
- workingBuffer = await sharp2(inputBuffer).png({ compressionLevel: 0, force: true, palette: false, quality: 100 }).toBuffer();
11419
+ workingBuffer = await sharp3(inputBuffer).png({ compressionLevel: 0, force: true, palette: false, quality: 100 }).toBuffer();
11270
11420
  }
11271
11421
  const pass = await processInternal(workingBuffer, isSVG, options);
11272
11422
  stages.push(...pass.stages);
@@ -11275,7 +11425,7 @@ async function processImage(inputBuffer, options = {}) {
11275
11425
  stages.push("resize");
11276
11426
  processed = await applyResize(processed, options.resize);
11277
11427
  }
11278
- const meta = await sharp2(processed).metadata();
11428
+ const meta = await sharp3(processed).metadata();
11279
11429
  return {
11280
11430
  buffer: processed,
11281
11431
  format: "png",
@@ -11481,7 +11631,7 @@ function coerceRawArgs(args) {
11481
11631
  "dry-run": bool(args["dry-run"])
11482
11632
  };
11483
11633
  }
11484
- var normalizeCommand = defineCommand99({
11634
+ var normalizeCommand = defineCommand100({
11485
11635
  meta: {
11486
11636
  name: "normalize",
11487
11637
  description: `Normalize logos / images: declarative recolor + bg removal + trim + resize. Operates on local files; writes in-place by default.
@@ -11535,8 +11685,68 @@ Examples:
11535
11685
  }
11536
11686
  });
11537
11687
 
11688
+ // src/commands/images/pinterest.ts
11689
+ import { defineCommand as defineCommand101 } from "citty";
11690
+ registerSchema({
11691
+ command: "images.pinterest",
11692
+ 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.",
11693
+ args: {
11694
+ query: { type: "string", description: "Search query", required: true },
11695
+ limit: { type: "number", description: "Max results (1-20, default 5)", required: false, default: 5 },
11696
+ "auto-ingest": {
11697
+ type: "number",
11698
+ description: "Auto-ingest top N and return Baker-owned URLs on ingested hits",
11699
+ required: false,
11700
+ default: 0
11701
+ },
11702
+ context: {
11703
+ type: "string",
11704
+ description: "Free-text hint applied to every auto-ingested hit (overrides the pin title)",
11705
+ required: false
11706
+ }
11707
+ }
11708
+ });
11709
+ var pinterestCommand = defineCommand101({
11710
+ meta: {
11711
+ name: "pinterest",
11712
+ 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'"
11713
+ },
11714
+ args: {
11715
+ query: { type: "positional", description: "Search query", required: false },
11716
+ limit: { type: "string", description: "Max results (1-20)", required: false },
11717
+ "auto-ingest": {
11718
+ type: "string",
11719
+ description: "Auto-ingest top N and return Baker-owned URLs on ingested hits",
11720
+ required: false
11721
+ },
11722
+ context: { type: "string", description: "Description context hint applied to auto-ingested hits", required: false }
11723
+ },
11724
+ run: async ({ args }) => {
11725
+ try {
11726
+ const query = args.query;
11727
+ if (!query) {
11728
+ writeJson({ ok: false, error: { code: "VALIDATION_ERROR", message: "Query is required" } });
11729
+ process.exit(1);
11730
+ }
11731
+ const body = { query };
11732
+ if (args.limit) body.limit = Number(args.limit);
11733
+ if (args["auto-ingest"]) body.autoIngest = Number(args["auto-ingest"]);
11734
+ if (args.context) body.descriptionContext = args.context;
11735
+ const data = await apiPost("/api/images/pinterest", body);
11736
+ writeJson({ ok: true, data });
11737
+ } catch (err) {
11738
+ if (err instanceof ApiError) {
11739
+ writeJson({ ok: false, error: { code: err.code, message: err.message } });
11740
+ process.exit(1);
11741
+ }
11742
+ writeJson({ ok: false, error: { code: "INTERNAL_ERROR", message: "Unexpected error" } });
11743
+ process.exit(1);
11744
+ }
11745
+ }
11746
+ });
11747
+
11538
11748
  // src/commands/images/screenshot.ts
11539
- import { defineCommand as defineCommand100 } from "citty";
11749
+ import { defineCommand as defineCommand102 } from "citty";
11540
11750
  registerSchema({
11541
11751
  command: "images.screenshot",
11542
11752
  description: "Capture a website screenshot via ScreenshotOne. Auto-ingests on success.",
@@ -11552,7 +11762,7 @@ registerSchema({
11552
11762
  }
11553
11763
  }
11554
11764
  });
11555
- var screenshotCommand = defineCommand100({
11765
+ var screenshotCommand = defineCommand102({
11556
11766
  meta: {
11557
11767
  name: "screenshot",
11558
11768
  description: "Screenshot a URL via ScreenshotOne. $0.009/capture. Auto-ingests to library.\n\nExample: baker images screenshot https://stripe.com --full-page"
@@ -11602,7 +11812,7 @@ var screenshotCommand = defineCommand100({
11602
11812
  });
11603
11813
 
11604
11814
  // src/commands/images/search.ts
11605
- import { defineCommand as defineCommand101 } from "citty";
11815
+ import { defineCommand as defineCommand103 } from "citty";
11606
11816
  registerSchema({
11607
11817
  command: "images.search",
11608
11818
  description: "Search images by text query. Only returns ready images.",
@@ -11618,7 +11828,7 @@ registerSchema({
11618
11828
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
11619
11829
  }
11620
11830
  });
11621
- var searchCommand = defineCommand101({
11831
+ var searchCommand = defineCommand103({
11622
11832
  meta: {
11623
11833
  name: "search",
11624
11834
  description: "Semantic search images by text query. Uses hybrid BM25 + vector + reranking. Example: baker images search 'hero banner' --aspect-ratio 16:9 --tags logo"
@@ -11678,7 +11888,7 @@ var searchCommand = defineCommand101({
11678
11888
  });
11679
11889
 
11680
11890
  // src/commands/images/sticker.ts
11681
- import { defineCommand as defineCommand102 } from "citty";
11891
+ import { defineCommand as defineCommand104 } from "citty";
11682
11892
  registerSchema({
11683
11893
  command: "images.sticker",
11684
11894
  description: "Search Giphy stickers \u2014 transparent-background overlays for ad creative.",
@@ -11710,7 +11920,7 @@ registerSchema({
11710
11920
  }
11711
11921
  }
11712
11922
  });
11713
- var stickerCommand = defineCommand102({
11923
+ var stickerCommand = defineCommand104({
11714
11924
  meta: {
11715
11925
  name: "sticker",
11716
11926
  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"
@@ -11757,7 +11967,7 @@ var stickerCommand = defineCommand102({
11757
11967
  });
11758
11968
 
11759
11969
  // src/commands/images/stock.ts
11760
- import { defineCommand as defineCommand103 } from "citty";
11970
+ import { defineCommand as defineCommand105 } from "citty";
11761
11971
  registerSchema({
11762
11972
  command: "images.stock",
11763
11973
  description: "Stock photo, vector illustration, icon-set, and PSD search via Magnific (Freepik's developer API).",
@@ -11815,7 +12025,7 @@ registerSchema({
11815
12025
  }
11816
12026
  }
11817
12027
  });
11818
- var stockCommand = defineCommand103({
12028
+ var stockCommand = defineCommand105({
11819
12029
  meta: {
11820
12030
  name: "stock",
11821
12031
  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"
@@ -11871,9 +12081,9 @@ var stockCommand = defineCommand103({
11871
12081
  });
11872
12082
 
11873
12083
  // src/commands/images/upload.ts
11874
- import { readFile as readFile7 } from "fs/promises";
12084
+ import { readFile as readFile8 } from "fs/promises";
11875
12085
  import { extname as extname2 } from "path";
11876
- import { defineCommand as defineCommand104 } from "citty";
12086
+ import { defineCommand as defineCommand106 } from "citty";
11877
12087
  var MIME_MAP = {
11878
12088
  ".png": "image/png",
11879
12089
  ".jpg": "image/jpeg",
@@ -11928,7 +12138,7 @@ function detectContentType(filePath) {
11928
12138
  }
11929
12139
  return mime;
11930
12140
  }
11931
- var uploadCommand = defineCommand104({
12141
+ var uploadCommand = defineCommand106({
11932
12142
  meta: {
11933
12143
  name: "upload",
11934
12144
  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'"
@@ -12011,7 +12221,7 @@ async function uploadLocal(target, args) {
12011
12221
  });
12012
12222
  return;
12013
12223
  }
12014
- const fileBuffer = await readFile7(target);
12224
+ const fileBuffer = await readFile8(target);
12015
12225
  const base64 = fileBuffer.toString("base64");
12016
12226
  const body = { base64, contentType };
12017
12227
  if (args.source) body.source = args.source;
@@ -12021,7 +12231,7 @@ async function uploadLocal(target, args) {
12021
12231
  }
12022
12232
 
12023
12233
  // src/commands/images/upscale.ts
12024
- import { defineCommand as defineCommand105 } from "citty";
12234
+ import { defineCommand as defineCommand107 } from "citty";
12025
12235
  registerSchema({
12026
12236
  command: "images.upscale",
12027
12237
  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).",
@@ -12036,7 +12246,7 @@ registerSchema({
12036
12246
  }
12037
12247
  });
12038
12248
  var POLL_INTERVAL_MS3 = 1500;
12039
- var upscaleCommand = defineCommand105({
12249
+ var upscaleCommand = defineCommand107({
12040
12250
  meta: {
12041
12251
  name: "upscale",
12042
12252
  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"
@@ -12091,7 +12301,7 @@ var upscaleCommand = defineCommand105({
12091
12301
  });
12092
12302
 
12093
12303
  // src/commands/images/use.ts
12094
- import { defineCommand as defineCommand106 } from "citty";
12304
+ import { defineCommand as defineCommand108 } from "citty";
12095
12305
  registerSchema({
12096
12306
  command: "images.use",
12097
12307
  description: "Ingest a URL and wait for the library record to be ready.",
@@ -12107,7 +12317,7 @@ registerSchema({
12107
12317
  }
12108
12318
  });
12109
12319
  var POLL_INTERVAL_MS4 = 1500;
12110
- var useCommand = defineCommand106({
12320
+ var useCommand = defineCommand108({
12111
12321
  meta: {
12112
12322
  name: "use",
12113
12323
  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"
@@ -12153,7 +12363,7 @@ var useCommand = defineCommand106({
12153
12363
  });
12154
12364
 
12155
12365
  // src/commands/images/index.ts
12156
- var imagesCommand = defineCommand107({
12366
+ var imagesCommand = defineCommand109({
12157
12367
  meta: {
12158
12368
  name: "images",
12159
12369
  description: `Find, source, and normalize images. Subcommands route by provider so cost + license are explicit.
@@ -12165,6 +12375,7 @@ Library + search:
12165
12375
  External providers:
12166
12376
  baker images stock <q> [--type photo|vector|psd] Magnific (Freepik's dev API) \u2014 photos, vectors, illustrations, PSDs
12167
12377
  baker images google <q> Google Images via the official Custom Search API
12378
+ baker images pinterest <q> Pinterest reference imagery via ScrapeCreators (photo-real mood boards)
12168
12379
  baker images logo <domain> Brand logo via Brandfetch CDN
12169
12380
  baker images icon <name> [--set \u2026] Iconify (200+ sets)
12170
12381
  baker images gif <q> [--trending] Giphy GIFs / reaction memes (paid-social creative)
@@ -12172,7 +12383,9 @@ External providers:
12172
12383
  baker images extract <url> Firecrawl page extract
12173
12384
  baker images screenshot <url> ScreenshotOne capture
12174
12385
 
12175
- Ingest + management:
12386
+ AI generation (run on the Convex backend, cost-tracked):
12387
+ baker images generate <prompt> [--model \u2026] [--aspect-ratio \u2026] [--reference url1,url2]
12388
+ Generate an image with AI (OpenRouter models) and ingest it
12176
12389
  baker images ingest <url> --source <enum> Save remote URL to library
12177
12390
  baker images use <url> Ingest and wait for ready
12178
12391
  baker images upload ./file Upload local file
@@ -12195,6 +12408,8 @@ Paid transforms (run on the Convex backend, cost-tracked):
12195
12408
  find: findCommand,
12196
12409
  stock: stockCommand,
12197
12410
  google: googleCommand2,
12411
+ pinterest: pinterestCommand,
12412
+ generate: generateCommand,
12198
12413
  logo: logoCommand,
12199
12414
  icon: iconCommand,
12200
12415
  gif: gifCommand,
@@ -12214,10 +12429,10 @@ Paid transforms (run on the Convex backend, cost-tracked):
12214
12429
  });
12215
12430
 
12216
12431
  // src/commands/research/index.ts
12217
- import { defineCommand as defineCommand118 } from "citty";
12432
+ import { defineCommand as defineCommand120 } from "citty";
12218
12433
 
12219
12434
  // src/commands/research/advertisers.ts
12220
- import { defineCommand as defineCommand108 } from "citty";
12435
+ import { defineCommand as defineCommand110 } from "citty";
12221
12436
 
12222
12437
  // src/commands/research/output.ts
12223
12438
  var RESEARCH_DATA_NOTE = "Estimates based on third-party SERP data \u2014 not exact figures. Use for directional insights, not precise measurement.";
@@ -12330,7 +12545,7 @@ var FIELDS3 = {
12330
12545
  etv: "Estimated traffic value (USD)",
12331
12546
  visibility: "SERP visibility score (0-1)"
12332
12547
  };
12333
- var advertisersCommand = defineCommand108({
12548
+ var advertisersCommand = defineCommand110({
12334
12549
  meta: {
12335
12550
  name: "advertisers",
12336
12551
  description: `Find domains competing for a keyword in Google SERPs.
@@ -12377,7 +12592,7 @@ Examples:
12377
12592
  });
12378
12593
 
12379
12594
  // src/commands/research/autocomplete.ts
12380
- import { defineCommand as defineCommand109 } from "citty";
12595
+ import { defineCommand as defineCommand111 } from "citty";
12381
12596
  registerSchema({
12382
12597
  command: "research.autocomplete",
12383
12598
  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).",
@@ -12400,7 +12615,7 @@ registerSchema({
12400
12615
  var FIELDS4 = {
12401
12616
  suggestion: "Autocomplete suggestion from Google"
12402
12617
  };
12403
- var autocompleteCommand = defineCommand109({
12618
+ var autocompleteCommand = defineCommand111({
12404
12619
  meta: {
12405
12620
  name: "autocomplete",
12406
12621
  description: `Get Google Autocomplete suggestions for keyword expansion.
@@ -12446,7 +12661,7 @@ Examples:
12446
12661
  });
12447
12662
 
12448
12663
  // src/commands/research/countries.ts
12449
- import { defineCommand as defineCommand110 } from "citty";
12664
+ import { defineCommand as defineCommand112 } from "citty";
12450
12665
  registerSchema({
12451
12666
  command: "research.countries",
12452
12667
  description: "List all supported country codes for --location flag in research commands.",
@@ -12503,7 +12718,7 @@ var FIELDS5 = {
12503
12718
  code: "Country code to pass as --location",
12504
12719
  name: "Country name"
12505
12720
  };
12506
- var countriesCommand = defineCommand110({
12721
+ var countriesCommand = defineCommand112({
12507
12722
  meta: {
12508
12723
  name: "countries",
12509
12724
  description: "List all supported country codes for --location flag."
@@ -12514,7 +12729,7 @@ var countriesCommand = defineCommand110({
12514
12729
  });
12515
12730
 
12516
12731
  // src/commands/research/intent.ts
12517
- import { defineCommand as defineCommand111 } from "citty";
12732
+ import { defineCommand as defineCommand113 } from "citty";
12518
12733
  registerSchema({
12519
12734
  command: "research.intent",
12520
12735
  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.",
@@ -12537,7 +12752,7 @@ var FIELDS6 = {
12537
12752
  intent: "Primary Google Search intent: informational, navigational, commercial, transactional",
12538
12753
  probability: "Confidence score 0.0-1.0"
12539
12754
  };
12540
- var intentCommand = defineCommand111({
12755
+ var intentCommand = defineCommand113({
12541
12756
  meta: {
12542
12757
  name: "intent",
12543
12758
  description: `Classify Google Search intent for keywords. Returns intent type and confidence.
@@ -12585,7 +12800,7 @@ Examples:
12585
12800
  });
12586
12801
 
12587
12802
  // src/commands/research/keyword-gap.ts
12588
- import { defineCommand as defineCommand112 } from "citty";
12803
+ import { defineCommand as defineCommand114 } from "citty";
12589
12804
  registerSchema({
12590
12805
  command: "research.keyword-gap",
12591
12806
  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.",
@@ -12614,7 +12829,7 @@ var FIELDS7 = {
12614
12829
  cpc: "Cost per click USD",
12615
12830
  their_position: "Competitor's ranking position"
12616
12831
  };
12617
- var keywordGapCommand = defineCommand112({
12832
+ var keywordGapCommand = defineCommand114({
12618
12833
  meta: {
12619
12834
  name: "keyword-gap",
12620
12835
  description: `Find keywords a competitor has that you don't. Supports pagination via --offset.
@@ -12688,7 +12903,7 @@ Examples:
12688
12903
  });
12689
12904
 
12690
12905
  // src/commands/research/keywords-for-site.ts
12691
- import { defineCommand as defineCommand113 } from "citty";
12906
+ import { defineCommand as defineCommand115 } from "citty";
12692
12907
  registerSchema({
12693
12908
  command: "research.keywords-for-site",
12694
12909
  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.",
@@ -12721,7 +12936,7 @@ var FIELDS8 = {
12721
12936
  competition: "LOW, MEDIUM, or HIGH",
12722
12937
  competition_index: "Competition score 0-100"
12723
12938
  };
12724
- var keywordsForSiteCommand = defineCommand113({
12939
+ var keywordsForSiteCommand = defineCommand115({
12725
12940
  meta: {
12726
12941
  name: "keywords-for-site",
12727
12942
  description: `Get keywords a competitor targets in Google. Use --type to filter paid/organic.
@@ -12774,7 +12989,7 @@ Examples:
12774
12989
  });
12775
12990
 
12776
12991
  // src/commands/research/languages.ts
12777
- import { defineCommand as defineCommand114 } from "citty";
12992
+ import { defineCommand as defineCommand116 } from "citty";
12778
12993
  registerSchema({
12779
12994
  command: "research.languages",
12780
12995
  description: "List all supported language codes for --language flag in research commands.",
@@ -12804,7 +13019,7 @@ var FIELDS9 = {
12804
13019
  code: "Language code to pass as --language",
12805
13020
  name: "Language name (also accepted by --language)"
12806
13021
  };
12807
- var languagesCommand2 = defineCommand114({
13022
+ var languagesCommand2 = defineCommand116({
12808
13023
  meta: {
12809
13024
  name: "languages",
12810
13025
  description: "List all supported language codes for --language flag."
@@ -12815,7 +13030,7 @@ var languagesCommand2 = defineCommand114({
12815
13030
  });
12816
13031
 
12817
13032
  // src/commands/research/lighthouse.ts
12818
- import { defineCommand as defineCommand115 } from "citty";
13033
+ import { defineCommand as defineCommand117 } from "citty";
12819
13034
  registerSchema({
12820
13035
  command: "research.lighthouse",
12821
13036
  description: "Landing page performance audit. Returns metrics that affect Google Ads Quality Score and CPC.",
@@ -12834,7 +13049,7 @@ var FIELDS10 = {
12834
13049
  speed_index_ms: "Speed Index in ms (good: < 3400)",
12835
13050
  interactive_ms: "Time to Interactive in ms (good: < 3800)"
12836
13051
  };
12837
- var lighthouseCommand = defineCommand115({
13052
+ var lighthouseCommand = defineCommand117({
12838
13053
  meta: {
12839
13054
  name: "lighthouse",
12840
13055
  description: `Landing page performance audit. Metrics affecting Google Ads Quality Score.
@@ -12872,7 +13087,7 @@ Examples:
12872
13087
  });
12873
13088
 
12874
13089
  // src/commands/research/relevant-pages.ts
12875
- import { defineCommand as defineCommand116 } from "citty";
13090
+ import { defineCommand as defineCommand118 } from "citty";
12876
13091
  registerSchema({
12877
13092
  command: "research.relevant-pages",
12878
13093
  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).",
@@ -12898,7 +13113,7 @@ var FIELDS11 = {
12898
13113
  keywords: "Total organic keywords the page ranks for",
12899
13114
  top_10: "Keywords in positions 1-10"
12900
13115
  };
12901
- var relevantPagesCommand = defineCommand116({
13116
+ var relevantPagesCommand = defineCommand118({
12902
13117
  meta: {
12903
13118
  name: "relevant-pages",
12904
13119
  description: `Get the top pages of a competitor domain with traffic data.
@@ -12944,7 +13159,7 @@ Examples:
12944
13159
  });
12945
13160
 
12946
13161
  // src/commands/research/web.ts
12947
- import { defineCommand as defineCommand117 } from "citty";
13162
+ import { defineCommand as defineCommand119 } from "citty";
12948
13163
  registerSchema({
12949
13164
  command: "research.web",
12950
13165
  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).",
@@ -12995,7 +13210,7 @@ async function runDeepResearch(question) {
12995
13210
  }
12996
13211
  throw new Error("Deep research timed out");
12997
13212
  }
12998
- var webCommand = defineCommand117({
13213
+ var webCommand = defineCommand119({
12999
13214
  meta: {
13000
13215
  name: "web",
13001
13216
  description: `Search the web with AI to answer any open-ended marketing question. Uses live internet data via Google Search.
@@ -13055,7 +13270,7 @@ Examples:
13055
13270
  });
13056
13271
 
13057
13272
  // src/commands/research/index.ts
13058
- var researchCommand = defineCommand118({
13273
+ var researchCommand = defineCommand120({
13059
13274
  meta: {
13060
13275
  name: "research",
13061
13276
  description: `Competitive intelligence and AI-powered research commands.
@@ -13095,10 +13310,10 @@ Examples:
13095
13310
  });
13096
13311
 
13097
13312
  // src/commands/scheduled-actions/index.ts
13098
- import { defineCommand as defineCommand125 } from "citty";
13313
+ import { defineCommand as defineCommand127 } from "citty";
13099
13314
 
13100
13315
  // src/commands/scheduled-actions/create.ts
13101
- import { defineCommand as defineCommand119 } from "citty";
13316
+ import { defineCommand as defineCommand121 } from "citty";
13102
13317
 
13103
13318
  // src/commands/scheduled-actions/shared.ts
13104
13319
  var TEMP_SCHEDULED_ACTION_PREFIX = "temp_sched_";
@@ -13203,7 +13418,7 @@ registerSchema({
13203
13418
  prompt: { type: "string", description: "Additional prompt instructions for the spawned agent", required: false }
13204
13419
  }
13205
13420
  });
13206
- var createCommand2 = defineCommand119({
13421
+ var createCommand2 = defineCommand121({
13207
13422
  meta: {
13208
13423
  name: "create",
13209
13424
  description: 'Stage a scheduled action. Example: baker scheduled-actions create --name "Weekly report" --description "..." --cron "0 9 * * MON"'
@@ -13251,7 +13466,7 @@ var createCommand2 = defineCommand119({
13251
13466
  });
13252
13467
 
13253
13468
  // src/commands/scheduled-actions/delete.ts
13254
- import { defineCommand as defineCommand120 } from "citty";
13469
+ import { defineCommand as defineCommand122 } from "citty";
13255
13470
  registerSchema({
13256
13471
  command: "scheduled-actions.delete",
13257
13472
  description: "Stage deletion of a published scheduled action or cancellation of a temp_sched_* draft creation.",
@@ -13259,7 +13474,7 @@ registerSchema({
13259
13474
  id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
13260
13475
  }
13261
13476
  });
13262
- var deleteCommand2 = defineCommand120({
13477
+ var deleteCommand2 = defineCommand122({
13263
13478
  meta: {
13264
13479
  name: "delete",
13265
13480
  description: "Stage scheduled action deletion. Example: baker scheduled-actions delete <id-or-temp_sched_id>"
@@ -13288,7 +13503,7 @@ var deleteCommand2 = defineCommand120({
13288
13503
  });
13289
13504
 
13290
13505
  // src/commands/scheduled-actions/get.ts
13291
- import { defineCommand as defineCommand121 } from "citty";
13506
+ import { defineCommand as defineCommand123 } from "citty";
13292
13507
  registerSchema({
13293
13508
  command: "scheduled-actions.get",
13294
13509
  description: "Get a published scheduled action or a temp_sched_* draft-created scheduled action.",
@@ -13296,7 +13511,7 @@ registerSchema({
13296
13511
  id: { type: "string", description: "Published scheduled action ID or temp_sched_* draft ID", required: true }
13297
13512
  }
13298
13513
  });
13299
- var getCommand3 = defineCommand121({
13514
+ var getCommand3 = defineCommand123({
13300
13515
  meta: {
13301
13516
  name: "get",
13302
13517
  description: "Get a scheduled action. Example: baker scheduled-actions get <id-or-temp_sched_id>"
@@ -13333,13 +13548,13 @@ var getCommand3 = defineCommand121({
13333
13548
  });
13334
13549
 
13335
13550
  // src/commands/scheduled-actions/list.ts
13336
- import { defineCommand as defineCommand122 } from "citty";
13551
+ import { defineCommand as defineCommand124 } from "citty";
13337
13552
  registerSchema({
13338
13553
  command: "scheduled-actions.list",
13339
13554
  description: "List published scheduled actions. Includes draft state when BAKER_CHAT_ID is set.",
13340
13555
  args: {}
13341
13556
  });
13342
- var listCommand2 = defineCommand122({
13557
+ var listCommand2 = defineCommand124({
13343
13558
  meta: {
13344
13559
  name: "list",
13345
13560
  description: "List scheduled actions. Includes staged draft ops when BAKER_CHAT_ID is set."
@@ -13360,7 +13575,7 @@ var listCommand2 = defineCommand122({
13360
13575
  });
13361
13576
 
13362
13577
  // src/commands/scheduled-actions/trigger.ts
13363
- import { defineCommand as defineCommand123 } from "citty";
13578
+ import { defineCommand as defineCommand125 } from "citty";
13364
13579
  registerSchema({
13365
13580
  command: "scheduled-actions.trigger",
13366
13581
  description: "Immediately trigger a published scheduled action. Does not require BAKER_CHAT_ID and rejects temp_sched_* IDs.",
@@ -13368,7 +13583,7 @@ registerSchema({
13368
13583
  id: { type: "string", description: "Published scheduled action ID", required: true }
13369
13584
  }
13370
13585
  });
13371
- var triggerCommand = defineCommand123({
13586
+ var triggerCommand = defineCommand125({
13372
13587
  meta: {
13373
13588
  name: "trigger",
13374
13589
  description: "Immediately trigger a published scheduled action. Example: baker scheduled-actions trigger <id>"
@@ -13405,7 +13620,7 @@ var triggerCommand = defineCommand123({
13405
13620
  });
13406
13621
 
13407
13622
  // src/commands/scheduled-actions/update.ts
13408
- import { defineCommand as defineCommand124 } from "citty";
13623
+ import { defineCommand as defineCommand126 } from "citty";
13409
13624
  registerSchema({
13410
13625
  command: "scheduled-actions.update",
13411
13626
  description: "Stage an update to a published scheduled action or temp_sched_* draft-created scheduled action.",
@@ -13430,7 +13645,7 @@ registerSchema({
13430
13645
  prompt: { type: "string", description: "Replacement additional spawned-agent instructions", required: false }
13431
13646
  }
13432
13647
  });
13433
- var updateCommand2 = defineCommand124({
13648
+ var updateCommand2 = defineCommand126({
13434
13649
  meta: {
13435
13650
  name: "update",
13436
13651
  description: "Stage a scheduled action update. Example: baker scheduled-actions update <id> --enabled false"
@@ -13500,7 +13715,7 @@ var updateCommand2 = defineCommand124({
13500
13715
  });
13501
13716
 
13502
13717
  // src/commands/scheduled-actions/index.ts
13503
- var scheduledActionsCommand = defineCommand125({
13718
+ var scheduledActionsCommand = defineCommand127({
13504
13719
  meta: {
13505
13720
  name: "scheduled-actions",
13506
13721
  description: `Manage Scheduled Actions. Subcommands: list, get, create, update, delete, trigger.
@@ -13526,8 +13741,8 @@ Examples:
13526
13741
  });
13527
13742
 
13528
13743
  // src/commands/schema.ts
13529
- import { defineCommand as defineCommand126 } from "citty";
13530
- var schemaCommand = defineCommand126({
13744
+ import { defineCommand as defineCommand128 } from "citty";
13745
+ var schemaCommand = defineCommand128({
13531
13746
  meta: {
13532
13747
  name: "schema",
13533
13748
  description: "Inspect command argument schemas (for AI agent introspection). Lists all commands if no argument given. Example: baker schema images.search"
@@ -13563,10 +13778,10 @@ var schemaCommand = defineCommand126({
13563
13778
  });
13564
13779
 
13565
13780
  // src/commands/testimonials/index.ts
13566
- import { defineCommand as defineCommand130 } from "citty";
13781
+ import { defineCommand as defineCommand132 } from "citty";
13567
13782
 
13568
13783
  // src/commands/testimonials/get.ts
13569
- import { defineCommand as defineCommand127 } from "citty";
13784
+ import { defineCommand as defineCommand129 } from "citty";
13570
13785
  registerSchema({
13571
13786
  command: "testimonials.get",
13572
13787
  description: "Get a single testimonial by ID",
@@ -13574,7 +13789,7 @@ registerSchema({
13574
13789
  id: { type: "string", description: "Testimonial ID", required: true }
13575
13790
  }
13576
13791
  });
13577
- var getCommand4 = defineCommand127({
13792
+ var getCommand4 = defineCommand129({
13578
13793
  meta: { name: "get", description: "Get a single testimonial by ID. Example: baker testimonials get j571abc123" },
13579
13794
  args: {
13580
13795
  id: { type: "positional", description: "Testimonial ID", required: false },
@@ -13611,7 +13826,7 @@ var getCommand4 = defineCommand127({
13611
13826
  });
13612
13827
 
13613
13828
  // src/commands/testimonials/list.ts
13614
- import { defineCommand as defineCommand128 } from "citty";
13829
+ import { defineCommand as defineCommand130 } from "citty";
13615
13830
  registerSchema({
13616
13831
  command: "testimonials.list",
13617
13832
  description: "List testimonials with optional filters.",
@@ -13641,7 +13856,7 @@ registerSchema({
13641
13856
  limit: { type: "number", description: "Max results (default 50)", required: false, default: 50 }
13642
13857
  }
13643
13858
  });
13644
- var listCommand3 = defineCommand128({
13859
+ var listCommand3 = defineCommand130({
13645
13860
  meta: {
13646
13861
  name: "list",
13647
13862
  description: "List testimonials with optional filters. Example: baker testimonials list --source google --sentiment positive"
@@ -13690,7 +13905,7 @@ var listCommand3 = defineCommand128({
13690
13905
  });
13691
13906
 
13692
13907
  // src/commands/testimonials/search.ts
13693
- import { defineCommand as defineCommand129 } from "citty";
13908
+ import { defineCommand as defineCommand131 } from "citty";
13694
13909
  registerSchema({
13695
13910
  command: "testimonials.search",
13696
13911
  description: "Search testimonials by text query. Uses hybrid BM25 + vector + reranking.",
@@ -13721,7 +13936,7 @@ registerSchema({
13721
13936
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
13722
13937
  }
13723
13938
  });
13724
- var searchCommand2 = defineCommand129({
13939
+ var searchCommand2 = defineCommand131({
13725
13940
  meta: {
13726
13941
  name: "search",
13727
13942
  description: "Semantic search testimonials by text query. Uses hybrid BM25 + vector + reranking. Example: baker testimonials search 'great service' --rating-min 4"
@@ -13792,7 +14007,7 @@ var searchCommand2 = defineCommand129({
13792
14007
  });
13793
14008
 
13794
14009
  // src/commands/testimonials/index.ts
13795
- var testimonialsCommand = defineCommand130({
14010
+ var testimonialsCommand = defineCommand132({
13796
14011
  meta: {
13797
14012
  name: "testimonials",
13798
14013
  description: `Find and browse testimonials in Baker. Subcommands: search, get, list.
@@ -13811,10 +14026,10 @@ Examples:
13811
14026
  });
13812
14027
 
13813
14028
  // src/commands/videos/index.ts
13814
- import { defineCommand as defineCommand135 } from "citty";
14029
+ import { defineCommand as defineCommand137 } from "citty";
13815
14030
 
13816
14031
  // src/commands/videos/delete.ts
13817
- import { defineCommand as defineCommand131 } from "citty";
14032
+ import { defineCommand as defineCommand133 } from "citty";
13818
14033
  registerSchema({
13819
14034
  command: "videos.delete",
13820
14035
  description: "Delete a video by ID",
@@ -13828,7 +14043,7 @@ registerSchema({
13828
14043
  }
13829
14044
  }
13830
14045
  });
13831
- var deleteCommand3 = defineCommand131({
14046
+ var deleteCommand3 = defineCommand133({
13832
14047
  meta: {
13833
14048
  name: "delete",
13834
14049
  description: "Delete a video by ID. Use --dry-run to preview. Example: baker videos delete j571abc123 --dry-run"
@@ -13869,7 +14084,7 @@ var deleteCommand3 = defineCommand131({
13869
14084
  });
13870
14085
 
13871
14086
  // src/commands/videos/get.ts
13872
- import { defineCommand as defineCommand132 } from "citty";
14087
+ import { defineCommand as defineCommand134 } from "citty";
13873
14088
  registerSchema({
13874
14089
  command: "videos.get",
13875
14090
  description: "Get a single video by ID",
@@ -13877,7 +14092,7 @@ registerSchema({
13877
14092
  id: { type: "string", description: "Video ID", required: true }
13878
14093
  }
13879
14094
  });
13880
- var getCommand5 = defineCommand132({
14095
+ var getCommand5 = defineCommand134({
13881
14096
  meta: { name: "get", description: "Get a single video by ID. Example: baker videos get j571abc123" },
13882
14097
  args: {
13883
14098
  id: { type: "positional", description: "Video ID", required: false },
@@ -13914,7 +14129,7 @@ var getCommand5 = defineCommand132({
13914
14129
  });
13915
14130
 
13916
14131
  // src/commands/videos/search.ts
13917
- import { defineCommand as defineCommand133 } from "citty";
14132
+ import { defineCommand as defineCommand135 } from "citty";
13918
14133
  registerSchema({
13919
14134
  command: "videos.search",
13920
14135
  description: "Search videos by text query. Only returns ready videos.",
@@ -13924,7 +14139,7 @@ registerSchema({
13924
14139
  tags: { type: "string", description: "Comma-separated tags to filter by", required: false }
13925
14140
  }
13926
14141
  });
13927
- var searchCommand3 = defineCommand133({
14142
+ var searchCommand3 = defineCommand135({
13928
14143
  meta: {
13929
14144
  name: "search",
13930
14145
  description: "Semantic search videos by text query. Uses hybrid BM25 + vector + reranking. Example: baker videos search 'product demo' --tags tutorial"
@@ -13971,9 +14186,9 @@ var searchCommand3 = defineCommand133({
13971
14186
  });
13972
14187
 
13973
14188
  // src/commands/videos/upload.ts
13974
- import { readFile as readFile8, stat as stat3 } from "fs/promises";
14189
+ import { readFile as readFile9, stat as stat3 } from "fs/promises";
13975
14190
  import { extname as extname3 } from "path";
13976
- import { defineCommand as defineCommand134 } from "citty";
14191
+ import { defineCommand as defineCommand136 } from "citty";
13977
14192
  var MIME_MAP2 = {
13978
14193
  ".mp4": "video/mp4",
13979
14194
  ".mov": "video/quicktime",
@@ -14007,7 +14222,7 @@ function detectContentType2(filePath) {
14007
14222
  }
14008
14223
  return mime;
14009
14224
  }
14010
- var uploadCommand2 = defineCommand134({
14225
+ var uploadCommand2 = defineCommand136({
14011
14226
  meta: {
14012
14227
  name: "upload",
14013
14228
  description: "Upload a video file to Baker via Mux direct upload. Auto-detects content type. Example: baker videos upload ./demo.mp4"
@@ -14036,7 +14251,7 @@ var uploadCommand2 = defineCommand134({
14036
14251
  return;
14037
14252
  }
14038
14253
  const { uploadUrl, videoId } = await apiPost("/api/videos/upload", {});
14039
- const fileBuffer = await readFile8(filePath);
14254
+ const fileBuffer = await readFile9(filePath);
14040
14255
  const uploadResponse = await fetch(uploadUrl, {
14041
14256
  method: "PUT",
14042
14257
  headers: { "Content-Type": contentType },
@@ -14061,7 +14276,7 @@ var uploadCommand2 = defineCommand134({
14061
14276
  });
14062
14277
 
14063
14278
  // src/commands/videos/index.ts
14064
- var videosCommand = defineCommand135({
14279
+ var videosCommand = defineCommand137({
14065
14280
  meta: {
14066
14281
  name: "videos",
14067
14282
  description: `Find and manage videos in Baker. Subcommands: search, get, upload, delete.
@@ -14098,7 +14313,7 @@ function getCliVersion() {
14098
14313
  }
14099
14314
 
14100
14315
  // src/cli.ts
14101
- var main = defineCommand136({
14316
+ var main = defineCommand138({
14102
14317
  meta: {
14103
14318
  name: "baker",
14104
14319
  version: getCliVersion(),