@koda-sl/baker-cli 0.192.0 → 0.192.1

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 CHANGED
@@ -4701,10 +4701,11 @@ baker canvas catalog | jq '.compositions[].id'
4701
4701
  // URL source — font file for font_specimen (direct fetch; magic-byte sniffed, so octet-stream CDNs work)
4702
4702
  { "id": "src", "type": "ingest", "params": { "source": "url", "url": "https://cdn.example.com/brand.ttf", "expect": "font" } }
4703
4703
 
4704
- // Path source — relative path resolved against process.cwd()
4704
+ // Path source — relative to the canvas file's own directory (validate/run resolve it there)
4705
4705
  { "id": "src", "type": "ingest", "params": { "source": "path", "path": "./inputs/headshot.png", "expect": "image" } }
4706
4706
 
4707
- // Path source — absolute path used as-is
4707
+ // Path source — an absolute path is used as-is, and so resolves only on the machine that wrote it.
4708
+ // Keep canvases portable: creative canvases are validated for this (`absolute-reference`).
4708
4709
  { "id": "src", "type": "ingest", "params": { "source": "path", "path": "/abs/work/clip.mp4", "expect": "video" } }
4709
4710
  ```
4710
4711
 
package/dist/cli.js CHANGED
@@ -20906,7 +20906,7 @@ function todoPath(el, label) {
20906
20906
  const t = el.type.toLowerCase();
20907
20907
  const fresh = t === "person" || t === "animal" || t === "location" ? " [SOURCE FRESH \u2014 a DIFFERENT person/animal/set than the original ad; do not reuse the source's individual]" : "";
20908
20908
  const same = el.same_as ? ` [SAME INDIVIDUAL as ${el.same_as} \u2014 a different wardrobe/look of the same person; reuse that cast person, change only the outfit]` : "";
20909
- return `[TODO: drop one real source image for ${label} (${el.type})${desc}${expr} \u2014 reused across every frame it appears in${fresh}${same}]`;
20909
+ return `[TODO: drop one real source image for ${label} (${el.type})${desc}${expr} \u2014 reused across every frame it appears in${fresh}${same}; use a path relative to this canvas file, never an absolute path]`;
20910
20910
  }
20911
20911
  function buildElementSlots(elements) {
20912
20912
  const usedIds = /* @__PURE__ */ new Set([
@@ -21753,7 +21753,7 @@ function emitScreenScene(i, scene, lengths, out, surfaceIngests, nodes, clips) {
21753
21753
  type: "ingest",
21754
21754
  params: {
21755
21755
  source: "path",
21756
- path: `[TODO: supply the REAL screen for "${label}" \u2014 NEVER AI-generate a UI. Capture a clean, text-free screenshot with \`baker images screenshot https://<brand-domain>/<path>\` (image-library skill); spoken/overlay text rides the overlay layer, not the screenshot]`,
21756
+ path: `[TODO: supply the REAL screen for "${label}" \u2014 NEVER AI-generate a UI. Capture a clean, text-free screenshot with \`baker images screenshot https://<brand-domain>/<path>\` (image-library skill); spoken/overlay text rides the overlay layer, not the screenshot. Wire it in as a path relative to this canvas file, never an absolute path]`,
21757
21757
  expect: "image"
21758
21758
  }
21759
21759
  });
@@ -21805,7 +21805,7 @@ function emitGraphicScene(i, scene, lengths, out, surfaceIngests, nodes, clips)
21805
21805
  type: "ingest",
21806
21806
  params: {
21807
21807
  source: "path",
21808
- path: `[TODO: supply the REAL designed graphic for "${label}" \u2014 NEVER AI-generate a designed panel (its typography/wordmarks garble). Rebuild it as brand HTML in video-overlay-composition (the scene's text/logos are already seeded there), export the design from the brand kit, or source stock art; text rides the overlay layer, not this plate]`,
21808
+ path: `[TODO: supply the REAL designed graphic for "${label}" \u2014 NEVER AI-generate a designed panel (its typography/wordmarks garble). Rebuild it as brand HTML in video-overlay-composition (the scene's text/logos are already seeded there), export the design from the brand kit, or source stock art; text rides the overlay layer, not this plate. Wire it in as a path relative to this canvas file, never an absolute path]`,
21809
21809
  expect: "image"
21810
21810
  }
21811
21811
  });
@@ -24082,6 +24082,10 @@ function mimeForFile(filePath) {
24082
24082
  function toPosix(p) {
24083
24083
  return p.split(path12.sep).join("/");
24084
24084
  }
24085
+ function isInside(dir, target) {
24086
+ const rel = path12.relative(dir, target);
24087
+ return !rel.startsWith("..") && !path12.isAbsolute(rel);
24088
+ }
24085
24089
  function localPathRefsFromCanvas(parsed) {
24086
24090
  const nodes = parsed?.nodes;
24087
24091
  if (!Array.isArray(nodes)) return [];
@@ -24120,6 +24124,13 @@ async function uploadRunSnapshot(client, opts) {
24120
24124
  const skipped = [];
24121
24125
  for (const refPath of await sourceRefsToSnapshot(canvasDir, opts.parsed)) {
24122
24126
  const abs = path12.isAbsolute(refPath) ? refPath : path12.resolve(canvasDir, refPath);
24127
+ if (!isInside(canvasDir, abs)) {
24128
+ skipped.push({
24129
+ path: toPosix(path12.relative(canvasDir, abs)),
24130
+ reason: "outside the creative folder \u2014 read from the workspace on rerun"
24131
+ });
24132
+ continue;
24133
+ }
24123
24134
  let st;
24124
24135
  try {
24125
24136
  st = await stat2(abs);
@@ -24776,7 +24787,7 @@ function todoPath2(el, label) {
24776
24787
  const expr = el.expression ? `, with a ${el.expression} expression` : "";
24777
24788
  const t = el.type.toLowerCase();
24778
24789
  const lock = t === "person" || t === "animal" ? " \u2014 REQUIRED: this is the emotional hero; ground it in a real reference (image-library / video-library / Pinterest), do not delete this slot and free-generate" : "";
24779
- return `[TODO: drop a real image for ${label} (${el.type})${desc}${expr}${lock}]`;
24790
+ return `[TODO: drop a real image for ${label} (${el.type})${desc}${expr}${lock} \u2014 replace with a path relative to this canvas file, never an absolute path]`;
24780
24791
  }
24781
24792
  function sheetSubjectDescription(el) {
24782
24793
  const desc = el.description ?? `the ${el.type}`;
@@ -24867,7 +24878,11 @@ function scaffoldStaticAd(input, elementsInput, opts) {
24867
24878
  nodes.push({
24868
24879
  id: "brandfont",
24869
24880
  type: "ingest",
24870
- params: { source: "path", path: "[TODO: path to brand font .otf/.ttf]", expect: "font" }
24881
+ params: {
24882
+ source: "path",
24883
+ path: "[TODO: brand font .otf/.ttf, as a path relative to this canvas file (e.g. ../../brand/fonts/Brand-Bold.otf) \u2014 never an absolute path]",
24884
+ expect: "font"
24885
+ }
24871
24886
  });
24872
24887
  nodes.push({
24873
24888
  id: "type_ref",