@koda-sl/baker-cli 0.358.0 → 0.359.0-dev.5dbf6338c
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 +4 -4
- package/canvas/avocado-tutorial.json +1 -1
- package/canvas/hello-world-overlay.json +1 -1
- package/dist/{chunk-AI4HWQVN.js → chunk-K2IKLMCM.js} +4 -4
- package/dist/chunk-K2IKLMCM.js.map +1 -0
- package/dist/cli.js +146 -136
- 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
package/dist/cli.js
CHANGED
|
@@ -69,7 +69,7 @@ import {
|
|
|
69
69
|
validateCanvasDeep,
|
|
70
70
|
withoutCastName,
|
|
71
71
|
ytDlpBlockSignal
|
|
72
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-K2IKLMCM.js";
|
|
73
73
|
import {
|
|
74
74
|
csvOrJson,
|
|
75
75
|
daysAgoIso,
|
|
@@ -36644,9 +36644,134 @@ var critiqueCommand = defineCommand109({
|
|
|
36644
36644
|
// src/commands/canvas/inspect.ts
|
|
36645
36645
|
import { execFile } from "child_process";
|
|
36646
36646
|
import { readdir as readdir2, readFile as readFile4, stat } from "fs/promises";
|
|
36647
|
-
import
|
|
36647
|
+
import path6 from "path";
|
|
36648
36648
|
import { promisify } from "util";
|
|
36649
36649
|
import { defineCommand as defineCommand110 } from "citty";
|
|
36650
|
+
|
|
36651
|
+
// src/commands/canvas/normalize-paths.ts
|
|
36652
|
+
import { existsSync as existsSync4, realpathSync } from "fs";
|
|
36653
|
+
import { writeFile as writeFile2 } from "fs/promises";
|
|
36654
|
+
import path5 from "path";
|
|
36655
|
+
|
|
36656
|
+
// src/commands/canvas/resolve-paths.ts
|
|
36657
|
+
import path4 from "path";
|
|
36658
|
+
function resolveRelativeCanvasPaths(canvas, baseDir) {
|
|
36659
|
+
if (!canvas || typeof canvas !== "object") return canvas;
|
|
36660
|
+
const c = canvas;
|
|
36661
|
+
if (!Array.isArray(c.nodes)) return canvas;
|
|
36662
|
+
return { ...canvas, nodes: c.nodes.map((n) => resolveNode(n, baseDir)) };
|
|
36663
|
+
}
|
|
36664
|
+
function localPathParam(node) {
|
|
36665
|
+
if (node.type === "ingest") return node.params?.source === "path" ? "path" : null;
|
|
36666
|
+
if (node.type === "hyperframe_render" || node.type === "hyperframe_snapshot") return "composition";
|
|
36667
|
+
return null;
|
|
36668
|
+
}
|
|
36669
|
+
function resolveNode(node, baseDir) {
|
|
36670
|
+
if (!node || typeof node !== "object") return node;
|
|
36671
|
+
const n = node;
|
|
36672
|
+
const params = n.params;
|
|
36673
|
+
if (!params || typeof params !== "object") return node;
|
|
36674
|
+
const key = localPathParam(n);
|
|
36675
|
+
if (key && isResolvableRelative(params[key])) {
|
|
36676
|
+
return { ...node, params: { ...params, [key]: path4.resolve(baseDir, params[key]) } };
|
|
36677
|
+
}
|
|
36678
|
+
return node;
|
|
36679
|
+
}
|
|
36680
|
+
function isResolvableRelative(value) {
|
|
36681
|
+
return typeof value === "string" && value.length > 0 && !value.includes("[TODO") && !looksLikeHttpUrl(value) && !path4.isAbsolute(value);
|
|
36682
|
+
}
|
|
36683
|
+
|
|
36684
|
+
// src/commands/canvas/normalize-paths.ts
|
|
36685
|
+
function findWorkspaceRoot(startDir, exists2 = existsSync4, maxDepth = 12) {
|
|
36686
|
+
let dir = path5.resolve(startDir);
|
|
36687
|
+
for (let i = 0; i < maxDepth; i++) {
|
|
36688
|
+
if (exists2(path5.join(dir, "package.json"))) return dir;
|
|
36689
|
+
const parent = path5.dirname(dir);
|
|
36690
|
+
if (parent === dir) break;
|
|
36691
|
+
dir = parent;
|
|
36692
|
+
}
|
|
36693
|
+
return null;
|
|
36694
|
+
}
|
|
36695
|
+
function canvasOutputsRoot(canvasFile, cwd = process.cwd(), exists2 = existsSync4) {
|
|
36696
|
+
const root = findWorkspaceRoot(path5.dirname(path5.resolve(cwd, canvasFile)), exists2) ?? cwd;
|
|
36697
|
+
return path5.join(root, "canvas");
|
|
36698
|
+
}
|
|
36699
|
+
function canonicalize(target2) {
|
|
36700
|
+
const abs = path5.resolve(target2);
|
|
36701
|
+
let dir = abs;
|
|
36702
|
+
for (; ; ) {
|
|
36703
|
+
try {
|
|
36704
|
+
const real = realpathSync(dir);
|
|
36705
|
+
return dir === abs ? real : path5.join(real, path5.relative(dir, abs));
|
|
36706
|
+
} catch {
|
|
36707
|
+
const parent = path5.dirname(dir);
|
|
36708
|
+
if (parent === dir) return abs;
|
|
36709
|
+
dir = parent;
|
|
36710
|
+
}
|
|
36711
|
+
}
|
|
36712
|
+
}
|
|
36713
|
+
function isInside(root, target2) {
|
|
36714
|
+
const rel = path5.relative(root, target2);
|
|
36715
|
+
return rel !== "" && !rel.startsWith("..") && !path5.isAbsolute(rel);
|
|
36716
|
+
}
|
|
36717
|
+
function toCanvasRelative(canvasDir, target2) {
|
|
36718
|
+
return path5.relative(canvasDir, target2).split(path5.sep).join("/");
|
|
36719
|
+
}
|
|
36720
|
+
var RUNTIME_WORKSPACE_ROOT = "/home/user/repo";
|
|
36721
|
+
function rewriteTarget(value, workspaceRoot) {
|
|
36722
|
+
if (typeof value !== "string" || value.length === 0) return null;
|
|
36723
|
+
if (value.includes("[TODO") || looksLikeHttpUrl(value) || !path5.isAbsolute(value)) return null;
|
|
36724
|
+
const target2 = canonicalize(value);
|
|
36725
|
+
if (isInside(workspaceRoot, target2)) return target2;
|
|
36726
|
+
const fromRuntime = path5.relative(RUNTIME_WORKSPACE_ROOT, path5.normalize(value));
|
|
36727
|
+
if (fromRuntime !== "" && !fromRuntime.startsWith("..") && !path5.isAbsolute(fromRuntime)) {
|
|
36728
|
+
return path5.join(workspaceRoot, fromRuntime);
|
|
36729
|
+
}
|
|
36730
|
+
return null;
|
|
36731
|
+
}
|
|
36732
|
+
function normalizeCanvasPaths(canvas, canvasDir, workspaceRoot) {
|
|
36733
|
+
if (!canvas || typeof canvas !== "object") return { canvas, rewrites: [] };
|
|
36734
|
+
const c = canvas;
|
|
36735
|
+
if (!Array.isArray(c.nodes)) return { canvas, rewrites: [] };
|
|
36736
|
+
const root = canonicalize(workspaceRoot);
|
|
36737
|
+
const dir = canonicalize(canvasDir);
|
|
36738
|
+
const rewrites = [];
|
|
36739
|
+
const nodes = c.nodes.map((node) => {
|
|
36740
|
+
if (!node || typeof node !== "object") return node;
|
|
36741
|
+
const n = node;
|
|
36742
|
+
const params = n.params;
|
|
36743
|
+
if (!params || typeof params !== "object") return node;
|
|
36744
|
+
const nodeId = typeof n.id === "string" ? n.id : "?";
|
|
36745
|
+
if (n.type === "ingest" && params.source === "path" && looksLikeHttpUrl(params.path)) {
|
|
36746
|
+
rewrites.push({ nodeId, param: "source", from: "path", to: "url" });
|
|
36747
|
+
return { ...node, params: coercePathUrlToUrl(params) };
|
|
36748
|
+
}
|
|
36749
|
+
const key = localPathParam(n);
|
|
36750
|
+
if (!key) return node;
|
|
36751
|
+
const target2 = rewriteTarget(params[key], root);
|
|
36752
|
+
if (target2 === null) return node;
|
|
36753
|
+
const to = toCanvasRelative(dir, target2);
|
|
36754
|
+
rewrites.push({ nodeId, param: key, from: params[key], to });
|
|
36755
|
+
return { ...node, params: { ...params, [key]: to } };
|
|
36756
|
+
});
|
|
36757
|
+
return rewrites.length === 0 ? { canvas, rewrites } : { canvas: { ...canvas, nodes }, rewrites };
|
|
36758
|
+
}
|
|
36759
|
+
async function healCanvasPaths(filePath, canvas) {
|
|
36760
|
+
const canvasDir = path5.dirname(filePath);
|
|
36761
|
+
const workspaceRoot = findWorkspaceRoot(canvasDir);
|
|
36762
|
+
if (!workspaceRoot) return { canvas, rewrites: [], text: null };
|
|
36763
|
+
const normalized = normalizeCanvasPaths(canvas, canvasDir, workspaceRoot);
|
|
36764
|
+
if (normalized.rewrites.length === 0) return { ...normalized, text: null };
|
|
36765
|
+
const text2 = `${JSON.stringify(normalized.canvas, null, 2)}
|
|
36766
|
+
`;
|
|
36767
|
+
await writeFile2(filePath, text2, "utf8");
|
|
36768
|
+
return { ...normalized, text: text2 };
|
|
36769
|
+
}
|
|
36770
|
+
function describeRewrites(rewrites) {
|
|
36771
|
+
return rewrites.map((r) => ` ${r.nodeId}.${r.param}: ${r.from} \u2192 ${r.to}`).join("\n");
|
|
36772
|
+
}
|
|
36773
|
+
|
|
36774
|
+
// src/commands/canvas/inspect.ts
|
|
36650
36775
|
var execFileAsync = promisify(execFile);
|
|
36651
36776
|
var inspectCommand = defineCommand110({
|
|
36652
36777
|
meta: {
|
|
@@ -36655,14 +36780,15 @@ var inspectCommand = defineCommand110({
|
|
|
36655
36780
|
},
|
|
36656
36781
|
args: {
|
|
36657
36782
|
run: { type: "positional", required: true, description: "Run id (e.g. r_01K...) or absolute run directory" },
|
|
36658
|
-
"outputs-dir": { type: "string", description: "Per-run outputs root (default
|
|
36783
|
+
"outputs-dir": { type: "string", description: "Per-run outputs root (default <workspace root>/canvas, where `canvas run` writes)" },
|
|
36659
36784
|
thumbnails: {
|
|
36660
36785
|
type: "boolean",
|
|
36661
36786
|
description: "Extract start/middle/end frames from every video output (requires ffmpeg)"
|
|
36662
36787
|
}
|
|
36663
36788
|
},
|
|
36664
36789
|
async run({ args: args5 }) {
|
|
36665
|
-
const
|
|
36790
|
+
const cwd = process.cwd();
|
|
36791
|
+
const outputsDir = args5["outputs-dir"] ? path6.resolve(String(args5["outputs-dir"])) : path6.join(findWorkspaceRoot(cwd) ?? cwd, "canvas");
|
|
36666
36792
|
const runArg = String(args5.run);
|
|
36667
36793
|
const runDir = await resolveRunDir(runArg, outputsDir);
|
|
36668
36794
|
const manifest = await loadManifest(runDir);
|
|
@@ -36674,7 +36800,7 @@ var inspectCommand = defineCommand110({
|
|
|
36674
36800
|
}
|
|
36675
36801
|
const summary = {
|
|
36676
36802
|
ok: true,
|
|
36677
|
-
run_id: manifest.run_id ??
|
|
36803
|
+
run_id: manifest.run_id ?? path6.basename(runDir),
|
|
36678
36804
|
run_dir: runDir,
|
|
36679
36805
|
stats: manifest.stats ?? null,
|
|
36680
36806
|
output: manifest.output ?? null,
|
|
@@ -36687,18 +36813,18 @@ var inspectCommand = defineCommand110({
|
|
|
36687
36813
|
}
|
|
36688
36814
|
});
|
|
36689
36815
|
async function resolveRunDir(run, outputsDir) {
|
|
36690
|
-
if (
|
|
36816
|
+
if (path6.isAbsolute(run)) {
|
|
36691
36817
|
const s2 = await stat(run).catch(() => null);
|
|
36692
36818
|
if (s2?.isDirectory()) return run;
|
|
36693
36819
|
throw new Error(`inspect: ${run} is not a directory`);
|
|
36694
36820
|
}
|
|
36695
|
-
const candidate =
|
|
36821
|
+
const candidate = path6.join(outputsDir, run);
|
|
36696
36822
|
const s = await stat(candidate).catch(() => null);
|
|
36697
36823
|
if (s?.isDirectory()) return candidate;
|
|
36698
36824
|
throw new Error(`inspect: no run directory at ${candidate}`);
|
|
36699
36825
|
}
|
|
36700
36826
|
async function loadManifest(runDir) {
|
|
36701
|
-
const manifestPath =
|
|
36827
|
+
const manifestPath = path6.join(runDir, "manifest.json");
|
|
36702
36828
|
try {
|
|
36703
36829
|
const raw = await readFile4(manifestPath, "utf-8");
|
|
36704
36830
|
return JSON.parse(raw);
|
|
@@ -36710,7 +36836,7 @@ async function listRunFiles(runDir) {
|
|
|
36710
36836
|
const out = [];
|
|
36711
36837
|
const names = await readdir2(runDir);
|
|
36712
36838
|
for (const name of names) {
|
|
36713
|
-
const abs =
|
|
36839
|
+
const abs = path6.join(runDir, name);
|
|
36714
36840
|
const s = await stat(abs).catch(() => null);
|
|
36715
36841
|
if (!s?.isFile()) continue;
|
|
36716
36842
|
out.push({ name, path: abs, size: s.size });
|
|
@@ -36763,95 +36889,6 @@ import { readFile as readFile12 } from "fs/promises";
|
|
|
36763
36889
|
import path16 from "path";
|
|
36764
36890
|
import { defineCommand as defineCommand111 } from "citty";
|
|
36765
36891
|
|
|
36766
|
-
// src/commands/canvas/normalize-paths.ts
|
|
36767
|
-
import { existsSync as existsSync4, realpathSync } from "fs";
|
|
36768
|
-
import { writeFile as writeFile2 } from "fs/promises";
|
|
36769
|
-
import path5 from "path";
|
|
36770
|
-
function findWorkspaceRoot(startDir, exists2 = existsSync4, maxDepth = 12) {
|
|
36771
|
-
let dir = path5.resolve(startDir);
|
|
36772
|
-
for (let i = 0; i < maxDepth; i++) {
|
|
36773
|
-
if (exists2(path5.join(dir, "package.json"))) return dir;
|
|
36774
|
-
const parent = path5.dirname(dir);
|
|
36775
|
-
if (parent === dir) break;
|
|
36776
|
-
dir = parent;
|
|
36777
|
-
}
|
|
36778
|
-
return null;
|
|
36779
|
-
}
|
|
36780
|
-
function canonicalize(target2) {
|
|
36781
|
-
const abs = path5.resolve(target2);
|
|
36782
|
-
let dir = abs;
|
|
36783
|
-
for (; ; ) {
|
|
36784
|
-
try {
|
|
36785
|
-
const real = realpathSync(dir);
|
|
36786
|
-
return dir === abs ? real : path5.join(real, path5.relative(dir, abs));
|
|
36787
|
-
} catch {
|
|
36788
|
-
const parent = path5.dirname(dir);
|
|
36789
|
-
if (parent === dir) return abs;
|
|
36790
|
-
dir = parent;
|
|
36791
|
-
}
|
|
36792
|
-
}
|
|
36793
|
-
}
|
|
36794
|
-
function isInside(root, target2) {
|
|
36795
|
-
const rel = path5.relative(root, target2);
|
|
36796
|
-
return rel !== "" && !rel.startsWith("..") && !path5.isAbsolute(rel);
|
|
36797
|
-
}
|
|
36798
|
-
function toCanvasRelative(canvasDir, target2) {
|
|
36799
|
-
return path5.relative(canvasDir, target2).split(path5.sep).join("/");
|
|
36800
|
-
}
|
|
36801
|
-
var RUNTIME_WORKSPACE_ROOT = "/home/user/repo";
|
|
36802
|
-
function rewriteTarget(value, workspaceRoot) {
|
|
36803
|
-
if (typeof value !== "string" || value.length === 0) return null;
|
|
36804
|
-
if (value.includes("[TODO") || looksLikeHttpUrl(value) || !path5.isAbsolute(value)) return null;
|
|
36805
|
-
const target2 = canonicalize(value);
|
|
36806
|
-
if (isInside(workspaceRoot, target2)) return target2;
|
|
36807
|
-
const fromRuntime = path5.relative(RUNTIME_WORKSPACE_ROOT, path5.normalize(value));
|
|
36808
|
-
if (fromRuntime !== "" && !fromRuntime.startsWith("..") && !path5.isAbsolute(fromRuntime)) {
|
|
36809
|
-
return path5.join(workspaceRoot, fromRuntime);
|
|
36810
|
-
}
|
|
36811
|
-
return null;
|
|
36812
|
-
}
|
|
36813
|
-
function normalizeCanvasPaths(canvas, canvasDir, workspaceRoot) {
|
|
36814
|
-
if (!canvas || typeof canvas !== "object") return { canvas, rewrites: [] };
|
|
36815
|
-
const c = canvas;
|
|
36816
|
-
if (!Array.isArray(c.nodes)) return { canvas, rewrites: [] };
|
|
36817
|
-
const root = canonicalize(workspaceRoot);
|
|
36818
|
-
const dir = canonicalize(canvasDir);
|
|
36819
|
-
const rewrites = [];
|
|
36820
|
-
const nodes = c.nodes.map((node) => {
|
|
36821
|
-
if (!node || typeof node !== "object") return node;
|
|
36822
|
-
const n = node;
|
|
36823
|
-
const params = n.params;
|
|
36824
|
-
if (!params || typeof params !== "object") return node;
|
|
36825
|
-
const nodeId = typeof n.id === "string" ? n.id : "?";
|
|
36826
|
-
if (n.type === "ingest" && params.source === "path" && looksLikeHttpUrl(params.path)) {
|
|
36827
|
-
rewrites.push({ nodeId, param: "source", from: "path", to: "url" });
|
|
36828
|
-
return { ...node, params: coercePathUrlToUrl(params) };
|
|
36829
|
-
}
|
|
36830
|
-
const key = n.type === "ingest" && params.source === "path" ? "path" : n.type === "hyperframe_render" ? "composition" : null;
|
|
36831
|
-
if (!key) return node;
|
|
36832
|
-
const target2 = rewriteTarget(params[key], root);
|
|
36833
|
-
if (target2 === null) return node;
|
|
36834
|
-
const to = toCanvasRelative(dir, target2);
|
|
36835
|
-
rewrites.push({ nodeId, param: key, from: params[key], to });
|
|
36836
|
-
return { ...node, params: { ...params, [key]: to } };
|
|
36837
|
-
});
|
|
36838
|
-
return rewrites.length === 0 ? { canvas, rewrites } : { canvas: { ...canvas, nodes }, rewrites };
|
|
36839
|
-
}
|
|
36840
|
-
async function healCanvasPaths(filePath, canvas) {
|
|
36841
|
-
const canvasDir = path5.dirname(filePath);
|
|
36842
|
-
const workspaceRoot = findWorkspaceRoot(canvasDir);
|
|
36843
|
-
if (!workspaceRoot) return { canvas, rewrites: [], text: null };
|
|
36844
|
-
const normalized = normalizeCanvasPaths(canvas, canvasDir, workspaceRoot);
|
|
36845
|
-
if (normalized.rewrites.length === 0) return { ...normalized, text: null };
|
|
36846
|
-
const text2 = `${JSON.stringify(normalized.canvas, null, 2)}
|
|
36847
|
-
`;
|
|
36848
|
-
await writeFile2(filePath, text2, "utf8");
|
|
36849
|
-
return { ...normalized, text: text2 };
|
|
36850
|
-
}
|
|
36851
|
-
function describeRewrites(rewrites) {
|
|
36852
|
-
return rewrites.map((r) => ` ${r.nodeId}.${r.param}: ${r.from} \u2192 ${r.to}`).join("\n");
|
|
36853
|
-
}
|
|
36854
|
-
|
|
36855
36892
|
// src/commands/canvas/placeholders.ts
|
|
36856
36893
|
function unsuppliedPlaceholderAssets(canvas) {
|
|
36857
36894
|
const nodes = canvas?.nodes;
|
|
@@ -36868,31 +36905,6 @@ function unsuppliedPlaceholderAssets(canvas) {
|
|
|
36868
36905
|
return out;
|
|
36869
36906
|
}
|
|
36870
36907
|
|
|
36871
|
-
// src/commands/canvas/resolve-paths.ts
|
|
36872
|
-
import path6 from "path";
|
|
36873
|
-
function resolveRelativeCanvasPaths(canvas, baseDir) {
|
|
36874
|
-
if (!canvas || typeof canvas !== "object") return canvas;
|
|
36875
|
-
const c = canvas;
|
|
36876
|
-
if (!Array.isArray(c.nodes)) return canvas;
|
|
36877
|
-
return { ...canvas, nodes: c.nodes.map((n) => resolveNode(n, baseDir)) };
|
|
36878
|
-
}
|
|
36879
|
-
function resolveNode(node, baseDir) {
|
|
36880
|
-
if (!node || typeof node !== "object") return node;
|
|
36881
|
-
const n = node;
|
|
36882
|
-
const params = n.params;
|
|
36883
|
-
if (!params || typeof params !== "object") return node;
|
|
36884
|
-
if (n.type === "ingest" && params.source === "path" && isResolvableRelative(params.path)) {
|
|
36885
|
-
return { ...node, params: { ...params, path: path6.resolve(baseDir, params.path) } };
|
|
36886
|
-
}
|
|
36887
|
-
if (n.type === "hyperframe_render" && isResolvableRelative(params.composition)) {
|
|
36888
|
-
return { ...node, params: { ...params, composition: path6.resolve(baseDir, params.composition) } };
|
|
36889
|
-
}
|
|
36890
|
-
return node;
|
|
36891
|
-
}
|
|
36892
|
-
function isResolvableRelative(value) {
|
|
36893
|
-
return typeof value === "string" && value.length > 0 && !value.includes("[TODO") && !looksLikeHttpUrl(value) && !path6.isAbsolute(value);
|
|
36894
|
-
}
|
|
36895
|
-
|
|
36896
36908
|
// src/commands/canvas/source-version.ts
|
|
36897
36909
|
import { readFile as readFile6 } from "fs/promises";
|
|
36898
36910
|
import path8 from "path";
|
|
@@ -41002,12 +41014,9 @@ function localPathRefsFromCanvas(parsed) {
|
|
|
41002
41014
|
const n = node;
|
|
41003
41015
|
const params = n.params;
|
|
41004
41016
|
if (!params || typeof params !== "object") continue;
|
|
41005
|
-
|
|
41006
|
-
|
|
41007
|
-
|
|
41008
|
-
if (n.type === "hyperframe_render" && isSnapshotablePath(params.composition)) {
|
|
41009
|
-
refs.add(params.composition);
|
|
41010
|
-
}
|
|
41017
|
+
const key = localPathParam(n);
|
|
41018
|
+
const value = key ? params[key] : void 0;
|
|
41019
|
+
if (isSnapshotablePath(value)) refs.add(value);
|
|
41011
41020
|
}
|
|
41012
41021
|
return [...refs];
|
|
41013
41022
|
}
|
|
@@ -41692,8 +41701,8 @@ var runCommand = defineCommand111({
|
|
|
41692
41701
|
type: "string",
|
|
41693
41702
|
description: "What the person asked for, IN THEIR OWN WORDS \u2014 paste their message, do not summarise it. The review compares the finished video against this and reports what they asked for that is missing or contradicted. Without it the review can only say whether the video is well made, not whether it is the one they wanted: every other check grades the render against the spec, and a spec that misread the request agrees with itself."
|
|
41694
41703
|
},
|
|
41695
|
-
"cache-dir": { type: "string", description: "Cache root (default
|
|
41696
|
-
"outputs-dir": { type: "string", description: "Per-run outputs root (default
|
|
41704
|
+
"cache-dir": { type: "string", description: "Cache root (default <workspace root>/canvas/.cache, whatever directory you run from)" },
|
|
41705
|
+
"outputs-dir": { type: "string", description: "Per-run outputs root (default <workspace root>/canvas, whatever directory you run from)" },
|
|
41697
41706
|
"run-id": { type: "string", description: "Override run id (also resumes that run, re-attaching its in-flight jobs)" },
|
|
41698
41707
|
fresh: {
|
|
41699
41708
|
type: "boolean",
|
|
@@ -41771,6 +41780,7 @@ function stopBeforeKinds(until) {
|
|
|
41771
41780
|
}
|
|
41772
41781
|
async function executeCanvasRun(opts) {
|
|
41773
41782
|
const filePath = path16.resolve(opts.file);
|
|
41783
|
+
const canvasRoot = canvasOutputsRoot(filePath);
|
|
41774
41784
|
const raw = await readFile12(filePath, "utf8");
|
|
41775
41785
|
let parsed;
|
|
41776
41786
|
try {
|
|
@@ -41782,7 +41792,7 @@ async function executeCanvasRun(opts) {
|
|
|
41782
41792
|
process.exit(2);
|
|
41783
41793
|
}
|
|
41784
41794
|
const attemptedSlug = creativeSlugFromCanvasPath(filePath);
|
|
41785
|
-
if (attemptedSlug) await clearCreativeDirty(attemptedSlug);
|
|
41795
|
+
if (attemptedSlug) await clearCreativeDirty(attemptedSlug, path16.join(canvasRoot, ".dirty"));
|
|
41786
41796
|
const healed = await healCanvasPaths(filePath, parsed);
|
|
41787
41797
|
parsed = healed.canvas;
|
|
41788
41798
|
const canvasText = healed.text ?? raw;
|
|
@@ -41878,8 +41888,8 @@ ${describeRewrites(healed.rewrites)}
|
|
|
41878
41888
|
}
|
|
41879
41889
|
}
|
|
41880
41890
|
const engine = createEngineFromEnv({
|
|
41881
|
-
cacheDir: opts.cacheDir,
|
|
41882
|
-
outputsDir: opts.outputsDir,
|
|
41891
|
+
cacheDir: opts.cacheDir ?? path16.join(canvasRoot, ".cache"),
|
|
41892
|
+
outputsDir: opts.outputsDir ?? canvasRoot,
|
|
41883
41893
|
log: (line) => process.stdout.write(`${line}
|
|
41884
41894
|
`),
|
|
41885
41895
|
remoteCache: opts.remoteCache
|
|
@@ -41899,7 +41909,7 @@ ${describeRewrites(healed.rewrites)}
|
|
|
41899
41909
|
const canvasSha = sha256Hex(Buffer.from(canvasText));
|
|
41900
41910
|
const creativeSlug = creativeSlugFromCanvasPath(filePath) ?? void 0;
|
|
41901
41911
|
const client = opts.record === false ? null : buildBackendClient();
|
|
41902
|
-
const outputsDir = opts.outputsDir ? path16.resolve(opts.outputsDir) :
|
|
41912
|
+
const outputsDir = opts.outputsDir ? path16.resolve(opts.outputsDir) : canvasRoot;
|
|
41903
41913
|
const { runId, resumed, source, concurrentRunId } = await resolveRunId({
|
|
41904
41914
|
explicitRunId: opts.runId,
|
|
41905
41915
|
fresh: opts.fresh === true,
|
|
@@ -41933,7 +41943,7 @@ ${describeRewrites(healed.rewrites)}
|
|
|
41933
41943
|
const canvasSnapshotUrl = client && creativeSlug ? await uploadRunSnapshot(client, { canvasPath: filePath, raw: canvasText, creativeSlug, parsed }) ?? void 0 : void 0;
|
|
41934
41944
|
const recordMeta = {
|
|
41935
41945
|
creativeSlug,
|
|
41936
|
-
canvasPath: path16.relative(
|
|
41946
|
+
canvasPath: path16.relative(path16.dirname(canvasRoot), filePath) || void 0,
|
|
41937
41947
|
canvasSha,
|
|
41938
41948
|
// The fingerprint the dashboard compares against the current source to flag
|
|
41939
41949
|
// "edited since last render". Computed from the on-disk canvas.json +
|