@vibeframe/cli 0.52.1 → 0.54.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.
- package/LICENSE +21 -0
- package/dist/agent/tools/index.d.ts +1 -0
- package/dist/agent/tools/index.d.ts.map +1 -1
- package/dist/agent/tools/index.js +3 -0
- package/dist/agent/tools/index.js.map +1 -1
- package/dist/agent/tools/scene.d.ts +17 -0
- package/dist/agent/tools/scene.d.ts.map +1 -0
- package/dist/agent/tools/scene.js +263 -0
- package/dist/agent/tools/scene.js.map +1 -0
- package/dist/agent/tools/scene.test.d.ts +2 -0
- package/dist/agent/tools/scene.test.d.ts.map +1 -0
- package/dist/agent/tools/scene.test.js +139 -0
- package/dist/agent/tools/scene.test.js.map +1 -0
- package/dist/commands/_shared/scene-html-emit.d.ts +120 -0
- package/dist/commands/_shared/scene-html-emit.d.ts.map +1 -0
- package/dist/commands/_shared/scene-html-emit.js +422 -0
- package/dist/commands/_shared/scene-html-emit.js.map +1 -0
- package/dist/commands/_shared/scene-html-emit.test.d.ts +2 -0
- package/dist/commands/_shared/scene-html-emit.test.d.ts.map +1 -0
- package/dist/commands/_shared/scene-html-emit.test.js +396 -0
- package/dist/commands/_shared/scene-html-emit.test.js.map +1 -0
- package/dist/commands/_shared/scene-lint.d.ts +110 -0
- package/dist/commands/_shared/scene-lint.d.ts.map +1 -0
- package/dist/commands/_shared/scene-lint.js +207 -0
- package/dist/commands/_shared/scene-lint.js.map +1 -0
- package/dist/commands/_shared/scene-lint.test.d.ts +2 -0
- package/dist/commands/_shared/scene-lint.test.d.ts.map +1 -0
- package/dist/commands/_shared/scene-lint.test.js +208 -0
- package/dist/commands/_shared/scene-lint.test.js.map +1 -0
- package/dist/commands/_shared/scene-project.d.ts +101 -0
- package/dist/commands/_shared/scene-project.d.ts.map +1 -0
- package/dist/commands/_shared/scene-project.js +281 -0
- package/dist/commands/_shared/scene-project.js.map +1 -0
- package/dist/commands/_shared/scene-project.test.d.ts +2 -0
- package/dist/commands/_shared/scene-project.test.d.ts.map +1 -0
- package/dist/commands/_shared/scene-project.test.js +203 -0
- package/dist/commands/_shared/scene-project.test.js.map +1 -0
- package/dist/commands/_shared/scene-render.d.ts +79 -0
- package/dist/commands/_shared/scene-render.d.ts.map +1 -0
- package/dist/commands/_shared/scene-render.js +138 -0
- package/dist/commands/_shared/scene-render.js.map +1 -0
- package/dist/commands/_shared/scene-render.test.d.ts +2 -0
- package/dist/commands/_shared/scene-render.test.d.ts.map +1 -0
- package/dist/commands/_shared/scene-render.test.js +145 -0
- package/dist/commands/_shared/scene-render.test.js.map +1 -0
- package/dist/commands/_shared/segments-to-scenes.d.ts +85 -0
- package/dist/commands/_shared/segments-to-scenes.d.ts.map +1 -0
- package/dist/commands/_shared/segments-to-scenes.js +202 -0
- package/dist/commands/_shared/segments-to-scenes.js.map +1 -0
- package/dist/commands/_shared/segments-to-scenes.test.d.ts +2 -0
- package/dist/commands/_shared/segments-to-scenes.test.d.ts.map +1 -0
- package/dist/commands/_shared/segments-to-scenes.test.js +219 -0
- package/dist/commands/_shared/segments-to-scenes.test.js.map +1 -0
- package/dist/commands/_shared/tts-resolve.d.ts +75 -0
- package/dist/commands/_shared/tts-resolve.d.ts.map +1 -0
- package/dist/commands/_shared/tts-resolve.js +89 -0
- package/dist/commands/_shared/tts-resolve.js.map +1 -0
- package/dist/commands/_shared/tts-resolve.test.d.ts +6 -0
- package/dist/commands/_shared/tts-resolve.test.d.ts.map +1 -0
- package/dist/commands/_shared/tts-resolve.test.js +147 -0
- package/dist/commands/_shared/tts-resolve.test.js.map +1 -0
- package/dist/commands/ai-script-pipeline-cli.d.ts.map +1 -1
- package/dist/commands/ai-script-pipeline-cli.js +49 -0
- package/dist/commands/ai-script-pipeline-cli.js.map +1 -1
- package/dist/commands/ai-script-pipeline.d.ts +16 -0
- package/dist/commands/ai-script-pipeline.d.ts.map +1 -1
- package/dist/commands/ai-script-pipeline.js +28 -0
- package/dist/commands/ai-script-pipeline.js.map +1 -1
- package/dist/commands/ai.test.js +4 -1
- package/dist/commands/ai.test.js.map +1 -1
- package/dist/commands/scene.d.ts +86 -0
- package/dist/commands/scene.d.ts.map +1 -0
- package/dist/commands/scene.js +719 -0
- package/dist/commands/scene.js.map +1 -0
- package/dist/commands/scene.test.d.ts +2 -0
- package/dist/commands/scene.test.d.ts.map +1 -0
- package/dist/commands/scene.test.js +219 -0
- package/dist/commands/scene.test.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/pipeline/renderers/chrome.d.ts +26 -0
- package/dist/pipeline/renderers/chrome.d.ts.map +1 -0
- package/dist/pipeline/renderers/chrome.js +48 -0
- package/dist/pipeline/renderers/chrome.js.map +1 -0
- package/dist/pipeline/renderers/hyperframes.d.ts.map +1 -1
- package/dist/pipeline/renderers/hyperframes.js +2 -32
- package/dist/pipeline/renderers/hyperframes.js.map +1 -1
- package/dist/utils/provider-resolver.d.ts.map +1 -1
- package/dist/utils/provider-resolver.js +6 -2
- package/dist/utils/provider-resolver.js.map +1 -1
- package/package.json +32 -13
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module _shared/scene-html-emit
|
|
3
|
+
*
|
|
4
|
+
* Pure HTML emitters for `vibe scene add`. Each preset produces a self-contained
|
|
5
|
+
* Hyperframes-compatible scene composition: a `<template>`-wrapped `<div
|
|
6
|
+
* data-composition-id>` with scoped CSS, optional audio/image, and a paused
|
|
7
|
+
* GSAP timeline registered on `window.__timelines`.
|
|
8
|
+
*
|
|
9
|
+
* Also exposes helpers that mutate the root index.html:
|
|
10
|
+
* - `nextSceneStart()` — sum existing clip end-times to choose the new start
|
|
11
|
+
* - `insertClipIntoRoot()` — splice a `<div class="clip">` reference before the
|
|
12
|
+
* root's closing div, preserving the user's hand-edited markup
|
|
13
|
+
* - `slugifySceneName()` — name → kebab-case scene id
|
|
14
|
+
*
|
|
15
|
+
* Pure functions only — no I/O. The orchestrating command (`scene add`) wires
|
|
16
|
+
* these to the filesystem.
|
|
17
|
+
*/
|
|
18
|
+
export type ScenePreset = "simple" | "announcement" | "explainer" | "kinetic-type" | "product-shot";
|
|
19
|
+
export declare const SCENE_PRESETS: readonly ScenePreset[];
|
|
20
|
+
/**
|
|
21
|
+
* One word from a Whisper word-level transcript. Mirrors
|
|
22
|
+
* {@link import("@vibeframe/ai-providers").TranscriptWord} but is duplicated
|
|
23
|
+
* here so this module stays pure (no provider package import).
|
|
24
|
+
*/
|
|
25
|
+
export interface SceneTranscriptWord {
|
|
26
|
+
text: string;
|
|
27
|
+
start: number;
|
|
28
|
+
end: number;
|
|
29
|
+
}
|
|
30
|
+
export interface EmitSceneInput {
|
|
31
|
+
/** Kebab-case scene id; appears in `data-composition-id` and template id. */
|
|
32
|
+
id: string;
|
|
33
|
+
preset: ScenePreset;
|
|
34
|
+
/** Canvas width in px (must match the root composition). */
|
|
35
|
+
width: number;
|
|
36
|
+
/** Canvas height in px (must match the root composition). */
|
|
37
|
+
height: number;
|
|
38
|
+
/** Visible composition duration in seconds. */
|
|
39
|
+
duration: number;
|
|
40
|
+
/** Headline text — required for non-simple presets; defaulted from id. */
|
|
41
|
+
headline?: string;
|
|
42
|
+
/** Secondary text (subhead/caption). Often the narration. */
|
|
43
|
+
subhead?: string;
|
|
44
|
+
/** Optional small label above the headline (explainer / product-shot). */
|
|
45
|
+
kicker?: string;
|
|
46
|
+
/** Project-relative image path (e.g. "assets/scene-intro.png"). */
|
|
47
|
+
imagePath?: string;
|
|
48
|
+
/** Project-relative narration audio path (e.g. "assets/narration-intro.mp3"). */
|
|
49
|
+
audioPath?: string;
|
|
50
|
+
/**
|
|
51
|
+
* Word-level timings (Whisper output) for narration sync. When supplied, the
|
|
52
|
+
* `simple`, `explainer`, and `kinetic-type` presets render each word as its
|
|
53
|
+
* own `<span class="word">` and animate them at their absolute audio start
|
|
54
|
+
* times via GSAP. `announcement` and `product-shot` ignore this field —
|
|
55
|
+
* their headlines are intentionally static.
|
|
56
|
+
*/
|
|
57
|
+
transcript?: SceneTranscriptWord[];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Slugify a free-form scene name to a kebab-case id usable in HTML attributes
|
|
61
|
+
* and filenames. Strips diacritics, collapses whitespace, lowercases.
|
|
62
|
+
*/
|
|
63
|
+
export declare function slugifySceneName(name: string): string;
|
|
64
|
+
/**
|
|
65
|
+
* Render a transcript as `<span class="word" data-i="N">…</span>` markup,
|
|
66
|
+
* separated by literal whitespace so kerning and wrapping behave naturally.
|
|
67
|
+
* Returns the empty string when there's nothing to render.
|
|
68
|
+
*/
|
|
69
|
+
export declare function renderTranscriptSpans(transcript: SceneTranscriptWord[]): string;
|
|
70
|
+
/**
|
|
71
|
+
* Build absolute-timing GSAP tweens that fade each transcript word in at its
|
|
72
|
+
* narration `start` time. The `targetSelector` parametrises the scope so the
|
|
73
|
+
* same routine can drive `simple` (`.caption .word`), `explainer`
|
|
74
|
+
* (`#subtitle .word`), or `kinetic-type` (`.kinetic .word`).
|
|
75
|
+
*
|
|
76
|
+
* Each tween is `tl.fromTo(sel, {opacity:0,y:10}, {opacity:1,y:0,duration:0.18}, start)`
|
|
77
|
+
* — short enough to feel responsive at any speech rate, long enough to avoid
|
|
78
|
+
* popping at 30fps. Words clamp to non-negative starts.
|
|
79
|
+
*/
|
|
80
|
+
export declare function buildTranscriptTweens(transcript: SceneTranscriptWord[], targetSelector: string): string;
|
|
81
|
+
/**
|
|
82
|
+
* Emit the full per-scene HTML. Returns a complete `<template>`-wrapped
|
|
83
|
+
* composition ready to write to `compositions/scene-<id>.html`.
|
|
84
|
+
*/
|
|
85
|
+
export declare function emitSceneHtml(input: EmitSceneInput): string;
|
|
86
|
+
/**
|
|
87
|
+
* Sum existing `<div class="clip">` end-times to find where the next scene
|
|
88
|
+
* should start. Returns 0 for an empty root.
|
|
89
|
+
*/
|
|
90
|
+
export declare function nextSceneStart(rootHtml: string): number;
|
|
91
|
+
export interface ClipReferenceInput {
|
|
92
|
+
/** Scene id — used to derive the composition src path. */
|
|
93
|
+
id: string;
|
|
94
|
+
start: number;
|
|
95
|
+
duration: number;
|
|
96
|
+
trackIndex?: number;
|
|
97
|
+
/** Override the default `compositions/scene-<id>.html` src. */
|
|
98
|
+
src?: string;
|
|
99
|
+
}
|
|
100
|
+
/** Build the `<div class="clip" data-composition-id=... data-composition-src=...>` reference string. */
|
|
101
|
+
export declare function buildClipReference(opts: ClipReferenceInput): string;
|
|
102
|
+
/**
|
|
103
|
+
* Insert a clip reference inside the root composition's `#root` div, just
|
|
104
|
+
* before its closing `</div>`. Throws if the expected closing tag isn't
|
|
105
|
+
* found — callers should surface this as a structured error so users know
|
|
106
|
+
* to inspect a hand-edited root.
|
|
107
|
+
*
|
|
108
|
+
* Also grows the root's `data-duration` to fit the new clip's end-time.
|
|
109
|
+
*/
|
|
110
|
+
export declare function insertClipIntoRoot(rootHtml: string, clip: ClipReferenceInput): string;
|
|
111
|
+
/**
|
|
112
|
+
* Read the root composition's canvas dims by parsing `data-width`/`data-height`
|
|
113
|
+
* on the `#root` div. Returns null if either is missing — caller should fall
|
|
114
|
+
* back to the project's aspect config.
|
|
115
|
+
*/
|
|
116
|
+
export declare function readRootDims(rootHtml: string): {
|
|
117
|
+
width: number;
|
|
118
|
+
height: number;
|
|
119
|
+
} | null;
|
|
120
|
+
//# sourceMappingURL=scene-html-emit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene-html-emit.d.ts","sourceRoot":"","sources":["../../../src/commands/_shared/scene-html-emit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,cAAc,GACd,WAAW,GACX,cAAc,GACd,cAAc,CAAC;AAEnB,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAMtC,CAAC;AAEX;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,cAAc;IAC7B,6EAA6E;IAC7E,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,WAAW,CAAC;IACpB,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACpC;AA4BD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CASrD;AAMD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,mBAAmB,EAAE,GAAG,MAAM,CAI/E;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,mBAAmB,EAAE,EACjC,cAAc,EAAE,MAAM,GACrB,MAAM,CAQR;AAwPD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CA2C3D;AAMD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CASvD;AAED,MAAM,WAAW,kBAAkB;IACjC,0DAA0D;IAC1D,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wGAAwG;AACxG,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAMnE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB,GAAG,MAAM,CAiCrF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAKvF"}
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
export const SCENE_PRESETS = [
|
|
2
|
+
"simple",
|
|
3
|
+
"announcement",
|
|
4
|
+
"explainer",
|
|
5
|
+
"kinetic-type",
|
|
6
|
+
"product-shot",
|
|
7
|
+
];
|
|
8
|
+
const GSAP_CDN = "https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js";
|
|
9
|
+
/** Minimal HTML escaper for text we inline into elements/attributes. */
|
|
10
|
+
function esc(text) {
|
|
11
|
+
return text
|
|
12
|
+
.replace(/&/g, "&")
|
|
13
|
+
.replace(/</g, "<")
|
|
14
|
+
.replace(/>/g, ">")
|
|
15
|
+
.replace(/"/g, """)
|
|
16
|
+
.replace(/'/g, "'");
|
|
17
|
+
}
|
|
18
|
+
/** Normalise whitespace and trim — used on user-supplied headlines/subheads. */
|
|
19
|
+
function clean(text) {
|
|
20
|
+
return (text ?? "").replace(/\s+/g, " ").trim();
|
|
21
|
+
}
|
|
22
|
+
/** Humanise a scene id — "product-shot" → "Product Shot". */
|
|
23
|
+
function humanise(id) {
|
|
24
|
+
return id
|
|
25
|
+
.split(/[-_]+/)
|
|
26
|
+
.filter(Boolean)
|
|
27
|
+
.map((w) => w.charAt(0).toUpperCase() + w.slice(1))
|
|
28
|
+
.join(" ");
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Slugify a free-form scene name to a kebab-case id usable in HTML attributes
|
|
32
|
+
* and filenames. Strips diacritics, collapses whitespace, lowercases.
|
|
33
|
+
*/
|
|
34
|
+
export function slugifySceneName(name) {
|
|
35
|
+
const normalised = name
|
|
36
|
+
.normalize("NFKD")
|
|
37
|
+
.replace(/[̀-ͯ]/g, "");
|
|
38
|
+
const slug = normalised
|
|
39
|
+
.toLowerCase()
|
|
40
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
41
|
+
.replace(/^-+|-+$/g, "");
|
|
42
|
+
return slug || "scene";
|
|
43
|
+
}
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Word-sync helpers
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
/**
|
|
48
|
+
* Render a transcript as `<span class="word" data-i="N">…</span>` markup,
|
|
49
|
+
* separated by literal whitespace so kerning and wrapping behave naturally.
|
|
50
|
+
* Returns the empty string when there's nothing to render.
|
|
51
|
+
*/
|
|
52
|
+
export function renderTranscriptSpans(transcript) {
|
|
53
|
+
return transcript
|
|
54
|
+
.map((w, i) => `<span class="word" data-i="${i}">${esc(w.text)}</span>`)
|
|
55
|
+
.join(" ");
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Build absolute-timing GSAP tweens that fade each transcript word in at its
|
|
59
|
+
* narration `start` time. The `targetSelector` parametrises the scope so the
|
|
60
|
+
* same routine can drive `simple` (`.caption .word`), `explainer`
|
|
61
|
+
* (`#subtitle .word`), or `kinetic-type` (`.kinetic .word`).
|
|
62
|
+
*
|
|
63
|
+
* Each tween is `tl.fromTo(sel, {opacity:0,y:10}, {opacity:1,y:0,duration:0.18}, start)`
|
|
64
|
+
* — short enough to feel responsive at any speech rate, long enough to avoid
|
|
65
|
+
* popping at 30fps. Words clamp to non-negative starts.
|
|
66
|
+
*/
|
|
67
|
+
export function buildTranscriptTweens(transcript, targetSelector) {
|
|
68
|
+
return transcript
|
|
69
|
+
.map((w, i) => {
|
|
70
|
+
const start = Math.max(0, Number(w.start.toFixed(3)));
|
|
71
|
+
const sel = `${targetSelector}[data-i="${i}"]`;
|
|
72
|
+
return `tl.fromTo('${sel}', { opacity: 0, y: 10 }, { opacity: 1, y: 0, duration: 0.18, ease: 'power2.out' }, ${start});`;
|
|
73
|
+
})
|
|
74
|
+
.join("\n ");
|
|
75
|
+
}
|
|
76
|
+
function buildPreset(input) {
|
|
77
|
+
const id = input.id;
|
|
78
|
+
const scope = `[data-composition-id="${id}"]`;
|
|
79
|
+
const headline = clean(input.headline) || humanise(id);
|
|
80
|
+
const subhead = clean(input.subhead);
|
|
81
|
+
const kicker = clean(input.kicker);
|
|
82
|
+
const dur = input.duration;
|
|
83
|
+
const hasImage = !!input.imagePath;
|
|
84
|
+
const backdrop = hasImage
|
|
85
|
+
? `${scope} .backdrop {
|
|
86
|
+
position: absolute;
|
|
87
|
+
inset: 0;
|
|
88
|
+
width: 100%;
|
|
89
|
+
height: 100%;
|
|
90
|
+
background-image: url("${esc(input.imagePath)}");
|
|
91
|
+
background-size: cover;
|
|
92
|
+
background-position: center;
|
|
93
|
+
}
|
|
94
|
+
${scope} .backdrop::after {
|
|
95
|
+
content: "";
|
|
96
|
+
position: absolute;
|
|
97
|
+
inset: 0;
|
|
98
|
+
background: linear-gradient(180deg, rgba(0,0,0,0.0) 30%, rgba(0,0,0,0.55) 100%);
|
|
99
|
+
}`
|
|
100
|
+
: `${scope} .backdrop {
|
|
101
|
+
position: absolute;
|
|
102
|
+
inset: 0;
|
|
103
|
+
background: radial-gradient(ellipse at center, #1a1a2e 0%, #000 70%);
|
|
104
|
+
}`;
|
|
105
|
+
const backdropMarkup = `<div class="backdrop"></div>`;
|
|
106
|
+
switch (input.preset) {
|
|
107
|
+
case "simple": {
|
|
108
|
+
const transcript = input.transcript;
|
|
109
|
+
const useWordSync = !!(transcript && transcript.length > 0);
|
|
110
|
+
const captionText = subhead || headline;
|
|
111
|
+
const captionInner = useWordSync
|
|
112
|
+
? renderTranscriptSpans(transcript)
|
|
113
|
+
: esc(captionText);
|
|
114
|
+
const wordCss = useWordSync
|
|
115
|
+
? `\n ${scope} .caption .word { display: inline-block; opacity: 0; }`
|
|
116
|
+
: "";
|
|
117
|
+
const timeline = useWordSync
|
|
118
|
+
? `${buildTranscriptTweens(transcript, `${scope} .caption .word`)}
|
|
119
|
+
tl.to('${scope} .caption', { opacity: 0, duration: 0.4, ease: 'power2.in' }, ${(dur - 0.4).toFixed(2)});`
|
|
120
|
+
: `tl.from('${scope} .caption', { opacity: 0, y: 28, duration: 0.6, ease: 'power2.out' }, 0.1);
|
|
121
|
+
tl.to('${scope} .caption', { opacity: 0, duration: 0.4, ease: 'power2.in' }, ${(dur - 0.4).toFixed(2)});`;
|
|
122
|
+
return {
|
|
123
|
+
css: `${scope} {
|
|
124
|
+
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
125
|
+
font-family: -apple-system, "Helvetica Neue", Arial, sans-serif;
|
|
126
|
+
color: #fff; overflow: hidden; background: #000;
|
|
127
|
+
}
|
|
128
|
+
${backdrop}
|
|
129
|
+
${scope} .caption {
|
|
130
|
+
position: absolute;
|
|
131
|
+
left: 8%; right: 8%; bottom: 12%;
|
|
132
|
+
text-align: center;
|
|
133
|
+
font-size: 56px;
|
|
134
|
+
font-weight: 700;
|
|
135
|
+
line-height: 1.2;
|
|
136
|
+
text-shadow: 0 4px 20px rgba(0,0,0,0.65);
|
|
137
|
+
}${wordCss}`,
|
|
138
|
+
body: `${backdropMarkup}
|
|
139
|
+
<div class="caption" id="caption">${captionInner}</div>`,
|
|
140
|
+
timeline,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
case "announcement": {
|
|
144
|
+
return {
|
|
145
|
+
css: `${scope} {
|
|
146
|
+
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
147
|
+
font-family: -apple-system, "Helvetica Neue", Arial, sans-serif;
|
|
148
|
+
color: #fff; overflow: hidden; background: #000;
|
|
149
|
+
}
|
|
150
|
+
${backdrop}
|
|
151
|
+
${scope} .announce {
|
|
152
|
+
position: absolute; inset: 0;
|
|
153
|
+
display: flex; align-items: center; justify-content: center;
|
|
154
|
+
text-align: center;
|
|
155
|
+
padding: 0 8%;
|
|
156
|
+
}
|
|
157
|
+
${scope} .announce h1 {
|
|
158
|
+
margin: 0;
|
|
159
|
+
font-size: 160px;
|
|
160
|
+
font-weight: 900;
|
|
161
|
+
letter-spacing: -4px;
|
|
162
|
+
line-height: 1;
|
|
163
|
+
background: linear-gradient(90deg, #8e2de2, #00c9ff);
|
|
164
|
+
-webkit-background-clip: text; background-clip: text; color: transparent;
|
|
165
|
+
text-shadow: 0 8px 40px rgba(142,45,226,0.35);
|
|
166
|
+
}`,
|
|
167
|
+
body: `${backdropMarkup}
|
|
168
|
+
<div class="announce"><h1 id="headline">${esc(headline)}</h1></div>`,
|
|
169
|
+
timeline: `tl.from('${scope} #headline', { opacity: 0, scale: 0.8, duration: 0.9, ease: 'back.out(1.6)' }, 0.15);
|
|
170
|
+
tl.to('${scope} #headline', { opacity: 0, duration: 0.4, ease: 'power2.in' }, ${(dur - 0.4).toFixed(2)});`,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
case "explainer": {
|
|
174
|
+
const k = kicker || humanise(id).toUpperCase();
|
|
175
|
+
const sub = subhead || "";
|
|
176
|
+
const transcript = input.transcript;
|
|
177
|
+
const useWordSync = !!(transcript && transcript.length > 0 && sub);
|
|
178
|
+
const subtitleInner = useWordSync ? renderTranscriptSpans(transcript) : esc(sub);
|
|
179
|
+
const wordCss = useWordSync
|
|
180
|
+
? `\n ${scope} #subtitle .word { display: inline-block; opacity: 0; }`
|
|
181
|
+
: "";
|
|
182
|
+
const subtitleTween = useWordSync
|
|
183
|
+
? buildTranscriptTweens(transcript, `${scope} #subtitle .word`)
|
|
184
|
+
: sub
|
|
185
|
+
? `tl.from('${scope} #subtitle', { opacity: 0, y: 30, duration: 0.55, ease: 'power3.out' }, 0.55);`
|
|
186
|
+
: "";
|
|
187
|
+
return {
|
|
188
|
+
css: `${scope} {
|
|
189
|
+
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
190
|
+
font-family: -apple-system, "Helvetica Neue", Arial, sans-serif;
|
|
191
|
+
color: #fff; overflow: hidden; background: #000;
|
|
192
|
+
}
|
|
193
|
+
${backdrop}
|
|
194
|
+
${scope} .stage {
|
|
195
|
+
position: absolute; inset: 0;
|
|
196
|
+
display: flex; flex-direction: column; justify-content: center;
|
|
197
|
+
gap: 24px; padding: 0 10%;
|
|
198
|
+
}
|
|
199
|
+
${scope} .kicker {
|
|
200
|
+
font-size: 28px; letter-spacing: 6px; text-transform: uppercase;
|
|
201
|
+
color: #00c9ff; font-weight: 600;
|
|
202
|
+
}
|
|
203
|
+
${scope} .title {
|
|
204
|
+
font-size: 110px; font-weight: 800; letter-spacing: -2px;
|
|
205
|
+
line-height: 1.05; margin: 0;
|
|
206
|
+
}
|
|
207
|
+
${scope} .subtitle {
|
|
208
|
+
font-size: 38px; font-weight: 300; color: #c0c0d0; max-width: 80%;
|
|
209
|
+
}${wordCss}`,
|
|
210
|
+
body: `${backdropMarkup}
|
|
211
|
+
<div class="stage">
|
|
212
|
+
<div class="kicker" id="kicker">${esc(k)}</div>
|
|
213
|
+
<h1 class="title" id="title">${esc(headline)}</h1>${sub ? `
|
|
214
|
+
<div class="subtitle" id="subtitle">${subtitleInner}</div>` : ""}
|
|
215
|
+
</div>`,
|
|
216
|
+
timeline: `tl.from('${scope} #kicker', { opacity: 0, y: 16, duration: 0.4, ease: 'power2.out' }, 0.1);
|
|
217
|
+
tl.from('${scope} #title', { opacity: 0, y: 60, duration: 0.7, ease: 'power3.out' }, 0.25);
|
|
218
|
+
${subtitleTween}`,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
case "kinetic-type": {
|
|
222
|
+
const transcript = input.transcript;
|
|
223
|
+
const useWordSync = !!(transcript && transcript.length > 0);
|
|
224
|
+
// When transcript is supplied, drive word entries from it (narration is
|
|
225
|
+
// the ground truth — what's spoken is what's shown). Otherwise fall back
|
|
226
|
+
// to splitting the headline.
|
|
227
|
+
const words = useWordSync
|
|
228
|
+
? transcript.map((w) => w.text)
|
|
229
|
+
: headline.split(/\s+/).filter(Boolean);
|
|
230
|
+
const wordSpans = words
|
|
231
|
+
.map((w, i) => `<span class="word" data-i="${i}" id="w-${i}">${esc(w)}</span>`)
|
|
232
|
+
.join(" ");
|
|
233
|
+
const stagger = Math.max(0.08, Math.min(0.3, (dur - 0.6) / Math.max(words.length, 1)));
|
|
234
|
+
const tweens = useWordSync
|
|
235
|
+
? transcript
|
|
236
|
+
.map((w, i) => {
|
|
237
|
+
const start = Math.max(0, Number(w.start.toFixed(3)));
|
|
238
|
+
return `tl.from('${scope} #w-${i}', { opacity: 0, y: 80, scale: 0.8, duration: 0.35, ease: 'back.out(1.8)' }, ${start});`;
|
|
239
|
+
})
|
|
240
|
+
.join("\n ")
|
|
241
|
+
: words
|
|
242
|
+
.map((_, i) => {
|
|
243
|
+
const start = (0.05 + i * stagger).toFixed(2);
|
|
244
|
+
return `tl.from('${scope} #w-${i}', { opacity: 0, y: 80, scale: 0.8, duration: 0.45, ease: 'back.out(1.8)' }, ${start});`;
|
|
245
|
+
})
|
|
246
|
+
.join("\n ");
|
|
247
|
+
return {
|
|
248
|
+
css: `${scope} {
|
|
249
|
+
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
250
|
+
font-family: "Helvetica Neue", Arial, sans-serif;
|
|
251
|
+
color: #fff; overflow: hidden; background: #000;
|
|
252
|
+
}
|
|
253
|
+
${backdrop}
|
|
254
|
+
${scope} .kinetic {
|
|
255
|
+
position: absolute; inset: 0;
|
|
256
|
+
display: flex; align-items: center; justify-content: center;
|
|
257
|
+
text-align: center; padding: 0 6%;
|
|
258
|
+
font-size: 180px; font-weight: 900; letter-spacing: -6px;
|
|
259
|
+
line-height: 1; text-shadow: 0 6px 30px rgba(0,0,0,0.6);
|
|
260
|
+
}
|
|
261
|
+
${scope} .kinetic .word { display: inline-block; margin: 0 12px; }`,
|
|
262
|
+
body: `${backdropMarkup}
|
|
263
|
+
<div class="kinetic">${wordSpans}</div>`,
|
|
264
|
+
timeline: tweens,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
case "product-shot": {
|
|
268
|
+
const label = kicker || humanise(id);
|
|
269
|
+
return {
|
|
270
|
+
css: `${scope} {
|
|
271
|
+
position: absolute; inset: 0; width: 100%; height: 100%;
|
|
272
|
+
font-family: -apple-system, "Helvetica Neue", Arial, sans-serif;
|
|
273
|
+
color: #fff; overflow: hidden; background: #000;
|
|
274
|
+
}
|
|
275
|
+
${backdrop}
|
|
276
|
+
${scope} .backdrop { transform-origin: center; }
|
|
277
|
+
${scope} .label {
|
|
278
|
+
position: absolute; top: 8%; left: 8%;
|
|
279
|
+
padding: 12px 24px; border-radius: 999px;
|
|
280
|
+
background: rgba(0,0,0,0.55); backdrop-filter: blur(6px);
|
|
281
|
+
font-size: 24px; font-weight: 600; letter-spacing: 2px;
|
|
282
|
+
text-transform: uppercase;
|
|
283
|
+
}
|
|
284
|
+
${scope} .product-headline {
|
|
285
|
+
position: absolute; left: 8%; right: 8%; bottom: 14%;
|
|
286
|
+
font-size: 72px; font-weight: 800; letter-spacing: -1px;
|
|
287
|
+
line-height: 1.1; text-shadow: 0 4px 20px rgba(0,0,0,0.7);
|
|
288
|
+
}${subhead ? `
|
|
289
|
+
${scope} .product-sub {
|
|
290
|
+
position: absolute; left: 8%; right: 8%; bottom: 8%;
|
|
291
|
+
font-size: 28px; font-weight: 400; color: #d0d0e0;
|
|
292
|
+
text-shadow: 0 2px 10px rgba(0,0,0,0.7);
|
|
293
|
+
}` : ""}`,
|
|
294
|
+
body: `${backdropMarkup}
|
|
295
|
+
<div class="label" id="label">${esc(label)}</div>
|
|
296
|
+
<div class="product-headline" id="headline">${esc(headline)}</div>${subhead ? `
|
|
297
|
+
<div class="product-sub" id="subhead">${esc(subhead)}</div>` : ""}`,
|
|
298
|
+
timeline: `tl.fromTo('${scope} .backdrop', { scale: 1.0 }, { scale: 1.08, duration: ${dur.toFixed(2)}, ease: 'none' }, 0);
|
|
299
|
+
tl.from('${scope} #label', { opacity: 0, x: -30, duration: 0.5, ease: 'power3.out' }, 0.2);
|
|
300
|
+
tl.from('${scope} #headline', { opacity: 0, y: 40, duration: 0.6, ease: 'power3.out' }, 0.4);${subhead ? `
|
|
301
|
+
tl.from('${scope} #subhead', { opacity: 0, y: 20, duration: 0.5, ease: 'power3.out' }, 0.65);` : ""}`,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Emit the full per-scene HTML. Returns a complete `<template>`-wrapped
|
|
308
|
+
* composition ready to write to `compositions/scene-<id>.html`.
|
|
309
|
+
*/
|
|
310
|
+
export function emitSceneHtml(input) {
|
|
311
|
+
if (input.duration <= 0) {
|
|
312
|
+
throw new Error(`Scene duration must be > 0, got ${input.duration}`);
|
|
313
|
+
}
|
|
314
|
+
if (input.width <= 0 || input.height <= 0) {
|
|
315
|
+
throw new Error(`Invalid canvas dims: ${input.width}x${input.height}`);
|
|
316
|
+
}
|
|
317
|
+
const id = input.id;
|
|
318
|
+
const dur = Number(input.duration.toFixed(3));
|
|
319
|
+
const parts = buildPreset({ ...input, id, duration: dur });
|
|
320
|
+
const audioBlock = input.audioPath
|
|
321
|
+
? `\n <audio
|
|
322
|
+
id="narration"
|
|
323
|
+
data-start="0"
|
|
324
|
+
data-duration="auto"
|
|
325
|
+
data-track-index="2"
|
|
326
|
+
src="${esc(input.audioPath)}"
|
|
327
|
+
data-volume="1"
|
|
328
|
+
></audio>\n`
|
|
329
|
+
: "";
|
|
330
|
+
return `<template id="scene-${id}-template">
|
|
331
|
+
<div data-composition-id="${id}" data-start="0" data-duration="${dur}" data-width="${input.width}" data-height="${input.height}">
|
|
332
|
+
<style>
|
|
333
|
+
${parts.css}
|
|
334
|
+
</style>
|
|
335
|
+
|
|
336
|
+
${parts.body}
|
|
337
|
+
${audioBlock}
|
|
338
|
+
<script src="${GSAP_CDN}"></script>
|
|
339
|
+
<script>
|
|
340
|
+
window.__timelines = window.__timelines || {};
|
|
341
|
+
const tl = gsap.timeline({ paused: true });
|
|
342
|
+
|
|
343
|
+
${parts.timeline}
|
|
344
|
+
|
|
345
|
+
window.__timelines["${id}"] = tl;
|
|
346
|
+
</script>
|
|
347
|
+
</div>
|
|
348
|
+
</template>
|
|
349
|
+
`;
|
|
350
|
+
}
|
|
351
|
+
// ---------------------------------------------------------------------------
|
|
352
|
+
// Root index.html mutation
|
|
353
|
+
// ---------------------------------------------------------------------------
|
|
354
|
+
/**
|
|
355
|
+
* Sum existing `<div class="clip">` end-times to find where the next scene
|
|
356
|
+
* should start. Returns 0 for an empty root.
|
|
357
|
+
*/
|
|
358
|
+
export function nextSceneStart(rootHtml) {
|
|
359
|
+
const clipRegex = /<div\s+class="clip"[^>]*?\sdata-start="([\d.]+)"[^>]*?\sdata-duration="([\d.]+)"/gi;
|
|
360
|
+
let maxEnd = 0;
|
|
361
|
+
let match;
|
|
362
|
+
while ((match = clipRegex.exec(rootHtml)) !== null) {
|
|
363
|
+
const end = parseFloat(match[1]) + parseFloat(match[2]);
|
|
364
|
+
if (Number.isFinite(end) && end > maxEnd)
|
|
365
|
+
maxEnd = end;
|
|
366
|
+
}
|
|
367
|
+
return maxEnd;
|
|
368
|
+
}
|
|
369
|
+
/** Build the `<div class="clip" data-composition-id=... data-composition-src=...>` reference string. */
|
|
370
|
+
export function buildClipReference(opts) {
|
|
371
|
+
const start = Number(opts.start.toFixed(3));
|
|
372
|
+
const duration = Number(opts.duration.toFixed(3));
|
|
373
|
+
const track = opts.trackIndex ?? 1;
|
|
374
|
+
const src = opts.src ?? `compositions/scene-${opts.id}.html`;
|
|
375
|
+
return `<div class="clip" data-composition-id="${esc(opts.id)}" data-composition-src="${esc(src)}" data-start="${start}" data-duration="${duration}" data-track-index="${track}"></div>`;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Insert a clip reference inside the root composition's `#root` div, just
|
|
379
|
+
* before its closing `</div>`. Throws if the expected closing tag isn't
|
|
380
|
+
* found — callers should surface this as a structured error so users know
|
|
381
|
+
* to inspect a hand-edited root.
|
|
382
|
+
*
|
|
383
|
+
* Also grows the root's `data-duration` to fit the new clip's end-time.
|
|
384
|
+
*/
|
|
385
|
+
export function insertClipIntoRoot(rootHtml, clip) {
|
|
386
|
+
const clipDiv = buildClipReference(clip);
|
|
387
|
+
// Find the root closing tag. Match `</div>` followed by blank line + `<script>`,
|
|
388
|
+
// which matches `buildEmptyRootHtml` and any user-edited root that keeps the
|
|
389
|
+
// standard structure.
|
|
390
|
+
const closeMatch = rootHtml.match(/\n(\s*)<\/div>(\s*\n\s*<script>)/);
|
|
391
|
+
if (!closeMatch) {
|
|
392
|
+
throw new Error("Could not find root composition closing </div>. Ensure index.html follows the layout from `vibe scene init`.");
|
|
393
|
+
}
|
|
394
|
+
const closeIdx = closeMatch.index;
|
|
395
|
+
const closeIndent = closeMatch[1];
|
|
396
|
+
const childIndent = closeIndent + " ";
|
|
397
|
+
// Splice the clip just above the closing div, indented one level deeper.
|
|
398
|
+
const insertion = `\n${childIndent}${clipDiv}`;
|
|
399
|
+
let updated = rootHtml.slice(0, closeIdx) + insertion + rootHtml.slice(closeIdx);
|
|
400
|
+
// Grow root data-duration to fit the new clip end (never shrink — preserves
|
|
401
|
+
// user-set padding).
|
|
402
|
+
const newEnd = clip.start + clip.duration;
|
|
403
|
+
updated = updated.replace(/(<div\b[^>]*\bid="root"[^>]*\bdata-duration=")([\d.]+)(")/, (_full, prefix, value, suffix) => {
|
|
404
|
+
const current = parseFloat(value);
|
|
405
|
+
const next = Math.max(current, newEnd);
|
|
406
|
+
return `${prefix}${Number(next.toFixed(3))}${suffix}`;
|
|
407
|
+
});
|
|
408
|
+
return updated;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Read the root composition's canvas dims by parsing `data-width`/`data-height`
|
|
412
|
+
* on the `#root` div. Returns null if either is missing — caller should fall
|
|
413
|
+
* back to the project's aspect config.
|
|
414
|
+
*/
|
|
415
|
+
export function readRootDims(rootHtml) {
|
|
416
|
+
const widthMatch = rootHtml.match(/<div\b[^>]*\bid="root"[^>]*\bdata-width="(\d+)"/);
|
|
417
|
+
const heightMatch = rootHtml.match(/<div\b[^>]*\bid="root"[^>]*\bdata-height="(\d+)"/);
|
|
418
|
+
if (!widthMatch || !heightMatch)
|
|
419
|
+
return null;
|
|
420
|
+
return { width: parseInt(widthMatch[1], 10), height: parseInt(heightMatch[1], 10) };
|
|
421
|
+
}
|
|
422
|
+
//# sourceMappingURL=scene-html-emit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene-html-emit.js","sourceRoot":"","sources":["../../../src/commands/_shared/scene-html-emit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scene-html-emit.test.d.ts","sourceRoot":"","sources":["../../../src/commands/_shared/scene-html-emit.test.ts"],"names":[],"mappings":""}
|