@koda-sl/baker-cli 0.370.0 → 0.371.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.
@@ -617,7 +617,7 @@ ${originalIndentation}`;
617
617
  });
618
618
 
619
619
  // src/engine/index.ts
620
- import path18 from "path";
620
+ import path19 from "path";
621
621
 
622
622
  // src/engine/client/http.ts
623
623
  var CONTENT_POLICY_CODE = "content_policy_blocked";
@@ -666,17 +666,17 @@ var HttpClient = class {
666
666
  this.fetchFn = opts.fetchFn ?? fetch;
667
667
  this.sleepFn = opts.sleepFn ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
668
668
  }
669
- async postJson(path19, body, signal) {
670
- return await this.requestJson("POST", path19, body, signal);
669
+ async postJson(path20, body, signal) {
670
+ return await this.requestJson("POST", path20, body, signal);
671
671
  }
672
- async putJson(path19, body, signal) {
673
- return await this.requestJson("PUT", path19, body, signal);
672
+ async putJson(path20, body, signal) {
673
+ return await this.requestJson("PUT", path20, body, signal);
674
674
  }
675
- async getJson(path19, signal) {
676
- return await this.requestJson("GET", path19, void 0, signal);
675
+ async getJson(path20, signal) {
676
+ return await this.requestJson("GET", path20, void 0, signal);
677
677
  }
678
- async requestJson(method, path19, body, signal) {
679
- const url = `${this.baseUrl}${path19.startsWith("/") ? path19 : `/${path19}`}`;
678
+ async requestJson(method, path20, body, signal) {
679
+ const url = `${this.baseUrl}${path20.startsWith("/") ? path20 : `/${path20}`}`;
680
680
  for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
681
681
  const outcome = await this.attempt(method, url, body, attempt, signal);
682
682
  if (outcome.kind === "value") return outcome.value;
@@ -852,12 +852,12 @@ var BackendClient = class {
852
852
  }
853
853
  async pollJob(jobId, signal) {
854
854
  const deadline = Date.now() + JOB_POLL_MAX_MS;
855
- const path19 = `/api/canvas/jobs/${encodeURIComponent(jobId)}`;
855
+ const path20 = `/api/canvas/jobs/${encodeURIComponent(jobId)}`;
856
856
  for (let attempt = 0; ; attempt++) {
857
857
  if (signal?.aborted) {
858
858
  throw new BackendHttpError({ kind: "network", cause: signal.reason ?? new Error("aborted") });
859
859
  }
860
- const job = await this.http.getJson(path19, signal);
860
+ const job = await this.http.getJson(path20, signal);
861
861
  if (job.status === "completed") return job.result;
862
862
  if (job.status === "failed") throw failedJobError(job.error);
863
863
  if (Date.now() > deadline) {
@@ -936,8 +936,8 @@ var BackendClient = class {
936
936
  await this.http.postJson("/api/creatives/definition", payload, signal);
937
937
  }
938
938
  getArtifact(kind, name, version, signal) {
939
- const path19 = version ? `/api/canvas/artifacts/${encodeURIComponent(kind)}/${encodeURIComponent(name)}/${encodeURIComponent(version)}` : `/api/canvas/artifacts/${encodeURIComponent(kind)}/${encodeURIComponent(name)}`;
940
- return this.http.getJson(path19, signal);
939
+ const path20 = version ? `/api/canvas/artifacts/${encodeURIComponent(kind)}/${encodeURIComponent(name)}/${encodeURIComponent(version)}` : `/api/canvas/artifacts/${encodeURIComponent(kind)}/${encodeURIComponent(name)}`;
940
+ return this.http.getJson(path20, signal);
941
941
  }
942
942
  };
943
943
 
@@ -1014,6 +1014,15 @@ var LayerExecutionError = class extends CanvasError {
1014
1014
  function describeFailureReason(reason) {
1015
1015
  return reason instanceof Error ? reason.message : String(reason);
1016
1016
  }
1017
+ function isInputRejection(reason) {
1018
+ if (!(reason instanceof NodeExecutionError) || reason.cause.kind !== "remote") return false;
1019
+ const { status, provider } = reason.cause;
1020
+ return (status === 400 || status === 422) && provider === void 0;
1021
+ }
1022
+ function runFailureCode(e) {
1023
+ const reasons = e instanceof LayerExecutionError ? e.failures.map((f) => f.reason) : [e];
1024
+ return reasons.length > 0 && reasons.every(isInputRejection) ? "input_invalid" : "runtime";
1025
+ }
1017
1026
  function failureDetail(reason) {
1018
1027
  if (reason instanceof NodeExecutionError) {
1019
1028
  const c = reason.cause;
@@ -3405,8 +3414,8 @@ function nodesBeforeCheckpoint(graph, types, stopKinds) {
3405
3414
  }
3406
3415
 
3407
3416
  // src/engine/engine/validator.ts
3408
- import { readFile as readFile2 } from "fs/promises";
3409
- import path3 from "path";
3417
+ import { readFile as readFile3 } from "fs/promises";
3418
+ import path4 from "path";
3410
3419
  import { z as z2 } from "zod";
3411
3420
 
3412
3421
  // src/engine/lib/url.ts
@@ -3646,6 +3655,75 @@ function didYouMean(query, candidates, max = 3) {
3646
3655
  return scored.slice(0, max).map((s) => s.c);
3647
3656
  }
3648
3657
 
3658
+ // src/engine/engine/prompt-limit.ts
3659
+ import { readFile as readFile2 } from "fs/promises";
3660
+ import path3 from "path";
3661
+ var PROMPT_OVER_MODEL_LIMIT = "PROMPT_OVER_MODEL_LIMIT";
3662
+ async function staticTextOf(value, nodes) {
3663
+ if (typeof value !== "string") return void 0;
3664
+ if (!value.startsWith(REF_PREFIX)) return value;
3665
+ const expr = parseRefExpr(value);
3666
+ if (!expr || expr.kind !== "ref" || expr.index !== void 0) return void 0;
3667
+ const target = nodes.get(expr.nodeId);
3668
+ const params = target?.params ?? {};
3669
+ if (target?.type === "text" && expr.output === "text" && typeof params.value === "string") return params.value;
3670
+ if (target?.type === "ingest" && expr.output === "asset" && params.source === "path" && (params.expect === "json" || params.expect === "text") && typeof params.path === "string" && path3.isAbsolute(params.path)) {
3671
+ try {
3672
+ return await readFile2(params.path, "utf8");
3673
+ } catch {
3674
+ return void 0;
3675
+ }
3676
+ }
3677
+ return void 0;
3678
+ }
3679
+ function cappedParamsOf(n) {
3680
+ if (!isManagedNodeKind(n.type)) return [];
3681
+ const model = n.params?.model;
3682
+ if (typeof model !== "string") return [];
3683
+ const spec = MODEL_REGISTRY[n.type][model];
3684
+ if (!spec) return [];
3685
+ return Object.entries(spec.params).flatMap(
3686
+ ([key, schema]) => schema.kind === "string" && schema.maxLength !== void 0 ? [{ key, max: schema.maxLength, model }] : []
3687
+ );
3688
+ }
3689
+ async function filledParam(n, raw, nodes) {
3690
+ const template = await staticTextOf(raw, nodes);
3691
+ if (template === void 0) return void 0;
3692
+ const names = extractSlots(template);
3693
+ if (names.length === 0 && template === raw) return void 0;
3694
+ const inputs = n.inputs ?? {};
3695
+ const slots = {};
3696
+ for (const name of names) {
3697
+ const text = await staticTextOf(inputs[name], nodes);
3698
+ if (text !== void 0) slots[name] = text;
3699
+ }
3700
+ return { length: renderTemplate(template, slots).length, slots };
3701
+ }
3702
+ function largestSlotNote(slots) {
3703
+ const largest = Object.entries(slots).sort((a, b) => b[1].length - a[1].length)[0];
3704
+ return largest ? `; {{${largest[0]}}} alone is ${largest[1].length}` : "";
3705
+ }
3706
+ async function filledPromptLimitIssues(canvas) {
3707
+ const nodes = new Map(canvas.nodes.map((n) => [n.id, n]));
3708
+ const issues = [];
3709
+ for (const [i, n] of canvas.nodes.entries()) {
3710
+ for (const { key, max, model } of cappedParamsOf(n)) {
3711
+ const filled = await filledParam(n, n.params?.[key], nodes);
3712
+ if (!filled || filled.length <= max) continue;
3713
+ issues.push({
3714
+ path: `nodes[${i}].params.${key}`,
3715
+ code: PROMPT_OVER_MODEL_LIMIT,
3716
+ message: `"${n.id}" ${key} is ${filled.length} characters once its slots are filled \u2014 ${filled.length - max} over the ${max} that "${model}" accepts` + largestSlotNote(filled.slots) + `. Shorten it before running: the model refuses it, after every node before "${n.id}" has already been paid for.`,
3717
+ received: filled.length,
3718
+ expected: `<= ${max} characters`,
3719
+ node_id: n.id,
3720
+ node_type: n.type
3721
+ });
3722
+ }
3723
+ }
3724
+ return issues;
3725
+ }
3726
+
3649
3727
  // src/engine/engine/validator.ts
3650
3728
  var MODEL_INPUT_KINDS = /* @__PURE__ */ new Set(["image", "video", "audio"]);
3651
3729
  var STAGE_CODES = {
@@ -3801,6 +3879,7 @@ async function validateCanvasDeep(input, registry) {
3801
3879
  }
3802
3880
  }
3803
3881
  await checkOverlayTimingBounds(canvas, issues);
3882
+ issues.push(...await filledPromptLimitIssues(canvas));
3804
3883
  const hasBlocking = issues.some(isBlocking);
3805
3884
  if (hasBlocking) return { ok: false, issues };
3806
3885
  const warnings = [...shallow.warnings ?? [], ...issues.filter((i) => !isBlocking(i))];
@@ -4088,8 +4167,8 @@ async function checkOverlayTimingBounds(canvas, issues) {
4088
4167
  const n = canvas.nodes[i];
4089
4168
  if (n?.type !== "hyperframe_render") continue;
4090
4169
  const composition = n.params?.composition;
4091
- if (typeof composition !== "string" || !path3.isAbsolute(composition)) continue;
4092
- const html = await readFile2(path3.join(composition, "index.html"), "utf8").catch(() => null);
4170
+ if (typeof composition !== "string" || !path4.isAbsolute(composition)) continue;
4171
+ const html = await readFile3(path4.join(composition, "index.html"), "utf8").catch(() => null);
4093
4172
  if (!html) continue;
4094
4173
  for (const w of overlayTimingIssues(html, durationS)) {
4095
4174
  issues.push({
@@ -4098,7 +4177,7 @@ async function checkOverlayTimingBounds(canvas, issues) {
4098
4177
  severity: "warning",
4099
4178
  node_id: n.id,
4100
4179
  node_type: n.type,
4101
- message: `an overlay in ${path3.basename(composition)}/index.html runs [${w.start}s, ${w.start + w.dur}s] but the video ends at ${durationS}s \u2014 it never hides on screen. Re-time its data-start/data-dur to fit the video`
4180
+ message: `an overlay in ${path4.basename(composition)}/index.html runs [${w.start}s, ${w.start + w.dur}s] but the video ends at ${durationS}s \u2014 it never hides on screen. Re-time its data-start/data-dur to fit the video`
4102
4181
  });
4103
4182
  }
4104
4183
  }
@@ -4900,9 +4979,9 @@ function checkOutputRef(ctx) {
4900
4979
  function pushZodIssues(issues, err, pathPrefix, code, nodeId, nodeType) {
4901
4980
  for (const issue of err.issues) {
4902
4981
  const tail2 = pathToString(issue.path);
4903
- const path19 = pathPrefix ? tail2 ? `${pathPrefix}.${tail2}` : pathPrefix : tail2;
4982
+ const path20 = pathPrefix ? tail2 ? `${pathPrefix}.${tail2}` : pathPrefix : tail2;
4904
4983
  issues.push({
4905
- path: path19,
4984
+ path: path20,
4906
4985
  code,
4907
4986
  message: issue.message,
4908
4987
  received: issue.code === "invalid_type" ? issue.received : void 0,
@@ -4911,8 +4990,8 @@ function pushZodIssues(issues, err, pathPrefix, code, nodeId, nodeType) {
4911
4990
  });
4912
4991
  }
4913
4992
  }
4914
- function pathToString(path19) {
4915
- return path19.map((p) => typeof p === "number" ? `[${p}]` : `.${String(p)}`).join("").replace(/^\./, "");
4993
+ function pathToString(path20) {
4994
+ return path20.map((p) => typeof p === "number" ? `[${p}]` : `.${String(p)}`).join("").replace(/^\./, "");
4916
4995
  }
4917
4996
  function buildDepGraph(canvas) {
4918
4997
  const graph = /* @__PURE__ */ new Map();
@@ -5571,9 +5650,9 @@ var NodeRegistry = class {
5571
5650
 
5572
5651
  // src/engine/nodes/ingest.ts
5573
5652
  import { execFile as execFileCb } from "child_process";
5574
- import { mkdtemp, readFile as readFile4, rm, stat as stat2 } from "fs/promises";
5653
+ import { mkdtemp, readFile as readFile5, rm, stat as stat2 } from "fs/promises";
5575
5654
  import { tmpdir } from "os";
5576
- import path6 from "path";
5655
+ import path7 from "path";
5577
5656
  import { promisify } from "util";
5578
5657
  import { z as z5 } from "zod";
5579
5658
 
@@ -5893,12 +5972,12 @@ async function fetchExternalBytes(url, options) {
5893
5972
 
5894
5973
  // src/lib/ytDlp.ts
5895
5974
  import { spawn } from "child_process";
5896
- import { readdir, readFile as readFile3 } from "fs/promises";
5897
- import path5 from "path";
5975
+ import { readdir, readFile as readFile4 } from "fs/promises";
5976
+ import path6 from "path";
5898
5977
 
5899
5978
  // src/lib/vimeoCookie.ts
5900
5979
  import { writeFile as writeFile3 } from "fs/promises";
5901
- import path4 from "path";
5980
+ import path5 from "path";
5902
5981
  var COOKIE_NAME = "vimeo";
5903
5982
  async function writeVimeoCookieFile(cookie, workDir) {
5904
5983
  const value = cookie?.trim();
@@ -5909,7 +5988,7 @@ async function writeVimeoCookieFile(cookie, workDir) {
5909
5988
  [".vimeo.com", "TRUE", "/", "TRUE", String(expires), COOKIE_NAME, value].join(" "),
5910
5989
  ""
5911
5990
  ].join("\n");
5912
- const filePath = path4.join(workDir, "vimeo-cookies.txt");
5991
+ const filePath = path5.join(workDir, "vimeo-cookies.txt");
5913
5992
  await writeFile3(filePath, jar, { mode: 384 });
5914
5993
  return filePath;
5915
5994
  }
@@ -5973,8 +6052,8 @@ function tail(text, maxLines) {
5973
6052
  return text.split("\n").slice(-maxLines).join("\n");
5974
6053
  }
5975
6054
  async function runYtDlp(args) {
5976
- const outTemplate = path5.join(args.workDir, "out.%(ext)s");
5977
- const infoPath = path5.join(args.workDir, "out.info.json");
6055
+ const outTemplate = path6.join(args.workDir, "out.%(ext)s");
6056
+ const infoPath = path6.join(args.workDir, "out.info.json");
5978
6057
  const argv = [
5979
6058
  args.url,
5980
6059
  "--no-playlist",
@@ -6012,10 +6091,10 @@ async function runYtDlp(args) {
6012
6091
  }
6013
6092
  let info = {};
6014
6093
  try {
6015
- info = JSON.parse(await readFile3(infoPath, "utf-8"));
6094
+ info = JSON.parse(await readFile4(infoPath, "utf-8"));
6016
6095
  } catch {
6017
6096
  }
6018
- return { filePath: path5.join(args.workDir, downloaded), info, tier, reducedQuality };
6097
+ return { filePath: path6.join(args.workDir, downloaded), info, tier, reducedQuality };
6019
6098
  }
6020
6099
  async function probeYtDlp(args) {
6021
6100
  const argv = [
@@ -6329,7 +6408,9 @@ function mapClientError(ctx, e) {
6329
6408
  kind: "remote",
6330
6409
  status: d.status,
6331
6410
  code: "invalid_params",
6332
- message: d.message
6411
+ message: d.message,
6412
+ // The request itself was refused; it fails the same way until the input changes.
6413
+ retryable: false
6333
6414
  });
6334
6415
  }
6335
6416
  if (d.kind === "unauthorized") {
@@ -6524,8 +6605,8 @@ function resolveLocalPath(input) {
6524
6605
  `ingest: ~ path expansion is not supported (got "${input}"). Use an absolute path or a cwd-relative path.`
6525
6606
  );
6526
6607
  }
6527
- if (path6.isAbsolute(input)) return input;
6528
- return path6.resolve(process.cwd(), input);
6608
+ if (path7.isAbsolute(input)) return input;
6609
+ return path7.resolve(process.cwd(), input);
6529
6610
  }
6530
6611
  var EXT_TO_MIME = {
6531
6612
  png: "image/png",
@@ -6573,7 +6654,7 @@ function sniffSvg(buf) {
6573
6654
  return head.startsWith("<?xml") ? head.includes("<svg") : head.startsWith("<svg");
6574
6655
  }
6575
6656
  function inferMimeFromPath(absPath, sniffBytes) {
6576
- const ext = path6.extname(absPath).slice(1).toLowerCase();
6657
+ const ext = path7.extname(absPath).slice(1).toLowerCase();
6577
6658
  const fromExt = EXT_TO_MIME[ext];
6578
6659
  if (fromExt) return fromExt;
6579
6660
  const fromBytes = sniffImageMime(sniffBytes);
@@ -6758,7 +6839,7 @@ async function execLocalFile(params, ctx) {
6758
6839
  }
6759
6840
  let bytes;
6760
6841
  try {
6761
- bytes = await readFile4(absPath);
6842
+ bytes = await readFile5(absPath);
6762
6843
  } catch (e) {
6763
6844
  if (e.code === "EACCES") {
6764
6845
  throw localExecError(ctx, `permission_denied: ${absPath}`);
@@ -6810,7 +6891,7 @@ function localFileMetadata(args) {
6810
6891
  strategy: "local_file",
6811
6892
  ingested_at: (/* @__PURE__ */ new Date()).toISOString(),
6812
6893
  file_size: args.fileSize,
6813
- original_filename: path6.basename(args.absPath),
6894
+ original_filename: path7.basename(args.absPath),
6814
6895
  ...args.rasterizedFrom ? { rasterized_from: args.rasterizedFrom } : {},
6815
6896
  ...args.durationMs !== void 0 ? { duration_ms: args.durationMs } : {}
6816
6897
  };
@@ -6832,7 +6913,7 @@ async function execYtDlp(params, ctx) {
6832
6913
  if (params.expect !== "video" && params.expect !== "audio") {
6833
6914
  throw new Error(`ingest: yt_dlp only handles video/audio, got expect=${params.expect}`);
6834
6915
  }
6835
- const workDir = await mkdtemp(path6.join(tmpdir(), "ingest-yt-"));
6916
+ const workDir = await mkdtemp(path7.join(tmpdir(), "ingest-yt-"));
6836
6917
  try {
6837
6918
  const { filePath, info, reducedQuality } = await runYtDlpForNode({
6838
6919
  url: params.url,
@@ -6847,7 +6928,7 @@ async function execYtDlp(params, ctx) {
6847
6928
  `file_too_large: yt-dlp output for ${params.url} is ${downloadedStats.size} bytes (limit ${MAX_ASSET_BYTES})`
6848
6929
  );
6849
6930
  }
6850
- const bytes = await readFile4(filePath);
6931
+ const bytes = await readFile5(filePath);
6851
6932
  const kind = params.expect;
6852
6933
  const mime = YT_DLP_MIME[kind];
6853
6934
  const metadata = buildYtDlpMetadata(params.url, info);
@@ -6936,9 +7017,9 @@ import { z as z6 } from "zod";
6936
7017
 
6937
7018
  // src/engine/nodes/local/lib/cli-runner.ts
6938
7019
  import { execFile as execFileCb2, spawn as spawn2 } from "child_process";
6939
- import { copyFile as copyFile2, mkdtemp as mkdtemp2, readFile as readFile5, rm as rm2, stat as stat3 } from "fs/promises";
7020
+ import { copyFile as copyFile2, mkdtemp as mkdtemp2, readFile as readFile6, rm as rm2, stat as stat3 } from "fs/promises";
6940
7021
  import { tmpdir as tmpdir2 } from "os";
6941
- import path7 from "path";
7022
+ import path8 from "path";
6942
7023
  import { promisify as promisify2 } from "util";
6943
7024
  var execFile2 = promisify2(execFileCb2);
6944
7025
  var DEFAULT_TIMEOUT_MS2 = 10 * 60 * 1e3;
@@ -6965,7 +7046,7 @@ function mimeForExt(ext) {
6965
7046
  }
6966
7047
  function extForAssetRef(ref) {
6967
7048
  if (ref.path) {
6968
- const e = path7.extname(ref.path);
7049
+ const e = path8.extname(ref.path);
6969
7050
  if (e) return e;
6970
7051
  }
6971
7052
  const reverse = {
@@ -6987,14 +7068,14 @@ function planArrayInputSlot(tmpDir, slot, values, lookup, stagedInputs) {
6987
7068
  const ref = values[i];
6988
7069
  if (!ref) continue;
6989
7070
  if (!ref.path) throw new Error(`cli-runner: inputs.${slot}[${i}] has no local path`);
6990
- const dest = path7.join(tmpDir, `in_${slot}_${i}${extForAssetRef(ref)}`);
7071
+ const dest = path8.join(tmpDir, `in_${slot}_${i}${extForAssetRef(ref)}`);
6991
7072
  stagedInputs.push({ srcPath: ref.path, destPath: dest });
6992
7073
  lookup.set(`in.${slot}.${i}`, dest);
6993
7074
  }
6994
7075
  }
6995
7076
  function planSingleInputSlot(tmpDir, slot, ref, lookup, stagedInputs) {
6996
7077
  if (!ref.path) throw new Error(`cli-runner: inputs.${slot} has no local path`);
6997
- const dest = path7.join(tmpDir, `in_${slot}${extForAssetRef(ref)}`);
7078
+ const dest = path8.join(tmpDir, `in_${slot}${extForAssetRef(ref)}`);
6998
7079
  stagedInputs.push({ srcPath: ref.path, destPath: dest });
6999
7080
  lookup.set(`in.${slot}`, dest);
7000
7081
  }
@@ -7002,7 +7083,7 @@ function planOutputs(tmpDir, outputs, lookup) {
7002
7083
  const outputPaths = [];
7003
7084
  for (const [name, spec] of Object.entries(outputs)) {
7004
7085
  const ext = spec.ext.startsWith(".") ? spec.ext : `.${spec.ext}`;
7005
- const absPath = path7.join(tmpDir, `out_${name}${ext}`);
7086
+ const absPath = path8.join(tmpDir, `out_${name}${ext}`);
7006
7087
  outputPaths.push({ name, absPath, spec });
7007
7088
  lookup.set(`out.${name}`, absPath);
7008
7089
  }
@@ -7043,8 +7124,8 @@ function rejectRawPaths(substituted, original, stagingDir) {
7043
7124
  throw new Error(`cli-runner: home-relative path "${original}" not allowed in args.`);
7044
7125
  }
7045
7126
  if (substituted.startsWith("/")) {
7046
- const resolved = path7.resolve(substituted);
7047
- if (!resolved.startsWith(`${stagingDir}${path7.sep}`) && resolved !== stagingDir) {
7127
+ const resolved = path8.resolve(substituted);
7128
+ if (!resolved.startsWith(`${stagingDir}${path8.sep}`) && resolved !== stagingDir) {
7048
7129
  throw new Error(
7049
7130
  `cli-runner: raw filesystem path "${original}" not allowed \u2014 declare an input slot and use {{in.<slot>}} instead.`
7050
7131
  );
@@ -7094,7 +7175,7 @@ function tailLines(text, maxLines) {
7094
7175
  }
7095
7176
  async function runCli(opts) {
7096
7177
  const { bin, args, inputs, outputs, ctx, timeoutMs = DEFAULT_TIMEOUT_MS2 } = opts;
7097
- const tmpDir = await mkdtemp2(path7.join(tmpdir2(), `cli-${bin.replace(/[^a-z0-9]/gi, "")}-`));
7178
+ const tmpDir = await mkdtemp2(path8.join(tmpdir2(), `cli-${bin.replace(/[^a-z0-9]/gi, "")}-`));
7098
7179
  try {
7099
7180
  const { lookup, stagedInputs, outputPaths } = planPlaceholders(tmpDir, inputs, outputs);
7100
7181
  await stageInputs(stagedInputs);
@@ -7116,7 +7197,7 @@ ${tailLines(stderr, 40)}`);
7116
7197
  if (!s?.isFile() || s.size === 0) {
7117
7198
  throw new Error(`cli-runner: declared output "${name}" missing or empty at ${absPath}`);
7118
7199
  }
