@koda-sl/baker-cli 0.369.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.
- package/README.md +7 -0
- package/dist/{chunk-AI4HWQVN.js → chunk-3NIBJ3GL.js} +191 -109
- package/dist/chunk-3NIBJ3GL.js.map +1 -0
- package/dist/cli.js +61 -15
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-AI4HWQVN.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,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" || !
|
|
4092
|
-
const html = await
|
|
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 ${
|
|
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
|
|
4982
|
+
const path20 = pathPrefix ? tail2 ? `${pathPrefix}.${tail2}` : pathPrefix : tail2;
|
|
4904
4983
|
issues.push({
|
|
4905
|
-
path:
|
|
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(
|
|
4915
|
-
return
|
|
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
|
|
5653
|
+
import { mkdtemp, readFile as readFile5, rm, stat as stat2 } from "fs/promises";
|
|
5575
5654
|
import { tmpdir } from "os";
|
|
5576
|
-
import
|
|
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
|
|
5897
|
-
import
|
|
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
|
|
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 =
|
|
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 =
|
|
5977
|
-
const infoPath =
|
|
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
|
|
6094
|
+
info = JSON.parse(await readFile4(infoPath, "utf-8"));
|
|
6016
6095
|
} catch {
|
|
6017
6096
|
}
|
|
6018
|
-
return { filePath:
|
|
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 (
|
|
6528
|
-
return
|
|
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 =
|
|
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
|
|
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:
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
7047
|
-
if (!resolved.startsWith(`${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(
|
|
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
|
|
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
|
|
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
|
|
7394
|
-
import
|
|
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 =
|
|
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
|
|
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(
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
7579
|
-
import
|
|
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 =
|
|
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
|
|
7604
|
-
const relPath =
|
|
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
|
|
7612
|
-
import
|
|
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 =
|
|
7770
|
+
const metaPath = path12.join(compositionDir, "meta.json");
|
|
7690
7771
|
let raw;
|
|
7691
7772
|
try {
|
|
7692
|
-
raw = await
|
|
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
|
|
7771
|
-
import
|
|
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
|
|
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
|
|
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
|
|
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
|
|
8182
|
+
import path14 from "path";
|
|
8102
8183
|
async function ensureHyperframesMetaJson(tmp, nodeId, meta, duration) {
|
|
8103
|
-
const metaPath =
|
|
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(
|
|
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 =
|
|
8294
|
+
const outputPath = path15.join(tmp, `output.${params.format}`);
|
|
8214
8295
|
await runRender({ tmp, outputPath, params, meta, ctx });
|
|
8215
|
-
const bytes = await
|
|
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 =
|
|
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
|
|
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 =
|
|
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,
|
|
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(
|
|
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 =
|
|
8393
|
-
const original = await
|
|
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 ${
|
|
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
|
|
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
|
|
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(
|
|
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 =
|
|
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 =
|
|
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,
|
|
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 =
|
|
8623
|
-
const original = await
|
|
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
|
|
9471
|
+
import { mkdtemp as mkdtemp6, readFile as readFile13, rm as rm6 } from "fs/promises";
|
|
9391
9472
|
import { tmpdir as tmpdir6 } from "os";
|
|
9392
|
-
import
|
|
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(
|
|
9531
|
-
const audioPath =
|
|
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
|
|
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
|
|
9733
|
-
import
|
|
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
|
|
9821
|
+
return path18.join(this.rootDir, `${cacheKey}.json`);
|
|
9741
9822
|
}
|
|
9742
9823
|
async get(cacheKey) {
|
|
9743
9824
|
try {
|
|
9744
|
-
const buf = await
|
|
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(
|
|
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 ??
|
|
9810
|
-
const outputsDir = opts.outputsDir ??
|
|
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(
|
|
9814
|
-
const localCache = new LocalCacheStore(
|
|
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-
|
|
9989
|
+
//# sourceMappingURL=chunk-3NIBJ3GL.js.map
|