@koda-sl/baker-cli 0.352.0 → 0.353.0-dev.0a55fe912
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 +2 -1
- package/dist/{chunk-4HRJQGVW.js → chunk-Q2VR3FVM.js} +20 -7
- package/dist/chunk-Q2VR3FVM.js.map +1 -0
- package/dist/cli.js +199 -168
- package/dist/cli.js.map +1 -1
- package/dist/engine/index.d.ts +8 -0
- package/dist/engine/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-4HRJQGVW.js.map +0 -1
package/dist/cli.js
CHANGED
|
@@ -42,6 +42,7 @@ import {
|
|
|
42
42
|
isAudioOnly,
|
|
43
43
|
isPersistedAssetRef,
|
|
44
44
|
isVimeoAuthFailure,
|
|
45
|
+
loadCompositionMeta,
|
|
45
46
|
looksLikeHttpUrl,
|
|
46
47
|
maxInputReferences,
|
|
47
48
|
maxInputSlot,
|
|
@@ -68,7 +69,7 @@ import {
|
|
|
68
69
|
validateCanvasDeep,
|
|
69
70
|
withoutCastName,
|
|
70
71
|
ytDlpBlockSignal
|
|
71
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-Q2VR3FVM.js";
|
|
72
73
|
import {
|
|
73
74
|
csvOrJson,
|
|
74
75
|
daysAgoIso,
|
|
@@ -35531,7 +35532,49 @@ import { defineCommand as defineCommand119 } from "citty";
|
|
|
35531
35532
|
|
|
35532
35533
|
// src/commands/canvas/catalog.ts
|
|
35533
35534
|
import { defineCommand as defineCommand108 } from "citty";
|
|
35534
|
-
|
|
35535
|
+
|
|
35536
|
+
// src/commands/canvas/composition-path.ts
|
|
35537
|
+
import { existsSync as existsSync4 } from "fs";
|
|
35538
|
+
import { readdir as readdir2 } from "fs/promises";
|
|
35539
|
+
import path3 from "path";
|
|
35540
|
+
function resolveShippedCanvasDir(name, startDir, exists2 = existsSync4, maxDepth = 8) {
|
|
35541
|
+
const rel = path3.join("canvas", name);
|
|
35542
|
+
let dir = startDir;
|
|
35543
|
+
for (let i = 0; i < maxDepth; i++) {
|
|
35544
|
+
const candidate = path3.join(dir, rel);
|
|
35545
|
+
if (exists2(path3.join(candidate, "meta.json"))) return candidate;
|
|
35546
|
+
const parent = path3.dirname(dir);
|
|
35547
|
+
if (parent === dir) break;
|
|
35548
|
+
dir = parent;
|
|
35549
|
+
}
|
|
35550
|
+
return path3.resolve(startDir, "../../../", rel);
|
|
35551
|
+
}
|
|
35552
|
+
async function listShippedCompositions(startDir, maxDepth = 8) {
|
|
35553
|
+
let dir = startDir;
|
|
35554
|
+
for (let i = 0; i < maxDepth; i++) {
|
|
35555
|
+
const root = path3.join(dir, "canvas");
|
|
35556
|
+
const found = await compositionsIn(root);
|
|
35557
|
+
if (found.length > 0) return found.sort((a, b) => a.id.localeCompare(b.id));
|
|
35558
|
+
const parent = path3.dirname(dir);
|
|
35559
|
+
if (parent === dir) break;
|
|
35560
|
+
dir = parent;
|
|
35561
|
+
}
|
|
35562
|
+
return [];
|
|
35563
|
+
}
|
|
35564
|
+
async function compositionsIn(root) {
|
|
35565
|
+
const children = await readdir2(root, { withFileTypes: true }).catch(() => []);
|
|
35566
|
+
const loaded = await Promise.all(
|
|
35567
|
+
children.filter((child) => child.isDirectory()).map(async (child) => {
|
|
35568
|
+
const compositionDir = path3.join(root, child.name);
|
|
35569
|
+
const meta = await loadCompositionMeta(compositionDir).catch(() => null);
|
|
35570
|
+
return meta ? { id: meta.id, title: meta.title, dir: compositionDir } : null;
|
|
35571
|
+
})
|
|
35572
|
+
);
|
|
35573
|
+
return loaded.filter((c) => c !== null);
|
|
35574
|
+
}
|
|
35575
|
+
|
|
35576
|
+
// src/commands/canvas/catalog.ts
|
|
35577
|
+
var DESCRIPTION = "The canvas node catalog. Start here: `baker canvas catalog` lists every node by category with one line each (a few KB). Then `--node video_generate` prints that node's full JSON Schema \u2014 params, inputs, outputs, models, when to use it. `--category image` narrows the list; add `--full` for that category's schemas. `--full` alone prints every schema (~160 KB) \u2014 prefer `--node`. The unfiltered list also carries `compositions` \u2014 ready-made motion graphics, each with the `dir` to copy next to your canvas.";
|
|
35535
35578
|
var ARGS = {
|
|
35536
35579
|
node: {
|
|
35537
35580
|
type: "string",
|
|
@@ -35550,12 +35593,16 @@ var ARGS = {
|
|
|
35550
35593
|
description: "Print full JSON Schemas instead of the one-line index (every node, or the --category)."
|
|
35551
35594
|
}
|
|
35552
35595
|
};
|
|
35596
|
+
async function canvasCatalog(opts) {
|
|
35597
|
+
const compositions = await listShippedCompositions(import.meta.dirname);
|
|
35598
|
+
return catalogView(generateCatalog(defaultRegistry(), { compositions }), opts);
|
|
35599
|
+
}
|
|
35553
35600
|
registerSchema({ command: "canvas.catalog", description: DESCRIPTION, args: ARGS });
|
|
35554
35601
|
var catalogCommand = defineCommand108({
|
|
35555
35602
|
meta: { name: "catalog", description: DESCRIPTION },
|
|
35556
35603
|
args: ARGS,
|
|
35557
35604
|
async run({ args: args5 }) {
|
|
35558
|
-
const view =
|
|
35605
|
+
const view = await canvasCatalog({
|
|
35559
35606
|
node: typeof args5.node === "string" ? args5.node : void 0,
|
|
35560
35607
|
category: typeof args5.category === "string" ? args5.category : void 0,
|
|
35561
35608
|
full: args5.full === true
|
|
@@ -35568,7 +35615,7 @@ var catalogCommand = defineCommand108({
|
|
|
35568
35615
|
|
|
35569
35616
|
// src/commands/canvas/critique.ts
|
|
35570
35617
|
import { readFile as readFile3 } from "fs/promises";
|
|
35571
|
-
import
|
|
35618
|
+
import path4 from "path";
|
|
35572
35619
|
import { defineCommand as defineCommand109 } from "citty";
|
|
35573
35620
|
|
|
35574
35621
|
// src/engine/scaffold/lib/critique.ts
|
|
@@ -35696,7 +35743,7 @@ var critiqueCommand = defineCommand109({
|
|
|
35696
35743
|
},
|
|
35697
35744
|
args: { file: { type: "positional", required: true, description: "Path to canvas JSON" } },
|
|
35698
35745
|
async run({ args: args5 }) {
|
|
35699
|
-
const filePath =
|
|
35746
|
+
const filePath = path4.resolve(String(args5.file));
|
|
35700
35747
|
const raw = await readFile3(filePath, "utf8");
|
|
35701
35748
|
let parsed;
|
|
35702
35749
|
try {
|
|
@@ -35728,8 +35775,8 @@ var critiqueCommand = defineCommand109({
|
|
|
35728
35775
|
|
|
35729
35776
|
// src/commands/canvas/inspect.ts
|
|
35730
35777
|
import { execFile } from "child_process";
|
|
35731
|
-
import { readdir as
|
|
35732
|
-
import
|
|
35778
|
+
import { readdir as readdir3, readFile as readFile4, stat } from "fs/promises";
|
|
35779
|
+
import path5 from "path";
|
|
35733
35780
|
import { promisify } from "util";
|
|
35734
35781
|
import { defineCommand as defineCommand110 } from "citty";
|
|
35735
35782
|
var execFileAsync = promisify(execFile);
|
|
@@ -35747,7 +35794,7 @@ var inspectCommand = defineCommand110({
|
|
|
35747
35794
|
}
|
|
35748
35795
|
},
|
|
35749
35796
|
async run({ args: args5 }) {
|
|
35750
|
-
const outputsDir =
|
|
35797
|
+
const outputsDir = path5.resolve(String(args5["outputs-dir"] ?? "canvas"));
|
|
35751
35798
|
const runArg = String(args5.run);
|
|
35752
35799
|
const runDir = await resolveRunDir(runArg, outputsDir);
|
|
35753
35800
|
const manifest = await loadManifest(runDir);
|
|
@@ -35759,7 +35806,7 @@ var inspectCommand = defineCommand110({
|
|
|
35759
35806
|
}
|
|
35760
35807
|
const summary = {
|
|
35761
35808
|
ok: true,
|
|
35762
|
-
run_id: manifest.run_id ??
|
|
35809
|
+
run_id: manifest.run_id ?? path5.basename(runDir),
|
|
35763
35810
|
run_dir: runDir,
|
|
35764
35811
|
stats: manifest.stats ?? null,
|
|
35765
35812
|
output: manifest.output ?? null,
|
|
@@ -35772,18 +35819,18 @@ var inspectCommand = defineCommand110({
|
|
|
35772
35819
|
}
|
|
35773
35820
|
});
|
|
35774
35821
|
async function resolveRunDir(run, outputsDir) {
|
|
35775
|
-
if (
|
|
35822
|
+
if (path5.isAbsolute(run)) {
|
|
35776
35823
|
const s2 = await stat(run).catch(() => null);
|
|
35777
35824
|
if (s2?.isDirectory()) return run;
|
|
35778
35825
|
throw new Error(`inspect: ${run} is not a directory`);
|
|
35779
35826
|
}
|
|
35780
|
-
const candidate =
|
|
35827
|
+
const candidate = path5.join(outputsDir, run);
|
|
35781
35828
|
const s = await stat(candidate).catch(() => null);
|
|
35782
35829
|
if (s?.isDirectory()) return candidate;
|
|
35783
35830
|
throw new Error(`inspect: no run directory at ${candidate}`);
|
|
35784
35831
|
}
|
|
35785
35832
|
async function loadManifest(runDir) {
|
|
35786
|
-
const manifestPath =
|
|
35833
|
+
const manifestPath = path5.join(runDir, "manifest.json");
|
|
35787
35834
|
try {
|
|
35788
35835
|
const raw = await readFile4(manifestPath, "utf-8");
|
|
35789
35836
|
return JSON.parse(raw);
|
|
@@ -35793,9 +35840,9 @@ async function loadManifest(runDir) {
|
|
|
35793
35840
|
}
|
|
35794
35841
|
async function listRunFiles(runDir) {
|
|
35795
35842
|
const out = [];
|
|
35796
|
-
const names = await
|
|
35843
|
+
const names = await readdir3(runDir);
|
|
35797
35844
|
for (const name of names) {
|
|
35798
|
-
const abs =
|
|
35845
|
+
const abs = path5.join(runDir, name);
|
|
35799
35846
|
const s = await stat(abs).catch(() => null);
|
|
35800
35847
|
if (!s?.isFile()) continue;
|
|
35801
35848
|
out.push({ name, path: abs, size: s.size });
|
|
@@ -35840,58 +35887,58 @@ async function probeDuration(filePath) {
|
|
|
35840
35887
|
}
|
|
35841
35888
|
|
|
35842
35889
|
// src/commands/canvas/rerun.ts
|
|
35843
|
-
import
|
|
35890
|
+
import path18 from "path";
|
|
35844
35891
|
import { defineCommand as defineCommand112 } from "citty";
|
|
35845
35892
|
|
|
35846
35893
|
// src/commands/canvas/run.ts
|
|
35847
35894
|
import { readFile as readFile12 } from "fs/promises";
|
|
35848
|
-
import
|
|
35895
|
+
import path17 from "path";
|
|
35849
35896
|
import { defineCommand as defineCommand111 } from "citty";
|
|
35850
35897
|
|
|
35851
35898
|
// src/commands/canvas/normalize-paths.ts
|
|
35852
|
-
import { existsSync as
|
|
35899
|
+
import { existsSync as existsSync5, realpathSync } from "fs";
|
|
35853
35900
|
import { writeFile as writeFile2 } from "fs/promises";
|
|
35854
|
-
import
|
|
35855
|
-
function findWorkspaceRoot(startDir, exists2 =
|
|
35856
|
-
let dir =
|
|
35901
|
+
import path6 from "path";
|
|
35902
|
+
function findWorkspaceRoot(startDir, exists2 = existsSync5, maxDepth = 12) {
|
|
35903
|
+
let dir = path6.resolve(startDir);
|
|
35857
35904
|
for (let i = 0; i < maxDepth; i++) {
|
|
35858
|
-
if (exists2(
|
|
35859
|
-
const parent =
|
|
35905
|
+
if (exists2(path6.join(dir, "package.json"))) return dir;
|
|
35906
|
+
const parent = path6.dirname(dir);
|
|
35860
35907
|
if (parent === dir) break;
|
|
35861
35908
|
dir = parent;
|
|
35862
35909
|
}
|
|
35863
35910
|
return null;
|
|
35864
35911
|
}
|
|
35865
35912
|
function canonicalize(target) {
|
|
35866
|
-
const abs =
|
|
35913
|
+
const abs = path6.resolve(target);
|
|
35867
35914
|
let dir = abs;
|
|
35868
35915
|
for (; ; ) {
|
|
35869
35916
|
try {
|
|
35870
35917
|
const real = realpathSync(dir);
|
|
35871
|
-
return dir === abs ? real :
|
|
35918
|
+
return dir === abs ? real : path6.join(real, path6.relative(dir, abs));
|
|
35872
35919
|
} catch {
|
|
35873
|
-
const parent =
|
|
35920
|
+
const parent = path6.dirname(dir);
|
|
35874
35921
|
if (parent === dir) return abs;
|
|
35875
35922
|
dir = parent;
|
|
35876
35923
|
}
|
|
35877
35924
|
}
|
|
35878
35925
|
}
|
|
35879
35926
|
function isInside(root, target) {
|
|
35880
|
-
const rel =
|
|
35881
|
-
return rel !== "" && !rel.startsWith("..") && !
|
|
35927
|
+
const rel = path6.relative(root, target);
|
|
35928
|
+
return rel !== "" && !rel.startsWith("..") && !path6.isAbsolute(rel);
|
|
35882
35929
|
}
|
|
35883
35930
|
function toCanvasRelative(canvasDir, target) {
|
|
35884
|
-
return
|
|
35931
|
+
return path6.relative(canvasDir, target).split(path6.sep).join("/");
|
|
35885
35932
|
}
|
|
35886
35933
|
var RUNTIME_WORKSPACE_ROOT = "/home/user/repo";
|
|
35887
35934
|
function rewriteTarget(value, workspaceRoot) {
|
|
35888
35935
|
if (typeof value !== "string" || value.length === 0) return null;
|
|
35889
|
-
if (value.includes("[TODO") || looksLikeHttpUrl(value) || !
|
|
35936
|
+
if (value.includes("[TODO") || looksLikeHttpUrl(value) || !path6.isAbsolute(value)) return null;
|
|
35890
35937
|
const target = canonicalize(value);
|
|
35891
35938
|
if (isInside(workspaceRoot, target)) return target;
|
|
35892
|
-
const fromRuntime =
|
|
35893
|
-
if (fromRuntime !== "" && !fromRuntime.startsWith("..") && !
|
|
35894
|
-
return
|
|
35939
|
+
const fromRuntime = path6.relative(RUNTIME_WORKSPACE_ROOT, path6.normalize(value));
|
|
35940
|
+
if (fromRuntime !== "" && !fromRuntime.startsWith("..") && !path6.isAbsolute(fromRuntime)) {
|
|
35941
|
+
return path6.join(workspaceRoot, fromRuntime);
|
|
35895
35942
|
}
|
|
35896
35943
|
return null;
|
|
35897
35944
|
}
|
|
@@ -35919,7 +35966,7 @@ function normalizeAbsoluteCanvasPaths(canvas, canvasDir, workspaceRoot) {
|
|
|
35919
35966
|
return rewrites.length === 0 ? { canvas, rewrites } : { canvas: { ...canvas, nodes }, rewrites };
|
|
35920
35967
|
}
|
|
35921
35968
|
async function healAbsoluteCanvasPaths(filePath, canvas) {
|
|
35922
|
-
const canvasDir =
|
|
35969
|
+
const canvasDir = path6.dirname(filePath);
|
|
35923
35970
|
const workspaceRoot = findWorkspaceRoot(canvasDir);
|
|
35924
35971
|
if (!workspaceRoot) return { canvas, rewrites: [], text: null };
|
|
35925
35972
|
const normalized = normalizeAbsoluteCanvasPaths(canvas, canvasDir, workspaceRoot);
|
|
@@ -35950,7 +35997,7 @@ function unsuppliedPlaceholderAssets(canvas) {
|
|
|
35950
35997
|
}
|
|
35951
35998
|
|
|
35952
35999
|
// src/commands/canvas/resolve-paths.ts
|
|
35953
|
-
import
|
|
36000
|
+
import path7 from "path";
|
|
35954
36001
|
function resolveRelativeCanvasPaths(canvas, baseDir) {
|
|
35955
36002
|
if (!canvas || typeof canvas !== "object") return canvas;
|
|
35956
36003
|
const c = canvas;
|
|
@@ -35963,24 +36010,24 @@ function resolveNode(node, baseDir) {
|
|
|
35963
36010
|
const params = n.params;
|
|
35964
36011
|
if (!params || typeof params !== "object") return node;
|
|
35965
36012
|
if (n.type === "ingest" && params.source === "path" && isResolvableRelative(params.path)) {
|
|
35966
|
-
return { ...node, params: { ...params, path:
|
|
36013
|
+
return { ...node, params: { ...params, path: path7.resolve(baseDir, params.path) } };
|
|
35967
36014
|
}
|
|
35968
36015
|
if (n.type === "hyperframe_render" && isResolvableRelative(params.composition)) {
|
|
35969
|
-
return { ...node, params: { ...params, composition:
|
|
36016
|
+
return { ...node, params: { ...params, composition: path7.resolve(baseDir, params.composition) } };
|
|
35970
36017
|
}
|
|
35971
36018
|
return node;
|
|
35972
36019
|
}
|
|
35973
36020
|
function isResolvableRelative(value) {
|
|
35974
|
-
return typeof value === "string" && value.length > 0 && !value.includes("[TODO") && !looksLikeHttpUrl(value) && !
|
|
36021
|
+
return typeof value === "string" && value.length > 0 && !value.includes("[TODO") && !looksLikeHttpUrl(value) && !path7.isAbsolute(value);
|
|
35975
36022
|
}
|
|
35976
36023
|
|
|
35977
36024
|
// src/commands/canvas/source-version.ts
|
|
35978
36025
|
import { readFile as readFile6 } from "fs/promises";
|
|
35979
|
-
import
|
|
36026
|
+
import path9 from "path";
|
|
35980
36027
|
|
|
35981
36028
|
// src/commands/canvas/scene-files.ts
|
|
35982
|
-
import { mkdir as mkdir2, readFile as readFile5, readdir as
|
|
35983
|
-
import
|
|
36029
|
+
import { mkdir as mkdir2, readFile as readFile5, readdir as readdir4, rm, writeFile as writeFile3 } from "fs/promises";
|
|
36030
|
+
import path8 from "path";
|
|
35984
36031
|
var SCENES_DIR = "scenes";
|
|
35985
36032
|
var GLOBAL_PROMPT_FILE = "prompt.json";
|
|
35986
36033
|
var REBUILD_FILE = "prompt.rebuild.json";
|
|
@@ -35997,38 +36044,38 @@ function splitBlueprint(blueprint) {
|
|
|
35997
36044
|
}
|
|
35998
36045
|
async function writeSceneFiles(outDir, blueprint) {
|
|
35999
36046
|
const { global, scenes } = splitBlueprint(blueprint);
|
|
36000
|
-
await writeFile3(
|
|
36047
|
+
await writeFile3(path8.join(outDir, GLOBAL_PROMPT_FILE), `${JSON.stringify(global, null, 2)}
|
|
36001
36048
|
`, "utf8");
|
|
36002
|
-
const scenesDir =
|
|
36049
|
+
const scenesDir = path8.join(outDir, SCENES_DIR);
|
|
36003
36050
|
await mkdir2(scenesDir, { recursive: true });
|
|
36004
36051
|
const written = /* @__PURE__ */ new Set();
|
|
36005
36052
|
for (let i = 0; i < scenes.length; i++) {
|
|
36006
36053
|
const name = sceneFileName(i, scenes.length);
|
|
36007
36054
|
written.add(name);
|
|
36008
|
-
await writeFile3(
|
|
36055
|
+
await writeFile3(path8.join(scenesDir, name), `${JSON.stringify(scenes[i], null, 2)}
|
|
36009
36056
|
`, "utf8");
|
|
36010
36057
|
}
|
|
36011
36058
|
for (const name of await listSceneFileNames(scenesDir)) {
|
|
36012
|
-
if (!written.has(name)) await rm(
|
|
36059
|
+
if (!written.has(name)) await rm(path8.join(scenesDir, name), { force: true });
|
|
36013
36060
|
}
|
|
36014
36061
|
}
|
|
36015
36062
|
async function listSceneFileNames(scenesDir) {
|
|
36016
36063
|
let entries;
|
|
36017
36064
|
try {
|
|
36018
|
-
entries = await
|
|
36065
|
+
entries = await readdir4(scenesDir);
|
|
36019
36066
|
} catch {
|
|
36020
36067
|
return [];
|
|
36021
36068
|
}
|
|
36022
36069
|
return entries.filter((n) => /^s\d+\.json$/.test(n)).sort(bySceneIndex);
|
|
36023
36070
|
}
|
|
36024
36071
|
async function listSceneFiles(creativeDir) {
|
|
36025
|
-
const scenesDir =
|
|
36026
|
-
return (await listSceneFileNames(scenesDir)).map((n) =>
|
|
36072
|
+
const scenesDir = path8.join(creativeDir, SCENES_DIR);
|
|
36073
|
+
return (await listSceneFileNames(scenesDir)).map((n) => path8.join(scenesDir, n));
|
|
36027
36074
|
}
|
|
36028
36075
|
async function reassembleBlueprint(creativeDir) {
|
|
36029
36076
|
const files = await listSceneFiles(creativeDir);
|
|
36030
36077
|
if (files.length === 0) return null;
|
|
36031
|
-
const globalRaw = await readFile5(
|
|
36078
|
+
const globalRaw = await readFile5(path8.join(creativeDir, GLOBAL_PROMPT_FILE), "utf8");
|
|
36032
36079
|
const global = JSON.parse(globalRaw);
|
|
36033
36080
|
const scenes = [];
|
|
36034
36081
|
for (const file of files) {
|
|
@@ -36050,8 +36097,8 @@ async function computeSourceSha(canvasPath) {
|
|
|
36050
36097
|
} catch {
|
|
36051
36098
|
return void 0;
|
|
36052
36099
|
}
|
|
36053
|
-
const canvasDir =
|
|
36054
|
-
const promptPath =
|
|
36100
|
+
const canvasDir = path9.dirname(canvasPath);
|
|
36101
|
+
const promptPath = path9.join(canvasDir, "prompt.json");
|
|
36055
36102
|
let promptBytes;
|
|
36056
36103
|
try {
|
|
36057
36104
|
promptBytes = await readFile6(promptPath);
|
|
@@ -36078,7 +36125,7 @@ async function computeSourceSha(canvasPath) {
|
|
|
36078
36125
|
|
|
36079
36126
|
// src/commands/canvas/scene-projection.ts
|
|
36080
36127
|
import { readFile as readFile7 } from "fs/promises";
|
|
36081
|
-
import
|
|
36128
|
+
import path10 from "path";
|
|
36082
36129
|
|
|
36083
36130
|
// src/engine/scaffold/video.ts
|
|
36084
36131
|
import { toCardinal as nwAr } from "n2words/ar-SA";
|
|
@@ -39484,12 +39531,12 @@ function nonPromptParamsDiverge(live = {}, rebuilt = {}) {
|
|
|
39484
39531
|
return false;
|
|
39485
39532
|
}
|
|
39486
39533
|
async function syncSceneNodeParams(canvas, canvasPath, log) {
|
|
39487
|
-
const creativeDir =
|
|
39534
|
+
const creativeDir = path10.dirname(canvasPath);
|
|
39488
39535
|
const blueprint = await reassembleBlueprint(creativeDir);
|
|
39489
39536
|
if (!blueprint) return "not_applicable";
|
|
39490
39537
|
let rebuildRaw;
|
|
39491
39538
|
try {
|
|
39492
|
-
rebuildRaw = await readFile7(
|
|
39539
|
+
rebuildRaw = await readFile7(path10.join(creativeDir, REBUILD_FILE), "utf8");
|
|
39493
39540
|
} catch {
|
|
39494
39541
|
log(
|
|
39495
39542
|
`[scenes] this creative has scene files but no ${REBUILD_FILE}, so edits to scenes/*.json are NOT reaching the render \u2014 the prompts inlined in the canvas are what renders. Re-scaffold the creative to restore the link, or edit the canvas node prompts directly.`
|
|
@@ -39624,13 +39671,13 @@ ${body}` : header || body || compactJson(record);
|
|
|
39624
39671
|
}
|
|
39625
39672
|
|
|
39626
39673
|
// src/commands/canvas/run-record.ts
|
|
39627
|
-
import
|
|
39674
|
+
import path11 from "path";
|
|
39628
39675
|
var MAX_RUN_NODES = 200;
|
|
39629
39676
|
var MAX_OUTPUTS_PER_NODE = 10;
|
|
39630
39677
|
var MAX_FINAL_OUTPUTS = 10;
|
|
39631
39678
|
var MAX_CREATIVE_SLUG_LENGTH = 100;
|
|
39632
39679
|
function creativeSlugFromCanvasPath(filePath) {
|
|
39633
|
-
const normalized = filePath.split(
|
|
39680
|
+
const normalized = filePath.split(path11.sep).join("/");
|
|
39634
39681
|
const match = normalized.match(/(?:^|\/)src\/creatives\/([a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\//);
|
|
39635
39682
|
const slug = match?.[1] ?? null;
|
|
39636
39683
|
return slug && slug.length <= MAX_CREATIVE_SLUG_LENGTH ? slug : null;
|
|
@@ -39923,24 +39970,24 @@ var RunRecordPoster = class {
|
|
|
39923
39970
|
|
|
39924
39971
|
// src/commands/canvas/run-retention.ts
|
|
39925
39972
|
import { rm as rm2 } from "fs/promises";
|
|
39926
|
-
import
|
|
39973
|
+
import path12 from "path";
|
|
39927
39974
|
function runDirsToPrune(entries, keep, currentRunId) {
|
|
39928
39975
|
const runs = entries.filter((e) => /^r_[0-9A-Za-z]+$/.test(e) && e !== currentRunId).sort();
|
|
39929
39976
|
if (keep <= 0) return runs;
|
|
39930
39977
|
return runs.slice(0, Math.max(0, runs.length - keep));
|
|
39931
39978
|
}
|
|
39932
39979
|
async function pruneOldRuns(outputsDir, keep, currentRunId, log) {
|
|
39933
|
-
const { readdir:
|
|
39980
|
+
const { readdir: readdir17 } = await import("fs/promises");
|
|
39934
39981
|
let entries;
|
|
39935
39982
|
try {
|
|
39936
|
-
entries = await
|
|
39983
|
+
entries = await readdir17(outputsDir);
|
|
39937
39984
|
} catch {
|
|
39938
39985
|
return;
|
|
39939
39986
|
}
|
|
39940
39987
|
const toPrune = runDirsToPrune(entries, keep, currentRunId);
|
|
39941
39988
|
if (toPrune.length === 0) return;
|
|
39942
39989
|
for (const dir of toPrune) {
|
|
39943
|
-
await rm2(
|
|
39990
|
+
await rm2(path12.join(outputsDir, dir), { recursive: true, force: true }).catch(
|
|
39944
39991
|
(e) => log(`[prune ] could not remove ${dir}: ${e.message}`)
|
|
39945
39992
|
);
|
|
39946
39993
|
}
|
|
@@ -39948,13 +39995,13 @@ async function pruneOldRuns(outputsDir, keep, currentRunId, log) {
|
|
|
39948
39995
|
}
|
|
39949
39996
|
|
|
39950
39997
|
// src/commands/canvas/dirty-marker.ts
|
|
39951
|
-
import { mkdir as mkdir3, readdir as
|
|
39952
|
-
import
|
|
39998
|
+
import { mkdir as mkdir3, readdir as readdir5, rm as rm3, writeFile as writeFile5 } from "fs/promises";
|
|
39999
|
+
import path13 from "path";
|
|
39953
40000
|
function creativeDirtyDir(base) {
|
|
39954
|
-
return base ??
|
|
40001
|
+
return base ?? path13.resolve("canvas", ".dirty");
|
|
39955
40002
|
}
|
|
39956
40003
|
function dirtyMarkerFile(slug, base) {
|
|
39957
|
-
return
|
|
40004
|
+
return path13.join(creativeDirtyDir(base), `${slug}.json`);
|
|
39958
40005
|
}
|
|
39959
40006
|
async function clearCreativeDirty(slug, base) {
|
|
39960
40007
|
try {
|
|
@@ -39965,17 +40012,17 @@ async function clearCreativeDirty(slug, base) {
|
|
|
39965
40012
|
|
|
39966
40013
|
// src/commands/canvas/run-resume.ts
|
|
39967
40014
|
import { mkdir as mkdir4, readFile as readFile9, rm as rm4, writeFile as writeFile6 } from "fs/promises";
|
|
39968
|
-
import
|
|
40015
|
+
import path14 from "path";
|
|
39969
40016
|
function markerKey(canvasPath) {
|
|
39970
40017
|
const slug = creativeSlugFromCanvasPath(canvasPath);
|
|
39971
|
-
const identity = slug ??
|
|
40018
|
+
const identity = slug ?? path14.relative(process.cwd(), path14.resolve(canvasPath));
|
|
39972
40019
|
return sha256Hex(Buffer.from(identity)).slice(0, 32);
|
|
39973
40020
|
}
|
|
39974
40021
|
function legacyMarkerKey(canvasPath) {
|
|
39975
|
-
return sha256Hex(Buffer.from(
|
|
40022
|
+
return sha256Hex(Buffer.from(path14.resolve(canvasPath))).slice(0, 32);
|
|
39976
40023
|
}
|
|
39977
40024
|
function markerFile(outputsDir, key) {
|
|
39978
|
-
return
|
|
40025
|
+
return path14.join(outputsDir, ".inflight", `${key}.json`);
|
|
39979
40026
|
}
|
|
39980
40027
|
var REMOTE_ADOPT_STALE_MS = 12e4;
|
|
39981
40028
|
function classifyRemoteRun(run, now) {
|
|
@@ -40022,8 +40069,8 @@ async function readMarkerRunId(outputsDir, canvasPath) {
|
|
|
40022
40069
|
async function markRunInFlight(outputsDir, canvasPath, runId) {
|
|
40023
40070
|
try {
|
|
40024
40071
|
const file = markerFile(outputsDir, markerKey(canvasPath));
|
|
40025
|
-
await mkdir4(
|
|
40026
|
-
await writeFile6(file, JSON.stringify({ runId, canvasPath:
|
|
40072
|
+
await mkdir4(path14.dirname(file), { recursive: true });
|
|
40073
|
+
await writeFile6(file, JSON.stringify({ runId, canvasPath: path14.resolve(canvasPath), startedAt: Date.now() }));
|
|
40027
40074
|
} catch {
|
|
40028
40075
|
}
|
|
40029
40076
|
}
|
|
@@ -40037,8 +40084,8 @@ async function clearRunMarker(outputsDir, canvasPath) {
|
|
|
40037
40084
|
}
|
|
40038
40085
|
|
|
40039
40086
|
// src/commands/canvas/run-snapshot.ts
|
|
40040
|
-
import { mkdir as mkdir5, readdir as
|
|
40041
|
-
import
|
|
40087
|
+
import { mkdir as mkdir5, readdir as readdir6, readFile as readFile10, stat as stat2, writeFile as writeFile7 } from "fs/promises";
|
|
40088
|
+
import path15 from "path";
|
|
40042
40089
|
var SNAPSHOT_SCHEMA = "baker-canvas-snapshot/1";
|
|
40043
40090
|
var MAX_SNAPSHOT_FILE_BYTES = 32 * 1024 * 1024;
|
|
40044
40091
|
var EXT_TO_MIME = {
|
|
@@ -40065,15 +40112,15 @@ var EXT_TO_MIME = {
|
|
|
40065
40112
|
woff2: "font/woff2"
|
|
40066
40113
|
};
|
|
40067
40114
|
function mimeForFile(filePath) {
|
|
40068
|
-
const ext =
|
|
40115
|
+
const ext = path15.extname(filePath).slice(1).toLowerCase();
|
|
40069
40116
|
return EXT_TO_MIME[ext] ?? "application/octet-stream";
|
|
40070
40117
|
}
|
|
40071
40118
|
function toPosix(p) {
|
|
40072
|
-
return p.split(
|
|
40119
|
+
return p.split(path15.sep).join("/");
|
|
40073
40120
|
}
|
|
40074
40121
|
function isInside2(dir, target) {
|
|
40075
|
-
const rel =
|
|
40076
|
-
return !rel.startsWith("..") && !
|
|
40122
|
+
const rel = path15.relative(dir, target);
|
|
40123
|
+
return !rel.startsWith("..") && !path15.isAbsolute(rel);
|
|
40077
40124
|
}
|
|
40078
40125
|
function localPathRefsFromCanvas(parsed) {
|
|
40079
40126
|
const nodes = parsed?.nodes;
|
|
@@ -40098,24 +40145,24 @@ function isSnapshotablePath(value) {
|
|
|
40098
40145
|
async function sourceRefsToSnapshot(canvasDir, parsed) {
|
|
40099
40146
|
const refs = new Set(localPathRefsFromCanvas(parsed));
|
|
40100
40147
|
for (const sceneFile of await listSceneFiles(canvasDir)) {
|
|
40101
|
-
refs.add(toPosix(
|
|
40148
|
+
refs.add(toPosix(path15.relative(canvasDir, sceneFile)));
|
|
40102
40149
|
}
|
|
40103
40150
|
refs.add(REBUILD_FILE);
|
|
40104
40151
|
return [...refs];
|
|
40105
40152
|
}
|
|
40106
40153
|
async function uploadRunSnapshot(client, opts) {
|
|
40107
40154
|
try {
|
|
40108
|
-
const canvasDir =
|
|
40155
|
+
const canvasDir = path15.dirname(opts.canvasPath);
|
|
40109
40156
|
const put = (bytes, mime) => putContentAddressed(client, bytes, mime, opts.signal);
|
|
40110
40157
|
const canvasBytes = Buffer.from(opts.raw);
|
|
40111
40158
|
const canvasUpload = await put(canvasBytes, "application/json");
|
|
40112
40159
|
const files = [];
|
|
40113
40160
|
const skipped = [];
|
|
40114
40161
|
for (const refPath of await sourceRefsToSnapshot(canvasDir, opts.parsed)) {
|
|
40115
|
-
const abs =
|
|
40162
|
+
const abs = path15.isAbsolute(refPath) ? refPath : path15.resolve(canvasDir, refPath);
|
|
40116
40163
|
if (!isInside2(canvasDir, abs)) {
|
|
40117
40164
|
skipped.push({
|
|
40118
|
-
path: toPosix(
|
|
40165
|
+
path: toPosix(path15.relative(canvasDir, abs)),
|
|
40119
40166
|
reason: "outside the creative folder \u2014 read from the workspace on rerun"
|
|
40120
40167
|
});
|
|
40121
40168
|
continue;
|
|
@@ -40124,12 +40171,12 @@ async function uploadRunSnapshot(client, opts) {
|
|
|
40124
40171
|
try {
|
|
40125
40172
|
st = await stat2(abs);
|
|
40126
40173
|
} catch {
|
|
40127
|
-
skipped.push({ path: toPosix(
|
|
40174
|
+
skipped.push({ path: toPosix(path15.relative(canvasDir, abs)), reason: "missing" });
|
|
40128
40175
|
continue;
|
|
40129
40176
|
}
|
|
40130
40177
|
const fileList = st.isDirectory() ? await listFilesRecursive(abs) : [abs];
|
|
40131
40178
|
for (const file of fileList) {
|
|
40132
|
-
const rel = toPosix(
|
|
40179
|
+
const rel = toPosix(path15.relative(canvasDir, file));
|
|
40133
40180
|
const size = (await stat2(file)).size;
|
|
40134
40181
|
if (size > MAX_SNAPSHOT_FILE_BYTES) {
|
|
40135
40182
|
skipped.push({ path: rel, reason: `too large (${size} bytes)` });
|
|
@@ -40144,7 +40191,7 @@ async function uploadRunSnapshot(client, opts) {
|
|
|
40144
40191
|
schema: SNAPSHOT_SCHEMA,
|
|
40145
40192
|
creativeSlug: opts.creativeSlug,
|
|
40146
40193
|
canvasSha: canvasUpload.sha256,
|
|
40147
|
-
canvas: { path:
|
|
40194
|
+
canvas: { path: path15.basename(opts.canvasPath), sha256: canvasUpload.sha256, url: canvasUpload.url },
|
|
40148
40195
|
files,
|
|
40149
40196
|
skipped: skipped.length > 0 ? skipped : void 0
|
|
40150
40197
|
};
|
|
@@ -40170,8 +40217,8 @@ async function putContentAddressed(client, bytes, mime, signal) {
|
|
|
40170
40217
|
return { sha256, url: publicUrl };
|
|
40171
40218
|
}
|
|
40172
40219
|
async function listFilesRecursive(dir) {
|
|
40173
|
-
const entries = await
|
|
40174
|
-
return entries.filter((d) => d.isFile()).map((d) =>
|
|
40220
|
+
const entries = await readdir6(dir, { recursive: true, withFileTypes: true });
|
|
40221
|
+
return entries.filter((d) => d.isFile()).map((d) => path15.join(d.parentPath, d.name));
|
|
40175
40222
|
}
|
|
40176
40223
|
var SnapshotConflictError = class extends Error {
|
|
40177
40224
|
conflicts;
|
|
@@ -40183,16 +40230,16 @@ var SnapshotConflictError = class extends Error {
|
|
|
40183
40230
|
};
|
|
40184
40231
|
async function restoreRunSnapshot(manifest, targetDir, opts = {}) {
|
|
40185
40232
|
const entries = [manifest.canvas, ...manifest.files];
|
|
40186
|
-
const resolvedTarget =
|
|
40233
|
+
const resolvedTarget = path15.resolve(targetDir);
|
|
40187
40234
|
const planned = [];
|
|
40188
40235
|
const conflicts = [];
|
|
40189
40236
|
const upToDate = [];
|
|
40190
40237
|
for (const entry of entries) {
|
|
40191
|
-
if (
|
|
40238
|
+
if (path15.isAbsolute(entry.path) || entry.path.split("/").includes("..")) {
|
|
40192
40239
|
throw new Error(`snapshot entry escapes the creative directory: ${entry.path}`);
|
|
40193
40240
|
}
|
|
40194
|
-
const target =
|
|
40195
|
-
if (target !== resolvedTarget && !target.startsWith(resolvedTarget +
|
|
40241
|
+
const target = path15.resolve(resolvedTarget, entry.path);
|
|
40242
|
+
if (target !== resolvedTarget && !target.startsWith(resolvedTarget + path15.sep)) {
|
|
40196
40243
|
throw new Error(`snapshot entry escapes the creative directory: ${entry.path}`);
|
|
40197
40244
|
}
|
|
40198
40245
|
const existing = await readFile10(target).catch(() => null);
|
|
@@ -40217,18 +40264,18 @@ async function restoreRunSnapshot(manifest, targetDir, opts = {}) {
|
|
|
40217
40264
|
if (sha256Hex(bytes) !== entry.sha256) {
|
|
40218
40265
|
throw new Error(`snapshot download for ${entry.path} does not match its recorded sha256`);
|
|
40219
40266
|
}
|
|
40220
|
-
await mkdir5(
|
|
40267
|
+
await mkdir5(path15.dirname(target), { recursive: true });
|
|
40221
40268
|
await writeFile7(target, bytes);
|
|
40222
40269
|
restored.push(entry.path);
|
|
40223
40270
|
}
|
|
40224
|
-
return { canvasPath:
|
|
40271
|
+
return { canvasPath: path15.resolve(resolvedTarget, manifest.canvas.path), restored, upToDate };
|
|
40225
40272
|
}
|
|
40226
40273
|
|
|
40227
40274
|
// src/engine/nodes/local/lib/render-review.ts
|
|
40228
40275
|
import { execFile as execFile2 } from "child_process";
|
|
40229
|
-
import { mkdtemp, readdir as
|
|
40276
|
+
import { mkdtemp, readdir as readdir7, readFile as readFile11, rm as rm5 } from "fs/promises";
|
|
40230
40277
|
import { tmpdir } from "os";
|
|
40231
|
-
import
|
|
40278
|
+
import path16 from "path";
|
|
40232
40279
|
import { promisify as promisify2 } from "util";
|
|
40233
40280
|
import { z as z39 } from "zod";
|
|
40234
40281
|
var RENDER_REVIEW_MODEL = "~google/gemini-pro-latest";
|
|
@@ -40650,11 +40697,11 @@ async function reviewRenderedVideo(opts) {
|
|
|
40650
40697
|
const duration = await videoDuration(opts.video);
|
|
40651
40698
|
if (duration === null) return null;
|
|
40652
40699
|
const spent = (usage) => opts.onSpend?.(usage);
|
|
40653
|
-
const dir = await mkdtemp(
|
|
40700
|
+
const dir = await mkdtemp(path16.join(tmpdir(), "baker-review-"));
|
|
40654
40701
|
try {
|
|
40655
40702
|
const grabbed = [];
|
|
40656
40703
|
for (const [i, at] of reviewFrameTimes(duration, RENDER_REVIEW_FRAMES).entries()) {
|
|
40657
|
-
const out =
|
|
40704
|
+
const out = path16.join(dir, `f${String(i).padStart(2, "0")}.jpg`);
|
|
40658
40705
|
try {
|
|
40659
40706
|
await execFileAsync2("ffmpeg", buildFrameGrabArgs(opts.video, at, out), { timeout: 3e4 });
|
|
40660
40707
|
grabbed.push({ at, image: await readFile11(out, { encoding: "base64" }) });
|
|
@@ -40704,7 +40751,7 @@ async function reviewRenderedVideo(opts) {
|
|
|
40704
40751
|
}
|
|
40705
40752
|
}
|
|
40706
40753
|
async function reviewContextBeside(canvasPath) {
|
|
40707
|
-
const raw = await readFile11(
|
|
40754
|
+
const raw = await readFile11(path16.join(path16.dirname(canvasPath), "prompt.json"), "utf-8").catch(() => null);
|
|
40708
40755
|
if (!raw) return {};
|
|
40709
40756
|
try {
|
|
40710
40757
|
const blueprint = JSON.parse(raw);
|
|
@@ -40720,12 +40767,12 @@ async function reviewContextBeside(canvasPath) {
|
|
|
40720
40767
|
}
|
|
40721
40768
|
}
|
|
40722
40769
|
async function sceneWindowsBeside(canvasPath) {
|
|
40723
|
-
const dir =
|
|
40724
|
-
const files = await
|
|
40770
|
+
const dir = path16.join(path16.dirname(canvasPath), "scenes");
|
|
40771
|
+
const files = await readdir7(dir).catch(() => null);
|
|
40725
40772
|
if (!files) return [];
|
|
40726
40773
|
const windows = [];
|
|
40727
40774
|
for (const name of files.filter((f) => f.endsWith(".json")).sort()) {
|
|
40728
|
-
const raw = await readFile11(
|
|
40775
|
+
const raw = await readFile11(path16.join(dir, name), "utf-8").catch(() => null);
|
|
40729
40776
|
if (!raw) continue;
|
|
40730
40777
|
try {
|
|
40731
40778
|
const scene = JSON.parse(raw);
|
|
@@ -40851,7 +40898,7 @@ function stopBeforeKinds(until) {
|
|
|
40851
40898
|
return null;
|
|
40852
40899
|
}
|
|
40853
40900
|
async function executeCanvasRun(opts) {
|
|
40854
|
-
const filePath =
|
|
40901
|
+
const filePath = path17.resolve(opts.file);
|
|
40855
40902
|
const raw = await readFile12(filePath, "utf8");
|
|
40856
40903
|
let parsed;
|
|
40857
40904
|
try {
|
|
@@ -40874,7 +40921,7 @@ ${describeRewrites(healed.rewrites)}
|
|
|
40874
40921
|
`
|
|
40875
40922
|
);
|
|
40876
40923
|
}
|
|
40877
|
-
parsed = resolveRelativeCanvasPaths(parsed,
|
|
40924
|
+
parsed = resolveRelativeCanvasPaths(parsed, path17.dirname(filePath));
|
|
40878
40925
|
try {
|
|
40879
40926
|
await syncStyleProjection(parsed, (line) => process.stderr.write(`${line}
|
|
40880
40927
|
`));
|
|
@@ -40980,7 +41027,7 @@ ${describeRewrites(healed.rewrites)}
|
|
|
40980
41027
|
const canvasSha = sha256Hex(Buffer.from(canvasText));
|
|
40981
41028
|
const creativeSlug = creativeSlugFromCanvasPath(filePath) ?? void 0;
|
|
40982
41029
|
const client = opts.record === false ? null : buildBackendClient();
|
|
40983
|
-
const outputsDir = opts.outputsDir ?
|
|
41030
|
+
const outputsDir = opts.outputsDir ? path17.resolve(opts.outputsDir) : path17.resolve("canvas");
|
|
40984
41031
|
const { runId, resumed, source, concurrentRunId } = await resolveRunId({
|
|
40985
41032
|
explicitRunId: opts.runId,
|
|
40986
41033
|
fresh: opts.fresh === true,
|
|
@@ -41014,7 +41061,7 @@ ${describeRewrites(healed.rewrites)}
|
|
|
41014
41061
|
const canvasSnapshotUrl = client && creativeSlug ? await uploadRunSnapshot(client, { canvasPath: filePath, raw: canvasText, creativeSlug, parsed }) ?? void 0 : void 0;
|
|
41015
41062
|
const recordMeta = {
|
|
41016
41063
|
creativeSlug,
|
|
41017
|
-
canvasPath:
|
|
41064
|
+
canvasPath: path17.relative(process.cwd(), filePath) || void 0,
|
|
41018
41065
|
canvasSha,
|
|
41019
41066
|
// The fingerprint the dashboard compares against the current source to flag
|
|
41020
41067
|
// "edited since last render". Computed from the on-disk canvas.json +
|
|
@@ -41272,7 +41319,7 @@ var rerunCommand = defineCommand112({
|
|
|
41272
41319
|
if (latest.canvasSha && manifest.canvasSha !== latest.canvasSha) {
|
|
41273
41320
|
fail2("snapshot_mismatch", `snapshot manifest for run ${latest.runId} does not match its recorded canvas sha`);
|
|
41274
41321
|
}
|
|
41275
|
-
const targetDir =
|
|
41322
|
+
const targetDir = path18.resolve("src", "creatives", slug);
|
|
41276
41323
|
let restoredCanvasPath;
|
|
41277
41324
|
try {
|
|
41278
41325
|
const restore = await restoreRunSnapshot(manifest, targetDir, { force: args5["force-remote"] === true });
|
|
@@ -41322,7 +41369,7 @@ async function fetchManifest(url) {
|
|
|
41322
41369
|
|
|
41323
41370
|
// src/commands/canvas/scaffold-static-ad.ts
|
|
41324
41371
|
import { access, mkdir as mkdir6, readFile as readFile14, writeFile as writeFile8 } from "fs/promises";
|
|
41325
|
-
import
|
|
41372
|
+
import path22 from "path";
|
|
41326
41373
|
import { defineCommand as defineCommand114 } from "citty";
|
|
41327
41374
|
|
|
41328
41375
|
// src/engine/scaffold/staticAd.ts
|
|
@@ -41610,7 +41657,7 @@ function staticAdReport(input, elementsInput, opts) {
|
|
|
41610
41657
|
}
|
|
41611
41658
|
|
|
41612
41659
|
// src/commands/canvas/creative-definition.ts
|
|
41613
|
-
import
|
|
41660
|
+
import path19 from "path";
|
|
41614
41661
|
var PLATFORM_VALUES = ["meta", "google", "linkedin", "tiktok", "youtube", "x", "other"];
|
|
41615
41662
|
var FORMAT_VALUES = ["1:1", "4:5", "9:16", "16:9", "1.91:1"];
|
|
41616
41663
|
function titleFromSlug(slug) {
|
|
@@ -41658,16 +41705,16 @@ function buildCreativeDefinition(input) {
|
|
|
41658
41705
|
}
|
|
41659
41706
|
|
|
41660
41707
|
// src/commands/canvas/scaffold-static-ad-paths.ts
|
|
41661
|
-
import
|
|
41708
|
+
import path20 from "path";
|
|
41662
41709
|
function resolveScaffoldStaticAdPaths(rawFile, out, cwd = process.cwd(), slug) {
|
|
41663
41710
|
const file = rawFile.trim();
|
|
41664
41711
|
const imageIsUrl = /^https?:\/\//i.test(file);
|
|
41665
|
-
const imageSource = imageIsUrl ? file :
|
|
41666
|
-
const outPath = out ?
|
|
41667
|
-
const blueprintPath =
|
|
41668
|
-
const creativeDir = slug ?
|
|
41669
|
-
const definitionPath = creativeDir ?
|
|
41670
|
-
const referencesDir = creativeDir ?
|
|
41712
|
+
const imageSource = imageIsUrl ? file : path20.resolve(cwd, file);
|
|
41713
|
+
const outPath = out ? path20.resolve(cwd, out) : slug ? path20.join(cwd, "src", "creatives", slug, `${slug}.canvas.json`) : imageIsUrl ? path20.join(cwd, "static-ad.canvas.json") : path20.join(path20.dirname(imageSource), "static-ad.canvas.json");
|
|
41714
|
+
const blueprintPath = path20.join(path20.dirname(outPath), "prompt.json");
|
|
41715
|
+
const creativeDir = slug ? path20.dirname(outPath) : null;
|
|
41716
|
+
const definitionPath = creativeDir ? path20.join(creativeDir, "_definition.md") : null;
|
|
41717
|
+
const referencesDir = creativeDir ? path20.join(creativeDir, "references") : null;
|
|
41671
41718
|
return { imageIsUrl, imageSource, outPath, blueprintPath, creativeDir, definitionPath, referencesDir };
|
|
41672
41719
|
}
|
|
41673
41720
|
var SCAFFOLD_SLUG_PATTERN = /^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
@@ -41677,8 +41724,8 @@ function isValidScaffoldSlug(slug) {
|
|
|
41677
41724
|
}
|
|
41678
41725
|
|
|
41679
41726
|
// src/commands/canvas/sync-definition.ts
|
|
41680
|
-
import { readdir as
|
|
41681
|
-
import
|
|
41727
|
+
import { readdir as readdir8, readFile as readFile13, stat as stat3 } from "fs/promises";
|
|
41728
|
+
import path21 from "path";
|
|
41682
41729
|
import { defineCommand as defineCommand113 } from "citty";
|
|
41683
41730
|
|
|
41684
41731
|
// src/commands/canvas/definition-graph.ts
|
|
@@ -41771,26 +41818,26 @@ async function syncCreativeDefinitionBestEffort(input) {
|
|
|
41771
41818
|
}
|
|
41772
41819
|
}
|
|
41773
41820
|
async function resolveCanvasPath(inputPath) {
|
|
41774
|
-
const resolved =
|
|
41821
|
+
const resolved = path21.resolve(inputPath);
|
|
41775
41822
|
let dir = resolved;
|
|
41776
41823
|
try {
|
|
41777
41824
|
if ((await stat3(resolved)).isFile()) {
|
|
41778
41825
|
if (resolved.endsWith(".canvas.json")) return resolved;
|
|
41779
|
-
dir =
|
|
41826
|
+
dir = path21.dirname(resolved);
|
|
41780
41827
|
}
|
|
41781
41828
|
} catch {
|
|
41782
|
-
dir = resolved.endsWith(".canvas.json") ?
|
|
41829
|
+
dir = resolved.endsWith(".canvas.json") ? path21.dirname(resolved) : resolved;
|
|
41783
41830
|
}
|
|
41784
41831
|
let entries;
|
|
41785
41832
|
try {
|
|
41786
|
-
entries = await
|
|
41833
|
+
entries = await readdir8(dir);
|
|
41787
41834
|
} catch {
|
|
41788
41835
|
return null;
|
|
41789
41836
|
}
|
|
41790
41837
|
const canvases = entries.filter((name) => name.endsWith(".canvas.json"));
|
|
41791
41838
|
const slug = creativeSlugFromCanvasPath(`${dir}/x/`);
|
|
41792
41839
|
const chosen = (slug ? canvases.find((name) => name === `${slug}.canvas.json`) : void 0) ?? canvases[0];
|
|
41793
|
-
return chosen ?
|
|
41840
|
+
return chosen ? path21.join(dir, chosen) : null;
|
|
41794
41841
|
}
|
|
41795
41842
|
var syncDefinitionCommand = defineCommand113({
|
|
41796
41843
|
meta: {
|
|
@@ -42071,7 +42118,7 @@ var scaffoldStaticAdCommand = defineCommand114({
|
|
|
42071
42118
|
process.cwd(),
|
|
42072
42119
|
slug
|
|
42073
42120
|
);
|
|
42074
|
-
await mkdir6(
|
|
42121
|
+
await mkdir6(path22.dirname(outPath), { recursive: true });
|
|
42075
42122
|
const { describeModel, selectModel, layoutModel, genModel } = resolveModels(args5);
|
|
42076
42123
|
let durableSourceUrl;
|
|
42077
42124
|
if (referencesDir) {
|
|
@@ -42191,7 +42238,7 @@ var scaffoldStaticAdCommand = defineCommand114({
|
|
|
42191
42238
|
run_estimated_credits: validation.estimatedCredits
|
|
42192
42239
|
},
|
|
42193
42240
|
checklist: {
|
|
42194
|
-
edit_prompt: `Edit ${
|
|
42241
|
+
edit_prompt: `Edit ${path22.basename(blueprintPath)} \u2014 it is the blueprint generated from your image; rewrite it into the ad you want (palette, copy, claims, subjects). It feeds the generator directly.`,
|
|
42195
42242
|
assets_to_supply: report.elements,
|
|
42196
42243
|
font_slot: report.includes_font ? "Drop a brand font at the [TODO] brandfont path (the describe pass recorded the ad's typefaces under `fonts` in prompt.json \u2014 match those). The font is wired into the render as a TYPE SPECIMEN reference so generated text takes the brand letterforms. Delete the brandfont + type_ref nodes to skip it." : "skipped (--skip-font)",
|
|
42197
42244
|
actor_sheets: report.actor_sheets.length > 0 ? `Each living hero (${report.actor_sheets.join(", ")}) is fused into a generated multi-view reference sheet (image_reference_sheet) that the render grounds on \u2014 so drop ONE clean photo at that hero's ingest and the sheet builds the consistent turnaround. Pass --skip-actor-sheets to ground on the lone photo instead.` : "none (no person/animal heroes detected, or --skip-actor-sheets)",
|
|
@@ -42960,8 +43007,8 @@ function injectAdBrandOverlay(indexHtml, overlayHtml) {
|
|
|
42960
43007
|
}
|
|
42961
43008
|
|
|
42962
43009
|
// src/engine/scaffold/ad-brand-source.ts
|
|
42963
|
-
import { readdir as
|
|
42964
|
-
import
|
|
43010
|
+
import { readdir as readdir9, readFile as readFile15 } from "fs/promises";
|
|
43011
|
+
import path23 from "path";
|
|
42965
43012
|
import sharp from "sharp";
|
|
42966
43013
|
var BRAND_DIR = "src/brand";
|
|
42967
43014
|
function paletteFromBrandDoc(markdown) {
|
|
@@ -43013,16 +43060,16 @@ function pickBrandMark(files) {
|
|
|
43013
43060
|
}
|
|
43014
43061
|
async function readBrandFromWorkspace(root = ".") {
|
|
43015
43062
|
const found = {};
|
|
43016
|
-
const doc = await readFile15(
|
|
43063
|
+
const doc = await readFile15(path23.join(root, BRAND_DIR, "BRAND.md"), "utf-8").catch(() => null);
|
|
43017
43064
|
if (doc) {
|
|
43018
43065
|
const palette = paletteFromBrandDoc(doc);
|
|
43019
43066
|
if (palette.length > 0) found.palette = palette;
|
|
43020
43067
|
}
|
|
43021
|
-
const dir =
|
|
43022
|
-
const files = await
|
|
43068
|
+
const dir = path23.join(root, BRAND_DIR, "logos");
|
|
43069
|
+
const files = await readdir9(dir).catch(() => null);
|
|
43023
43070
|
if (files) {
|
|
43024
43071
|
const mark = pickBrandMark(files);
|
|
43025
|
-
if (mark) found.logo =
|
|
43072
|
+
if (mark) found.logo = path23.join(BRAND_DIR, "logos", mark);
|
|
43026
43073
|
}
|
|
43027
43074
|
return found;
|
|
43028
43075
|
}
|
|
@@ -43032,20 +43079,20 @@ function svgIsLiveText(svg) {
|
|
|
43032
43079
|
async function markIsReal(markPath, root = ".") {
|
|
43033
43080
|
const brandLogos = await findBrandLogosDir(markPath, root);
|
|
43034
43081
|
if (brandLogos) return await markDirectoryIsReal(brandLogos);
|
|
43035
|
-
return await markDirectoryIsReal(
|
|
43082
|
+
return await markDirectoryIsReal(path23.dirname(markPath));
|
|
43036
43083
|
}
|
|
43037
43084
|
async function findBrandLogosDir(markPath, root) {
|
|
43038
43085
|
const candidates = [];
|
|
43039
|
-
let dir =
|
|
43086
|
+
let dir = path23.resolve(path23.dirname(markPath));
|
|
43040
43087
|
for (; ; ) {
|
|
43041
|
-
candidates.push(
|
|
43042
|
-
const parent =
|
|
43088
|
+
candidates.push(path23.join(dir, BRAND_DIR, "logos"));
|
|
43089
|
+
const parent = path23.dirname(dir);
|
|
43043
43090
|
if (parent === dir) break;
|
|
43044
43091
|
dir = parent;
|
|
43045
43092
|
}
|
|
43046
|
-
candidates.push(
|
|
43093
|
+
candidates.push(path23.join(root, BRAND_DIR, "logos"));
|
|
43047
43094
|
for (const candidate of candidates) {
|
|
43048
|
-
if (await
|
|
43095
|
+
if (await readdir9(candidate).then(
|
|
43049
43096
|
() => true,
|
|
43050
43097
|
() => false
|
|
43051
43098
|
))
|
|
@@ -43054,12 +43101,12 @@ async function findBrandLogosDir(markPath, root) {
|
|
|
43054
43101
|
return null;
|
|
43055
43102
|
}
|
|
43056
43103
|
async function markDirectoryIsReal(dir) {
|
|
43057
|
-
const files = await
|
|
43104
|
+
const files = await readdir9(dir).catch(() => null);
|
|
43058
43105
|
if (!files) return false;
|
|
43059
43106
|
const marks = files.filter((f) => /\.(svg|png|webp)$/i.test(f));
|
|
43060
43107
|
if (marks.length === 0) return false;
|
|
43061
43108
|
for (const f of marks.filter((f2) => /\.svg$/i.test(f2))) {
|
|
43062
|
-
const svg = await readFile15(
|
|
43109
|
+
const svg = await readFile15(path23.join(dir, f), "utf-8").catch(() => null);
|
|
43063
43110
|
if (svg === null || svgIsLiveText(svg)) return false;
|
|
43064
43111
|
}
|
|
43065
43112
|
return true;
|
|
@@ -43086,22 +43133,6 @@ async function markInkIsLight(markPath) {
|
|
|
43086
43133
|
}
|
|
43087
43134
|
}
|
|
43088
43135
|
|
|
43089
|
-
// src/commands/canvas/composition-path.ts
|
|
43090
|
-
import { existsSync as existsSync5 } from "fs";
|
|
43091
|
-
import path23 from "path";
|
|
43092
|
-
function resolveShippedCanvasDir(name, startDir, exists2 = existsSync5, maxDepth = 8) {
|
|
43093
|
-
const rel = path23.join("canvas", name);
|
|
43094
|
-
let dir = startDir;
|
|
43095
|
-
for (let i = 0; i < maxDepth; i++) {
|
|
43096
|
-
const candidate = path23.join(dir, rel);
|
|
43097
|
-
if (exists2(path23.join(candidate, "meta.json"))) return candidate;
|
|
43098
|
-
const parent = path23.dirname(dir);
|
|
43099
|
-
if (parent === dir) break;
|
|
43100
|
-
dir = parent;
|
|
43101
|
-
}
|
|
43102
|
-
return path23.resolve(startDir, "../../../", rel);
|
|
43103
|
-
}
|
|
43104
|
-
|
|
43105
43136
|
// src/commands/canvas/scaffold-ad.ts
|
|
43106
43137
|
function pinnedOnAvatar(handle, model) {
|
|
43107
43138
|
const hint = pinnedModelHint({ avatar: handle ?? void 0, model, generateAudio: true });
|
|
@@ -43652,7 +43683,7 @@ function routeVideoModel(input) {
|
|
|
43652
43683
|
|
|
43653
43684
|
// src/engine/nodes/local/lib/sceneDetect.ts
|
|
43654
43685
|
import { execFile as execFile3 } from "child_process";
|
|
43655
|
-
import { mkdtemp as mkdtemp2, readdir as
|
|
43686
|
+
import { mkdtemp as mkdtemp2, readdir as readdir10, readFile as readFile17, rm as rm6 } from "fs/promises";
|
|
43656
43687
|
import { tmpdir as tmpdir2 } from "os";
|
|
43657
43688
|
import { join as join3 } from "path";
|
|
43658
43689
|
import { promisify as promisify3 } from "util";
|
|
@@ -43726,7 +43757,7 @@ async function runSceneDetectOnce(filePath, threshold, minSceneLenS, timeoutMs)
|
|
|
43726
43757
|
],
|
|
43727
43758
|
{ encoding: "utf-8", maxBuffer: 32 * 1024 * 1024, timeout: timeoutMs }
|
|
43728
43759
|
);
|
|
43729
|
-
const csvName = (await
|
|
43760
|
+
const csvName = (await readdir10(outDir)).find((f) => f.toLowerCase().endsWith(".csv"));
|
|
43730
43761
|
if (!csvName) return [];
|
|
43731
43762
|
return parsePySceneDetectCsvCuts(await readFile17(join3(outDir, csvName), "utf-8"));
|
|
43732
43763
|
} finally {
|
|
@@ -45128,11 +45159,11 @@ Full guide: __tooling__/docs/tools/baker/creatives.md`
|
|
|
45128
45159
|
import { defineCommand as defineCommand124 } from "citty";
|
|
45129
45160
|
|
|
45130
45161
|
// src/commands/experiment/composition.ts
|
|
45131
|
-
import { readdir as
|
|
45162
|
+
import { readdir as readdir12, readFile as readFile24 } from "fs/promises";
|
|
45132
45163
|
import path30 from "path";
|
|
45133
45164
|
|
|
45134
45165
|
// src/commands/landing/import-graph.ts
|
|
45135
|
-
import { readdir as
|
|
45166
|
+
import { readdir as readdir11, readFile as readFile23, stat as stat5 } from "fs/promises";
|
|
45136
45167
|
import path29 from "path";
|
|
45137
45168
|
var SOURCE_EXT = /\.(astro|ts|tsx|js|jsx|mjs|cjs|vue|svelte)$/;
|
|
45138
45169
|
var RESOLVE_CANDIDATES = [
|
|
@@ -45160,7 +45191,7 @@ async function isFile(p) {
|
|
|
45160
45191
|
async function walkFiles(dir) {
|
|
45161
45192
|
let entries;
|
|
45162
45193
|
try {
|
|
45163
|
-
entries = await
|
|
45194
|
+
entries = await readdir11(dir, { withFileTypes: true });
|
|
45164
45195
|
} catch {
|
|
45165
45196
|
return [];
|
|
45166
45197
|
}
|
|
@@ -45263,7 +45294,7 @@ function formsOnlyIn(these, those) {
|
|
|
45263
45294
|
}
|
|
45264
45295
|
async function knownFlows(root) {
|
|
45265
45296
|
try {
|
|
45266
|
-
const entries = await
|
|
45297
|
+
const entries = await readdir12(path30.join(root, "src/lib/flow-engine/flows"), { withFileTypes: true });
|
|
45267
45298
|
return new Set(entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name));
|
|
45268
45299
|
} catch {
|
|
45269
45300
|
return /* @__PURE__ */ new Set();
|
|
@@ -45284,7 +45315,7 @@ async function readForms(root, slug) {
|
|
|
45284
45315
|
|
|
45285
45316
|
// src/commands/experiment/fold.ts
|
|
45286
45317
|
import { statSync } from "fs";
|
|
45287
|
-
import { cp as cp3, mkdir as mkdir9, readdir as
|
|
45318
|
+
import { cp as cp3, mkdir as mkdir9, readdir as readdir13, readFile as readFile25, rm as rm8, stat as stat6, writeFile as writeFile12 } from "fs/promises";
|
|
45288
45319
|
import path32 from "path";
|
|
45289
45320
|
|
|
45290
45321
|
// ../api/src/experiments/variants.ts
|
|
@@ -45359,7 +45390,7 @@ async function isDir(p) {
|
|
|
45359
45390
|
async function filesUnder(dir, prefix = "") {
|
|
45360
45391
|
let entries;
|
|
45361
45392
|
try {
|
|
45362
|
-
entries = await
|
|
45393
|
+
entries = await readdir13(dir, { withFileTypes: true });
|
|
45363
45394
|
} catch {
|
|
45364
45395
|
return [];
|
|
45365
45396
|
}
|
|
@@ -55723,7 +55754,7 @@ Full guide: __tooling__/docs/tools/baker/images.md`
|
|
|
55723
55754
|
import { defineCommand as defineCommand182 } from "citty";
|
|
55724
55755
|
|
|
55725
55756
|
// src/commands/landing/critique.ts
|
|
55726
|
-
import { readdir as
|
|
55757
|
+
import { readdir as readdir15, readFile as readFile30, stat as stat9 } from "fs/promises";
|
|
55727
55758
|
import path37 from "path";
|
|
55728
55759
|
import { defineCommand as defineCommand171 } from "citty";
|
|
55729
55760
|
|
|
@@ -56934,7 +56965,7 @@ async function writeCritiqueSnapshot(projectRoot, snapshot) {
|
|
|
56934
56965
|
}
|
|
56935
56966
|
|
|
56936
56967
|
// src/commands/landing/source-version.ts
|
|
56937
|
-
import { readdir as
|
|
56968
|
+
import { readdir as readdir14, readFile as readFile29, stat as stat8 } from "fs/promises";
|
|
56938
56969
|
import path36 from "path";
|
|
56939
56970
|
var CRITIQUED_ROOTS = ["src/pages/", "src/components/"];
|
|
56940
56971
|
async function landingSourceRelPaths(root, slug) {
|
|
@@ -56990,7 +57021,7 @@ async function isFile2(p) {
|
|
|
56990
57021
|
async function walkAstro(dir) {
|
|
56991
57022
|
let entries;
|
|
56992
57023
|
try {
|
|
56993
|
-
entries = await
|
|
57024
|
+
entries = await readdir14(dir, { withFileTypes: true });
|
|
56994
57025
|
} catch {
|
|
56995
57026
|
return [];
|
|
56996
57027
|
}
|
|
@@ -57123,7 +57154,7 @@ async function readCompetitorNames(projectRoot) {
|
|
|
57123
57154
|
const dir = path37.join(projectRoot, "src", "content", "competitors");
|
|
57124
57155
|
let entries;
|
|
57125
57156
|
try {
|
|
57126
|
-
entries = (await
|
|
57157
|
+
entries = (await readdir15(dir)).filter((f) => f.endsWith(".md"));
|
|
57127
57158
|
} catch {
|
|
57128
57159
|
return [];
|
|
57129
57160
|
}
|
|
@@ -57141,7 +57172,7 @@ async function readCompetitorNames(projectRoot) {
|
|
|
57141
57172
|
}
|
|
57142
57173
|
async function listLandingSlugs(projectRoot) {
|
|
57143
57174
|
try {
|
|
57144
|
-
const entries = await
|
|
57175
|
+
const entries = await readdir15(path37.join(projectRoot, "src", "pages"), { withFileTypes: true });
|
|
57145
57176
|
return entries.filter((e) => e.isDirectory() && !e.name.startsWith("_") && !e.name.startsWith(".")).map((e) => e.name).sort();
|
|
57146
57177
|
} catch {
|
|
57147
57178
|
return [];
|
|
@@ -60334,7 +60365,7 @@ Full guide: __tooling__/docs/tools/baker/landing.md`
|
|
|
60334
60365
|
|
|
60335
60366
|
// src/commands/landing/variant.ts
|
|
60336
60367
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
60337
|
-
import { mkdir as mkdir14, readdir as
|
|
60368
|
+
import { mkdir as mkdir14, readdir as readdir16, readFile as readFile31, stat as stat10, writeFile as writeFile19 } from "fs/promises";
|
|
60338
60369
|
import path45 from "path";
|
|
60339
60370
|
import { defineCommand as defineCommand181 } from "citty";
|
|
60340
60371
|
registerSchema({
|
|
@@ -60371,7 +60402,7 @@ async function readInternalId(definitionPath) {
|
|
|
60371
60402
|
async function archivedVariantNumbers(root, internalId) {
|
|
60372
60403
|
if (!internalId) return [];
|
|
60373
60404
|
try {
|
|
60374
|
-
const entries = await
|
|
60405
|
+
const entries = await readdir16(path45.resolve(root, "src/_variants", internalId), { withFileTypes: true });
|
|
60375
60406
|
return entries.filter((entry) => entry.isDirectory()).map((entry) => Number(entry.name)).filter((n) => Number.isInteger(n) && n > 0);
|
|
60376
60407
|
} catch {
|
|
60377
60408
|
return [];
|
|
@@ -60401,7 +60432,7 @@ async function exists(p) {
|
|
|
60401
60432
|
}
|
|
60402
60433
|
async function listLandingSlugs2(root) {
|
|
60403
60434
|
try {
|
|
60404
|
-
const entries = await
|
|
60435
|
+
const entries = await readdir16(path45.resolve(root, "src", "pages"), { withFileTypes: true });
|
|
60405
60436
|
return entries.filter((e) => e.isDirectory() && !e.name.startsWith("_") && !e.name.startsWith(".")).map((e) => e.name).sort();
|
|
60406
60437
|
} catch {
|
|
60407
60438
|
return [];
|
|
@@ -60410,7 +60441,7 @@ async function listLandingSlugs2(root) {
|
|
|
60410
60441
|
async function listComponents(componentsDir, prefix = "") {
|
|
60411
60442
|
let entries;
|
|
60412
60443
|
try {
|
|
60413
|
-
entries = await
|
|
60444
|
+
entries = await readdir16(componentsDir, { withFileTypes: true });
|
|
60414
60445
|
} catch {
|
|
60415
60446
|
return [];
|
|
60416
60447
|
}
|