@koda-sl/baker-cli 0.129.1-dev.972f3c9aa → 0.131.0-dev.597b50181

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.
@@ -1995,7 +1995,17 @@ var VideoMeta = z.object({
1995
1995
  // Per video_generate node: the scene's natural visual span. The validator warns
1996
1996
  // when a clip's span exceeds the assigned model's max clip duration (e.g. a 9.2s
1997
1997
  // scene on Veo, which caps at 8s) — the clip would truncate.
1998
- clip_spans: z.array(z.object({ node: z.string(), span_s: z.number() })).optional()
1998
+ clip_spans: z.array(z.object({ node: z.string(), span_s: z.number() })).optional(),
1999
+ // WHY the graph has the nodes it has: one route per scene (clip / still_hold /
2000
+ // screen_still / graphic_plate / brand_card / phrase_slice / phrase_run /
2001
+ // composite) + a node-type histogram, stamped by scaffold-video. Read this first
2002
+ // when a canvas looks big.
2003
+ graph_stats: z.object({
2004
+ nodes_total: z.number(),
2005
+ nodes_billable: z.number(),
2006
+ node_types: z.record(z.string(), z.number()),
2007
+ scene_routes: z.array(z.object({ scene: z.number(), route: z.string(), window_s: z.number() }))
2008
+ }).strict().optional()
1999
2009
  }).strict().optional();
