@koda-sl/baker-cli 0.265.0-dev.1f1c09c80 → 0.265.1-dev.1f1c09c80

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
@@ -32656,7 +32656,7 @@ function buildAdBrandOverlay(opts) {
32656
32656
  ];
32657
32657
  if (logo) {
32658
32658
  parts.push(
32659
- `<img class="ov clip pos-top-left brand-mark" src="${escapeHtml2(logo.file)}" alt="${escapeHtml2(logo.alt)}" data-start="0" data-dur="${totalS}" />`
32659
+ `<img class="clip brand-mark" src="${escapeHtml2(logo.file)}" alt="${escapeHtml2(logo.alt)}" data-start="0" data-dur="${totalS}" />`
32660
32660
  );
32661
32661
  }
32662
32662
  const cardBits = [];
@@ -32668,7 +32668,7 @@ function buildAdBrandOverlay(opts) {
32668
32668
  cardBits.push(`<div class="endcard-cta"${style}>${escapeHtml2(cta.trim())}</div>`);
32669
32669
  }
32670
32670
  parts.push(
32671
- `<div class="ov clip pos-center endcard" data-start="${cardAtS}" data-dur="${cardDurationS}" data-role="cta">`,
32671
+ `<div class="clip endcard" data-start="${cardAtS}" data-dur="${cardDurationS}" data-role="cta">`,
32672
32672
  ...cardBits.map((b) => ` ${b}`),
32673
32673
  "</div>"
32674
32674
  );