7119
- const bytes = await readFile5(absPath);
7200
+ const bytes = await readFile6(absPath);
7120
7201
  const ref = await ctx.assets.ingestBytes({
7121
7202
  bytes: Buffer.from(bytes),
7122
7203
  kind: spec.kind,
@@ -7386,17 +7467,17 @@ var ffmpegNode = defineNode({
7386
7467
  import { mkdtemp as mkdtemp3, rm as rm3, writeFile as writeFile4 } from "fs/promises";
7387
7468
  import { createRequire } from "module";
7388
7469
  import { tmpdir as tmpdir3 } from "os";
7389
- import path9 from "path";
7470
+ import path10 from "path";
7390
7471
  import { z as z9 } from "zod";
7391
7472
 
7392
7473
  // src/engine/nodes/local/lib/assets.ts
7393
- import { copyFile as copyFile3, readFile as readFile6 } from "fs/promises";
7394
- import path8 from "path";
7474
+ import { copyFile as copyFile3, readFile as readFile7 } from "fs/promises";
7475
+ import path9 from "path";
7395
7476
  async function stageAsset(ref, destDir, filename) {
7396
7477
  if (!ref.path) {
7397
7478
  throw new Error(`stageAsset: ref (${ref.kind}/${ref.mime}) has no local path`);
7398
7479
  }
7399
- const dest = path8.join(destDir, filename);
7480
+ const dest = path9.join(destDir, filename);
7400
7481
  await copyFile3(ref.path, dest);
7401
7482
  return dest;
7402
7483
  }
@@ -7405,7 +7486,7 @@ async function refToUrl(ref) {
7405
7486
  if (!ref.path) {
7406
7487
  throw new Error("refToUrl: AssetRef has neither url nor path");
7407
7488
  }
7408
- const bytes = await readFile6(ref.path);
7489
+ const bytes = await readFile7(ref.path);
7409
7490
  return `data:${ref.mime};base64,${bytes.toString("base64")}`;
7410
7491
  }
7411
7492
  var ASSET_KINDS = /* @__PURE__ */ new Set(["image", "video", "audio", "json", "text", "font"]);
@@ -7479,11 +7560,11 @@ var fontSpecimenNode = defineNode({
7479
7560
  outputKinds: { image: "image" },
7480
7561
  cost: () => ({ credits: 0, seconds_estimate: 5 }),
7481
7562
  async execute({ inputs, params, ctx }) {
7482
- const tmp = await mkdtemp3(path9.join(tmpdir3(), "font-specimen-"));
7563
+ const tmp = await mkdtemp3(path10.join(tmpdir3(), "font-specimen-"));
7483
7564
  try {
7484
7565
  const fontFilename = `font.${extForMime(inputs.font.mime)}`;
7485
7566
  await stageAsset(inputs.font, tmp, fontFilename);
7486
- const entryPath = path9.join(tmp, "index.html");
7567
+ const entryPath = path10.join(tmp, "index.html");
7487
7568
  await writeFile4(entryPath, buildSpecimenHtml(params, fontFilename), "utf-8");
7488
7569
  ctx.log(`rendering specimen (${params.font_size}px, ${params.text.split("\n").length} lines)`);
7489
7570
  const pwSpecifier = ["play", "wright"].join("");
@@ -7567,16 +7648,16 @@ var fontSpecimenNode = defineNode({
7567
7648
 
7568
7649
  // src/engine/nodes/local/hyperframe.ts
7569
7650
  import { execFile as execFile4 } from "child_process";
7570
- import { copyFile as copyFile4, mkdtemp as mkdtemp4, readFile as readFile10, rm as rm4, stat as stat5, writeFile as writeFile6 } from "fs/promises";
7651
+ import { copyFile as copyFile4, mkdtemp as mkdtemp4, readFile as readFile11, rm as rm4, stat as stat5, writeFile as writeFile6 } from "fs/promises";
7571
7652
  import { createRequire as createRequire2 } from "module";
7572
7653
  import { cpus, tmpdir as tmpdir4 } from "os";
7573
- import path14 from "path";
7654
+ import path15 from "path";
7574
7655
  import { promisify as promisify4 } from "util";
7575
7656
  import { z as z11 } from "zod";
7576
7657
 
7577
7658
  // src/engine/engine/composition-hash.ts
7578
- import { readdir as readdir2, readFile as readFile7, stat as stat4 } from "fs/promises";
7579
- import path10 from "path";
7659
+ import { readdir as readdir2, readFile as readFile8, stat as stat4 } from "fs/promises";
7660
+ import path11 from "path";
7580
7661
  var SKIP_DIRS = /* @__PURE__ */ new Set([".cache", ".git", "node_modules", "dist", "build", ".next", ".turbo"]);
7581
7662
  function isSkippedName(name) {
7582
7663
  if (name.startsWith(".")) return true;
@@ -7593,23 +7674,23 @@ async function collectFiles(root, current) {
7593
7674
  const names = await readdir2(current);
7594
7675
  for (const name of names) {
7595
7676
  if (isSkippedName(name)) continue;
7596
- const abs = path10.join(current, name);
7677
+ const abs = path11.join(current, name);
7597
7678
  const s = await stat4(abs);
7598
7679
  if (s.isDirectory()) {
7599
7680
  out.push(...await collectFiles(root, abs));
7600
7681
  continue;
7601
7682
  }
7602
7683
  if (!s.isFile()) continue;
7603
- const bytes = await readFile7(abs);
7604
- const relPath = path10.relative(root, abs).split(path10.sep).join("/");
7684
+ const bytes = await readFile8(abs);
7685
+ const relPath = path11.relative(root, abs).split(path11.sep).join("/");
7605
7686
  out.push({ relPath, contentSha: sha256Hex(bytes) });
7606
7687
  }
7607
7688
  return out;
7608
7689
  }
7609
7690
 
7610
7691
  // src/engine/engine/composition-meta.ts
7611
- import { readFile as readFile8 } from "fs/promises";
7612
- import path11 from "path";
7692
+ import { readFile as readFile9 } from "fs/promises";
7693
+ import path12 from "path";
7613
7694
  import { z as z10 } from "zod";
7614
7695
  var InputKind = z10.enum(["video", "image", "audio", "json"]);
7615
7696
  var InputSpec = z10.object({
@@ -7686,10 +7767,10 @@ var CompositionMetaSchema = z10.object({
7686
7767
  params: z10.record(z10.string(), ParamSpec).default({})
7687
7768
  }).strict();
7688
7769
  async function loadCompositionMeta(compositionDir) {
7689
- const metaPath = path11.join(compositionDir, "meta.json");
7770
+ const metaPath = path12.join(compositionDir, "meta.json");
7690
7771
  let raw;
7691
7772
  try {
7692
- raw = await readFile8(metaPath, "utf-8");
7773
+ raw = await readFile9(metaPath, "utf-8");
7693
7774
  } catch (e) {
7694
7775
  throw new Error(`composition meta: cannot read ${metaPath} (${e.message})`);
7695
7776
  }
@@ -7767,8 +7848,8 @@ function defaultFilenameForInput(key, kind) {
7767
7848
 
7768
7849
  // src/engine/nodes/local/lib/hyperframe-check.ts
7769
7850
  import { execFile as execFile3 } from "child_process";
7770
- import { readFile as readFile9 } from "fs/promises";
7771
- import path12 from "path";
7851
+ import { readFile as readFile10 } from "fs/promises";
7852
+ import path13 from "path";
7772
7853
  import { promisify as promisify3 } from "util";
7773
7854
 
7774
7855
  // src/engine/nodes/local/lib/caption-style.ts
@@ -7992,7 +8073,7 @@ async function runSnapshotSmoke(args, timeoutMs) {
7992
8073
  }
7993
8074
  async function runNestedCompositionSmoke(opts) {
7994
8075
  const { dir, nodeId, ctx, timeoutMs, samples } = opts;
7995
- const indexHtml = await readFile9(path12.join(dir, "index.html"), "utf-8").catch(() => "");
8076
+ const indexHtml = await readFile10(path13.join(dir, "index.html"), "utf-8").catch(() => "");
7996
8077
  if (!indexHtml || !usesNestedCompositions(indexHtml)) return;
7997
8078
  const snap = await runSnapshotSmoke(
7998
8079
  buildSnapshotArgs(dir, Math.min(samples, 3), hasFrameVisionKey()),
@@ -8008,7 +8089,7 @@ async function runNestedCompositionSmoke(opts) {
8008
8089
  ${snap.message}`
8009
8090
  );
8010
8091
  }
8011
- const described = await readFile9(path12.join(dir, "snapshots", "descriptions.md"), "utf-8").catch(() => "");
8092
+ const described = await readFile10(path13.join(dir, "snapshots", "descriptions.md"), "utf-8").catch(() => "");
8012
8093
  for (const line of condenseFrameDescriptions(described)) {
8013
8094
  ctx.log(`${nodeId}: frame check \u2014 ${line}`);
8014
8095
  }
@@ -8044,7 +8125,7 @@ async function runHyperframesCheck(opts) {
8044
8125
  ${detail}`
8045
8126
  );
8046
8127
  }
8047
- const composition = await readFile9(path12.join(dir, "index.html"), "utf-8").catch(() => "");
8128
+ const composition = await readFile10(path13.join(dir, "index.html"), "utf-8").catch(() => "");
8048
8129
  const captionComplaint = fragmentedCaptions(captionTextsFrom(composition));
8049
8130
  if (captionComplaint) {
8050
8131
  ctx.log(`${nodeId}: caption style \u2014 ${captionComplaint}`);
@@ -8098,9 +8179,9 @@ ${stderr.slice(0, 1500)}`;
8098
8179
 
8099
8180
  // src/engine/nodes/local/lib/hyperframe-meta.ts
8100
8181
  import { writeFile as writeFile5 } from "fs/promises";
8101
- import path13 from "path";
8182
+ import path14 from "path";
8102
8183
  async function ensureHyperframesMetaJson(tmp, nodeId, meta, duration) {
8103
- const metaPath = path13.join(tmp, "meta.json");
8184
+ const metaPath = path14.join(tmp, "meta.json");
8104
8185
  await writeFile5(
8105
8186
  metaPath,
8106
8187
  JSON.stringify(
@@ -8200,7 +8281,7 @@ var hyperframeRenderNode = defineNode({
8200
8281
  const compositionDir = await resolveCompositionDir(params.composition);
8201
8282
  const meta = await loadCompositionMeta(compositionDir);
8202
8283
  const compositionParams = validateAndParseDynamicParams(meta, params);
8203
- const tmp = await mkdtemp4(path14.join(tmpdir4(), "hf-render-"));
8284
+ const tmp = await mkdtemp4(path15.join(tmpdir4(), "hf-render-"));
8204
8285
  try {
8205
8286
  await copyComposition(compositionDir, tmp);
8206
8287
  await vendorGsap(tmp, ctx);
@@ -8210,9 +8291,9 @@ var hyperframeRenderNode = defineNode({
8210
8291
  await substituteCompositionFiles(tmp, substitutionValues);
8211
8292
  await ensureHyperframesMetaJson(tmp, ctx.nodeId, meta, duration);
8212
8293
  await runHyperframesCheck({ dir: tmp, nodeId: "hyperframe_render", ctx, timeoutMs: params.timeout_ms });
8213
- const outputPath = path14.join(tmp, `output.${params.format}`);
8294
+ const outputPath = path15.join(tmp, `output.${params.format}`);
8214
8295
  await runRender({ tmp, outputPath, params, meta, ctx });
8215
- const bytes = await readFile10(outputPath);
8296
+ const bytes = await readFile11(outputPath);
8216
8297
  ctx.log(`rendered ${bytes.length} bytes`);
8217
8298
  const ref = await ctx.assets.ingestBytes({
8218
8299
  bytes: Buffer.from(bytes),
@@ -8234,10 +8315,10 @@ var hyperframeRenderNode = defineNode({
8234
8315
  }
8235
8316
  });
8236
8317
  async function resolveCompositionDir(composition) {
8237
- const compositionPath = path14.isAbsolute(composition) ? composition : path14.resolve(process.cwd(), composition);
8318
+ const compositionPath = path15.isAbsolute(composition) ? composition : path15.resolve(process.cwd(), composition);
8238
8319
  const s = await stat5(compositionPath);
8239
8320
  if (s.isDirectory()) return compositionPath;
8240
- return path14.dirname(compositionPath);
8321
+ return path15.dirname(compositionPath);
8241
8322
  }
8242
8323
  async function validateComposition(rawParams) {
8243
8324
  const issues = await validateCompositionParams(rawParams);
@@ -8319,7 +8400,7 @@ async function copyComposition(srcDir, destDir) {
8319
8400
  await cp(srcDir, destDir, {
8320
8401
  recursive: true,
8321
8402
  filter: (src) => {
8322
- const name = path14.basename(src);
8403
+ const name = path15.basename(src);
8323
8404
  if (name === ".cache" || name === "node_modules" || name === ".git") return false;
8324
8405
  return true;
8325
8406
  }
@@ -8328,7 +8409,7 @@ async function copyComposition(srcDir, destDir) {
8328
8409
  async function vendorGsap(tmp, ctx) {
8329
8410
  try {
8330
8411
  const gsapMin = require_2.resolve("gsap/dist/gsap.min.js");
8331
- await copyFile4(gsapMin, path14.join(tmp, "gsap.min.js"));
8412
+ await copyFile4(gsapMin, path15.join(tmp, "gsap.min.js"));
8332
8413
  } catch (e) {
8333
8414
  ctx.log(`warning: could not vendor gsap.min.js (${e.message}); compositions must self-supply`);
8334
8415
  }
@@ -8343,7 +8424,7 @@ async function stageInputs2(tmp, inputs, meta, ctx) {
8343
8424
  await stageAsset(ref, tmp, filename);
8344
8425
  ctx.log(`staged ${spec.kind} \u2192 ${filename}`);
8345
8426
  if (spec.kind === "video" && primaryDuration === null) {
8346
- primaryDuration = await probeDurationSeconds(path14.join(tmp, filename));
8427
+ primaryDuration = await probeDurationSeconds(path15.join(tmp, filename));
8347
8428
  }
8348
8429
  }
8349
8430
  return primaryDuration;
@@ -8389,8 +8470,8 @@ function coerceImageParam(value) {
8389
8470
  throw new Error("hyperframe_render: image param must be a URL string or AssetRef");
8390
8471
  }
8391
8472
  async function substituteCompositionFiles(tmp, values) {
8392
- const entryPath = path14.join(tmp, "index.html");
8393
- const original = await readFile10(entryPath, "utf-8");
8473
+ const entryPath = path15.join(tmp, "index.html");
8474
+ const original = await readFile11(entryPath, "utf-8");
8394
8475
  const { output, missing } = substituteVariables(original, values);
8395
8476
  if (missing.length > 0) {
8396
8477
  throw new Error(
@@ -8406,7 +8487,7 @@ function workerCount() {
8406
8487
  async function runRender(opts) {
8407
8488
  const { tmp, outputPath, params, meta, ctx } = opts;
8408
8489
  const args = buildRenderArgs(tmp, outputPath, meta, params.format);
8409
- ctx.log(`rendering ${meta.width}x${meta.height}@${meta.fps}fps ${params.format} from ${path14.basename(tmp)}`);
8490
+ ctx.log(`rendering ${meta.width}x${meta.height}@${meta.fps}fps ${params.format} from ${path15.basename(tmp)}`);
8410
8491
  try {
8411
8492
  await execFileAsync2("npx", args, { timeout: params.timeout_ms, maxBuffer: 64 * 1024 * 1024 });
8412
8493
  } catch (e) {
@@ -8450,10 +8531,10 @@ async function probeDurationSeconds(filePath) {
8450
8531
 
8451
8532
  // src/engine/nodes/local/hyperframe-snapshot.ts
8452
8533
  import { execFile as execFile5 } from "child_process";
8453
- import { copyFile as copyFile5, mkdtemp as mkdtemp5, readFile as readFile11, rm as rm5, writeFile as writeFile7 } from "fs/promises";
8534
+ import { copyFile as copyFile5, mkdtemp as mkdtemp5, readFile as readFile12, rm as rm5, writeFile as writeFile7 } from "fs/promises";
8454
8535
  import { createRequire as createRequire3 } from "module";
8455
8536
  import { tmpdir as tmpdir5 } from "os";
8456
- import path15 from "path";
8537
+ import path16 from "path";
8457
8538
  import { promisify as promisify5 } from "util";
8458
8539
  import { z as z12 } from "zod";
8459
8540
  var _execFileAsync = promisify5(execFile5);
@@ -8500,7 +8581,7 @@ var hyperframeSnapshotNode = defineNode({
8500
8581
  const compositionDir = await resolveCompositionDir(params.composition);
8501
8582
  const meta = await loadCompositionMeta(compositionDir);
8502
8583
  const compositionParams = validateAndParseDynamicParams2(meta, params);
8503
- const tmp = await mkdtemp5(path15.join(tmpdir5(), "hf-snap-"));
8584
+ const tmp = await mkdtemp5(path16.join(tmpdir5(), "hf-snap-"));
8504
8585
  try {
8505
8586
  await copyComposition2(compositionDir, tmp);
8506
8587
  await vendorGsap2(tmp, ctx);
@@ -8515,7 +8596,7 @@ var hyperframeSnapshotNode = defineNode({
8515
8596
  timeoutMs: params.timeout_ms,
8516
8597
  samples: 1
8517
8598
  });
8518
- const entryPath = path15.join(tmp, "index.html");
8599
+ const entryPath = path16.join(tmp, "index.html");
8519
8600
  const entryUrl = `file://${entryPath}`;
8520
8601
  ctx.log(`snapshotting ${meta.width}x${meta.height}@${DEVICE_SCALE_FACTOR2}x wait=${params.wait_for.kind}`);
8521
8602
  const pwSpecifier = ["play", "wright"].join("");
@@ -8576,7 +8657,7 @@ async function copyComposition2(srcDir, destDir) {
8576
8657
  await cp(srcDir, destDir, {
8577
8658
  recursive: true,
8578
8659
  filter: (src) => {
8579
- const name = path15.basename(src);
8660
+ const name = path16.basename(src);
8580
8661
  if (name === ".cache" || name === "node_modules" || name === ".git") return false;
8581
8662
  return true;
8582
8663
  }
@@ -8585,7 +8666,7 @@ async function copyComposition2(srcDir, destDir) {
8585
8666
  async function vendorGsap2(tmp, ctx) {
8586
8667
  try {
8587
8668
  const gsapMin = require_3.resolve("gsap/dist/gsap.min.js");
8588
- await copyFile5(gsapMin, path15.join(tmp, "gsap.min.js"));
8669
+ await copyFile5(gsapMin, path16.join(tmp, "gsap.min.js"));
8589
8670
  } catch (e) {
8590
8671
  ctx.log(`warning: could not vendor gsap.min.js (${e.message}); compositions must self-supply`);
8591
8672
  }
@@ -8619,8 +8700,8 @@ function coerceImageParam2(value) {
8619
8700
  throw new Error("hyperframe_snapshot: image param must be a URL string or AssetRef");
8620
8701
  }
8621
8702
  async function substituteCompositionFiles2(tmp, values) {
8622
- const entryPath = path15.join(tmp, "index.html");
8623
- const original = await readFile11(entryPath, "utf-8");
8703
+ const entryPath = path16.join(tmp, "index.html");
8704
+ const original = await readFile12(entryPath, "utf-8");
8624
8705
  const { output, missing } = substituteVariables(original, values);
8625
8706
  if (missing.length > 0) {
8626
8707
  throw new Error(
@@ -9387,9 +9468,9 @@ var videoLipsyncNode = delegated({
9387
9468
  });
9388
9469
 
9389
9470
  // src/engine/nodes/remote/videoTranscribe.ts
9390
- import { mkdtemp as mkdtemp6, readFile as readFile12, rm as rm6 } from "fs/promises";
9471
+ import { mkdtemp as mkdtemp6, readFile as readFile13, rm as rm6 } from "fs/promises";
9391
9472
  import { tmpdir as tmpdir6 } from "os";
9392
- import path16 from "path";
9473
+ import path17 from "path";
9393
9474
  import { z as z33 } from "zod";
9394
9475
 
9395
9476
  // src/engine/nodes/local/lib/ffmpeg.ts
@@ -9527,14 +9608,14 @@ async function tryExtractAudio(inputs, ctx) {
9527
9608
  ctx.log("video_transcribe: no audio track detected, sending full video");
9528
9609
  return null;
9529
9610
  }
9530
- tmpDir = await mkdtemp6(path16.join(tmpdir6(), "vtx-"));
9531
- const audioPath = path16.join(tmpDir, "audio.mp3");
9611
+ tmpDir = await mkdtemp6(path17.join(tmpdir6(), "vtx-"));
9612
+ const audioPath = path17.join(tmpDir, "audio.mp3");
9532
9613
  ctx.log("video_transcribe: extracting audio (mono 16kHz mp3)");
9533
9614
  await runFfmpeg(
9534
9615
  ["-i", video.path, "-vn", "-ac", "1", "-ar", "16000", "-b:a", "64k", "-f", "mp3", "-y", audioPath],
9535
9616
  { timeout_ms: AUDIO_EXTRACT_TIMEOUT_MS }
9536
9617
  );
9537
- const bytes = await readFile12(audioPath);
9618
+ const bytes = await readFile13(audioPath);
9538
9619
  if (bytes.byteLength === 0) {
9539
9620
  ctx.log("video_transcribe: extracted audio is empty, sending full video");
9540
9621
  return null;
@@ -9729,19 +9810,19 @@ function safeCost(def) {
9729
9810
 
9730
9811
  // src/engine/storage/cache-store.ts
9731
9812
  import { randomUUID as randomUUID2 } from "crypto";
9732
- import { mkdir as mkdir3, readFile as readFile13, rename as rename2, writeFile as writeFile8 } from "fs/promises";
9733
- import path17 from "path";
9813
+ import { mkdir as mkdir3, readFile as readFile14, rename as rename2, writeFile as writeFile8 } from "fs/promises";
9814
+ import path18 from "path";
9734
9815
  var LocalCacheStore = class {
9735
9816
  rootDir;
9736
9817
  constructor(rootDir) {
9737
9818
  this.rootDir = rootDir;
9738
9819
  }
9739
9820
  filePath(cacheKey) {
9740
- return path17.join(this.rootDir, `${cacheKey}.json`);
9821
+ return path18.join(this.rootDir, `${cacheKey}.json`);
9741
9822
  }
9742
9823
  async get(cacheKey) {
9743
9824
  try {
9744
- const buf = await readFile13(this.filePath(cacheKey), "utf8");
9825
+ const buf = await readFile14(this.filePath(cacheKey), "utf8");
9745
9826
  return JSON.parse(buf);
9746
9827
  } catch (e) {
9747
9828
  if (e.code === "ENOENT") return null;
@@ -9750,7 +9831,7 @@ var LocalCacheStore = class {
9750
9831
  }
9751
9832
  async put(entry) {
9752
9833
  const dest = this.filePath(entry.cacheKey);
9753
- await mkdir3(path17.dirname(dest), { recursive: true });
9834
+ await mkdir3(path18.dirname(dest), { recursive: true });
9754
9835
  const tmp = `${dest}.tmp-${process.pid}-${randomUUID2()}`;
9755
9836
  await writeFile8(tmp, JSON.stringify(entry, null, 0));
9756
9837
  await rename2(tmp, dest);
@@ -9806,12 +9887,12 @@ function defaultRegistry() {
9806
9887
  }
9807
9888
  function createEngineFromEnv(opts = {}) {
9808
9889
  const cwd = opts.cwd ?? process.cwd();
9809
- const cacheDir = opts.cacheDir ?? path18.join(cwd, "canvas", ".cache");
9810
- const outputsDir = opts.outputsDir ?? path18.join(cwd, "canvas");
9890
+ const cacheDir = opts.cacheDir ?? path19.join(cwd, "canvas", ".cache");
9891
+ const outputsDir = opts.outputsDir ?? path19.join(cwd, "canvas");
9811
9892
  const connection = requireConnection();
9812
9893
  const client = new BackendClient({ baseUrl: connection.BAKER_API_URL, apiKey: connection.BAKER_API_KEY });
9813
- const assets = new LocalAssetStore(path18.join(cacheDir, "assets"));
9814
- const localCache = new LocalCacheStore(path18.join(cacheDir, "index"));
9894
+ const assets = new LocalAssetStore(path19.join(cacheDir, "assets"));
9895
+ const localCache = new LocalCacheStore(path19.join(cacheDir, "index"));
9815
9896
  const remoteCacheEnabled = opts.remoteCache ?? remoteCacheEnabledFromEnv();
9816
9897
  const cache = remoteCacheEnabled ? new LayeredCacheStore({
9817
9898
  local: localCache,
@@ -9836,6 +9917,7 @@ export {
9836
9917
  RunAbortedError,
9837
9918
  LayerExecutionError,
9838
9919
  describeFailureReason,
9920
+ runFailureCode,
9839
9921
  AD_FORMAT_PLATFORMS,
9840
9922
  platformFormats,
9841
9923
  withoutCastName,
@@ -9904,4 +9986,4 @@ export {
9904
9986
  defaultRegistry,
9905
9987
  createEngineFromEnv
9906
9988
  };
9907
- //# sourceMappingURL=chunk-AI4HWQVN.js.map
9989
+ //# sourceMappingURL=chunk-3NIBJ3GL.js.map