storyforge 0.13.0 → 0.13.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.
@@ -5510,25 +5510,40 @@ var renderGeminiManimRemotion = async (shot, ctx) => {
5510
5510
  const totalFrames = Math.max(1, Math.round(shot.durationSec * ctx.fps));
5511
5511
  if (ctx.signal?.aborted) throw new Error("aborted");
5512
5512
  ctx.progress.emit({ phase: "compositing", shotId: shot.id });
5513
+ const remotion = requireRemotionRoot();
5514
+ const publicRel = path3.posix.join("clip-render-cache", ctx.chunkId, `${shot.id}-manim.mp4`);
5515
+ const publicAbs = path3.join(remotion.cwd, "public", publicRel);
5516
+ fs3.mkdirSync(path3.dirname(publicAbs), { recursive: true });
5517
+ fs3.copyFileSync(manimSceneOut, publicAbs);
5518
+ const overlayText = (shot.overlayText ?? "").trim();
5519
+ const dims = ctx.aspect === "9:16" ? { width: 1080, height: 1920 } : { width: 1920, height: 1080 };
5520
+ const overlays = overlayText ? [
5521
+ {
5522
+ text: overlayText,
5523
+ x: dims.width / 2,
5524
+ y: ctx.aspect === "9:16" ? 280 : 150,
5525
+ fontSize: ctx.aspect === "9:16" ? 88 : 72,
5526
+ color: "#FFFFFF",
5527
+ fontWeight: 800,
5528
+ startFrame: 6,
5529
+ fadeDuration: 8,
5530
+ textAlign: "center"
5531
+ }
5532
+ ] : [];
5513
5533
  const propsPath = path3.join(ctx.tmpDir, "remotion", `${shot.id}_gmr_props.json`);
5514
5534
  fs3.mkdirSync(path3.dirname(propsPath), { recursive: true });
5515
5535
  fs3.writeFileSync(
5516
5536
  propsPath,
5517
5537
  JSON.stringify(
5518
5538
  {
5519
- imagePath: localImage,
5520
- manimSrc: manimSceneOut,
5521
- manimDurationFrames,
5522
- durationInFrames: totalFrames,
5523
- overlayText: shot.overlayText ?? "",
5524
- intent: shot.intent ?? ""
5539
+ videoSrc: publicRel,
5540
+ overlays
5525
5541
  },
5526
5542
  null,
5527
5543
  2
5528
5544
  )
5529
5545
  );
5530
- const remotion = requireRemotionRoot();
5531
- const compId = ctx.aspect === "9:16" ? "ForgeVideoVertical" : "ForgeVideo";
5546
+ const compId = ctx.aspect === "9:16" ? "ManimOverlayVertical" : "ManimOverlay";
5532
5547
  const r = await runCmd(
5533
5548
  "npx",
5534
5549
  [
@@ -5835,6 +5850,28 @@ var renderHyperframes = async (shot, ctx) => {
5835
5850
  // ../pipeline/src/clip-render/engines/manim-remotion.ts
5836
5851
  import * as fs5 from "fs";
5837
5852
  import * as path6 from "path";
5853
+ var ASPECT_DIMS2 = {
5854
+ "16:9": { width: 1920, height: 1080 },
5855
+ "9:16": { width: 1080, height: 1920 }
5856
+ };
5857
+ function buildOverlays(overlayText, ctx) {
5858
+ const t = (overlayText ?? "").trim();
5859
+ if (!t) return [];
5860
+ const dims = ASPECT_DIMS2[ctx.aspect];
5861
+ return [
5862
+ {
5863
+ text: t,
5864
+ x: dims.width / 2,
5865
+ y: ctx.aspect === "9:16" ? 280 : 150,
5866
+ fontSize: ctx.aspect === "9:16" ? 88 : 72,
5867
+ color: "#FFFFFF",
5868
+ fontWeight: 800,
5869
+ startFrame: 6,
5870
+ fadeDuration: 8,
5871
+ textAlign: "center"
5872
+ }
5873
+ ];
5874
+ }
5838
5875
  var renderManimRemotion = async (shot, ctx) => {
5839
5876
  if (ctx.signal?.aborted) throw new Error("aborted");
5840
5877
  const manimSceneOut = path6.join(ctx.tmpDir, "manim", `${shot.id}_manim.mp4`);
@@ -5843,28 +5880,28 @@ var renderManimRemotion = async (shot, ctx) => {
5843
5880
  ctx.progress.emit({ phase: "rendering", shotId: shot.id });
5844
5881
  await renderManim(shot, manimCtx);
5845
5882
  const manimDurationSec = await probeDuration(manimSceneOut) ?? 7;
5846
- const manimDurationFrames = Math.max(1, Math.round(manimDurationSec * ctx.fps));
5847
5883
  const totalFrames = Math.max(1, Math.round(shot.durationSec * ctx.fps));
5848
5884
  if (ctx.signal?.aborted) throw new Error("aborted");
5849
5885
  ctx.progress.emit({ phase: "compositing", shotId: shot.id });
5886
+ const remotion = requireRemotionRoot();
5887
+ const publicRel = path6.posix.join("clip-render-cache", ctx.chunkId, `${shot.id}-manim.mp4`);
5888
+ const publicAbs = path6.join(remotion.cwd, "public", publicRel);
5889
+ fs5.mkdirSync(path6.dirname(publicAbs), { recursive: true });
5890
+ fs5.copyFileSync(manimSceneOut, publicAbs);
5850
5891
  const propsPath = path6.join(ctx.tmpDir, "remotion", `${shot.id}_mr_props.json`);
5851
5892
  fs5.mkdirSync(path6.dirname(propsPath), { recursive: true });
5852
5893
  fs5.writeFileSync(
5853
5894
  propsPath,
5854
5895
  JSON.stringify(
5855
5896
  {
5856
- manimSrc: manimSceneOut,
5857
- manimDurationFrames,
5858
- durationInFrames: totalFrames,
5859
- overlayText: shot.overlayText ?? "",
5860
- intent: shot.intent ?? ""
5897
+ videoSrc: publicRel,
5898
+ overlays: buildOverlays(shot.overlayText ?? "", ctx)
5861
5899
  },
5862
5900
  null,
5863
5901
  2
5864
5902
  )
5865
5903
  );
5866
- const remotion = requireRemotionRoot();
5867
- const compId = ctx.aspect === "9:16" ? "ForgeVideoVertical" : "ForgeVideo";
5904
+ const compId = ctx.aspect === "9:16" ? "ManimOverlayVertical" : "ManimOverlay";
5868
5905
  const r = await runCmd(
5869
5906
  "npx",
5870
5907
  [
@@ -5911,21 +5948,22 @@ var renderManimRemotion = async (shot, ctx) => {
5911
5948
  ctx.progress.emit({
5912
5949
  phase: "compositing",
5913
5950
  shotId: shot.id,
5914
- warnings: [`remotion overlay failed, used raw manim clamped to ${shot.durationSec}s: ${tail}`]
5951
+ warnings: [`ManimOverlay render failed, used raw manim clamped to ${shot.durationSec}s: ${tail}`]
5915
5952
  });
5916
5953
  return;
5917
5954
  }
5955
+ void manimDurationSec;
5918
5956
  };
5919
5957
 
5920
5958
  // ../pipeline/src/clip-render/engines/remotion.ts
5921
5959
  import * as fs6 from "fs";
5922
5960
  import * as path7 from "path";
5923
- var ASPECT_DIMS2 = {
5961
+ var ASPECT_DIMS3 = {
5924
5962
  "16:9": { width: 1920, height: 1080 },
5925
5963
  "9:16": { width: 1080, height: 1920 }
5926
5964
  };
5927
5965
  function writeEntryForInlineTsx(ctx, shotId, durationFrames) {
5928
- const dims = ASPECT_DIMS2[ctx.aspect];
5966
+ const dims = ASPECT_DIMS3[ctx.aspect];
5929
5967
  const dir = path7.join(ctx.tmpDir, "remotion", shotId);
5930
5968
  fs6.mkdirSync(dir, { recursive: true });
5931
5969
  const componentPath = path7.join(dir, `${shotId}.tsx`);
@@ -6076,23 +6114,37 @@ var renderStockRemotion = async (shot, ctx) => {
6076
6114
  await searchAndDownloadPexels(query, shot.durationSec, stockPath, ctx.signal);
6077
6115
  if (ctx.signal?.aborted) throw new Error("aborted");
6078
6116
  ctx.progress.emit({ phase: "compositing", shotId: shot.id });
6079
- const totalFrames = Math.max(1, Math.round(shot.durationSec * ctx.fps));
6117
+ const remotion = requireRemotionRoot();
6118
+ const stockPublicRel = path8.posix.join("clip-render-cache", ctx.chunkId, `${shot.id}-stock.mp4`);
6119
+ const stockPublicAbs = path8.join(remotion.cwd, "public", stockPublicRel);
6120
+ fs7.mkdirSync(path8.dirname(stockPublicAbs), { recursive: true });
6121
+ fs7.copyFileSync(stockPath, stockPublicAbs);
6122
+ const overlayText = (shot.overlayText ?? "").trim();
6123
+ const dims = ctx.aspect === "9:16" ? { width: 1080, height: 1920 } : { width: 1920, height: 1080 };
6124
+ const overlays = overlayText ? [
6125
+ {
6126
+ text: overlayText,
6127
+ x: dims.width / 2,
6128
+ y: ctx.aspect === "9:16" ? 280 : 150,
6129
+ fontSize: ctx.aspect === "9:16" ? 88 : 72,
6130
+ color: "#FFFFFF",
6131
+ fontWeight: 800,
6132
+ startFrame: 6,
6133
+ fadeDuration: 8,
6134
+ textAlign: "center"
6135
+ }
6136
+ ] : [];
6080
6137
  const propsPath = path8.join(ctx.tmpDir, "remotion", `${shot.id}_stock_props.json`);
6138
+ fs7.mkdirSync(path8.dirname(propsPath), { recursive: true });
6081
6139
  fs7.writeFileSync(
6082
6140
  propsPath,
6083
6141
  JSON.stringify(
6084
- {
6085
- stockSrc: stockPath,
6086
- durationInFrames: totalFrames,
6087
- overlayText: shot.overlayText ?? "",
6088
- intent: shot.intent ?? ""
6089
- },
6142
+ { videoSrc: stockPublicRel, overlays },
6090
6143
  null,
6091
6144
  2
6092
6145
  )
6093
6146
  );
6094
- const remotion = requireRemotionRoot();
6095
- const compId = ctx.aspect === "9:16" ? "ForgeVideoVertical" : "ForgeVideo";
6147
+ const compId = ctx.aspect === "9:16" ? "ManimOverlayVertical" : "ManimOverlay";
6096
6148
  const r = await runCmd(
6097
6149
  "npx",
6098
6150
  [
@@ -6200,7 +6252,7 @@ import * as fs9 from "fs";
6200
6252
  import * as path10 from "path";
6201
6253
  import { JSDOM } from "jsdom";
6202
6254
  import { Readability } from "@mozilla/readability";
6203
- var ASPECT_DIMS3 = {
6255
+ var ASPECT_DIMS4 = {
6204
6256
  "16:9": { width: 1920, height: 1080 },
6205
6257
  "9:16": { width: 1080, height: 1920 }
6206
6258
  };
@@ -6293,7 +6345,7 @@ var renderWebArticleRemotion = async (shot, ctx) => {
6293
6345
  `web-article+remotion: readability returned no title for ${shot.sourceUrl}`
6294
6346
  );
6295
6347
  }
6296
- const dims = ASPECT_DIMS3[ctx.aspect];
6348
+ const dims = ASPECT_DIMS4[ctx.aspect];
6297
6349
  const durationFrames = Math.max(1, Math.round(shot.durationSec * ctx.fps));
6298
6350
  const leadImageUrl = resolveLeadImage(article.leadImage, shot.sourceUrl);
6299
6351
  const propsPayload = {
@@ -6363,7 +6415,7 @@ var activeDeps = DEFAULT_DEPS;
6363
6415
  import * as fs10 from "fs";
6364
6416
  import * as path11 from "path";
6365
6417
  import { getTweet } from "react-tweet/api";
6366
- var ASPECT_DIMS4 = {
6418
+ var ASPECT_DIMS5 = {
6367
6419
  "16:9": { width: 1920, height: 1080 },
6368
6420
  "9:16": { width: 1080, height: 1920 }
6369
6421
  };
@@ -6419,7 +6471,7 @@ var renderXPostRemotion = async (shot, ctx) => {
6419
6471
  const tweet = await loadTweet(tweetId, cacheDir);
6420
6472
  if (ctx.signal?.aborted) throw new Error("aborted");
6421
6473
  const durationFrames = Math.max(1, Math.round(shot.durationSec * ctx.fps));
6422
- const dims = ASPECT_DIMS4[ctx.aspect];
6474
+ const dims = ASPECT_DIMS5[ctx.aspect];
6423
6475
  const remotion = requireRemotionRoot();
6424
6476
  const entry = path11.join(
6425
6477
  remotion.cwd,
@@ -6492,7 +6544,7 @@ var renderXPostRemotion = async (shot, ctx) => {
6492
6544
  import { createHash } from "crypto";
6493
6545
  import * as fs11 from "fs";
6494
6546
  import * as path12 from "path";
6495
- var ASPECT_DIMS5 = {
6547
+ var ASPECT_DIMS6 = {
6496
6548
  "16:9": { width: 1920, height: 1080 },
6497
6549
  "9:16": { width: 1080, height: 1920 }
6498
6550
  };
@@ -6774,7 +6826,7 @@ var renderYouTubeClipRemotion = async (shot, ctx) => {
6774
6826
  await cutSegment(fullPath, segmentPath, startSec, endSec, ctx.signal);
6775
6827
  await verifySegment(segmentPath, startSec, endSec, ctx.signal);
6776
6828
  if (ctx.signal?.aborted) throw new Error("aborted");
6777
- const dims = ASPECT_DIMS5[ctx.aspect];
6829
+ const dims = ASPECT_DIMS6[ctx.aspect];
6778
6830
  fs11.mkdirSync(path12.dirname(ctx.sceneOutPath), { recursive: true });
6779
6831
  await composeFinal({
6780
6832
  segmentPath,
package/dist/index.js CHANGED
@@ -1689,7 +1689,7 @@ Return ONLY the complete updated TSX. No markdown fences, no explanation.`;
1689
1689
  return "0.0.0";
1690
1690
  })();
1691
1691
  void (async () => {
1692
- const { BridgePoller } = await import("./bridge-poller-J7R4YRNI.js");
1692
+ const { BridgePoller } = await import("./bridge-poller-PLJGEDFJ.js");
1693
1693
  const poller = new BridgePoller({ baseUrl: bridgeUrl, token: bridgeToken2, clientVersion: `storyforge ${pkgVersion}` });
1694
1694
  poller.start();
1695
1695
  })();
@@ -2512,7 +2512,7 @@ function resolveBridgeToken2(explicit) {
2512
2512
  // package.json
2513
2513
  var package_default = {
2514
2514
  name: "storyforge",
2515
- version: "0.13.0",
2515
+ version: "0.13.1",
2516
2516
  description: "StoryForge \u2014 local bridge for the Forge video production web app. Parallel clip-render orchestrator (Remotion 4 + Manim + HyperFrames + ffmpeg) + final video stitcher + dependency doctor.",
2517
2517
  type: "module",
2518
2518
  bin: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storyforge",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "StoryForge — local bridge for the Forge video production web app. Parallel clip-render orchestrator (Remotion 4 + Manim + HyperFrames + ffmpeg) + final video stitcher + dependency doctor.",
5
5
  "type": "module",
6
6
  "bin": {