2000
2010
  var CanvasMetadata = z.object({
2001
2011
  name: z.string().optional(),
@@ -2519,6 +2529,41 @@ function imageProfileFor(modelId) {
2519
2529
  return void 0;
2520
2530
  }
2521
2531
 
2532
+ // src/engine/scaffold/spine-input.ts
2533
+ function spineInputFlags(work, lenS) {
2534
+ return work.still ? ["-loop", "1", "-t", lenS.toFixed(3)] : [];
2535
+ }
2536
+ function spineInputOps(work, lenS, dims) {
2537
+ const fit = work.still?.fit ?? "fill";
2538
+ const scale = fit === "pad" ? `scale=${dims.w}:${dims.h}:force_original_aspect_ratio=decrease,pad=${dims.w}:${dims.h}:(ow-iw)/2:(oh-ih)/2:color=black` : `scale=${dims.w}:${dims.h}:force_original_aspect_ratio=increase,crop=${dims.w}:${dims.h}`;
2539
+ const normalize = `${scale},format=yuv420p,fps=30,setsar=1,settb=AVTB`;
2540
+ if (work.trim) {
2541
+ const start = work.trim.offset_s > 0 ? `start=${work.trim.offset_s.toFixed(3)}:` : "";
2542
+ return `${normalize},trim=${start}duration=${lenS.toFixed(3)},setpts=PTS-STARTPTS`;
2543
+ }
2544
+ if (work.still) return `${normalize},trim=duration=${lenS.toFixed(3)}`;
2545
+ return normalize;
2546
+ }
2547
+ function parseSpineInputLens(args) {
2548
+ const lens = /* @__PURE__ */ new Map();
2549
+ let inputIndex = 0;
2550
+ for (let i = 0; i < args.length; i++) {
2551
+ if (args[i] !== "-i") continue;
2552
+ if (args[i - 2] === "-t") {
2553
+ const v = Number(args[i - 1]);
2554
+ if (Number.isFinite(v)) lens.set(inputIndex, v);
2555
+ }
2556
+ inputIndex++;
2557
+ }
2558
+ const graph = args.join(" ");
2559
+ for (const m of graph.matchAll(/\[(\d+):v\][^;[]*?trim=(?:start=[\d.]+:)?duration=([\d.]+)/g)) {
2560
+ const idx = Number(m[1]);
2561
+ const v = Number(m[2]);
2562
+ if (Number.isFinite(idx) && Number.isFinite(v)) lens.set(idx, v);
2563
+ }
2564
+ return lens;
2565
+ }
2566
+
2522
2567
  // src/engine/engine/define.ts
2523
2568
  function resolveOutputKinds(spec, params) {
2524
2569
  if (!spec) return {};
@@ -2614,7 +2659,8 @@ var STAGE_CODES = {
2614
2659
  SPINE_UNNORMALIZED: "VIDEO_SPINE_UNNORMALIZED",
2615
2660
  ODD_DIMENSIONS: "VIDEO_ODD_DIMENSIONS",
2616
2661
  REGION_DROPPED: "VIDEO_REGION_DROPPED",
2617
- OVERLAY_OUT_OF_BOUNDS: "VIDEO_OVERLAY_OUT_OF_BOUNDS"
2662
+ OVERLAY_OUT_OF_BOUNDS: "VIDEO_OVERLAY_OUT_OF_BOUNDS",
2663
+ ORPHAN_NODE: "ORPHAN_NODE"
2618
2664
  };
2619
2665
  var SPAN_MODEL_SLACK_S = 0.25;
2620
2666
  var VIDEO_TIME_SLACK_S = 0.75;
@@ -2678,6 +2724,7 @@ function validateCanvas(input, registry) {
2678
2724
  checkAllSlots(ctx);
2679
2725
  const estimatedCredits = estimateCredits(ctx);
2680
2726
  checkOutputRef(ctx);
2727
+ checkOrphanNodes(ctx);
2681
2728
  checkVideoInvariants(ctx);
2682
2729
  const hasBlocking = issues.some(isBlocking);
2683
2730
  if (hasBlocking) return { ok: false, issues };
@@ -3207,8 +3254,11 @@ function spineTotalS(ctx, spine) {
3207
3254
  let total = 0;
3208
3255
  const inputs = Object.entries(spine.inputs ?? {}).filter(([k]) => /^c\d+$/.test(k));
3209
3256
  if (inputs.length === 0) return null;
3210
- for (const [, v] of inputs) {
3211
- const d = liveNodeDurationS(ctx, refNodeOf(ctx, v));
3257
+ const rawArgs = spine.params.args;
3258
+ const absorbed = Array.isArray(rawArgs) ? parseSpineInputLens(rawArgs.map(String)) : /* @__PURE__ */ new Map();
3259
+ for (const [k, v] of inputs) {
3260
+ const inputIdx = Number(k.slice(1));
3261
+ const d = absorbed.get(inputIdx) ?? liveNodeDurationS(ctx, refNodeOf(ctx, v));
3212
3262
  if (d === null) return null;
3213
3263
  total += d;
3214
3264
  }
@@ -3550,6 +3600,28 @@ function checkAspectConsistency(ctx) {
3550
3600
  message: `video_generate nodes disagree on aspect_ratio (${[...ratios].sort().join(", ")}) \u2014 the spine's segments would render at different shapes and the composite silently crops. Pin every clip to the same aspect_ratio`
3551
3601
  });
3552
3602
  }
3603
+ function checkOrphanNodes(ctx) {
3604
+ const out = ctx.canvas.output;
3605
+ if (!out || !ctx.idToIndex.has(out.node)) return;
3606
+ const graph = buildDepGraph(ctx.canvas);
3607
+ const reachable = /* @__PURE__ */ new Set();
3608
+ const stack = [out.node];
3609
+ while (stack.length > 0) {
3610
+ const id = stack.pop();
3611
+ if (id === void 0 || reachable.has(id)) continue;
3612
+ reachable.add(id);
3613
+ for (const dep of graph.get(id) ?? []) stack.push(dep);
3614
+ }
3615
+ for (const n of ctx.canvas.nodes) {
3616
+ if (reachable.has(n.id) || n.type === "ingest") continue;
3617
+ ctx.issues.push({
3618
+ path: `nodes[${ctx.idToIndex.get(n.id)}]`,
3619
+ code: STAGE_CODES.ORPHAN_NODE,
3620
+ severity: "warning",
3621
+ message: `node "${n.id}" (${n.type}) is not reachable from output "${out.node}" \u2014 it will still execute (and bill, if billable) but nothing consumes its result; wire it in or remove it`
3622
+ });
3623
+ }
3624
+ }
3553
3625
  function checkOutputRef(ctx) {
3554
3626
  const out = ctx.canvas.output;
3555
3627
  if (!out) return;
@@ -7610,6 +7682,8 @@ export {
7610
7682
  clipProfileFor,
7611
7683
  clipParamRecipe,
7612
7684
  imageProfileFor,
7685
+ spineInputFlags,
7686
+ spineInputOps,
7613
7687
  elementMentionKeywords,
7614
7688
  toModelSafeImage,
7615
7689
  BackendClient2,
@@ -7622,4 +7696,4 @@ export {
7622
7696
  defaultRegistry,
7623
7697
  createEngineFromEnv
7624
7698
  };
7625
- //# sourceMappingURL=chunk-J2LYFDVC.js.map
7699
+ //# sourceMappingURL=chunk-4QK7JC6O.js.map