storyforge 0.15.0 → 0.17.0
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.
|
@@ -5648,7 +5648,22 @@ var renderGeminiRemotion = async (shot, ctx) => {
|
|
|
5648
5648
|
intent: shot.intent ?? "",
|
|
5649
5649
|
...shot.citationUrl ? { citationUrl: shot.citationUrl } : {},
|
|
5650
5650
|
...shot.quotedPhrase ? { quotedPhrase: shot.quotedPhrase } : {},
|
|
5651
|
-
...shot.textPosition ? { textPosition: shot.textPosition } : {}
|
|
5651
|
+
...shot.textPosition ? { textPosition: shot.textPosition } : {},
|
|
5652
|
+
...shot.textAnimation ? { textAnimation: shot.textAnimation } : {},
|
|
5653
|
+
...shot.textAccent ? { textAccent: shot.textAccent } : {},
|
|
5654
|
+
...shot.textAccentColor ? { textAccentColor: shot.textAccentColor } : {},
|
|
5655
|
+
...shot.textColor ? { textColor: shot.textColor } : {},
|
|
5656
|
+
// ── Tesla-grade primitive composition fields (v10+) ──
|
|
5657
|
+
// These were being silently dropped before this fix, so
|
|
5658
|
+
// ForgeShot's PrimitiveDispatch never fired.
|
|
5659
|
+
...shot.shotKind ? { shotKind: shot.shotKind } : {},
|
|
5660
|
+
...shot.heroText ? { heroText: shot.heroText } : {},
|
|
5661
|
+
...shot.chipLabel ? { chipLabel: shot.chipLabel } : {},
|
|
5662
|
+
...shot.statBadges ? { statBadges: shot.statBadges } : {},
|
|
5663
|
+
...shot.bars ? { bars: shot.bars } : {},
|
|
5664
|
+
...shot.comparisonImage ? { comparisonImage: shot.comparisonImage } : {},
|
|
5665
|
+
...shot.photoFilter ? { photoFilter: shot.photoFilter } : {},
|
|
5666
|
+
...typeof shot.vignette === "boolean" ? { vignette: shot.vignette } : {}
|
|
5652
5667
|
},
|
|
5653
5668
|
null,
|
|
5654
5669
|
2
|
|
@@ -5755,6 +5770,71 @@ function overlayFontSize(aspect) {
|
|
|
5755
5770
|
function escapeHtml(s) {
|
|
5756
5771
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
5757
5772
|
}
|
|
5773
|
+
function wrapLlmHyperframesHtml(rawHtml, opts) {
|
|
5774
|
+
const { width, height } = dimensionsForAspect(opts.aspect);
|
|
5775
|
+
const compositionId = `forge-shot-${opts.shotId}`;
|
|
5776
|
+
const lower = rawHtml.toLowerCase();
|
|
5777
|
+
const hasDoctype = lower.includes("<!doctype");
|
|
5778
|
+
const hasHtmlTag = /<html[\s>]/i.test(rawHtml);
|
|
5779
|
+
const hasBody = /<body[\s>]/i.test(rawHtml);
|
|
5780
|
+
const hasCompositionId = rawHtml.includes("data-composition-id");
|
|
5781
|
+
const hasTimelineRegistration = /window\.__timelines\s*\[/.test(rawHtml);
|
|
5782
|
+
const hasGsapTimeline = /gsap\.timeline\s*\(/.test(rawHtml);
|
|
5783
|
+
let patched = rawHtml;
|
|
5784
|
+
if (hasGsapTimeline && !hasTimelineRegistration) {
|
|
5785
|
+
patched = patched.replace(
|
|
5786
|
+
/(<script\b[^>]*>)([\s\S]*?gsap\.timeline\s*\([\s\S]*?)(<\/script>)/i,
|
|
5787
|
+
(_full, open, body, close) => {
|
|
5788
|
+
const inject = `
|
|
5789
|
+
window.__timelines = window.__timelines || {};
|
|
5790
|
+
window.__timelines[${JSON.stringify(compositionId)}] = tl;
|
|
5791
|
+
try { tl.pause(); } catch(e) {}
|
|
5792
|
+
`;
|
|
5793
|
+
return `${open}${body}${inject}${close}`;
|
|
5794
|
+
}
|
|
5795
|
+
);
|
|
5796
|
+
}
|
|
5797
|
+
if (!hasCompositionId) {
|
|
5798
|
+
if (hasBody) {
|
|
5799
|
+
patched = patched.replace(
|
|
5800
|
+
/<body([^>]*)>([\s\S]*?)<\/body>/i,
|
|
5801
|
+
(_full, attrs, inner) => `<body${attrs}><div id="root" data-composition-id="${compositionId}" data-start="0" data-width="${width}" data-height="${height}">${inner}</div></body>`
|
|
5802
|
+
);
|
|
5803
|
+
} else {
|
|
5804
|
+
const scripts = [];
|
|
5805
|
+
const styles = [];
|
|
5806
|
+
const visible = patched.replace(/<script[\s\S]*?<\/script>/gi, (m) => {
|
|
5807
|
+
scripts.push(m);
|
|
5808
|
+
return "";
|
|
5809
|
+
}).replace(/<style[\s\S]*?<\/style>/gi, (m) => {
|
|
5810
|
+
styles.push(m);
|
|
5811
|
+
return "";
|
|
5812
|
+
});
|
|
5813
|
+
patched = styles.join("") + `<div id="root" data-composition-id="${compositionId}" data-start="0" data-width="${width}" data-height="${height}">` + visible + `</div>` + scripts.join("");
|
|
5814
|
+
}
|
|
5815
|
+
}
|
|
5816
|
+
if (!hasDoctype || !hasHtmlTag || !hasBody) {
|
|
5817
|
+
patched = `<!doctype html>
|
|
5818
|
+
<html lang="en">
|
|
5819
|
+
<head>
|
|
5820
|
+
<meta charset="utf-8" />
|
|
5821
|
+
<title>${compositionId}</title>
|
|
5822
|
+
<style>
|
|
5823
|
+
html,body{margin:0;padding:0;width:${width}px;height:${height}px;overflow:hidden;background:#000;font-family:'Inter',system-ui,sans-serif;}
|
|
5824
|
+
</style>
|
|
5825
|
+
</head>
|
|
5826
|
+
<body>
|
|
5827
|
+
${patched}
|
|
5828
|
+
</body>
|
|
5829
|
+
</html>`;
|
|
5830
|
+
} else {
|
|
5831
|
+
patched = patched.replace(
|
|
5832
|
+
/<head([^>]*)>/i,
|
|
5833
|
+
(_m, attrs) => `<head${attrs}><style>html,body{margin:0;padding:0;width:${width}px;height:${height}px;overflow:hidden;background:#000;}</style>`
|
|
5834
|
+
);
|
|
5835
|
+
}
|
|
5836
|
+
return patched;
|
|
5837
|
+
}
|
|
5758
5838
|
|
|
5759
5839
|
// ../pipeline/src/clip-render/engines/hyperframes.ts
|
|
5760
5840
|
var HyperFramesNotInstalledError = class extends Error {
|
|
@@ -5814,7 +5894,11 @@ ${stderrTail}`));
|
|
|
5814
5894
|
}
|
|
5815
5895
|
function resolveShotHtml(shot, aspect) {
|
|
5816
5896
|
if (shot.hyperframesHtml && shot.hyperframesHtml.trim().length > 0) {
|
|
5817
|
-
return shot.hyperframesHtml
|
|
5897
|
+
return wrapLlmHyperframesHtml(shot.hyperframesHtml, {
|
|
5898
|
+
shotId: shot.id,
|
|
5899
|
+
durationSec: shot.durationSec,
|
|
5900
|
+
aspect
|
|
5901
|
+
});
|
|
5818
5902
|
}
|
|
5819
5903
|
if (shot.imagePath || shot.overlayText) {
|
|
5820
5904
|
return buildHyperframesHtml(shot, {
|
|
@@ -7197,6 +7281,11 @@ var renderHyperframesRunPod = async (shot, ctx) => {
|
|
|
7197
7281
|
}
|
|
7198
7282
|
ctx.progress.emit({ phase: "preparing", shotId: shot.id });
|
|
7199
7283
|
const dims = ctx.aspect === "9:16" ? { width: 1080, height: 1920 } : { width: 1920, height: 1080 };
|
|
7284
|
+
const wrappedHtml = wrapLlmHyperframesHtml(shot.hyperframesHtml, {
|
|
7285
|
+
shotId: shot.id,
|
|
7286
|
+
durationSec: shot.durationSec,
|
|
7287
|
+
aspect: ctx.aspect
|
|
7288
|
+
});
|
|
7200
7289
|
const status = await runJob(
|
|
7201
7290
|
endpointId,
|
|
7202
7291
|
{
|
|
@@ -7205,7 +7294,7 @@ var renderHyperframesRunPod = async (shot, ctx) => {
|
|
|
7205
7294
|
// so the payload must be nested under `input_data`.
|
|
7206
7295
|
input: {
|
|
7207
7296
|
input_data: {
|
|
7208
|
-
html:
|
|
7297
|
+
html: wrappedHtml,
|
|
7209
7298
|
durationSec: shot.durationSec,
|
|
7210
7299
|
fps: ctx.fps,
|
|
7211
7300
|
width: dims.width,
|
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-
|
|
1692
|
+
const { BridgePoller } = await import("./bridge-poller-TOYJEO7S.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.
|
|
2515
|
+
version: "0.17.0",
|
|
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.
|
|
3
|
+
"version": "0.17.0",
|
|
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": {
|