storyforge 0.12.2 → 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`);
@@ -5972,7 +6010,7 @@ var renderRemotion = async (shot, ctx) => {
5972
6010
  } else {
5973
6011
  const remotion = requireRemotionRoot();
5974
6012
  entryArg = remotion.entry;
5975
- compId = ctx.aspect === "9:16" ? "ForgeVideoVertical" : "ForgeVideo";
6013
+ compId = ctx.aspect === "9:16" ? "KineticTextVertical" : "KineticText";
5976
6014
  remotionCwd = remotion.cwd;
5977
6015
  }
5978
6016
  const propsPath = path7.join(ctx.tmpDir, "remotion", `${shot.id}_props.json`);
@@ -5982,7 +6020,9 @@ var renderRemotion = async (shot, ctx) => {
5982
6020
  JSON.stringify(
5983
6021
  {
5984
6022
  durationInFrames: durationFrames,
5985
- overlayText: shot.overlayText ?? "",
6023
+ text: shot.overlayText ?? "",
6024
+ accentColor: "#58C4DD",
6025
+ bgColor: "#080A12",
5986
6026
  intent: shot.intent ?? ""
5987
6027
  },
5988
6028
  null,
@@ -6074,23 +6114,37 @@ var renderStockRemotion = async (shot, ctx) => {
6074
6114
  await searchAndDownloadPexels(query, shot.durationSec, stockPath, ctx.signal);
6075
6115
  if (ctx.signal?.aborted) throw new Error("aborted");
6076
6116
  ctx.progress.emit({ phase: "compositing", shotId: shot.id });
6077
- 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
+ ] : [];
6078
6137
  const propsPath = path8.join(ctx.tmpDir, "remotion", `${shot.id}_stock_props.json`);
6138
+ fs7.mkdirSync(path8.dirname(propsPath), { recursive: true });
6079
6139
  fs7.writeFileSync(
6080
6140
  propsPath,
6081
6141
  JSON.stringify(
6082
- {
6083
- stockSrc: stockPath,
6084
- durationInFrames: totalFrames,
6085
- overlayText: shot.overlayText ?? "",
6086
- intent: shot.intent ?? ""
6087
- },
6142
+ { videoSrc: stockPublicRel, overlays },
6088
6143
  null,
6089
6144
  2
6090
6145
  )
6091
6146
  );
6092
- const remotion = requireRemotionRoot();
6093
- const compId = ctx.aspect === "9:16" ? "ForgeVideoVertical" : "ForgeVideo";
6147
+ const compId = ctx.aspect === "9:16" ? "ManimOverlayVertical" : "ManimOverlay";
6094
6148
  const r = await runCmd(
6095
6149
  "npx",
6096
6150
  [
@@ -6198,7 +6252,7 @@ import * as fs9 from "fs";
6198
6252
  import * as path10 from "path";
6199
6253
  import { JSDOM } from "jsdom";
6200
6254
  import { Readability } from "@mozilla/readability";
6201
- var ASPECT_DIMS3 = {
6255
+ var ASPECT_DIMS4 = {
6202
6256
  "16:9": { width: 1920, height: 1080 },
6203
6257
  "9:16": { width: 1080, height: 1920 }
6204
6258
  };
@@ -6291,7 +6345,7 @@ var renderWebArticleRemotion = async (shot, ctx) => {
6291
6345
  `web-article+remotion: readability returned no title for ${shot.sourceUrl}`
6292
6346
  );
6293
6347
  }
6294
- const dims = ASPECT_DIMS3[ctx.aspect];
6348
+ const dims = ASPECT_DIMS4[ctx.aspect];
6295
6349
  const durationFrames = Math.max(1, Math.round(shot.durationSec * ctx.fps));
6296
6350
  const leadImageUrl = resolveLeadImage(article.leadImage, shot.sourceUrl);
6297
6351
  const propsPayload = {
@@ -6361,7 +6415,7 @@ var activeDeps = DEFAULT_DEPS;
6361
6415
  import * as fs10 from "fs";
6362
6416
  import * as path11 from "path";
6363
6417
  import { getTweet } from "react-tweet/api";
6364
- var ASPECT_DIMS4 = {
6418
+ var ASPECT_DIMS5 = {
6365
6419
  "16:9": { width: 1920, height: 1080 },
6366
6420
  "9:16": { width: 1080, height: 1920 }
6367
6421
  };
@@ -6417,7 +6471,7 @@ var renderXPostRemotion = async (shot, ctx) => {
6417
6471
  const tweet = await loadTweet(tweetId, cacheDir);
6418
6472
  if (ctx.signal?.aborted) throw new Error("aborted");
6419
6473
  const durationFrames = Math.max(1, Math.round(shot.durationSec * ctx.fps));
6420
- const dims = ASPECT_DIMS4[ctx.aspect];
6474
+ const dims = ASPECT_DIMS5[ctx.aspect];
6421
6475
  const remotion = requireRemotionRoot();
6422
6476
  const entry = path11.join(
6423
6477
  remotion.cwd,
@@ -6490,7 +6544,7 @@ var renderXPostRemotion = async (shot, ctx) => {
6490
6544
  import { createHash } from "crypto";
6491
6545
  import * as fs11 from "fs";
6492
6546
  import * as path12 from "path";
6493
- var ASPECT_DIMS5 = {
6547
+ var ASPECT_DIMS6 = {
6494
6548
  "16:9": { width: 1920, height: 1080 },
6495
6549
  "9:16": { width: 1080, height: 1920 }
6496
6550
  };
@@ -6772,7 +6826,7 @@ var renderYouTubeClipRemotion = async (shot, ctx) => {
6772
6826
  await cutSegment(fullPath, segmentPath, startSec, endSec, ctx.signal);
6773
6827
  await verifySegment(segmentPath, startSec, endSec, ctx.signal);
6774
6828
  if (ctx.signal?.aborted) throw new Error("aborted");
6775
- const dims = ASPECT_DIMS5[ctx.aspect];
6829
+ const dims = ASPECT_DIMS6[ctx.aspect];
6776
6830
  fs11.mkdirSync(path12.dirname(ctx.sceneOutPath), { recursive: true });
6777
6831
  await composeFinal({
6778
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-TZM5T7CN.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.12.2",
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.12.2",
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": {