@koda-sl/baker-cli 0.444.0-dev.cac1750ec → 0.447.0-dev.397af7869

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
@@ -45,6 +45,7 @@ import {
45
45
  SEEDANCE_DURATIONS,
46
46
  SEEDANCE_PROFILE,
47
47
  SOUND_EFFECT_MODEL,
48
+ SPEC_SHAPES_HINT,
48
49
  SPOKEN_CLIP_DURATION_S,
49
50
  SPOKEN_WORDS_PER_SECOND,
50
51
  STATIC_ADAPT_FORMAT_ROLE,
@@ -69,6 +70,7 @@ import {
69
70
  ValidationError,
70
71
  VideoBlueprintSchema,
71
72
  YtDlpError,
73
+ adSpecErrorText,
72
74
  adSpecFromBlueprint,
73
75
  adSpecJsonSchema,
74
76
  adaptBrief,
@@ -171,6 +173,7 @@ import {
171
173
  samePictureSizes,
172
174
  sanitizeId,
173
175
  sceneWindowsBeside,
176
+ sceneWordProblems,
174
177
  sha256Hex,
175
178
  shapeListRows,
176
179
  specimenText,
@@ -198,7 +201,7 @@ import {
198
201
  withoutCastName,
199
202
  wordCount,
200
203
  ytDlpBlockSignal
201
- } from "./chunk-GY352NRN.js";
204
+ } from "./chunk-WMAHVZMY.js";
202
205
  import {
203
206
  NAME_CONTAINS_ARG,
204
207
  csvOrJson,
@@ -71038,7 +71041,7 @@ function toPosix(p) {
71038
71041
  }
71039
71042
 
71040
71043
  // src/commands/creatives/ideas-model.ts
71041
- import { parse as parseYaml2 } from "yaml";
71044
+ import { parse as parseYaml2, YAMLParseError } from "yaml";
71042
71045
  var IDEA_ANGLES = [
71043
71046
  "pain_relief",
71044
71047
  "aspiration",
@@ -71087,6 +71090,18 @@ function frontmatterOf(markdown) {
71087
71090
  return null;
71088
71091
  }
71089
71092
  }
71093
+ function frontmatterError(markdown) {
71094
+ const block2 = FRONTMATTER.exec(markdown)?.[1];
71095
+ if (block2 === void 0) return null;
71096
+ try {
71097
+ parseYaml2(block2);
71098
+ return null;
71099
+ } catch (e) {
71100
+ const line = e instanceof YAMLParseError ? e.linePos?.[0]?.line : void 0;
71101
+ const at = line ? ` at line ${line} (\`${block2.split(/\r?\n/)[line - 1]?.trim() ?? ""}\`)` : "";
71102
+ return `the frontmatter is not valid YAML${at}: put each text value wholly in double quotes, with any quote inside it as \\" or as single quotes`;
71103
+ }
71104
+ }
71090
71105
  function text2(value2) {
71091
71106
  if (typeof value2 === "string") return value2.trim() || void 0;
71092
71107
  if (typeof value2 === "number") return String(value2);
@@ -71141,6 +71156,8 @@ function fieldProblems(f) {
71141
71156
  return problems;
71142
71157
  }
71143
71158
  function parseIdea(id, markdown) {
71159
+ const unparsable = frontmatterError(markdown);
71160
+ if (unparsable) return { problems: [unparsable] };
71144
71161
  const fm = frontmatterOf(markdown) ?? {};
71145
71162
  const f = {
71146
71163
  who: text2(fm.who),
@@ -71714,6 +71731,14 @@ async function staticSpecGate(canvas, canvasDir) {
71714
71731
  fix: "Write the ad in prompt.json: the scene the viewer sees and each line of copy as it prints. Then re-run."
71715
71732
  };
71716
71733
  }
71734
+ const sceneWords = spec.native ? [] : sceneWordProblems(spec);
71735
+ if (sceneWords.length > 0) {
71736
+ return {
71737
+ code: "scene_words_not_in_copy",
71738
+ problems: sceneWords,
71739
+ fix: "Edit prompt.json: every word or figure the picture shows is a `copy` line (`in_scene`, with `on`); describe any other surface without words. Then re-run."
71740
+ };
71741
+ }
71717
71742
  const concept = conceptProblems(spec);
71718
71743
  if (concept.length > 0) {
71719
71744
  return {
@@ -71809,7 +71834,8 @@ async function prepareCanvas(canvasPath, opts = {}) {
71809
71834
  staticCopy = native === "not_applicable" ? await syncStaticAdBrief(canvas, log) : native;
71810
71835
  if (logo === "regenerated" || pictures === "regenerated") staticCopy = "regenerated";
71811
71836
  } catch (e) {
71812
- throw new CanvasPrepareError("style_projection", `prompt.json is not readable or not a valid ad: ${errorMessage(e)}`, {
71837
+ throw new CanvasPrepareError("style_projection", `prompt.json is not readable or not a valid ad:
71838
+ ${adSpecErrorText(e)}`, {
71813
71839
  fix: `Fix ${path14.join(canvasDir, "prompt.json")} so it parses as JSON (and, for a static ad, matches the ad spec the message names), then re-run.`
71814
71840
  });
71815
71841
  }
@@ -73579,15 +73605,17 @@ function correctionOf(finding, band) {
73579
73605
  if (misread2) return `Re-letter ${misread2[1]} exactly as written, letter for letter (it now reads ${misread2[2]}).`;
73580
73606
  const missing = what.match(MISSING);
73581
73607
  if (missing) return `Add the line ${missing[1]}, spelled exactly, where it belongs in the layout.`;
73608
+ if (SIZES_FINDING.test(what)) return FOLLOW_PICTURE;
73582
73609
  const described2 = what.replace(CATEGORY, "").replace(/\.$/, "");
73583
73610
  return `Fix this: ${described2.charAt(0).toLowerCase()}${described2.slice(1)}.`;
73584
73611
  }
73585
73612
  function autoFixStep(canvas, review, opts = {}) {
73586
73613
  if ((opts.round ?? 0) >= AUTO_FIX_ROUNDS) return null;
73587
- const blocking = (review ?? []).filter((f) => f.severity === "blocking");
73588
- if (blocking.length === 0) return null;
73589
- if (isNativeCanvas(canvas)) return { kind: "respec", findings: unique(blocking.map((f) => f.what)) };
73614
+ const flagged = (review ?? []).filter((f) => f.severity === "blocking");
73615
+ if (flagged.length === 0) return null;
73616
+ if (isNativeCanvas(canvas)) return { kind: "respec", findings: unique(flagged.map((f) => f.what)) };
73590
73617
  const relaid = relaidSizes(canvas);
73618
+ const blocking = onDerivedSizes(flagged, relaid);
73591
73619
  const unplaceable = new Set((opts.tooFar ?? []).filter((format) => relaid.some((r) => r.format === format)));
73592
73620
  const misplaced = (f) => {
73593
73621
  const what = withoutSize(f.what);
@@ -73631,8 +73659,8 @@ function autoFixStep(canvas, review, opts = {}) {
73631
73659
  pictureFindings.filter((f) => !BRIEF.test(withoutSize(f.what))).flatMap((f) => correctionOf(f.what) ?? [])
73632
73660
  );
73633
73661
  if (changes.length === 0) return sizesOnly();
73634
- const flagged = new Set(blocking.flatMap((f) => sizesOf(f.what)));
73635
- const keep = relaid.map((r) => r.format).filter((format) => !flagged.has(format));
73662
+ const named = new Set(blocking.flatMap((f) => sizesOf(f.what)));
73663
+ const keep = relaid.map((r) => r.format).filter((format) => !named.has(format));
73636
73664
  const remade = every.filter((size) => !keep.includes(size));
73637
73665
  const kept = {
73638
73666
  ...keep.length > 0 ? { keep } : {},
@@ -73645,6 +73673,17 @@ function autoFixStep(canvas, review, opts = {}) {
73645
73673
  return { kind: "fix", instruction, ...Object.keys(edits).length > 0 ? { relay: edits } : {}, ...kept };
73646
73674
  }
73647
73675
  var unique = (lines) => [...new Set(lines)];
73676
+ var SIZES_FINDING = /^SIZES:/i;
73677
+ var FOLLOW_PICTURE = "Show exactly what the finished ad (Image 2) shows: its people, products, panels and their order, and nothing it does not show.";
73678
+ function onDerivedSizes(findings, relaid) {
73679
+ if (relaid.length === 0) return [...findings];
73680
+ return findings.flatMap((f) => {
73681
+ const sizes = sizesOf(f.what);
73682
+ const onPicture = sizes.length > 0 && sizes.every((size) => !relaid.some((r) => r.format === size));
73683
+ if (!onPicture || !SIZES_FINDING.test(withoutSize(f.what))) return [f];
73684
+ return relaid.map((r) => ({ ...f, what: `${r.format}: ${withoutSize(f.what)}` }));
73685
+ });
73686
+ }
73648
73687
  function deliveredSizes(canvas) {
73649
73688
  const nodes = canvas?.nodes;
73650
73689
  const labels = Array.isArray(nodes) ? nodes.find((n) => n.id === "final" && n.type === "collect")?.params?.labels : void 0;
@@ -74322,7 +74361,8 @@ function viewerCheckFailure(outcome2, slug) {
74322
74361
  ...outcome2.verdict.missed.map(missLine),
74323
74362
  ...missing ? [`They needed: ${missing}`] : [],
74324
74363
  "Rewrite the copy in prompt.json so the words on the ad say it plainly (name the offer and who it is for; a stranger reads only what is printed), then re-run.",
74325
- `Check new copy before rendering with \`baker canvas viewer-check ${slug}\`.`,
74364
+ // The run asks the viewer itself, from the same cache: a separate check is one more wait (dev, Oct 2026).
74365
+ `Then run the same \`baker canvas run\` again: it checks the new copy before it spends (or \`baker canvas viewer-check ${slug}\` alone).`,
74326
74366
  "If this ad will run to people who already know the brand, record that viewer in _definition.md (`targetAdSet` and `viewer`, from `baker ads meta adsets --audience`) instead of rewriting."
74327
74367
  ].join(" ");
74328
74368
  return {
@@ -75252,7 +75292,7 @@ var runCommand = defineCommand139({
75252
75292
  },
75253
75293
  concurrency: {
75254
75294
  type: "string",
75255
- description: "Max nodes per layer in flight at once (default 8; env BAKER_CANVAS_CONCURRENCY)"
75295
+ description: "Max nodes running at once (default 8; env BAKER_CANVAS_CONCURRENCY)"
75256
75296
  },
75257
75297
  parallel: {
75258
75298
  type: "string",
@@ -76036,7 +76076,7 @@ var rerunCommand = defineCommand140({
76036
76076
  },
76037
76077
  fresh: { type: "boolean", default: false, description: "Start a new run id instead of resuming an interrupted one" },
76038
76078
  regenerate: { type: "string", description: "Comma-separated node ids to force fresh this run" },
76039
- concurrency: { type: "string", description: "Max nodes per layer in flight at once" }
76079
+ concurrency: { type: "string", description: "Max nodes running at once" }
76040
76080
  },
76041
76081
  async run({ args: args8 }) {
76042
76082
  process.stderr.write("[deprecated] `baker canvas rerun <slug>` is now `baker canvas run --slug <slug>`.\n");
@@ -81054,7 +81094,7 @@ function ideasHints(report) {
81054
81094
  if (next.length === 1) hints2.push(`Build: \`baker creatives make ${next[0]}\`.`);
81055
81095
  if (next.length > 1)
81056
81096
  hints2.push(
81057
- `Build ${next.join(", ")} at once: one \`creative-producer\` per idea, all spawned in one message in the background, each given its idea id, and handle each as it returns. Never build them one after another: each render takes minutes.`
81097
+ `Build ${next.join(", ")} at once: one \`creative-producer\` per idea, all spawned in one message in the background, each given its idea id, and handle each as it returns. Never build them one after another: each render takes minutes. Edited an idea after this check? Run \`baker creatives ideas\` again first: a producer cannot build an idea with a problem.`
81058
81098
  );
81059
81099
  return hints2;
81060
81100
  }
@@ -81927,7 +81967,7 @@ var learnCommand = defineCommand158({
81927
81967
 
81928
81968
  // src/commands/creatives/make.ts
81929
81969
  import { execFile as execFile3 } from "child_process";
81930
- import { mkdtemp as mkdtemp2, readFile as readFile38, rm as rm7, writeFile as writeFile24 } from "fs/promises";
81970
+ import { mkdtemp as mkdtemp2, readFile as readFile38, rm as rm7, stat as stat7, writeFile as writeFile24 } from "fs/promises";
81931
81971
  import { tmpdir as tmpdir3 } from "os";
81932
81972
  import path46 from "path";
81933
81973
  import { promisify as promisify3 } from "util";
@@ -82025,8 +82065,16 @@ async function findCandidates(searches, deps) {
82025
82065
  }
82026
82066
  return [];
82027
82067
  }
82028
- async function pickReference(root, searches, deps = liveReferenceDeps(root)) {
82068
+ var candidateOf = (c) => ({
82069
+ adId: String(c.ad_id),
82070
+ platform: asPlatform(c.platform),
82071
+ ...c.advertiser_id ? { advertiserId: c.advertiser_id } : {}
82072
+ });
82073
+ async function pickReference(root, searches, deps = liveReferenceDeps(root), prepare) {
82029
82074
  const candidates = (await findCandidates(searches, deps)).slice(0, FITS_TRIED);
82075
+ const first = candidates[0];
82076
+ const building = first && prepare ? prepare(candidateOf(first)) : void 0;
82077
+ void building?.catch(() => void 0);
82030
82078
  const fits = await Promise.all(candidates.map((c) => deps.fit(asPlatform(c.platform), String(c.ad_id))));
82031
82079
  let unchecked = null;
82032
82080
  let checked = 0;
@@ -82038,14 +82086,13 @@ async function pickReference(root, searches, deps = liveReferenceDeps(root)) {
82038
82086
  if (!(fit.ok && fitsIdea(fit.fit))) continue;
82039
82087
  const layers = fit.fit.why_it_wins;
82040
82088
  return {
82041
- adId: String(candidate.ad_id),
82042
- platform: asPlatform(candidate.platform),
82043
- ...candidate.advertiser_id ? { advertiserId: candidate.advertiser_id } : {},
82089
+ ...candidateOf(candidate),
82044
82090
  why: [layers.disguise, layers.trigger, layers.logic].filter(Boolean).join("; "),
82045
- tried: index + 1
82091
+ tried: index + 1,
82092
+ ...building ? index === 0 ? { prepared: building } : { discarded: building } : {}
82046
82093
  };
82047
82094
  }
82048
- return noReference(candidates.length, checked, unchecked);
82095
+ return { ...noReference(candidates.length, checked, unchecked), ...building ? { discarded: building } : {} };
82049
82096
  }
82050
82097
  function noReference(found, checked, unchecked) {
82051
82098
  if (found > 0 && checked === 0 && unchecked) {
@@ -82113,24 +82160,37 @@ async function scaffoldIdea(root, idea, args8, slug, temperature) {
82113
82160
  reference: null
82114
82161
  };
82115
82162
  }
82116
- const reference = args8.reference ? { adId: args8.reference, platform: asPlatform(args8.platform), why: "chosen by hand", tried: 0 } : args8.fromIdea ? { code: "FROM_IDEA", message: "Asked to start from the idea." } : await pickReference(root, referenceSearchesFor(idea, temperature).map(buildSearchBody));
82117
- if ("code" in reference) {
82118
- return { scaffold: await scaffoldFromIdea(idea, slug, viewerFlags), reference: null, fromIdea: reference.message };
82119
- }
82120
- const scaffold = await baker([
82163
+ const onReference = (c) => baker([
82121
82164
  "canvas",
82122
82165
  "scaffold-static-ad",
82123
82166
  "--source-ad-id",
82124
- reference.adId,
82167
+ c.adId,
82125
82168
  "--source-platform",
82126
- reference.platform,
82127
- ...reference.advertiserId ? ["--source-advertiser-id", reference.advertiserId] : [],
82169
+ c.platform,
82170
+ ...c.advertiserId ? ["--source-advertiser-id", c.advertiserId] : [],
82128
82171
  "--slug",
82129
82172
  slug,
82130
82173
  "--title",
82131
82174
  idea.message.slice(0, 120),
82132
82175
  ...viewerFlags
82133
82176
  ]);
82177
+ const dir = path46.join(root, "src", "creatives", slug);
82178
+ const fresh = !await stat7(dir).catch(() => null);
82179
+ const reference = args8.reference ? { adId: args8.reference, platform: asPlatform(args8.platform), why: "chosen by hand", tried: 0 } : args8.fromIdea ? { code: "FROM_IDEA", message: "Asked to start from the idea." } : await pickReference(
82180
+ root,
82181
+ referenceSearchesFor(idea, temperature).map(buildSearchBody),
82182
+ void 0,
82183
+ fresh ? onReference : void 0
82184
+ );
82185
+ if ("discarded" in reference && reference.discarded) {
82186
+ await reference.discarded.catch(() => void 0);
82187
+ await rm7(dir, { recursive: true, force: true });
82188
+ }
82189
+ if ("code" in reference) {
82190
+ return { scaffold: await scaffoldFromIdea(idea, slug, viewerFlags), reference: null, fromIdea: reference.message };
82191
+ }
82192
+ const prepared = "prepared" in reference ? await reference.prepared?.catch(() => null) : null;
82193
+ const scaffold = prepared?.ok === true ? prepared : await onReference(reference);
82134
82194
  return { scaffold, reference };
82135
82195
  }
82136
82196
  async function scaffoldFromIdea(idea, slug, viewerFlags) {
@@ -82227,6 +82287,7 @@ function makeEnvelope(made) {
82227
82287
  `Rewrite before running: ${made.unsourcedCopy.map((l) => JSON.stringify(l)).join(", ")} claim a figure nothing the company wrote holds (the reference's promise, not ours).`
82228
82288
  ] : [],
82229
82289
  `Write the copy lines and the scene in src/creatives/${made.slug}/prompt.json${made.reference ? ": the drafted lines are the reference's, so keep one only if the Knowledge says it (badges, ratings and guarantees too)" : ""}. Say the message in the customer's words${quote ? ` ("${quote.slice(0, 80)}")` : ""}; keep \`message\` as it is.`,
82290
+ SPEC_SHAPES_HINT,
82230
82291
  `Then: baker canvas run ${made.canvasPath} (it validates and asks the viewer itself: nothing to run before it).`,
82231
82292
  // The scaffold's own next steps name a separate validate; the run does it (dev, Oct 2026: five validates before one run).
82232
82293
  ...made.scaffoldHints.filter((h) => !/canvas (?:validate|viewer-check)/.test(h)).slice(0, 4)
@@ -84004,7 +84065,7 @@ import { readdir as readdir19, readFile as readFile42 } from "fs/promises";
84004
84065
  import path48 from "path";
84005
84066
 
84006
84067
  // src/commands/landing/import-graph.ts
84007
- import { readdir as readdir18, readFile as readFile41, stat as stat7 } from "fs/promises";
84068
+ import { readdir as readdir18, readFile as readFile41, stat as stat8 } from "fs/promises";
84008
84069
  import path47 from "path";
84009
84070
  var SOURCE_EXT = /\.(astro|ts|tsx|js|jsx|mjs|cjs|vue|svelte)$/;
84010
84071
  var RESOLVE_CANDIDATES = [
@@ -84024,7 +84085,7 @@ var IMPORT_RE = /(?<![A-Za-z0-9_$])(?:import|export)\s*(?:[\s\S]*?\bfrom\s*)?["'
84024
84085
  var DYNAMIC_IMPORT_RE = /\bimport\s*\(\s*["']([^"']+)["']\s*\)/g;
84025
84086
  async function isFile(p) {
84026
84087
  try {
84027
- return (await stat7(p)).isFile();
84088
+ return (await stat8(p)).isFile();
84028
84089
  } catch {
84029
84090
  return false;
84030
84091
  }
@@ -84156,7 +84217,7 @@ async function readForms(root, slug) {
84156
84217
 
84157
84218
  // src/commands/experiment/fold.ts
84158
84219
  import { statSync } from "fs";
84159
- import { cp as cp3, mkdir as mkdir15, readdir as readdir20, readFile as readFile43, rm as rm8, stat as stat8, writeFile as writeFile25 } from "fs/promises";
84220
+ import { cp as cp3, mkdir as mkdir15, readdir as readdir20, readFile as readFile43, rm as rm8, stat as stat9, writeFile as writeFile25 } from "fs/promises";
84160
84221
  import path50 from "path";
84161
84222
 
84162
84223
  // ../api/src/experiments/variants.ts
@@ -84223,7 +84284,7 @@ function posix2(p) {
84223
84284
  }
84224
84285
  async function isDir(p) {
84225
84286
  try {
84226
- return (await stat8(p)).isDirectory();
84287
+ return (await stat9(p)).isDirectory();
84227
84288
  } catch {
84228
84289
  return false;
84229
84290
  }
@@ -91625,7 +91686,7 @@ function cropSprite(input, region) {
91625
91686
 
91626
91687
  // src/lib/image/io.ts
91627
91688
  import { randomBytes } from "crypto";
91628
- import { glob as fsGlob, readFile as readFile46, rename as rename2, stat as stat9, writeFile as writeFile26 } from "fs/promises";
91689
+ import { glob as fsGlob, readFile as readFile46, rename as rename2, stat as stat10, writeFile as writeFile26 } from "fs/promises";
91629
91690
  import { dirname as dirname2, extname as extname3, join as join5, resolve as resolve4 } from "path";
91630
91691
  var REMOTE_RE = /^https?:\/\//i;
91631
91692
  var GLOB_RE = /[*?[\]{}]/;
@@ -91662,7 +91723,7 @@ async function readImageBuffer(pathOrUrl) {
91662
91723
  }
91663
91724
  async function isDirectory(path68) {
91664
91725
  try {
91665
- const s = await stat9(path68);
91726
+ const s = await stat10(path68);
91666
91727
  return s.isDirectory();
91667
91728
  } catch {
91668
91729
  return false;
@@ -95120,7 +95181,7 @@ Full guide: __tooling__/docs/tools/baker/images.md`
95120
95181
  import { defineCommand as defineCommand226 } from "citty";
95121
95182
 
95122
95183
  // src/commands/landing/critique.ts
95123
- import { readdir as readdir22, readFile as readFile48, stat as stat11 } from "fs/promises";
95184
+ import { readdir as readdir22, readFile as readFile48, stat as stat12 } from "fs/promises";
95124
95185
  import path55 from "path";
95125
95186
  import { defineCommand as defineCommand213 } from "citty";
95126
95187
 
@@ -96331,7 +96392,7 @@ async function writeCritiqueSnapshot(projectRoot, snapshot) {
96331
96392
  }
96332
96393
 
96333
96394
  // src/commands/landing/source-version.ts
96334
- import { readdir as readdir21, readFile as readFile47, stat as stat10 } from "fs/promises";
96395
+ import { readdir as readdir21, readFile as readFile47, stat as stat11 } from "fs/promises";
96335
96396
  import path54 from "path";
96336
96397
  var CRITIQUED_ROOTS = ["src/pages/", "src/components/"];
96337
96398
  async function landingSourceRelPaths(root, slug) {
@@ -96379,7 +96440,7 @@ async function computeLegacyLandingSourceSha(landingDir) {
96379
96440
  }
96380
96441
  async function isFile2(p) {
96381
96442
  try {
96382
- return (await stat10(p)).isFile();
96443
+ return (await stat11(p)).isFile();
96383
96444
  } catch {
96384
96445
  return false;
96385
96446
  }
@@ -96557,7 +96618,7 @@ function present(f) {
96557
96618
  }
96558
96619
  async function isDir2(p) {
96559
96620
  try {
96560
- return (await stat11(p)).isDirectory();
96621
+ return (await stat12(p)).isDirectory();
96561
96622
  } catch {
96562
96623
  return false;
96563
96624
  }
@@ -99875,7 +99936,7 @@ Full guide: __tooling__/docs/tools/baker/landing.md`
99875
99936
 
99876
99937
  // src/commands/landing/variant.ts
99877
99938
  import { randomUUID as randomUUID4 } from "crypto";
99878
- import { mkdir as mkdir20, readdir as readdir23, readFile as readFile49, stat as stat12, writeFile as writeFile32 } from "fs/promises";
99939
+ import { mkdir as mkdir20, readdir as readdir23, readFile as readFile49, stat as stat13, writeFile as writeFile32 } from "fs/promises";
99879
99940
  import path63 from "path";
99880
99941
  import { defineCommand as defineCommand225 } from "citty";
99881
99942
  registerSchema({
@@ -99927,14 +99988,14 @@ function fail11(code, message, fix) {
99927
99988
  }
99928
99989
  async function isDir3(p) {
99929
99990
  try {
99930
- return (await stat12(p)).isDirectory();
99991
+ return (await stat13(p)).isDirectory();
99931
99992
  } catch {
99932
99993
  return false;
99933
99994
  }
99934
99995
  }
99935
99996
  async function exists2(p) {
99936
99997
  try {
99937
- await stat12(p);
99998
+ await stat13(p);
99938
99999
  return true;
99939
100000
  } catch {
99940
100001
  return false;
@@ -108003,7 +108064,7 @@ var groupCommand2 = defineCommand295({
108003
108064
  });
108004
108065
 
108005
108066
  // src/commands/videos/ingest.ts
108006
- import { mkdtemp as mkdtemp4, rm as rm10, stat as stat13 } from "fs/promises";
108067
+ import { mkdtemp as mkdtemp4, rm as rm10, stat as stat14 } from "fs/promises";
108007
108068
  import { tmpdir as tmpdir5 } from "os";
108008
108069
  import path67 from "path";
108009
108070
  import { defineCommand as defineCommand296 } from "citty";
@@ -108276,7 +108337,7 @@ async function downloadThenIngest(args8, country) {
108276
108337
  // we allow to fetch it cannot drift apart.
108277
108338
  timeoutMs: downloadTimeoutMs(durationSeconds(probe.info))
108278
108339
  });
108279
- const stats = await stat13(filePath);
108340
+ const stats = await stat14(filePath);
108280
108341
  if (stats.size > MAX_VIDEO_INGEST_BYTES) {
108281
108342
  throw new ApiError(
108282
108343
  "VALIDATION_ERROR",
@@ -108437,7 +108498,7 @@ var searchCommand6 = defineCommand298({
108437
108498
  var tagsCommand6 = makeTagsCommand("videos", "video", "/api/videos/tags");
108438
108499
 
108439
108500
  // src/commands/videos/upload.ts
108440
- import { stat as stat14 } from "fs/promises";
108501
+ import { stat as stat15 } from "fs/promises";
108441
108502
  import { basename as basename4 } from "path";
108442
108503
  import { defineCommand as defineCommand299 } from "citty";
108443
108504
  registerSchema({
@@ -108505,7 +108566,7 @@ var uploadCommand2 = defineCommand299({
108505
108566
  const contentType = args8["content-type"] || detectVideoContentType(filePath);
108506
108567
  const descriptionContext = args8.context;
108507
108568
  if (args8["dry-run"]) {
108508
- const fileStats = await stat14(filePath);
108569
+ const fileStats = await stat15(filePath);
108509
108570
  const originalFilename = basename4(filePath);
108510
108571
  writeJson({
108511
108572
  ok: true,