@koda-sl/baker-cli 0.361.0-dev.d766dc120 → 0.362.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/dist/cli.js CHANGED
@@ -69,7 +69,7 @@ import {
69
69
  validateCanvasDeep,
70
70
  withoutCastName,
71
71
  ytDlpBlockSignal
72
- } from "./chunk-K2IKLMCM.js";
72
+ } from "./chunk-AI4HWQVN.js";
73
73
  import {
74
74
  csvOrJson,
75
75
  daysAgoIso,
@@ -34118,12 +34118,13 @@ function readFlowConversions2(slug, definitions) {
34118
34118
  endings: joinFlowConversions(flowEventKeys(tree, slug), definitions)
34119
34119
  };
34120
34120
  }
34121
- function conversionsEnvelope(args5, definitions, candidates) {
34121
+ function conversionsEnvelope(args5, definitions, candidates, serverHints = []) {
34122
34122
  const flow = args5.flowSlug === void 0 ? null : readFlowConversions2(args5.flowSlug, definitions);
34123
34123
  const forms = flow === null ? readWorkspaceFlows() : [];
34124
34124
  const coverage = flowCoverage(forms, definitions);
34125
34125
  const page = pageCandidates(definitions, candidates, args5.candidates);
34126
34126
  const hints2 = [
34127
+ ...serverHints,
34127
34128
  ...flow ? flowConversionHints(flow.slug, flow.endings, flow.noConversionReason) : [],
34128
34129
  ...flowCoverageHints(coverage),
34129
34130
  ...stagedHints(definitions),
@@ -34213,7 +34214,8 @@ var conversionsCommand3 = (() => {
34213
34214
  for (const eventKey of args6.eventKeys) refuseUnmatchableKey(eventKey);
34214
34215
  const before = await apiPost("/api/analytics/conversions", {});
34215
34216
  const write = conversionsWrite(args6, before.data.definitions);
34216
- const stored = write ? (await apiPost("/api/analytics/conversions", write)).data.definitions : before.data.definitions;
34217
+ const answer = write ? await apiPost("/api/analytics/conversions", write) : before;
34218
+ const stored = answer.data.definitions;
34217
34219
  const report = await apiPost("/api/analytics/query", {
34218
34220
  preset: "conversions",
34219
34221
  days: args6.days
@@ -34221,7 +34223,8 @@ var conversionsCommand3 = (() => {
34221
34223
  const envelope = conversionsEnvelope(
34222
34224
  args6,
34223
34225
  mergeStoredWithCounts(stored, report.data.conversions ?? []),
34224
- report.data.eventCatalog ?? []
34226
+ report.data.eventCatalog ?? [],
34227
+ answer.hints ?? []
34225
34228
  );
34226
34229
  if (format === "md") process.stdout.write(renderConversionsMarkdown(envelope));
34227
34230
  else writeJsonEnvelope(withFormatHint(envelope, format));
@@ -36641,9 +36644,134 @@ var critiqueCommand = defineCommand109({
36641
36644
  // src/commands/canvas/inspect.ts
36642
36645
  import { execFile } from "child_process";
36643
36646
  import { readdir as readdir2, readFile as readFile4, stat } from "fs/promises";
36644
- import path4 from "path";
36647
+ import path6 from "path";
36645
36648
  import { promisify } from "util";
36646
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
36647
36775
  var execFileAsync = promisify(execFile);
36648
36776
  var inspectCommand = defineCommand110({
36649
36777
  meta: {
@@ -36652,14 +36780,15 @@ var inspectCommand = defineCommand110({
36652
36780
  },
36653
36781
  args: {
36654
36782
  run: { type: "positional", required: true, description: "Run id (e.g. r_01K...) or absolute run directory" },
36655
- "outputs-dir": { type: "string", description: "Per-run outputs root (default ./canvas)" },
36783
+ "outputs-dir": { type: "string", description: "Per-run outputs root (default <workspace root>/canvas, where `canvas run` writes)" },
36656
36784
  thumbnails: {
36657
36785
  type: "boolean",
36658
36786
  description: "Extract start/middle/end frames from every video output (requires ffmpeg)"
36659
36787
  }
36660
36788
  },
36661
36789
  async run({ args: args5 }) {
36662
- const outputsDir = path4.resolve(String(args5["outputs-dir"] ?? "canvas"));
36790
+ const cwd = process.cwd();
36791
+ const outputsDir = args5["outputs-dir"] ? path6.resolve(String(args5["outputs-dir"])) : path6.join(findWorkspaceRoot(cwd) ?? cwd, "canvas");
36663
36792
  const runArg = String(args5.run);
36664
36793
  const runDir = await resolveRunDir(runArg, outputsDir);
36665
36794
  const manifest = await loadManifest(runDir);
@@ -36671,7 +36800,7 @@ var inspectCommand = defineCommand110({
36671
36800
  }
36672
36801
  const summary = {
36673
36802
  ok: true,
36674
- run_id: manifest.run_id ?? path4.basename(runDir),
36803
+ run_id: manifest.run_id ?? path6.basename(runDir),
36675
36804
  run_dir: runDir,
36676
36805
  stats: manifest.stats ?? null,
36677
36806
  output: manifest.output ?? null,
@@ -36684,18 +36813,18 @@ var inspectCommand = defineCommand110({
36684
36813
  }
36685
36814
  });
36686
36815
  async function resolveRunDir(run, outputsDir) {
36687
- if (path4.isAbsolute(run)) {
36816
+ if (path6.isAbsolute(run)) {
36688
36817
  const s2 = await stat(run).catch(() => null);
36689
36818
  if (s2?.isDirectory()) return run;
36690
36819
  throw new Error(`inspect: ${run} is not a directory`);
36691
36820
  }
36692
- const candidate = path4.join(outputsDir, run);
36821
+ const candidate = path6.join(outputsDir, run);
36693
36822
  const s = await stat(candidate).catch(() => null);
36694
36823
  if (s?.isDirectory()) return candidate;
36695
36824
  throw new Error(`inspect: no run directory at ${candidate}`);
36696
36825
  }
36697
36826
  async function loadManifest(runDir) {
36698
- const manifestPath = path4.join(runDir, "manifest.json");
36827
+ const manifestPath = path6.join(runDir, "manifest.json");
36699
36828
  try {
36700
36829
  const raw = await readFile4(manifestPath, "utf-8");
36701
36830
  return JSON.parse(raw);
@@ -36707,7 +36836,7 @@ async function listRunFiles(runDir) {
36707
36836
  const out = [];
36708
36837
  const names = await readdir2(runDir);
36709
36838
  for (const name of names) {
36710
- const abs = path4.join(runDir, name);
36839
+ const abs = path6.join(runDir, name);
36711
36840
  const s = await stat(abs).catch(() => null);
36712
36841
  if (!s?.isFile()) continue;
36713
36842
  out.push({ name, path: abs, size: s.size });
@@ -36760,95 +36889,6 @@ import { readFile as readFile12 } from "fs/promises";
36760
36889
  import path16 from "path";
36761
36890
  import { defineCommand as defineCommand111 } from "citty";
36762
36891
 
36763
- // src/commands/canvas/normalize-paths.ts
36764
- import { existsSync as existsSync4, realpathSync } from "fs";
36765
- import { writeFile as writeFile2 } from "fs/promises";
36766
- import path5 from "path";
36767
- function findWorkspaceRoot(startDir, exists2 = existsSync4, maxDepth = 12) {
36768
- let dir = path5.resolve(startDir);
36769
- for (let i = 0; i < maxDepth; i++) {
36770
- if (exists2(path5.join(dir, "package.json"))) return dir;
36771
- const parent = path5.dirname(dir);
36772
- if (parent === dir) break;
36773
- dir = parent;
36774
- }
36775
- return null;
36776
- }
36777
- function canonicalize(target2) {
36778
- const abs = path5.resolve(target2);
36779
- let dir = abs;
36780
- for (; ; ) {
36781
- try {
36782
- const real = realpathSync(dir);
36783
- return dir === abs ? real : path5.join(real, path5.relative(dir, abs));
36784
- } catch {
36785
- const parent = path5.dirname(dir);
36786
- if (parent === dir) return abs;
36787
- dir = parent;
36788
- }
36789
- }
36790
- }
36791
- function isInside(root, target2) {
36792
- const rel = path5.relative(root, target2);
36793
- return rel !== "" && !rel.startsWith("..") && !path5.isAbsolute(rel);
36794
- }
36795
- function toCanvasRelative(canvasDir, target2) {
36796
- return path5.relative(canvasDir, target2).split(path5.sep).join("/");
36797
- }
36798
- var RUNTIME_WORKSPACE_ROOT = "/home/user/repo";
36799
- function rewriteTarget(value, workspaceRoot) {
36800
- if (typeof value !== "string" || value.length === 0) return null;
36801
- if (value.includes("[TODO") || looksLikeHttpUrl(value) || !path5.isAbsolute(value)) return null;
36802
- const target2 = canonicalize(value);
36803
- if (isInside(workspaceRoot, target2)) return target2;
36804
- const fromRuntime = path5.relative(RUNTIME_WORKSPACE_ROOT, path5.normalize(value));
36805
- if (fromRuntime !== "" && !fromRuntime.startsWith("..") && !path5.isAbsolute(fromRuntime)) {
36806
- return path5.join(workspaceRoot, fromRuntime);
36807
- }
36808
- return null;
36809
- }
36810
- function normalizeCanvasPaths(canvas, canvasDir, workspaceRoot) {
36811
- if (!canvas || typeof canvas !== "object") return { canvas, rewrites: [] };
36812
- const c = canvas;
36813
- if (!Array.isArray(c.nodes)) return { canvas, rewrites: [] };
36814
- const root = canonicalize(workspaceRoot);
36815
- const dir = canonicalize(canvasDir);
36816
- const rewrites = [];
36817
- const nodes = c.nodes.map((node) => {
36818
- if (!node || typeof node !== "object") return node;
36819
- const n = node;
36820
- const params = n.params;
36821
- if (!params || typeof params !== "object") return node;
36822
- const nodeId = typeof n.id === "string" ? n.id : "?";
36823
- if (n.type === "ingest" && params.source === "path" && looksLikeHttpUrl(params.path)) {
36824
- rewrites.push({ nodeId, param: "source", from: "path", to: "url" });
36825
- return { ...node, params: coercePathUrlToUrl(params) };
36826
- }
36827
- const key = n.type === "ingest" && params.source === "path" ? "path" : n.type === "hyperframe_render" ? "composition" : null;
36828
- if (!key) return node;
36829
- const target2 = rewriteTarget(params[key], root);
36830
- if (target2 === null) return node;
36831
- const to = toCanvasRelative(dir, target2);
36832
- rewrites.push({ nodeId, param: key, from: params[key], to });
36833
- return { ...node, params: { ...params, [key]: to } };
36834
- });
36835
- return rewrites.length === 0 ? { canvas, rewrites } : { canvas: { ...canvas, nodes }, rewrites };
36836
- }
36837
- async function healCanvasPaths(filePath, canvas) {
36838
- const canvasDir = path5.dirname(filePath);
36839
- const workspaceRoot = findWorkspaceRoot(canvasDir);
36840
- if (!workspaceRoot) return { canvas, rewrites: [], text: null };
36841
- const normalized = normalizeCanvasPaths(canvas, canvasDir, workspaceRoot);
36842
- if (normalized.rewrites.length === 0) return { ...normalized, text: null };
36843
- const text2 = `${JSON.stringify(normalized.canvas, null, 2)}
36844
- `;
36845
- await writeFile2(filePath, text2, "utf8");
36846
- return { ...normalized, text: text2 };
36847
- }
36848
- function describeRewrites(rewrites) {
36849
- return rewrites.map((r) => ` ${r.nodeId}.${r.param}: ${r.from} \u2192 ${r.to}`).join("\n");
36850
- }
36851
-
36852
36892
  // src/commands/canvas/placeholders.ts
36853
36893
  function unsuppliedPlaceholderAssets(canvas) {
36854
36894
  const nodes = canvas?.nodes;
@@ -36865,31 +36905,6 @@ function unsuppliedPlaceholderAssets(canvas) {
36865
36905
  return out;
36866
36906
  }
36867
36907
 
36868
- // src/commands/canvas/resolve-paths.ts
36869
- import path6 from "path";
36870
- function resolveRelativeCanvasPaths(canvas, baseDir) {
36871
- if (!canvas || typeof canvas !== "object") return canvas;
36872
- const c = canvas;
36873
- if (!Array.isArray(c.nodes)) return canvas;
36874
- return { ...canvas, nodes: c.nodes.map((n) => resolveNode(n, baseDir)) };
36875
- }
36876
- function resolveNode(node, baseDir) {
36877
- if (!node || typeof node !== "object") return node;
36878
- const n = node;
36879
- const params = n.params;
36880
- if (!params || typeof params !== "object") return node;
36881
- if (n.type === "ingest" && params.source === "path" && isResolvableRelative(params.path)) {
36882
- return { ...node, params: { ...params, path: path6.resolve(baseDir, params.path) } };
36883
- }
36884
- if (n.type === "hyperframe_render" && isResolvableRelative(params.composition)) {
36885
- return { ...node, params: { ...params, composition: path6.resolve(baseDir, params.composition) } };
36886
- }
36887
- return node;
36888
- }
36889
- function isResolvableRelative(value) {
36890
- return typeof value === "string" && value.length > 0 && !value.includes("[TODO") && !looksLikeHttpUrl(value) && !path6.isAbsolute(value);
36891
- }
36892
-
36893
36908
  // src/commands/canvas/source-version.ts
36894
36909
  import { readFile as readFile6 } from "fs/promises";
36895
36910
  import path8 from "path";
@@ -40999,12 +41014,9 @@ function localPathRefsFromCanvas(parsed) {
40999
41014
  const n = node;
41000
41015
  const params = n.params;
41001
41016
  if (!params || typeof params !== "object") continue;
41002
- if (n.type === "ingest" && params.source === "path" && isSnapshotablePath(params.path)) {
41003
- refs.add(params.path);
41004
- }
41005
- if (n.type === "hyperframe_render" && isSnapshotablePath(params.composition)) {
41006
- refs.add(params.composition);
41007
- }
41017
+ const key = localPathParam(n);
41018
+ const value = key ? params[key] : void 0;
41019
+ if (isSnapshotablePath(value)) refs.add(value);
41008
41020
  }
41009
41021
  return [...refs];
41010
41022
  }
@@ -41689,8 +41701,8 @@ var runCommand = defineCommand111({
41689
41701
  type: "string",
41690
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."
41691
41703
  },
41692
- "cache-dir": { type: "string", description: "Cache root (default ./canvas/.cache)" },
41693
- "outputs-dir": { type: "string", description: "Per-run outputs root (default ./canvas)" },
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)" },
41694
41706
  "run-id": { type: "string", description: "Override run id (also resumes that run, re-attaching its in-flight jobs)" },
41695
41707
  fresh: {
41696
41708
  type: "boolean",
@@ -41768,6 +41780,7 @@ function stopBeforeKinds(until) {
41768
41780
  }
41769
41781
  async function executeCanvasRun(opts) {
41770
41782
  const filePath = path16.resolve(opts.file);
41783
+ const canvasRoot = canvasOutputsRoot(filePath);
41771
41784
  const raw = await readFile12(filePath, "utf8");
41772
41785
  let parsed;
41773
41786
  try {
@@ -41779,7 +41792,7 @@ async function executeCanvasRun(opts) {
41779
41792
  process.exit(2);
41780
41793
  }
41781
41794
  const attemptedSlug = creativeSlugFromCanvasPath(filePath);
41782
- if (attemptedSlug) await clearCreativeDirty(attemptedSlug);
41795
+ if (attemptedSlug) await clearCreativeDirty(attemptedSlug, path16.join(canvasRoot, ".dirty"));
41783
41796
  const healed = await healCanvasPaths(filePath, parsed);
41784
41797
  parsed = healed.canvas;
41785
41798
  const canvasText = healed.text ?? raw;
@@ -41875,8 +41888,8 @@ ${describeRewrites(healed.rewrites)}
41875
41888
  }
41876
41889
  }
41877
41890
  const engine = createEngineFromEnv({
41878
- cacheDir: opts.cacheDir,
41879
- outputsDir: opts.outputsDir,
41891
+ cacheDir: opts.cacheDir ?? path16.join(canvasRoot, ".cache"),
41892
+ outputsDir: opts.outputsDir ?? canvasRoot,
41880
41893
  log: (line) => process.stdout.write(`${line}
41881
41894
  `),
41882
41895
  remoteCache: opts.remoteCache
@@ -41896,7 +41909,7 @@ ${describeRewrites(healed.rewrites)}
41896
41909
  const canvasSha = sha256Hex(Buffer.from(canvasText));
41897
41910
  const creativeSlug = creativeSlugFromCanvasPath(filePath) ?? void 0;
41898
41911
  const client = opts.record === false ? null : buildBackendClient();
41899
- const outputsDir = opts.outputsDir ? path16.resolve(opts.outputsDir) : path16.resolve("canvas");
41912
+ const outputsDir = opts.outputsDir ? path16.resolve(opts.outputsDir) : canvasRoot;
41900
41913
  const { runId, resumed, source, concurrentRunId } = await resolveRunId({
41901
41914
  explicitRunId: opts.runId,
41902
41915
  fresh: opts.fresh === true,
@@ -41930,7 +41943,7 @@ ${describeRewrites(healed.rewrites)}
41930
41943
  const canvasSnapshotUrl = client && creativeSlug ? await uploadRunSnapshot(client, { canvasPath: filePath, raw: canvasText, creativeSlug, parsed }) ?? void 0 : void 0;
41931
41944
  const recordMeta = {
41932
41945
  creativeSlug,
41933
- canvasPath: path16.relative(process.cwd(), filePath) || void 0,
41946
+ canvasPath: path16.relative(path16.dirname(canvasRoot), filePath) || void 0,
41934
41947
  canvasSha,
41935
41948
  // The fingerprint the dashboard compares against the current source to flag
41936
41949
  // "edited since last render". Computed from the on-disk canvas.json +
@@ -42841,12 +42854,12 @@ function fail3(code, message) {
42841
42854
  process.exit(2);
42842
42855
  }
42843
42856
  function resolveModels(args5) {
42844
- const pick2 = (flag, kind, fallback) => args5[flag] ? String(args5[flag]) : resolveModel(kind, fallback);
42857
+ const pick = (flag, kind, fallback) => args5[flag] ? String(args5[flag]) : resolveModel(kind, fallback);
42845
42858
  return {
42846
- describeModel: pick2("describe-model", "image_describe", "~google/gemini-pro-latest"),
42847
- selectModel: pick2("select-model", "text_generate", "~google/gemini-flash-latest"),
42848
- layoutModel: pick2("layout-model", "text_generate", "~google/gemini-flash-latest"),
42849
- genModel: pick2("gen-model", "image_generate", "openai/gpt-image-2")
42859
+ describeModel: pick("describe-model", "image_describe", "~google/gemini-pro-latest"),
42860
+ selectModel: pick("select-model", "text_generate", "~google/gemini-flash-latest"),
42861
+ layoutModel: pick("layout-model", "text_generate", "~google/gemini-flash-latest"),
42862
+ genModel: pick("gen-model", "image_generate", "openai/gpt-image-2")
42850
42863
  };
42851
42864
  }
42852
42865
  var PLATFORM_PLACEMENTS = {
@@ -44866,18 +44879,18 @@ function parseBudget(raw) {
44866
44879
  throw new Error(`--budget must be one of ${VIDEO_BUDGETS.join(", ")} (got "${v}")`);
44867
44880
  }
44868
44881
  function resolveModels2(args5) {
44869
- const pick2 = (flag, kind, fallback) => args5[flag] ? String(args5[flag]) : resolveModel2(kind, fallback);
44882
+ const pick = (flag, kind, fallback) => args5[flag] ? String(args5[flag]) : resolveModel2(kind, fallback);
44870
44883
  return {
44871
44884
  // Flash by default: ~2-3× faster per call than Pro, which keeps each
44872
44885
  // per-scene deconstruct step well inside the action time budget and turns a
44873
44886
  // ~9 min run into ~3-4 min. Override with --deconstruct-model
44874
44887
  // ~google/gemini-pro-latest for the densest extraction when speed matters less.
44875
- deconstructModel: pick2("deconstruct-model", "video_deconstruct", "~google/gemini-flash-latest"),
44876
- selectModel: pick2("select-model", "text_generate", "~google/gemini-flash-latest"),
44888
+ deconstructModel: pick("deconstruct-model", "video_deconstruct", "~google/gemini-flash-latest"),
44889
+ selectModel: pick("select-model", "text_generate", "~google/gemini-flash-latest"),
44877
44890
  // Default to the strongest image model (matches the static-ad scaffold); the
44878
44891
  // frame generators need the most faithful text/identity reproduction. Override
44879
44892
  // with --image-model for a cheaper/faster pass.
44880
- imageModel: pick2("image-model", "image_generate", "openai/gpt-image-2.5-sunburst")
44893
+ imageModel: pick("image-model", "image_generate", "openai/gpt-image-2.5-sunburst")
44881
44894
  };
44882
44895
  }
44883
44896
  function hasPhotorealCast(elements) {
@@ -69065,134 +69078,6 @@ function outputFlagForCommand(root, argv) {
69065
69078
  });
69066
69079
  }
69067
69080
 
69068
- // src/field-mask.ts
69069
- var FLAG2 = "--fields";
69070
- function parseFields(value) {
69071
- return value.split(",").map((field) => field.trim()).filter((field) => field.length > 0);
69072
- }
69073
- function takeFieldsFlag(root, argv) {
69074
- const end = argv.indexOf("--");
69075
- const limit = end === -1 ? argv.length : end;
69076
- const taken = /* @__PURE__ */ new Set();
69077
- const fields = [];
69078
- for (let index = 0; index < limit; index++) {
69079
- const token = argv[index] ?? "";
69080
- if (token.startsWith(`${FLAG2}=`)) {
69081
- taken.add(index);
69082
- fields.push(...parseFields(token.slice(FLAG2.length + 1)));
69083
- } else if (token === FLAG2) {
69084
- const value = argv[index + 1];
69085
- if (value === void 0 || index + 1 >= limit || value.startsWith("-")) {
69086
- return { argv, fields: null };
69087
- }
69088
- taken.add(index).add(index + 1);
69089
- fields.push(...parseFields(value));
69090
- index++;
69091
- }
69092
- }
69093
- if (taken.size === 0 || fields.length === 0) {
69094
- return { argv, fields: null };
69095
- }
69096
- const command = commandFor(root, argv);
69097
- if (!command || declaredArg(command, "fields") || PRINTS_NO_ENVELOPE.has(commandPathOf(root, argv))) {
69098
- return { argv, fields: null };
69099
- }
69100
- return { argv: argv.filter((_, index) => !taken.has(index)), fields };
69101
- }
69102
- function isRecord3(value) {
69103
- return typeof value === "object" && value !== null && !Array.isArray(value);
69104
- }
69105
- function pick(record, fields) {
69106
- return Object.fromEntries(fields.filter((field) => field in record).map((field) => [field, record[field]]));
69107
- }
69108
- function wrappedList(data, fields) {
69109
- if (fields.some((field) => field in data)) {
69110
- return null;
69111
- }
69112
- const lists = Object.entries(data).filter(
69113
- ([, value]) => Array.isArray(value) && value.every((item) => isRecord3(item))
69114
- );
69115
- return lists.length === 1 ? lists[0]?.[0] ?? null : null;
69116
- }
69117
- function recordsOf(data, fields) {
69118
- if (Array.isArray(data)) {
69119
- return data;
69120
- }
69121
- if (!isRecord3(data)) {
69122
- return [];
69123
- }
69124
- const list = wrappedList(data, fields);
69125
- return list === null ? [data] : data[list];
69126
- }
69127
- function maskData(data, fields) {
69128
- const mask = (item) => isRecord3(item) ? pick(item, fields) : item;
69129
- if (Array.isArray(data)) {
69130
- return data.map(mask);
69131
- }
69132
- if (!isRecord3(data)) {
69133
- return data;
69134
- }
69135
- const list = wrappedList(data, fields);
69136
- return list === null ? pick(data, fields) : { ...data, [list]: recordsOf(data, fields).map(mask) };
69137
- }
69138
- function unmatchedHint(data, fields) {
69139
- const records = recordsOf(data, fields).filter(isRecord3);
69140
- if (records.length === 0) {
69141
- return null;
69142
- }
69143
- const carried = new Set(records.flatMap((record) => Object.keys(record)));
69144
- const unmatched = fields.filter((field) => !carried.has(field));
69145
- if (unmatched.length === 0) {
69146
- return null;
69147
- }
69148
- return `--fields matched nothing for: ${unmatched.join(", ")}. The keys data carries are: ${[...carried].join(", ")}.`;
69149
- }
69150
- function maskPrintedEnvelope(text2, fields) {
69151
- let parsed;
69152
- try {
69153
- parsed = JSON.parse(text2);
69154
- } catch {
69155
- return null;
69156
- }
69157
- if (!isRecord3(parsed) || typeof parsed.ok !== "boolean") {
69158
- return null;
69159
- }
69160
- if (parsed.ok !== true || !("data" in parsed) || "dryRun" in parsed) {
69161
- return text2;
69162
- }
69163
- const masked = { ...parsed, data: maskData(parsed.data, fields) };
69164
- const miss = unmatchedHint(parsed.data, fields);
69165
- if (miss) {
69166
- masked.hints = [...Array.isArray(parsed.hints) ? parsed.hints : [], miss];
69167
- }
69168
- const indent = text2.trimStart().startsWith("{\n") ? 2 : void 0;
69169
- return `${JSON.stringify(masked, null, indent)}${text2.endsWith("\n") ? "\n" : ""}`;
69170
- }
69171
- function maskWrites(stream, fields) {
69172
- let applied = false;
69173
- const write = stream.write.bind(stream);
69174
- stream.write = (chunk, ...rest) => {
69175
- const masked = typeof chunk === "string" ? maskPrintedEnvelope(chunk, fields) : null;
69176
- if (masked === null) {
69177
- return write(chunk, ...rest);
69178
- }
69179
- applied = true;
69180
- return write(masked, ...rest);
69181
- };
69182
- return { sawEnvelope: () => applied };
69183
- }
69184
- function installFieldMask(fields, commandPath) {
69185
- const mask = maskWrites(process.stdout, fields);
69186
- process.on("exit", () => {
69187
- if (!mask.sawEnvelope()) {
69188
- process.stderr.write(
69189
- `--fields was not applied: \`baker ${commandPath}\` printed no JSON envelope to narrow. Add --output json to get the envelope, or drop --fields.
69190
- `
69191
- );
69192
- }
69193
- });
69194
- }
69195
-
69196
69081
  // src/version.ts
69197
69082
  import { readFileSync as readFileSync21 } from "fs";
69198
69083
  function packageJsonUrl() {
@@ -69219,7 +69104,6 @@ var main = defineCommand248({
69219
69104
  Auth: Set BAKER_API_KEY (starts with bk_) and BAKER_API_URL environment variables.
69220
69105
  Chat: Set BAKER_CHAT_ID for action and scheduled-agent commands that stage changes against a chat.
69221
69106
  Output: All commands return JSON envelopes: { ok: true, data: ... } or { ok: false, error: { code, message } }.
69222
- Fields: --fields a,b,c keeps only those keys of each record in data, on every command that prints the envelope.
69223
69107
  Formats: --output json works on every command that prints the envelope. --output md|files only where 'baker schema <command>' lists output. (The research commands additionally accept csv and jsonl.)
69224
69108
  Introspection: Run 'baker schema <command>' to inspect argument schemas.`
69225
69109
  },
@@ -69259,11 +69143,6 @@ installStreamTaps();
69259
69143
  logInvocation(process.argv.slice(2));
69260
69144
  installExitRecord();
69261
69145
  process.argv = [...process.argv.slice(0, 2), ...outputFlagForCommand(main, process.argv.slice(2))];
69262
- var fieldsFlag = takeFieldsFlag(main, process.argv.slice(2));
69263
- if (fieldsFlag.fields) {
69264
- process.argv = [...process.argv.slice(0, 2), ...fieldsFlag.argv];
69265
- installFieldMask(fieldsFlag.fields, commandPathOf(main, fieldsFlag.argv));
69266
- }
69267
69146
  refuseUnknownFlags(main, process.argv.slice(2));
69268
69147
  process.argv = [...process.argv.slice(0, 2), ...cacheFlagForParser(process.argv.slice(2))];
69269
69148
  runMain(main);