@koda-sl/baker-cli 0.353.0-dev.8bdd8f915 → 0.353.0-dev.afbf521d7
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/README.md +5 -5
- package/dist/{chunk-YBLNCFK4.js → chunk-RZWMHH4X.js} +190 -110
- package/dist/chunk-RZWMHH4X.js.map +1 -0
- package/dist/cli.js +11 -15
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-YBLNCFK4.js.map +0 -1
|
@@ -617,7 +617,7 @@ ${originalIndentation}`;
|
|
|
617
617
|
});
|
|
618
618
|
|
|
619
619
|
// src/engine/index.ts
|
|
620
|
-
import
|
|
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(
|
|
670
|
-
return await this.requestJson("POST",
|
|
669
|
+
async postJson(path20, body, signal) {
|
|
670
|
+
return await this.requestJson("POST", path20, body, signal);
|
|
671
671
|
}
|
|
672
|
-
async putJson(
|
|
673
|
-
return await this.requestJson("PUT",
|
|
672
|
+
async putJson(path20, body, signal) {
|
|
673
|
+
return await this.requestJson("PUT", path20, body, signal);
|
|
674
674
|
}
|
|
675
|
-
async getJson(
|
|
676
|
-
return await this.requestJson("GET",
|
|
675
|
+
async getJson(path20, signal) {
|
|
676
|
+
return await this.requestJson("GET", path20, void 0, signal);
|
|
677
677
|
}
|
|
678
|
-
async requestJson(method,
|
|
679
|
-
const url = `${this.baseUrl}${
|
|
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
|
|
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(
|
|
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
|
|
940
|
-
return this.http.getJson(
|
|
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
|
|
3409
|
-
import
|
|
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,74 @@ 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
|
+
const spec = typeof model === "string" ? MODEL_REGISTRY[n.type][model] : void 0;
|
|
3683
|
+
if (!spec || typeof model !== "string") return [];
|
|
3684
|
+
return Object.entries(spec.params).flatMap(
|
|
3685
|
+
([key, schema]) => schema.kind === "string" && schema.maxLength !== void 0 ? [{ key, max: schema.maxLength, model }] : []
|
|
3686
|
+
);
|
|
3687
|
+
}
|
|
3688
|
+
async function filledParam(n, raw, nodes) {
|
|
3689
|
+
const template = await staticTextOf(raw, nodes);
|
|
3690
|
+
if (template === void 0) return void 0;
|
|
3691
|
+
const names = extractSlots(template);
|
|
3692
|
+
if (names.length === 0 && template === raw) return void 0;
|
|
3693
|
+
const inputs = n.inputs ?? {};
|
|
3694
|
+
const slots = {};
|
|
3695
|
+
for (const name of names) {
|
|
3696
|
+
const text = await staticTextOf(inputs[name], nodes);
|
|
3697
|
+
if (text !== void 0) slots[name] = text;
|
|
3698
|
+
}
|
|
3699
|
+
return { length: renderTemplate(template, slots).length, slots };
|
|
3700
|
+
}
|
|
3701
|
+
function largestSlotNote(slots) {
|
|
3702
|
+
const largest = Object.entries(slots).sort((a, b) => b[1].length - a[1].length)[0];
|
|
3703
|
+
return largest ? `; {{${largest[0]}}} alone is ${largest[1].length}` : "";
|
|
3704
|
+
}
|
|
3705
|
+
async function filledPromptLimitIssues(canvas) {
|
|
3706
|
+
const nodes = new Map(canvas.nodes.map((n) => [n.id, n]));
|
|
3707
|
+
const issues = [];
|
|
3708
|
+
for (const [i, n] of canvas.nodes.entries()) {
|
|
3709
|
+
for (const { key, max, model } of cappedParamsOf(n)) {
|
|
3710
|
+
const filled = await filledParam(n, n.params?.[key], nodes);
|
|
3711
|
+
if (!filled || filled.length <= max) continue;
|
|
3712
|
+
issues.push({
|
|
3713
|
+
path: `nodes[${i}].params.${key}`,
|
|
3714
|
+
code: PROMPT_OVER_MODEL_LIMIT,
|
|
3715
|
+
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.`,
|
|
3716
|
+
received: filled.length,
|
|
3717
|
+
expected: `<= ${max} characters`,
|
|
3718
|
+
node_id: n.id,
|
|
3719
|
+
node_type: n.type
|
|
3720
|
+
});
|
|
3721
|
+
}
|
|
3722
|
+
}
|
|
3723
|
+
return issues;
|
|
3724
|
+
}
|
|
3725
|
+
|
|
3649
3726
|
// src/engine/engine/validator.ts
|
|
3650
3727
|
var MODEL_INPUT_KINDS = /* @__PURE__ */ new Set(["image", "video", "audio"]);
|
|
3651
3728
|
var STAGE_CODES = {
|
|
@@ -3801,6 +3878,7 @@ async function validateCanvasDeep(input, registry) {
|
|
|
3801
3878
|
}
|
|
3802
3879
|
}
|
|
3803
3880
|
await checkOverlayTimingBounds(canvas, issues);
|
|
3881
|
+
issues.push(...await filledPromptLimitIssues(canvas));
|
|
3804
3882
|
const hasBlocking = issues.some(isBlocking);
|
|
3805
3883
|
if (hasBlocking) return { ok: false, issues };
|
|
3806
3884
|
const warnings = [...shallow.warnings ?? [], ...issues.filter((i) => !isBlocking(i))];
|
|
@@ -4088,8 +4166,8 @@ async function checkOverlayTimingBounds(canvas, issues) {
|
|
|
4088
4166
|
const n = canvas.nodes[i];
|
|
4089
4167
|
if (n?.type !== "hyperframe_render") continue;
|
|
4090
4168
|
const composition = n.params?.composition;
|
|
4091
|
-
if (typeof composition !== "string" || !
|
|
4092
|
-
const html = await
|
|
4169
|
+
if (typeof composition !== "string" || !path4.isAbsolute(composition)) continue;
|
|
4170
|
+
const html = await readFile3(path4.join(composition, "index.html"), "utf8").catch(() => null);
|
|
4093
4171
|
if (!html) continue;
|
|
4094
4172
|
for (const w of overlayTimingIssues(html, durationS)) {
|
|
4095
4173
|
issues.push({
|
|
@@ -4098,7 +4176,7 @@ async function checkOverlayTimingBounds(canvas, issues) {
|
|
|
4098
4176
|
severity: "warning",
|
|
4099
4177
|
node_id: n.id,
|
|
4100
4178
|
node_type: n.type,
|
|
4101
|
-
message: `an overlay in ${
|
|
4179
|
+
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
4180
|
});
|
|
4103
4181
|
}
|
|
4104
4182
|
}
|
|
@@ -4900,9 +4978,9 @@ function checkOutputRef(ctx) {
|
|
|
4900
4978
|
function pushZodIssues(issues, err, pathPrefix, code, nodeId, nodeType) {
|
|
4901
4979
|
for (const issue of err.issues) {
|
|
4902
4980
|
const tail2 = pathToString(issue.path);
|
|
4903
|
-
const
|
|
4981
|
+
const path20 = pathPrefix ? tail2 ? `${pathPrefix}.${tail2}` : pathPrefix : tail2;
|
|
4904
4982
|
issues.push({
|
|
4905
|
-
path:
|
|
4983
|
+
path: path20,
|
|
4906
4984
|
code,
|
|
4907
4985
|
message: issue.message,
|
|
4908
4986
|
received: issue.code === "invalid_type" ? issue.received : void 0,
|
|
@@ -4911,8 +4989,8 @@ function pushZodIssues(issues, err, pathPrefix, code, nodeId, nodeType) {
|
|
|
4911
4989
|
});
|
|
4912
4990
|
}
|
|
4913
4991
|
}
|
|
4914
|
-
function pathToString(
|
|
4915
|
-
return
|
|
4992
|
+
function pathToString(path20) {
|
|
4993
|
+
return path20.map((p) => typeof p === "number" ? `[${p}]` : `.${String(p)}`).join("").replace(/^\./, "");
|
|
4916
4994
|
}
|
|
4917
4995
|
function buildDepGraph(canvas) {
|
|
4918
4996
|
const graph = /* @__PURE__ */ new Map();
|
|
@@ -5550,9 +5628,9 @@ var NodeRegistry = class {
|
|
|
5550
5628
|
|
|
5551
5629
|
// src/engine/nodes/ingest.ts
|
|
5552
5630
|
import { execFile as execFileCb } from "child_process";
|
|
5553
|
-
import { mkdtemp, readFile as
|
|
5631
|
+
import { mkdtemp, readFile as readFile5, rm, stat as stat2 } from "fs/promises";
|
|
5554
5632
|
import { tmpdir } from "os";
|
|
5555
|
-
import
|
|
5633
|
+
import path7 from "path";
|
|
5556
5634
|
import { promisify } from "util";
|
|
5557
5635
|
import { z as z5 } from "zod";
|
|
5558
5636
|
|
|
@@ -5872,12 +5950,12 @@ async function fetchExternalBytes(url, options) {
|
|
|
5872
5950
|
|
|
5873
5951
|
// src/lib/ytDlp.ts
|
|
5874
5952
|
import { spawn } from "child_process";
|
|
5875
|
-
import { readdir, readFile as
|
|
5876
|
-
import
|
|
5953
|
+
import { readdir, readFile as readFile4 } from "fs/promises";
|
|
5954
|
+
import path6 from "path";
|
|
5877
5955
|
|
|
5878
5956
|
// src/lib/vimeoCookie.ts
|
|
5879
5957
|
import { writeFile as writeFile3 } from "fs/promises";
|
|
5880
|
-
import
|
|
5958
|
+
import path5 from "path";
|
|
5881
5959
|
var COOKIE_NAME = "vimeo";
|
|
5882
5960
|
async function writeVimeoCookieFile(cookie, workDir) {
|
|
5883
5961
|
const value = cookie?.trim();
|
|
@@ -5888,7 +5966,7 @@ async function writeVimeoCookieFile(cookie, workDir) {
|
|
|
5888
5966
|
[".vimeo.com", "TRUE", "/", "TRUE", String(expires), COOKIE_NAME, value].join(" "),
|
|
5889
5967
|
""
|
|
5890
5968
|
].join("\n");
|
|
5891
|
-
const filePath =
|
|
5969
|
+
const filePath = path5.join(workDir, "vimeo-cookies.txt");
|
|
5892
5970
|
await writeFile3(filePath, jar, { mode: 384 });
|
|
5893
5971
|
return filePath;
|
|
5894
5972
|
}
|
|
@@ -5952,8 +6030,8 @@ function tail(text, maxLines) {
|
|
|
5952
6030
|
return text.split("\n").slice(-maxLines).join("\n");
|
|
5953
6031
|
}
|
|
5954
6032
|
async function runYtDlp(args) {
|
|
5955
|
-
const outTemplate =
|
|
5956
|
-
const infoPath =
|
|
6033
|
+
const outTemplate = path6.join(args.workDir, "out.%(ext)s");
|
|
6034
|
+
const infoPath = path6.join(args.workDir, "out.info.json");
|
|
5957
6035
|
const argv = [
|
|
5958
6036
|
args.url,
|
|
5959
6037
|
"--no-playlist",
|
|
@@ -5991,10 +6069,10 @@ async function runYtDlp(args) {
|
|
|
5991
6069
|
}
|
|
5992
6070
|
let info = {};
|
|
5993
6071
|
try {
|
|
5994
|
-
info = JSON.parse(await
|
|
6072
|
+
info = JSON.parse(await readFile4(infoPath, "utf-8"));
|
|
5995
6073
|
} catch {
|
|
5996
6074
|
}
|
|
5997
|
-
return { filePath:
|
|
6075
|
+
return { filePath: path6.join(args.workDir, downloaded), info, tier, reducedQuality };
|
|
5998
6076
|
}
|
|
5999
6077
|
async function probeYtDlp(args) {
|
|
6000
6078
|
const argv = [
|
|
@@ -6308,7 +6386,9 @@ function mapClientError(ctx, e) {
|
|
|
6308
6386
|
kind: "remote",
|
|
6309
6387
|
status: d.status,
|
|
6310
6388
|
code: "invalid_params",
|
|
6311
|
-
message: d.message
|
|
6389
|
+
message: d.message,
|
|
6390
|
+
// The request itself was refused; it fails the same way until the input changes.
|
|
6391
|
+
retryable: false
|
|
6312
6392
|
});
|
|
6313
6393
|
}
|
|
6314
6394
|
if (d.kind === "unauthorized") {
|
|
@@ -6503,8 +6583,8 @@ function resolveLocalPath(input) {
|
|
|
6503
6583
|
`ingest: ~ path expansion is not supported (got "${input}"). Use an absolute path or a cwd-relative path.`
|
|
6504
6584
|
);
|
|
6505
6585
|
}
|
|
6506
|
-
if (
|
|
6507
|
-
return
|
|
6586
|
+
if (path7.isAbsolute(input)) return input;
|
|
6587
|
+
return path7.resolve(process.cwd(), input);
|
|
6508
6588
|
}
|
|
6509
6589
|
var EXT_TO_MIME = {
|
|
6510
6590
|
png: "image/png",
|
|
@@ -6552,7 +6632,7 @@ function sniffSvg(buf) {
|
|
|
6552
6632
|
return head.startsWith("<?xml") ? head.includes("<svg") : head.startsWith("<svg");
|
|
6553
6633
|
}
|
|
6554
6634
|
function inferMimeFromPath(absPath, sniffBytes) {
|
|
6555
|
-
const ext =
|
|
6635
|
+
const ext = path7.extname(absPath).slice(1).toLowerCase();
|
|
6556
6636
|
const fromExt = EXT_TO_MIME[ext];
|
|
6557
6637
|
if (fromExt) return fromExt;
|
|
6558
6638
|
const fromBytes = sniffImageMime(sniffBytes);
|
|
@@ -6737,7 +6817,7 @@ async function execLocalFile(params, ctx) {
|
|
|
6737
6817
|
}
|
|
6738
6818
|
let bytes;
|
|
6739
6819
|
try {
|
|
6740
|
-
bytes = await
|
|
6820
|
+
bytes = await readFile5(absPath);
|
|
6741
6821
|
} catch (e) {
|
|
6742
6822
|
if (e.code === "EACCES") {
|
|
6743
6823
|
throw localExecError(ctx, `permission_denied: ${absPath}`);
|
|
@@ -6789,7 +6869,7 @@ function localFileMetadata(args) {
|
|
|
6789
6869
|
strategy: "local_file",
|
|
6790
6870
|
ingested_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6791
6871
|
file_size: args.fileSize,
|
|
6792
|
-
original_filename:
|
|
6872
|
+
original_filename: path7.basename(args.absPath),
|
|
6793
6873
|
...args.rasterizedFrom ? { rasterized_from: args.rasterizedFrom } : {},
|
|
6794
6874
|
...args.durationMs !== void 0 ? { duration_ms: args.durationMs } : {}
|
|
6795
6875
|
};
|
|
@@ -6811,7 +6891,7 @@ async function execYtDlp(params, ctx) {
|
|
|
6811
6891
|
if (params.expect !== "video" && params.expect !== "audio") {
|
|
6812
6892
|
throw new Error(`ingest: yt_dlp only handles video/audio, got expect=${params.expect}`);
|
|
6813
6893
|
}
|
|
6814
|
-
const workDir = await mkdtemp(
|
|
6894
|
+
const workDir = await mkdtemp(path7.join(tmpdir(), "ingest-yt-"));
|
|
6815
6895
|
try {
|
|
6816
6896
|
const { filePath, info, reducedQuality } = await runYtDlpForNode({
|
|
6817
6897
|
url: params.url,
|
|
@@ -6826,7 +6906,7 @@ async function execYtDlp(params, ctx) {
|
|
|
6826
6906
|
`file_too_large: yt-dlp output for ${params.url} is ${downloadedStats.size} bytes (limit ${MAX_ASSET_BYTES})`
|
|
6827
6907
|
);
|
|
6828
6908
|
}
|
|
6829
|
-
const bytes = await
|
|
6909
|
+
const bytes = await readFile5(filePath);
|
|
6830
6910
|
const kind = params.expect;
|
|
6831
6911
|
const mime = YT_DLP_MIME[kind];
|
|
6832
6912
|
const metadata = buildYtDlpMetadata(params.url, info);
|
|
@@ -6915,9 +6995,9 @@ import { z as z6 } from "zod";
|
|
|
6915
6995
|
|
|
6916
6996
|
// src/engine/nodes/local/lib/cli-runner.ts
|
|
6917
6997
|
import { execFile as execFileCb2, spawn as spawn2 } from "child_process";
|
|
6918
|
-
import { copyFile as copyFile2, mkdtemp as mkdtemp2, readFile as
|
|
6998
|
+
import { copyFile as copyFile2, mkdtemp as mkdtemp2, readFile as readFile6, rm as rm2, stat as stat3 } from "fs/promises";
|
|
6919
6999
|
import { tmpdir as tmpdir2 } from "os";
|
|
6920
|
-
import
|
|
7000
|
+
import path8 from "path";
|
|
6921
7001
|
import { promisify as promisify2 } from "util";
|
|
6922
7002
|
var execFile2 = promisify2(execFileCb2);
|
|
6923
7003
|
var DEFAULT_TIMEOUT_MS2 = 10 * 60 * 1e3;
|
|
@@ -6944,7 +7024,7 @@ function mimeForExt(ext) {
|
|
|
6944
7024
|
}
|
|
6945
7025
|
function extForAssetRef(ref) {
|
|
6946
7026
|
if (ref.path) {
|
|
6947
|
-
const e =
|
|
7027
|
+
const e = path8.extname(ref.path);
|
|
6948
7028
|
if (e) return e;
|
|
6949
7029
|
}
|
|
6950
7030
|
const reverse = {
|
|
@@ -6966,14 +7046,14 @@ function planArrayInputSlot(tmpDir, slot, values, lookup, stagedInputs) {
|
|
|
6966
7046
|
const ref = values[i];
|
|
6967
7047
|
if (!ref) continue;
|
|
6968
7048
|
if (!ref.path) throw new Error(`cli-runner: inputs.${slot}[${i}] has no local path`);
|
|
6969
|
-
const dest =
|
|
7049
|
+
const dest = path8.join(tmpDir, `in_${slot}_${i}${extForAssetRef(ref)}`);
|
|
6970
7050
|
stagedInputs.push({ srcPath: ref.path, destPath: dest });
|
|
6971
7051
|
lookup.set(`in.${slot}.${i}`, dest);
|
|
6972
7052
|
}
|
|
6973
7053
|
}
|
|
6974
7054
|
function planSingleInputSlot(tmpDir, slot, ref, lookup, stagedInputs) {
|
|
6975
7055
|
if (!ref.path) throw new Error(`cli-runner: inputs.${slot} has no local path`);
|
|
6976
|
-
const dest =
|
|
7056
|
+
const dest = path8.join(tmpDir, `in_${slot}${extForAssetRef(ref)}`);
|
|
6977
7057
|
stagedInputs.push({ srcPath: ref.path, destPath: dest });
|
|
6978
7058
|
lookup.set(`in.${slot}`, dest);
|
|
6979
7059
|
}
|
|
@@ -6981,7 +7061,7 @@ function planOutputs(tmpDir, outputs, lookup) {
|
|
|
6981
7061
|
const outputPaths = [];
|
|
6982
7062
|
for (const [name, spec] of Object.entries(outputs)) {
|
|
6983
7063
|
const ext = spec.ext.startsWith(".") ? spec.ext : `.${spec.ext}`;
|
|
6984
|
-
const absPath =
|
|
7064
|
+
const absPath = path8.join(tmpDir, `out_${name}${ext}`);
|
|
6985
7065
|
outputPaths.push({ name, absPath, spec });
|
|
6986
7066
|
lookup.set(`out.${name}`, absPath);
|
|
6987
7067
|
}
|
|
@@ -7022,8 +7102,8 @@ function rejectRawPaths(substituted, original, stagingDir) {
|
|
|
7022
7102
|
throw new Error(`cli-runner: home-relative path "${original}" not allowed in args.`);
|
|
7023
7103
|
}
|
|
7024
7104
|
if (substituted.startsWith("/")) {
|
|
7025
|
-
const resolved =
|
|
7026
|
-
if (!resolved.startsWith(`${stagingDir}${
|
|
7105
|
+
const resolved = path8.resolve(substituted);
|
|
7106
|
+
if (!resolved.startsWith(`${stagingDir}${path8.sep}`) && resolved !== stagingDir) {
|
|
7027
7107
|
throw new Error(
|
|
7028
7108
|
`cli-runner: raw filesystem path "${original}" not allowed \u2014 declare an input slot and use {{in.<slot>}} instead.`
|
|
7029
7109
|
);
|
|
@@ -7073,7 +7153,7 @@ function tailLines(text, maxLines) {
|
|
|
7073
7153
|
}
|
|
7074
7154
|
async function runCli(opts) {
|
|
7075
7155
|
const { bin, args, inputs, outputs, ctx, timeoutMs = DEFAULT_TIMEOUT_MS2 } = opts;
|
|
7076
|
-
const tmpDir = await mkdtemp2(
|
|
7156
|
+
const tmpDir = await mkdtemp2(path8.join(tmpdir2(), `cli-${bin.replace(/[^a-z0-9]/gi, "")}-`));
|
|
7077
7157
|
try {
|
|
7078
7158
|
const { lookup, stagedInputs, outputPaths } = planPlaceholders(tmpDir, inputs, outputs);
|
|
7079
7159
|
await stageInputs(stagedInputs);
|
|
@@ -7095,7 +7175,7 @@ ${tailLines(stderr, 40)}`);
|
|
|
7095
7175
|
if (!s?.isFile() || s.size === 0) {
|
|
7096
7176
|
throw new Error(`cli-runner: declared output "${name}" missing or empty at ${absPath}`);
|
|
7097
7177
|
}
|
|
7098
|
-
const bytes = await
|
|
7178
|
+
const bytes = await readFile6(absPath);
|
|
7099
7179
|
const ref = await ctx.assets.ingestBytes({
|
|
7100
7180
|
bytes: Buffer.from(bytes),
|
|
7101
7181
|
kind: spec.kind,
|
|
@@ -7365,17 +7445,17 @@ var ffmpegNode = defineNode({
|
|
|
7365
7445
|
import { mkdtemp as mkdtemp3, rm as rm3, writeFile as writeFile4 } from "fs/promises";
|
|
7366
7446
|
import { createRequire } from "module";
|
|
7367
7447
|
import { tmpdir as tmpdir3 } from "os";
|
|
7368
|
-
import
|
|
7448
|
+
import path10 from "path";
|
|
7369
7449
|
import { z as z9 } from "zod";
|
|
7370
7450
|
|
|
7371
7451
|
// src/engine/nodes/local/lib/assets.ts
|
|
7372
|
-
import { copyFile as copyFile3, readFile as
|
|
7373
|
-
import
|
|
7452
|
+
import { copyFile as copyFile3, readFile as readFile7 } from "fs/promises";
|
|
7453
|
+
import path9 from "path";
|
|
7374
7454
|
async function stageAsset(ref, destDir, filename) {
|
|
7375
7455
|
if (!ref.path) {
|
|
7376
7456
|
throw new Error(`stageAsset: ref (${ref.kind}/${ref.mime}) has no local path`);
|
|
7377
7457
|
}
|
|
7378
|
-
const dest =
|
|
7458
|
+
const dest = path9.join(destDir, filename);
|
|
7379
7459
|
await copyFile3(ref.path, dest);
|
|
7380
7460
|
return dest;
|
|
7381
7461
|
}
|
|
@@ -7384,7 +7464,7 @@ async function refToUrl(ref) {
|
|
|
7384
7464
|
if (!ref.path) {
|
|
7385
7465
|
throw new Error("refToUrl: AssetRef has neither url nor path");
|
|
7386
7466
|
}
|
|
7387
|
-
const bytes = await
|
|
7467
|
+
const bytes = await readFile7(ref.path);
|
|
7388
7468
|
return `data:${ref.mime};base64,${bytes.toString("base64")}`;
|
|
7389
7469
|
}
|
|
7390
7470
|
var ASSET_KINDS = /* @__PURE__ */ new Set(["image", "video", "audio", "json", "text", "font"]);
|
|
@@ -7458,11 +7538,11 @@ var fontSpecimenNode = defineNode({
|
|
|
7458
7538
|
outputKinds: { image: "image" },
|
|
7459
7539
|
cost: () => ({ credits: 0, seconds_estimate: 5 }),
|
|
7460
7540
|
async execute({ inputs, params, ctx }) {
|
|
7461
|
-
const tmp = await mkdtemp3(
|
|
7541
|
+
const tmp = await mkdtemp3(path10.join(tmpdir3(), "font-specimen-"));
|
|
7462
7542
|
try {
|
|
7463
7543
|
const fontFilename = `font.${extForMime(inputs.font.mime)}`;
|
|
7464
7544
|
await stageAsset(inputs.font, tmp, fontFilename);
|
|
7465
|
-
const entryPath =
|
|
7545
|
+
const entryPath = path10.join(tmp, "index.html");
|
|
7466
7546
|
await writeFile4(entryPath, buildSpecimenHtml(params, fontFilename), "utf-8");
|
|
7467
7547
|
ctx.log(`rendering specimen (${params.font_size}px, ${params.text.split("\n").length} lines)`);
|
|
7468
7548
|
const pwSpecifier = ["play", "wright"].join("");
|
|
@@ -7546,16 +7626,16 @@ var fontSpecimenNode = defineNode({
|
|
|
7546
7626
|
|
|
7547
7627
|
// src/engine/nodes/local/hyperframe.ts
|
|
7548
7628
|
import { execFile as execFile4 } from "child_process";
|
|
7549
|
-
import { copyFile as copyFile4, mkdtemp as mkdtemp4, readFile as
|
|
7629
|
+
import { copyFile as copyFile4, mkdtemp as mkdtemp4, readFile as readFile11, rm as rm4, stat as stat5, writeFile as writeFile6 } from "fs/promises";
|
|
7550
7630
|
import { createRequire as createRequire2 } from "module";
|
|
7551
7631
|
import { cpus, tmpdir as tmpdir4 } from "os";
|
|
7552
|
-
import
|
|
7632
|
+
import path15 from "path";
|
|
7553
7633
|
import { promisify as promisify4 } from "util";
|
|
7554
7634
|
import { z as z11 } from "zod";
|
|
7555
7635
|
|
|
7556
7636
|
// src/engine/engine/composition-hash.ts
|
|
7557
|
-
import { readdir as readdir2, readFile as
|
|
7558
|
-
import
|
|
7637
|
+
import { readdir as readdir2, readFile as readFile8, stat as stat4 } from "fs/promises";
|
|
7638
|
+
import path11 from "path";
|
|
7559
7639
|
var SKIP_DIRS = /* @__PURE__ */ new Set([".cache", ".git", "node_modules", "dist", "build", ".next", ".turbo"]);
|
|
7560
7640
|
function isSkippedName(name) {
|
|
7561
7641
|
if (name.startsWith(".")) return true;
|
|
@@ -7572,23 +7652,23 @@ async function collectFiles(root, current) {
|
|
|
7572
7652
|
const names = await readdir2(current);
|
|
7573
7653
|
for (const name of names) {
|
|
7574
7654
|
if (isSkippedName(name)) continue;
|
|
7575
|
-
const abs =
|
|
7655
|
+
const abs = path11.join(current, name);
|
|
7576
7656
|
const s = await stat4(abs);
|
|
7577
7657
|
if (s.isDirectory()) {
|
|
7578
7658
|
out.push(...await collectFiles(root, abs));
|
|
7579
7659
|
continue;
|
|
7580
7660
|
}
|
|
7581
7661
|
if (!s.isFile()) continue;
|
|
7582
|
-
const bytes = await
|
|
7583
|
-
const relPath =
|
|
7662
|
+
const bytes = await readFile8(abs);
|
|
7663
|
+
const relPath = path11.relative(root, abs).split(path11.sep).join("/");
|
|
7584
7664
|
out.push({ relPath, contentSha: sha256Hex(bytes) });
|
|
7585
7665
|
}
|
|
7586
7666
|
return out;
|
|
7587
7667
|
}
|
|
7588
7668
|
|
|
7589
7669
|
// src/engine/engine/composition-meta.ts
|
|
7590
|
-
import { readFile as
|
|
7591
|
-
import
|
|
7670
|
+
import { readFile as readFile9 } from "fs/promises";
|
|
7671
|
+
import path12 from "path";
|
|
7592
7672
|
import { z as z10 } from "zod";
|
|
7593
7673
|
var InputKind = z10.enum(["video", "image", "audio", "json"]);
|
|
7594
7674
|
var InputSpec = z10.object({
|
|
@@ -7665,10 +7745,10 @@ var CompositionMetaSchema = z10.object({
|
|
|
7665
7745
|
params: z10.record(z10.string(), ParamSpec).default({})
|
|
7666
7746
|
}).strict();
|
|
7667
7747
|
async function loadCompositionMeta(compositionDir) {
|
|
7668
|
-
const metaPath =
|
|
7748
|
+
const metaPath = path12.join(compositionDir, "meta.json");
|
|
7669
7749
|
let raw;
|
|
7670
7750
|
try {
|
|
7671
|
-
raw = await
|
|
7751
|
+
raw = await readFile9(metaPath, "utf-8");
|
|
7672
7752
|
} catch (e) {
|
|
7673
7753
|
throw new Error(`composition meta: cannot read ${metaPath} (${e.message})`);
|
|
7674
7754
|
}
|
|
@@ -7746,8 +7826,8 @@ function defaultFilenameForInput(key, kind) {
|
|
|
7746
7826
|
|
|
7747
7827
|
// src/engine/nodes/local/lib/hyperframe-check.ts
|
|
7748
7828
|
import { execFile as execFile3 } from "child_process";
|
|
7749
|
-
import { readFile as
|
|
7750
|
-
import
|
|
7829
|
+
import { readFile as readFile10 } from "fs/promises";
|
|
7830
|
+
import path13 from "path";
|
|
7751
7831
|
import { promisify as promisify3 } from "util";
|
|
7752
7832
|
|
|
7753
7833
|
// src/engine/nodes/local/lib/caption-style.ts
|
|
@@ -7971,7 +8051,7 @@ async function runSnapshotSmoke(args, timeoutMs) {
|
|
|
7971
8051
|
}
|
|
7972
8052
|
async function runNestedCompositionSmoke(opts) {
|
|
7973
8053
|
const { dir, nodeId, ctx, timeoutMs, samples } = opts;
|
|
7974
|
-
const indexHtml = await
|
|
8054
|
+
const indexHtml = await readFile10(path13.join(dir, "index.html"), "utf-8").catch(() => "");
|
|
7975
8055
|
if (!indexHtml || !usesNestedCompositions(indexHtml)) return;
|
|
7976
8056
|
const snap = await runSnapshotSmoke(
|
|
7977
8057
|
buildSnapshotArgs(dir, Math.min(samples, 3), hasFrameVisionKey()),
|
|
@@ -7987,7 +8067,7 @@ async function runNestedCompositionSmoke(opts) {
|
|
|
7987
8067
|
${snap.message}`
|
|
7988
8068
|
);
|
|
7989
8069
|
}
|
|
7990
|
-
const described = await
|
|
8070
|
+
const described = await readFile10(path13.join(dir, "snapshots", "descriptions.md"), "utf-8").catch(() => "");
|
|
7991
8071
|
for (const line of condenseFrameDescriptions(described)) {
|
|
7992
8072
|
ctx.log(`${nodeId}: frame check \u2014 ${line}`);
|
|
7993
8073
|
}
|
|
@@ -8023,7 +8103,7 @@ async function runHyperframesCheck(opts) {
|
|
|
8023
8103
|
${detail}`
|
|
8024
8104
|
);
|
|
8025
8105
|
}
|
|
8026
|
-
const composition = await
|
|
8106
|
+
const composition = await readFile10(path13.join(dir, "index.html"), "utf-8").catch(() => "");
|
|
8027
8107
|
const captionComplaint = fragmentedCaptions(captionTextsFrom(composition));
|
|
8028
8108
|
if (captionComplaint) {
|
|
8029
8109
|
ctx.log(`${nodeId}: caption style \u2014 ${captionComplaint}`);
|
|
@@ -8077,9 +8157,9 @@ ${stderr.slice(0, 1500)}`;
|
|
|
8077
8157
|
|
|
8078
8158
|
// src/engine/nodes/local/lib/hyperframe-meta.ts
|
|
8079
8159
|
import { writeFile as writeFile5 } from "fs/promises";
|
|
8080
|
-
import
|
|
8160
|
+
import path14 from "path";
|
|
8081
8161
|
async function ensureHyperframesMetaJson(tmp, nodeId, meta, duration) {
|
|
8082
|
-
const metaPath =
|
|
8162
|
+
const metaPath = path14.join(tmp, "meta.json");
|
|
8083
8163
|
await writeFile5(
|
|
8084
8164
|
metaPath,
|
|
8085
8165
|
JSON.stringify(
|
|
@@ -8179,7 +8259,7 @@ var hyperframeRenderNode = defineNode({
|
|
|
8179
8259
|
const compositionDir = await resolveCompositionDir(params.composition);
|
|
8180
8260
|
const meta = await loadCompositionMeta(compositionDir);
|
|
8181
8261
|
const compositionParams = validateAndParseDynamicParams(meta, params);
|
|
8182
|
-
const tmp = await mkdtemp4(
|
|
8262
|
+
const tmp = await mkdtemp4(path15.join(tmpdir4(), "hf-render-"));
|
|
8183
8263
|
try {
|
|
8184
8264
|
await copyComposition(compositionDir, tmp);
|
|
8185
8265
|
await vendorGsap(tmp, ctx);
|
|
@@ -8189,9 +8269,9 @@ var hyperframeRenderNode = defineNode({
|
|
|
8189
8269
|
await substituteCompositionFiles(tmp, substitutionValues);
|
|
8190
8270
|
await ensureHyperframesMetaJson(tmp, ctx.nodeId, meta, duration);
|
|
8191
8271
|
await runHyperframesCheck({ dir: tmp, nodeId: "hyperframe_render", ctx, timeoutMs: params.timeout_ms });
|
|
8192
|
-
const outputPath =
|
|
8272
|
+
const outputPath = path15.join(tmp, `output.${params.format}`);
|
|
8193
8273
|
await runRender({ tmp, outputPath, params, meta, ctx });
|
|
8194
|
-
const bytes = await
|
|
8274
|
+
const bytes = await readFile11(outputPath);
|
|
8195
8275
|
ctx.log(`rendered ${bytes.length} bytes`);
|
|
8196
8276
|
const ref = await ctx.assets.ingestBytes({
|
|
8197
8277
|
bytes: Buffer.from(bytes),
|
|
@@ -8213,10 +8293,10 @@ var hyperframeRenderNode = defineNode({
|
|
|
8213
8293
|
}
|
|
8214
8294
|
});
|
|
8215
8295
|
async function resolveCompositionDir(composition) {
|
|
8216
|
-
const compositionPath =
|
|
8296
|
+
const compositionPath = path15.isAbsolute(composition) ? composition : path15.resolve(process.cwd(), composition);
|
|
8217
8297
|
const s = await stat5(compositionPath);
|
|
8218
8298
|
if (s.isDirectory()) return compositionPath;
|
|
8219
|
-
return
|
|
8299
|
+
return path15.dirname(compositionPath);
|
|
8220
8300
|
}
|
|
8221
8301
|
async function validateComposition(rawParams) {
|
|
8222
8302
|
const issues = await validateCompositionParams(rawParams);
|
|
@@ -8298,7 +8378,7 @@ async function copyComposition(srcDir, destDir) {
|
|
|
8298
8378
|
await cp(srcDir, destDir, {
|
|
8299
8379
|
recursive: true,
|
|
8300
8380
|
filter: (src) => {
|
|
8301
|
-
const name =
|
|
8381
|
+
const name = path15.basename(src);
|
|
8302
8382
|
if (name === ".cache" || name === "node_modules" || name === ".git") return false;
|
|
8303
8383
|
return true;
|
|
8304
8384
|
}
|
|
@@ -8307,7 +8387,7 @@ async function copyComposition(srcDir, destDir) {
|
|
|
8307
8387
|
async function vendorGsap(tmp, ctx) {
|
|
8308
8388
|
try {
|
|
8309
8389
|
const gsapMin = require_2.resolve("gsap/dist/gsap.min.js");
|
|
8310
|
-
await copyFile4(gsapMin,
|
|
8390
|
+
await copyFile4(gsapMin, path15.join(tmp, "gsap.min.js"));
|
|
8311
8391
|
} catch (e) {
|
|
8312
8392
|
ctx.log(`warning: could not vendor gsap.min.js (${e.message}); compositions must self-supply`);
|
|
8313
8393
|
}
|
|
@@ -8322,7 +8402,7 @@ async function stageInputs2(tmp, inputs, meta, ctx) {
|
|
|
8322
8402
|
await stageAsset(ref, tmp, filename);
|
|
8323
8403
|
ctx.log(`staged ${spec.kind} \u2192 ${filename}`);
|
|
8324
8404
|
if (spec.kind === "video" && primaryDuration === null) {
|
|
8325
|
-
primaryDuration = await probeDurationSeconds(
|
|
8405
|
+
primaryDuration = await probeDurationSeconds(path15.join(tmp, filename));
|
|
8326
8406
|
}
|
|
8327
8407
|
}
|
|
8328
8408
|
return primaryDuration;
|
|
@@ -8368,8 +8448,8 @@ function coerceImageParam(value) {
|
|
|
8368
8448
|
throw new Error("hyperframe_render: image param must be a URL string or AssetRef");
|
|
8369
8449
|
}
|
|
8370
8450
|
async function substituteCompositionFiles(tmp, values) {
|
|
8371
|
-
const entryPath =
|
|
8372
|
-
const original = await
|
|
8451
|
+
const entryPath = path15.join(tmp, "index.html");
|
|
8452
|
+
const original = await readFile11(entryPath, "utf-8");
|
|
8373
8453
|
const { output, missing } = substituteVariables(original, values);
|
|
8374
8454
|
if (missing.length > 0) {
|
|
8375
8455
|
throw new Error(
|
|
@@ -8385,7 +8465,7 @@ function workerCount() {
|
|
|
8385
8465
|
async function runRender(opts) {
|
|
8386
8466
|
const { tmp, outputPath, params, meta, ctx } = opts;
|
|
8387
8467
|
const args = buildRenderArgs(tmp, outputPath, meta, params.format);
|
|
8388
|
-
ctx.log(`rendering ${meta.width}x${meta.height}@${meta.fps}fps ${params.format} from ${
|
|
8468
|
+
ctx.log(`rendering ${meta.width}x${meta.height}@${meta.fps}fps ${params.format} from ${path15.basename(tmp)}`);
|
|
8389
8469
|
try {
|
|
8390
8470
|
await execFileAsync2("npx", args, { timeout: params.timeout_ms, maxBuffer: 64 * 1024 * 1024 });
|
|
8391
8471
|
} catch (e) {
|
|
@@ -8429,10 +8509,10 @@ async function probeDurationSeconds(filePath) {
|
|
|
8429
8509
|
|
|
8430
8510
|
// src/engine/nodes/local/hyperframe-snapshot.ts
|
|
8431
8511
|
import { execFile as execFile5 } from "child_process";
|
|
8432
|
-
import { copyFile as copyFile5, mkdtemp as mkdtemp5, readFile as
|
|
8512
|
+
import { copyFile as copyFile5, mkdtemp as mkdtemp5, readFile as readFile12, rm as rm5, writeFile as writeFile7 } from "fs/promises";
|
|
8433
8513
|
import { createRequire as createRequire3 } from "module";
|
|
8434
8514
|
import { tmpdir as tmpdir5 } from "os";
|
|
8435
|
-
import
|
|
8515
|
+
import path16 from "path";
|
|
8436
8516
|
import { promisify as promisify5 } from "util";
|
|
8437
8517
|
import { z as z12 } from "zod";
|
|
8438
8518
|
var _execFileAsync = promisify5(execFile5);
|
|
@@ -8479,7 +8559,7 @@ var hyperframeSnapshotNode = defineNode({
|
|
|
8479
8559
|
const compositionDir = await resolveCompositionDir(params.composition);
|
|
8480
8560
|
const meta = await loadCompositionMeta(compositionDir);
|
|
8481
8561
|
const compositionParams = validateAndParseDynamicParams2(meta, params);
|
|
8482
|
-
const tmp = await mkdtemp5(
|
|
8562
|
+
const tmp = await mkdtemp5(path16.join(tmpdir5(), "hf-snap-"));
|
|
8483
8563
|
try {
|
|
8484
8564
|
await copyComposition2(compositionDir, tmp);
|
|
8485
8565
|
await vendorGsap2(tmp, ctx);
|
|
@@ -8494,7 +8574,7 @@ var hyperframeSnapshotNode = defineNode({
|
|
|
8494
8574
|
timeoutMs: params.timeout_ms,
|
|
8495
8575
|
samples: 1
|
|
8496
8576
|
});
|
|
8497
|
-
const entryPath =
|
|
8577
|
+
const entryPath = path16.join(tmp, "index.html");
|
|
8498
8578
|
const entryUrl = `file://${entryPath}`;
|
|
8499
8579
|
ctx.log(`snapshotting ${meta.width}x${meta.height}@${DEVICE_SCALE_FACTOR2}x wait=${params.wait_for.kind}`);
|
|
8500
8580
|
const pwSpecifier = ["play", "wright"].join("");
|
|
@@ -8555,7 +8635,7 @@ async function copyComposition2(srcDir, destDir) {
|
|
|
8555
8635
|
await cp(srcDir, destDir, {
|
|
8556
8636
|
recursive: true,
|
|
8557
8637
|
filter: (src) => {
|
|
8558
|
-
const name =
|
|
8638
|
+
const name = path16.basename(src);
|
|
8559
8639
|
if (name === ".cache" || name === "node_modules" || name === ".git") return false;
|
|
8560
8640
|
return true;
|
|
8561
8641
|
}
|
|
@@ -8564,7 +8644,7 @@ async function copyComposition2(srcDir, destDir) {
|
|
|
8564
8644
|
async function vendorGsap2(tmp, ctx) {
|
|
8565
8645
|
try {
|
|
8566
8646
|
const gsapMin = require_3.resolve("gsap/dist/gsap.min.js");
|
|
8567
|
-
await copyFile5(gsapMin,
|
|
8647
|
+
await copyFile5(gsapMin, path16.join(tmp, "gsap.min.js"));
|
|
8568
8648
|
} catch (e) {
|
|
8569
8649
|
ctx.log(`warning: could not vendor gsap.min.js (${e.message}); compositions must self-supply`);
|
|
8570
8650
|
}
|
|
@@ -8598,8 +8678,8 @@ function coerceImageParam2(value) {
|
|
|
8598
8678
|
throw new Error("hyperframe_snapshot: image param must be a URL string or AssetRef");
|
|
8599
8679
|
}
|
|
8600
8680
|
async function substituteCompositionFiles2(tmp, values) {
|
|
8601
|
-
const entryPath =
|
|
8602
|
-
const original = await
|
|
8681
|
+
const entryPath = path16.join(tmp, "index.html");
|
|
8682
|
+
const original = await readFile12(entryPath, "utf-8");
|
|
8603
8683
|
const { output, missing } = substituteVariables(original, values);
|
|
8604
8684
|
if (missing.length > 0) {
|
|
8605
8685
|
throw new Error(
|
|
@@ -9366,9 +9446,9 @@ var videoLipsyncNode = delegated({
|
|
|
9366
9446
|
});
|
|
9367
9447
|
|
|
9368
9448
|
// src/engine/nodes/remote/videoTranscribe.ts
|
|
9369
|
-
import { mkdtemp as mkdtemp6, readFile as
|
|
9449
|
+
import { mkdtemp as mkdtemp6, readFile as readFile13, rm as rm6 } from "fs/promises";
|
|
9370
9450
|
import { tmpdir as tmpdir6 } from "os";
|
|
9371
|
-
import
|
|
9451
|
+
import path17 from "path";
|
|
9372
9452
|
import { z as z33 } from "zod";
|
|
9373
9453
|
|
|
9374
9454
|
// src/engine/nodes/local/lib/ffmpeg.ts
|
|
@@ -9506,14 +9586,14 @@ async function tryExtractAudio(inputs, ctx) {
|
|
|
9506
9586
|
ctx.log("video_transcribe: no audio track detected, sending full video");
|
|
9507
9587
|
return null;
|
|
9508
9588
|
}
|
|
9509
|
-
tmpDir = await mkdtemp6(
|
|
9510
|
-
const audioPath =
|
|
9589
|
+
tmpDir = await mkdtemp6(path17.join(tmpdir6(), "vtx-"));
|
|
9590
|
+
const audioPath = path17.join(tmpDir, "audio.mp3");
|
|
9511
9591
|
ctx.log("video_transcribe: extracting audio (mono 16kHz mp3)");
|
|
9512
9592
|
await runFfmpeg(
|
|
9513
9593
|
["-i", video.path, "-vn", "-ac", "1", "-ar", "16000", "-b:a", "64k", "-f", "mp3", "-y", audioPath],
|
|
9514
9594
|
{ timeout_ms: AUDIO_EXTRACT_TIMEOUT_MS }
|
|
9515
9595
|
);
|
|
9516
|
-
const bytes = await
|
|
9596
|
+
const bytes = await readFile13(audioPath);
|
|
9517
9597
|
if (bytes.byteLength === 0) {
|
|
9518
9598
|
ctx.log("video_transcribe: extracted audio is empty, sending full video");
|
|
9519
9599
|
return null;
|
|
@@ -9704,19 +9784,19 @@ function safeCost(def) {
|
|
|
9704
9784
|
|
|
9705
9785
|
// src/engine/storage/cache-store.ts
|
|
9706
9786
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
9707
|
-
import { mkdir as mkdir3, readFile as
|
|
9708
|
-
import
|
|
9787
|
+
import { mkdir as mkdir3, readFile as readFile14, rename as rename2, writeFile as writeFile8 } from "fs/promises";
|
|
9788
|
+
import path18 from "path";
|
|
9709
9789
|
var LocalCacheStore = class {
|
|
9710
9790
|
rootDir;
|
|
9711
9791
|
constructor(rootDir) {
|
|
9712
9792
|
this.rootDir = rootDir;
|
|
9713
9793
|
}
|
|
9714
9794
|
filePath(cacheKey) {
|
|
9715
|
-
return
|
|
9795
|
+
return path18.join(this.rootDir, `${cacheKey}.json`);
|
|
9716
9796
|
}
|
|
9717
9797
|
async get(cacheKey) {
|
|
9718
9798
|
try {
|
|
9719
|
-
const buf = await
|
|
9799
|
+
const buf = await readFile14(this.filePath(cacheKey), "utf8");
|
|
9720
9800
|
return JSON.parse(buf);
|
|
9721
9801
|
} catch (e) {
|
|
9722
9802
|
if (e.code === "ENOENT") return null;
|
|
@@ -9725,7 +9805,7 @@ var LocalCacheStore = class {
|
|
|
9725
9805
|
}
|
|
9726
9806
|
async put(entry) {
|
|
9727
9807
|
const dest = this.filePath(entry.cacheKey);
|
|
9728
|
-
await mkdir3(
|
|
9808
|
+
await mkdir3(path18.dirname(dest), { recursive: true });
|
|
9729
9809
|
const tmp = `${dest}.tmp-${process.pid}-${randomUUID2()}`;
|
|
9730
9810
|
await writeFile8(tmp, JSON.stringify(entry, null, 0));
|
|
9731
9811
|
await rename2(tmp, dest);
|
|
@@ -9781,12 +9861,12 @@ function defaultRegistry() {
|
|
|
9781
9861
|
}
|
|
9782
9862
|
function createEngineFromEnv(opts = {}) {
|
|
9783
9863
|
const cwd = opts.cwd ?? process.cwd();
|
|
9784
|
-
const cacheDir = opts.cacheDir ??
|
|
9785
|
-
const outputsDir = opts.outputsDir ??
|
|
9864
|
+
const cacheDir = opts.cacheDir ?? path19.join(cwd, "canvas", ".cache");
|
|
9865
|
+
const outputsDir = opts.outputsDir ?? path19.join(cwd, "canvas");
|
|
9786
9866
|
const connection = requireConnection();
|
|
9787
9867
|
const client = new BackendClient({ baseUrl: connection.BAKER_API_URL, apiKey: connection.BAKER_API_KEY });
|
|
9788
|
-
const assets = new LocalAssetStore(
|
|
9789
|
-
const localCache = new LocalCacheStore(
|
|
9868
|
+
const assets = new LocalAssetStore(path19.join(cacheDir, "assets"));
|
|
9869
|
+
const localCache = new LocalCacheStore(path19.join(cacheDir, "index"));
|
|
9790
9870
|
const remoteCacheEnabled = opts.remoteCache ?? remoteCacheEnabledFromEnv();
|
|
9791
9871
|
const cache = remoteCacheEnabled ? new LayeredCacheStore({
|
|
9792
9872
|
local: localCache,
|
|
@@ -9811,6 +9891,7 @@ export {
|
|
|
9811
9891
|
RunAbortedError,
|
|
9812
9892
|
LayerExecutionError,
|
|
9813
9893
|
describeFailureReason,
|
|
9894
|
+
runFailureCode,
|
|
9814
9895
|
AD_FORMAT_PLATFORMS,
|
|
9815
9896
|
platformFormats,
|
|
9816
9897
|
withoutCastName,
|
|
@@ -9866,7 +9947,6 @@ export {
|
|
|
9866
9947
|
isAudioOnly,
|
|
9867
9948
|
durationSeconds,
|
|
9868
9949
|
canonicalUrl,
|
|
9869
|
-
coercePathUrlToUrl,
|
|
9870
9950
|
toModelSafeImage,
|
|
9871
9951
|
catalogView,
|
|
9872
9952
|
BackendClient2,
|
|
@@ -9879,4 +9959,4 @@ export {
|
|
|
9879
9959
|
defaultRegistry,
|
|
9880
9960
|
createEngineFromEnv
|
|
9881
9961
|
};
|
|
9882
|
-
//# sourceMappingURL=chunk-
|
|
9962
|
+
//# sourceMappingURL=chunk-RZWMHH4X.js.map
|