@@ -32677,15 +32677,22 @@ function buildAdBrandOverlay(opts) {
32677
32677
  function adBrandOverlayCss() {
32678
32678
  return [
32679
32679
  " /* --- brand layer (baker canvas scaffold-ad) --- */",
32680
- " .brand-mark { width: 220px; height: auto; opacity: 0.92;",
32681
- " filter: drop-shadow(0 2px 8px rgba(0,0,0,0.45)); }",
32682
- " .endcard { display: flex; flex-direction: column; align-items: center; gap: 56px;",
32680
+ " /* Positioned by this block alone. The composition that actually renders an ad",
32681
+ " is the caption track, which has no .pos-* helpers \u2014 relying on them put the",
32682
+ " brand layer in a file nothing opens and shipped an empty green end plate. */",
32683
+ " .brand-mark { position: absolute; top: 90px; left: 56px; width: 220px; height: auto;",
32684
+ " opacity: 0.92; filter: drop-shadow(0 2px 8px rgba(0,0,0,0.45)); }",
32685
+ " .endcard { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);",
32686
+ " display: flex; flex-direction: column; align-items: center; gap: 56px;",
32683
32687
  " width: 100%; max-width: 1080px; padding: 0 60px; text-align: center; }",
32684
32688
  " .endcard-logo { width: 620px; max-width: 78%; height: auto; }",
32685
32689
  " /* Capped and wrapping, not sized to its content: measured in a real browser,",
32686
32690
  " `GET YOUR FREE QUOTE` renders 948px wide against a 1080px canvas, so the next",
32687
32691
  " slightly longer call to action runs off the frame. Two lines beat an edge. */",
32688
- " .endcard-cta { font-size: 64px; font-weight: 900; text-transform: uppercase;",
32692
+ " /* Declares its own family: rendered without one it inherited the document",
32693
+ " default and the call to action came out in Times, beside sans-serif captions. */",
32694
+ " .endcard-cta { font-family: 'BrandFont', 'Arial Black', 'Helvetica Neue', Arial, sans-serif;",
32695
+ " font-size: 64px; font-weight: 900; text-transform: uppercase;",
32689
32696
  " letter-spacing: 0.01em; color: #fff; padding: 28px 58px; border-radius: 56px;",
32690
32697
  " max-width: 900px; line-height: 1.15; background: rgba(0,0,0,0.82); }"
32691
32698
  ].join("\n");
@@ -32694,7 +32701,11 @@ function injectAdBrandOverlay(indexHtml, overlayHtml) {
32694
32701
  if (!overlayHtml.trim()) return indexHtml;
32695
32702
  const withCss = indexHtml.replace(" </style>", `${adBrandOverlayCss()}
32696
32703
  </style>`);
32697
- return withCss.replace("<!--OVERLAYS-->", () => overlayHtml);
32704
+ if (withCss.includes("<!--OVERLAYS-->")) return withCss.replace("<!--OVERLAYS-->", () => overlayHtml);
32705
+ const rootClose = withCss.lastIndexOf("</div>");
32706
+ if (rootClose === -1) return withCss;
32707
+ return `${withCss.slice(0, rootClose)}${overlayHtml}
32708
+ ${withCss.slice(rootClose)}`;
32698
32709
  }
32699
32710
 
32700
32711
  // src/commands/canvas/composition-path.ts
@@ -32796,18 +32807,35 @@ var scaffoldAdCommand = defineCommand104({
32796
32807
  await writeSceneFiles(outDir, blueprint);
32797
32808
  await writeFile9(blueprintStylePath, renderStyleProjectionFromValue(blueprint), "utf8");
32798
32809
  const logoPath = spec.data.brand?.logo?.trim();
32810
+ const opts = {
32811
+ imageModel: AD_IMAGE_MODEL,
32812
+ videoModel: DEFAULT_VIDEO_GENERATE_MODEL,
32813
+ overlayCompositionPath: path23.relative(outDir, compositionDest),
32814
+ captionsCompositionPath: path23.relative(outDir, captionsDest),
32815
+ blueprintPath: path23.relative(outDir, blueprintPath),
32816
+ blueprintStylePath: path23.relative(outDir, blueprintStylePath),
32817
+ aspect: spec.data.format.aspect_ratio,
32818
+ resolution: spec.data.format.resolution,
32819
+ // A beat is one clause and one card, so the cap has to clear a whole clause.
32820
+ // The composition's default of 3 is TikTok karaoke styling; applied to an ad
32821
+ // it overrode the clause rule on every line and rendered "IS STANDARD. WE".
32822
+ // 8 is the composition's own maximum and clears every beat measured here.
32823
+ captionWordsPerGroup: 8
32824
+ };
32825
+ const canvas = scaffoldVideoCanvas(blueprint, adSpecCastElements(spec.data), opts);
32826
+ const renderNode3 = canvas.nodes.find((n) => n.type === "hyperframe_render");
32827
+ const renderedDir = renderNode3 ? path23.join(outDir, String(renderNode3.params?.composition ?? "")) : null;
32799
32828
  let staged = null;
32800
- if (logoPath) {
32829
+ if (logoPath && renderedDir) {
32801
32830
  const ext = path23.extname(logoPath) || ".png";
32802
- const dest = path23.join(compositionDest, `brand-mark${ext}`);
32803
32831
  try {
32804
- await copyFile(logoPath, dest);
32832
+ await copyFile(logoPath, path23.join(renderedDir, `brand-mark${ext}`));
32805
32833
  staged = { file: `brand-mark${ext}`, alt: spec.data.brand?.name ?? "brand" };
32806
32834
  } catch {
32807
32835
  }
32808
32836
  }
32809
32837
  const closing = blueprint.scenes[blueprint.scenes.length - 1];
32810
- const overlayHtml = endCardWanted(spec.data) && closing ? buildAdBrandOverlay({
32838
+ const overlayHtml = endCardWanted(spec.data) && closing && renderedDir ? buildAdBrandOverlay({
32811
32839
  logo: staged,
32812
32840
  cta: endCardCta(spec.data),
32813
32841
  cardAtS: closing.start_s,
@@ -32815,27 +32843,11 @@ var scaffoldAdCommand = defineCommand104({
32815
32843
  totalS: blueprint.estimated_duration_s,
32816
32844
  accent: firstHex(spec.data.brand?.palette)
32817
32845
  }) : "";
32818
- if (overlayHtml) {
32819
- const indexPath = path23.join(compositionDest, "index.html");
32846
+ if (overlayHtml && renderedDir) {
32847
+ const indexPath = path23.join(renderedDir, "index.html");
32820
32848
  const html = await readFile15(indexPath, "utf-8");
32821
32849
  await writeFile9(indexPath, injectAdBrandOverlay(html, overlayHtml), "utf-8");
32822
32850
  }
32823
- const opts = {
32824
- imageModel: AD_IMAGE_MODEL,
32825
- videoModel: DEFAULT_VIDEO_GENERATE_MODEL,
32826
- overlayCompositionPath: path23.relative(outDir, compositionDest),
32827
- captionsCompositionPath: path23.relative(outDir, captionsDest),
32828
- blueprintPath: path23.relative(outDir, blueprintPath),
32829
- blueprintStylePath: path23.relative(outDir, blueprintStylePath),
32830
- aspect: spec.data.format.aspect_ratio,
32831
- resolution: spec.data.format.resolution,
32832
- // A beat is one clause and one card, so the cap has to clear a whole clause.
32833
- // The composition's default of 3 is TikTok karaoke styling; applied to an ad
32834
- // it overrode the clause rule on every line and rendered "IS STANDARD. WE".
32835
- // 8 is the composition's own maximum and clears every beat measured here.
32836
- captionWordsPerGroup: 8
32837
- };
32838
- const canvas = scaffoldVideoCanvas(blueprint, adSpecCastElements(spec.data), opts);
32839
32851
  await writeFile9(outPath, `${JSON.stringify(canvas, null, 2)}
32840
32852
  `, "utf-8");
32841
32853
  writeJson({