@contractspec/lib.video-gen 1.42.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.
Files changed (137) hide show
  1. package/dist/browser/compositions/api-overview.js +645 -0
  2. package/dist/browser/compositions/index.js +1133 -0
  3. package/dist/browser/compositions/primitives/animated-text.js +144 -0
  4. package/dist/browser/compositions/primitives/brand-frame.js +181 -0
  5. package/dist/browser/compositions/primitives/code-block.js +226 -0
  6. package/dist/browser/compositions/primitives/index.js +656 -0
  7. package/dist/browser/compositions/primitives/progress-bar.js +59 -0
  8. package/dist/browser/compositions/primitives/terminal.js +265 -0
  9. package/dist/browser/compositions/primitives/transition.js +98 -0
  10. package/dist/browser/compositions/social-clip.js +500 -0
  11. package/dist/browser/compositions/terminal-demo.js +558 -0
  12. package/dist/browser/design/index.js +155 -0
  13. package/dist/browser/design/layouts.js +50 -0
  14. package/dist/browser/design/motion.js +43 -0
  15. package/dist/browser/design/tokens.js +28 -0
  16. package/dist/browser/design/typography.js +61 -0
  17. package/dist/browser/docs/compositions.docblock.js +182 -0
  18. package/dist/browser/docs/design.docblock.js +187 -0
  19. package/dist/browser/docs/generators.docblock.js +187 -0
  20. package/dist/browser/docs/rendering.docblock.js +197 -0
  21. package/dist/browser/docs/video-gen.docblock.js +141 -0
  22. package/dist/browser/generators/index.js +416 -0
  23. package/dist/browser/generators/scene-planner.js +205 -0
  24. package/dist/browser/generators/script-generator.js +147 -0
  25. package/dist/browser/generators/video-generator.js +414 -0
  26. package/dist/browser/index.js +1550 -0
  27. package/dist/browser/player/demo-player.js +1136 -0
  28. package/dist/browser/player/index.js +1136 -0
  29. package/dist/browser/remotion/Root.js +1189 -0
  30. package/dist/browser/remotion/index.js +1190 -0
  31. package/dist/browser/renderers/config.js +40 -0
  32. package/dist/browser/renderers/index.js +160 -0
  33. package/dist/browser/renderers/local.js +156 -0
  34. package/dist/browser/types.js +13 -0
  35. package/dist/compositions/api-overview.d.ts +16 -0
  36. package/dist/compositions/api-overview.js +640 -0
  37. package/dist/compositions/index.d.ts +7 -0
  38. package/dist/compositions/index.js +1128 -0
  39. package/dist/compositions/primitives/animated-text.d.ts +22 -0
  40. package/dist/compositions/primitives/animated-text.js +139 -0
  41. package/dist/compositions/primitives/brand-frame.d.ts +14 -0
  42. package/dist/compositions/primitives/brand-frame.js +176 -0
  43. package/dist/compositions/primitives/code-block.d.ts +18 -0
  44. package/dist/compositions/primitives/code-block.js +221 -0
  45. package/dist/compositions/primitives/index.d.ts +12 -0
  46. package/dist/compositions/primitives/index.js +651 -0
  47. package/dist/compositions/primitives/progress-bar.d.ts +12 -0
  48. package/dist/compositions/primitives/progress-bar.js +54 -0
  49. package/dist/compositions/primitives/terminal.d.ts +24 -0
  50. package/dist/compositions/primitives/terminal.js +260 -0
  51. package/dist/compositions/primitives/transition.d.ts +14 -0
  52. package/dist/compositions/primitives/transition.js +93 -0
  53. package/dist/compositions/social-clip.d.ts +16 -0
  54. package/dist/compositions/social-clip.js +495 -0
  55. package/dist/compositions/terminal-demo.d.ts +17 -0
  56. package/dist/compositions/terminal-demo.js +553 -0
  57. package/dist/design/index.d.ts +4 -0
  58. package/dist/design/index.js +150 -0
  59. package/dist/design/layouts.d.ts +69 -0
  60. package/dist/design/layouts.js +45 -0
  61. package/dist/design/motion.d.ts +72 -0
  62. package/dist/design/motion.js +38 -0
  63. package/dist/design/tokens.d.ts +31 -0
  64. package/dist/design/tokens.js +23 -0
  65. package/dist/design/typography.d.ts +61 -0
  66. package/dist/design/typography.js +56 -0
  67. package/dist/docs/compositions.docblock.d.ts +1 -0
  68. package/dist/docs/compositions.docblock.js +183 -0
  69. package/dist/docs/design.docblock.d.ts +1 -0
  70. package/dist/docs/design.docblock.js +188 -0
  71. package/dist/docs/generators.docblock.d.ts +1 -0
  72. package/dist/docs/generators.docblock.js +188 -0
  73. package/dist/docs/rendering.docblock.d.ts +1 -0
  74. package/dist/docs/rendering.docblock.js +198 -0
  75. package/dist/docs/video-gen.docblock.d.ts +1 -0
  76. package/dist/docs/video-gen.docblock.js +142 -0
  77. package/dist/generators/index.d.ts +5 -0
  78. package/dist/generators/index.js +411 -0
  79. package/dist/generators/scene-planner.d.ts +23 -0
  80. package/dist/generators/scene-planner.js +200 -0
  81. package/dist/generators/script-generator.d.ts +49 -0
  82. package/dist/generators/script-generator.js +142 -0
  83. package/dist/generators/video-generator.d.ts +20 -0
  84. package/dist/generators/video-generator.js +409 -0
  85. package/dist/index.d.ts +6 -0
  86. package/dist/index.js +1545 -0
  87. package/dist/node/compositions/api-overview.js +640 -0
  88. package/dist/node/compositions/index.js +1128 -0
  89. package/dist/node/compositions/primitives/animated-text.js +139 -0
  90. package/dist/node/compositions/primitives/brand-frame.js +176 -0
  91. package/dist/node/compositions/primitives/code-block.js +221 -0
  92. package/dist/node/compositions/primitives/index.js +651 -0
  93. package/dist/node/compositions/primitives/progress-bar.js +54 -0
  94. package/dist/node/compositions/primitives/terminal.js +260 -0
  95. package/dist/node/compositions/primitives/transition.js +93 -0
  96. package/dist/node/compositions/social-clip.js +495 -0
  97. package/dist/node/compositions/terminal-demo.js +553 -0
  98. package/dist/node/design/index.js +150 -0
  99. package/dist/node/design/layouts.js +45 -0
  100. package/dist/node/design/motion.js +38 -0
  101. package/dist/node/design/tokens.js +23 -0
  102. package/dist/node/design/typography.js +56 -0
  103. package/dist/node/docs/compositions.docblock.js +182 -0
  104. package/dist/node/docs/design.docblock.js +187 -0
  105. package/dist/node/docs/generators.docblock.js +187 -0
  106. package/dist/node/docs/rendering.docblock.js +197 -0
  107. package/dist/node/docs/video-gen.docblock.js +141 -0
  108. package/dist/node/generators/index.js +411 -0
  109. package/dist/node/generators/scene-planner.js +200 -0
  110. package/dist/node/generators/script-generator.js +142 -0
  111. package/dist/node/generators/video-generator.js +409 -0
  112. package/dist/node/index.js +1545 -0
  113. package/dist/node/player/demo-player.js +1131 -0
  114. package/dist/node/player/index.js +1131 -0
  115. package/dist/node/remotion/Root.js +1184 -0
  116. package/dist/node/remotion/index.js +1185 -0
  117. package/dist/node/renderers/config.js +35 -0
  118. package/dist/node/renderers/index.js +155 -0
  119. package/dist/node/renderers/local.js +151 -0
  120. package/dist/node/types.js +8 -0
  121. package/dist/player/demo-player.d.ts +55 -0
  122. package/dist/player/demo-player.js +1131 -0
  123. package/dist/player/index.d.ts +2 -0
  124. package/dist/player/index.js +1131 -0
  125. package/dist/remotion/Root.d.ts +2 -0
  126. package/dist/remotion/Root.js +1184 -0
  127. package/dist/remotion/index.d.ts +1 -0
  128. package/dist/remotion/index.js +1185 -0
  129. package/dist/renderers/config.d.ts +28 -0
  130. package/dist/renderers/config.js +35 -0
  131. package/dist/renderers/index.d.ts +3 -0
  132. package/dist/renderers/index.js +155 -0
  133. package/dist/renderers/local.d.ts +17 -0
  134. package/dist/renderers/local.js +151 -0
  135. package/dist/types.d.ts +63 -0
  136. package/dist/types.js +8 -0
  137. package/package.json +637 -0
@@ -0,0 +1,187 @@
1
+ // src/docs/generators.docblock.ts
2
+ import { registerDocBlocks } from "@contractspec/lib.contracts-spec/docs";
3
+ var generatorsDocBlocks = [
4
+ {
5
+ id: "docs.video-gen.generators",
6
+ title: "Video Generation Pipeline",
7
+ summary: "VideoGenerator, ScenePlanner, and ScriptGenerator -- from content brief to video project with optional LLM enhancement.",
8
+ kind: "reference",
9
+ visibility: "public",
10
+ route: "/docs/video-gen/generators",
11
+ tags: [
12
+ "video",
13
+ "generators",
14
+ "scene-planner",
15
+ "script-generator",
16
+ "llm",
17
+ "content-pipeline"
18
+ ],
19
+ owners: ["@contractspec/lib.video-gen"],
20
+ body: `# Video Generation Pipeline
21
+
22
+ The generators layer converts a \`VideoBrief\` (content brief + video config) into a fully specified \`VideoProject\` (scene graph ready for rendering). It follows the \`@contractspec/lib.content-gen\` pattern: optional LLM, deterministic fallback.
23
+
24
+ \`\`\`
25
+ VideoBrief
26
+ |
27
+ v
28
+ ScenePlanner.plan(brief) --> ScenePlan (scenes + durations)
29
+ |
30
+ v
31
+ ScriptGenerator.generate(brief) --> NarrationScript (text + segments)
32
+ |
33
+ v
34
+ VoiceProvider.synthesize(text) --> AudioTrack (optional)
35
+ |
36
+ v
37
+ VideoGenerator.generate(brief) --> VideoProject (complete scene graph)
38
+ \`\`\`
39
+
40
+ ## VideoGenerator
41
+
42
+ The main orchestrator. Wires ScenePlanner, ScriptGenerator, and optional VoiceProvider into a single pipeline.
43
+
44
+ \`\`\`ts
45
+ import { VideoGenerator } from "@contractspec/lib.video-gen/generators";
46
+ import type { VideoBrief } from "@contractspec/lib.video-gen/types";
47
+
48
+ // Minimal (deterministic, no LLM, no voice)
49
+ const generator = new VideoGenerator({ fps: 30 });
50
+
51
+ // Full (with LLM for richer scenes + voice narration)
52
+ const generator = new VideoGenerator({
53
+ llm: myLLMProvider,
54
+ voice: myVoiceProvider,
55
+ model: "gpt-4o",
56
+ temperature: 0.4,
57
+ defaultVoiceId: "rachel",
58
+ fps: 30,
59
+ });
60
+
61
+ const project = await generator.generate(brief);
62
+ \`\`\`
63
+
64
+ ### Pipeline Steps
65
+
66
+ 1. **Scene planning** -- \`ScenePlanner.plan(brief)\` breaks the brief into concrete \`PlannedScene[]\` with composition IDs, props, and durations.
67
+ 2. **Script generation** -- If \`brief.narration.enabled\`, \`ScriptGenerator.generate()\` produces a \`NarrationScript\` with per-scene text segments.
68
+ 3. **Voice synthesis** -- If a \`VoiceProvider\` is configured and narration is enabled, synthesizes audio via \`voice.synthesize()\`.
69
+ 4. **Assembly** -- Combines scenes, audio, and metadata into a \`VideoProject\`.
70
+
71
+ ### Constructor Options
72
+
73
+ | Option | Type | Default | Description |
74
+ |--------|------|---------|-------------|
75
+ | \`llm\` | \`LLMProvider\` | -- | Optional LLM for enhanced generation |
76
+ | \`voice\` | \`VoiceProvider\` | -- | Optional voice synthesis provider |
77
+ | \`model\` | \`string\` | -- | LLM model override |
78
+ | \`temperature\` | \`number\` | \`0.4\` | LLM temperature (lower = more deterministic) |
79
+ | \`defaultVoiceId\` | \`string\` | -- | Default voice for narration |
80
+ | \`fps\` | \`number\` | \`30\` | Frames per second |
81
+
82
+ ## ScenePlanner
83
+
84
+ Breaks a \`VideoBrief\` into concrete scenes mapped to registered compositions.
85
+
86
+ \`\`\`ts
87
+ import { ScenePlanner } from "@contractspec/lib.video-gen/generators";
88
+
89
+ const planner = new ScenePlanner({ fps: 30 });
90
+ const plan = await planner.plan(brief);
91
+
92
+ plan.scenes; // PlannedScene[]
93
+ plan.estimatedDurationSeconds; // total estimated duration
94
+ plan.narrationScript; // combined narration text
95
+ \`\`\`
96
+
97
+ ### Deterministic Path (no LLM)
98
+
99
+ Maps brief sections to \`SocialClip\` compositions:
100
+
101
+ | Brief Section | Scene | Duration |
102
+ |---------------|-------|----------|
103
+ | \`title\` + \`summary\` | Hook / title | 3s |
104
+ | \`problems\` | Problem statement | 4s |
105
+ | \`solutions\` | Solution showcase | 5s |
106
+ | \`metrics\` | Proof / results | 3s |
107
+ | \`callToAction\` | CTA | 2s |
108
+
109
+ If \`brief.targetDurationSeconds\` is set, all scene durations are scaled proportionally.
110
+
111
+ ### LLM-Enhanced Path
112
+
113
+ With an \`LLMProvider\`, the planner sends the brief to the LLM and requests a scene breakdown as JSON. The LLM can choose from \`ApiOverview\`, \`SocialClip\`, or \`TerminalDemo\` compositions. Falls back to deterministic on any failure.
114
+
115
+ ## ScriptGenerator
116
+
117
+ Produces narration text from a \`ContentBrief\` with style control.
118
+
119
+ \`\`\`ts
120
+ import { ScriptGenerator } from "@contractspec/lib.video-gen/generators";
121
+
122
+ const scriptGen = new ScriptGenerator({ temperature: 0.5 });
123
+ const script = await scriptGen.generate(brief.content, brief.narration);
124
+
125
+ script.fullText; // complete narration
126
+ script.segments; // NarrationSegment[] (per-scene text)
127
+ script.estimatedDurationSeconds; // at ~150 words/min
128
+ script.style; // "professional" | "casual" | "technical"
129
+ \`\`\`
130
+
131
+ ### Narration Styles
132
+
133
+ | Style | Tone |
134
+ |-------|------|
135
+ | \`professional\` | Clear, authoritative, concise |
136
+ | \`casual\` | Friendly, conversational, approachable |
137
+ | \`technical\` | Precise, detailed, accurate |
138
+
139
+ ### NarrationSegment
140
+
141
+ Each segment maps to a scene and provides timing estimates:
142
+
143
+ \`\`\`ts
144
+ interface NarrationSegment {
145
+ sceneId: string; // "intro", "problems", "solutions", "metrics", "cta"
146
+ text: string; // narration text for this segment
147
+ estimatedDurationSeconds: number; // at ~150 words/min
148
+ }
149
+ \`\`\`
150
+
151
+ ## Input Types
152
+
153
+ ### VideoBrief
154
+
155
+ \`\`\`ts
156
+ interface VideoBrief {
157
+ content: ContentBrief; // from @contractspec/lib.content-gen
158
+ format: VideoFormat; // landscape, portrait, square, or custom
159
+ targetDurationSeconds?: number; // auto-calculated if omitted
160
+ narration?: NarrationConfig; // { enabled, voiceId, language, style }
161
+ style?: VideoStyleOverrides; // colors, fonts, dark mode
162
+ compositionId?: string; // force a specific composition
163
+ }
164
+ \`\`\`
165
+
166
+ ### PlannedScene
167
+
168
+ \`\`\`ts
169
+ interface PlannedScene {
170
+ compositionId: string; // maps to a registered Remotion composition
171
+ props: Record<string, unknown>; // input props for the composition
172
+ durationInFrames: number; // scene duration
173
+ narrationText?: string; // narrator text for this scene
174
+ notes?: string; // planning notes (LLM path only)
175
+ }
176
+ \`\`\`
177
+
178
+ ## Guardrails
179
+
180
+ - Generators are **stateless** -- no side effects, no caching. Call \`generate()\` / \`plan()\` for each video.
181
+ - LLM responses are parsed as JSON; any parse failure falls back to deterministic.
182
+ - Temperature defaults are conservative (0.3-0.5) for reproducibility.
183
+ - Duration estimates use 150 words/min speaking rate.
184
+ `
185
+ }
186
+ ];
187
+ registerDocBlocks(generatorsDocBlocks);
@@ -0,0 +1,197 @@
1
+ // src/docs/rendering.docblock.ts
2
+ import { registerDocBlocks } from "@contractspec/lib.contracts-spec/docs";
3
+ var renderingDocBlocks = [
4
+ {
5
+ id: "docs.video-gen.rendering",
6
+ title: "Video Rendering & Playback",
7
+ summary: "LocalRenderer for MP4 output, render configuration, quality presets, DemoPlayer for web embedding, and Remotion Studio setup.",
8
+ kind: "reference",
9
+ visibility: "public",
10
+ route: "/docs/video-gen/rendering",
11
+ tags: [
12
+ "video",
13
+ "rendering",
14
+ "remotion",
15
+ "player",
16
+ "mp4",
17
+ "quality-presets"
18
+ ],
19
+ owners: ["@contractspec/lib.video-gen"],
20
+ body: `# Video Rendering & Playback
21
+
22
+ The rendering layer wraps \`@remotion/renderer\` for MP4/WebM output and \`@remotion/player\` for interactive web embedding. It implements the \`VideoProvider\` contract from \`@contractspec/lib.contracts-integrations\`.
23
+
24
+ ## LocalRenderer
25
+
26
+ Renders a \`VideoProject\` to a video file using the local Remotion renderer. Requires **Node.js** (not Bun-compatible).
27
+
28
+ \`\`\`ts
29
+ import { LocalRenderer } from "@contractspec/lib.video-gen/renderers/local";
30
+
31
+ const renderer = new LocalRenderer({
32
+ entryPoint: "./src/remotion/index.ts",
33
+ });
34
+
35
+ const result = await renderer.render(project, {
36
+ outputPath: "out/video.mp4",
37
+ codec: "h264",
38
+ crf: 18,
39
+ });
40
+
41
+ result.outputPath; // "out/video.mp4"
42
+ result.format; // "mp4"
43
+ result.durationSeconds; // total duration
44
+ result.fileSizeBytes; // file size
45
+ result.dimensions; // { width: 1920, height: 1080 }
46
+ \`\`\`
47
+
48
+ > **Important**: Import \`LocalRenderer\` from the \`/renderers/local\` subpath, not from the main entry. It dynamically imports \`@remotion/bundler\` and \`@remotion/renderer\` which are Node.js-only.
49
+
50
+ ### Auto-Variants
51
+
52
+ Set \`autoVariants: true\` to generate landscape + square + portrait versions:
53
+
54
+ \`\`\`ts
55
+ const result = await renderer.render(project, {
56
+ outputPath: "out/video.mp4",
57
+ autoVariants: true,
58
+ });
59
+
60
+ result.variants; // [
61
+ // { outputPath: "out/video-square.mp4", dimensions: { width: 1080, height: 1080 } },
62
+ // { outputPath: "out/video-portrait.mp4", dimensions: { width: 1080, height: 1920 } },
63
+ // ]
64
+ \`\`\`
65
+
66
+ ## Render Configuration
67
+
68
+ ### Defaults
69
+
70
+ \`\`\`ts
71
+ import {
72
+ defaultRenderConfig,
73
+ resolveRenderConfig,
74
+ qualityPresets,
75
+ codecFormatMap,
76
+ } from "@contractspec/lib.video-gen/renderers/config";
77
+
78
+ defaultRenderConfig.codec; // "h264"
79
+ defaultRenderConfig.outputFormat; // "mp4"
80
+ defaultRenderConfig.crf; // 18
81
+ defaultRenderConfig.pixelFormat; // "yuv420p"
82
+ \`\`\`
83
+
84
+ ### RenderConfig Options
85
+
86
+ | Option | Type | Default | Description |
87
+ |--------|------|---------|-------------|
88
+ | \`outputPath\` | \`string\` | -- | **Required**. Output file path |
89
+ | \`codec\` | \`"h264" \\| "h265" \\| "vp8" \\| "vp9"\` | \`"h264"\` | Video codec |
90
+ | \`outputFormat\` | \`"mp4" \\| "webm" \\| "gif"\` | \`"mp4"\` | Container format |
91
+ | \`crf\` | \`number\` | \`18\` | Constant Rate Factor (lower = better quality) |
92
+ | \`pixelFormat\` | \`string\` | \`"yuv420p"\` | Pixel format |
93
+ | \`concurrency\` | \`number\` | CPU count | Rendering threads |
94
+ | \`autoVariants\` | \`boolean\` | \`false\` | Generate format variants |
95
+
96
+ ### Quality Presets
97
+
98
+ \`\`\`ts
99
+ import { resolveRenderConfig } from "@contractspec/lib.video-gen/renderers/config";
100
+
101
+ // Draft (fastest, for previews)
102
+ resolveRenderConfig({ outputPath: "out/preview.mp4" }, "draft");
103
+ // -> crf: 28, concurrency: 1
104
+
105
+ // Standard (balanced)
106
+ resolveRenderConfig({ outputPath: "out/video.mp4" }, "standard");
107
+ // -> crf: 18
108
+
109
+ // High (best quality, for final output)
110
+ resolveRenderConfig({ outputPath: "out/final.mp4" }, "high");
111
+ // -> crf: 12
112
+ \`\`\`
113
+
114
+ ### Codec-to-Format Mapping
115
+
116
+ | Codec | Format |
117
+ |-------|--------|
118
+ | \`h264\` | \`mp4\` |
119
+ | \`h265\` | \`mp4\` |
120
+ | \`vp8\` | \`webm\` |
121
+ | \`vp9\` | \`webm\` |
122
+
123
+ ## DemoPlayer (Web Embedding)
124
+
125
+ Embeddable Remotion Player for interactive video demos in React apps. Wraps \`@remotion/player\` with ContractSpec compositions.
126
+
127
+ \`\`\`tsx
128
+ import { DemoPlayer } from "@contractspec/lib.video-gen/player";
129
+
130
+ <DemoPlayer
131
+ compositionId="ApiOverview"
132
+ inputProps={{
133
+ specName: "CreateUser",
134
+ specCode: "export const createUser = defineCommand({...})",
135
+ }}
136
+ controls
137
+ autoPlay
138
+ loop
139
+ width="100%"
140
+ clickToPlay
141
+ doubleClickToFullscreen
142
+ />
143
+ \`\`\`
144
+
145
+ ### DemoPlayer Props
146
+
147
+ | Prop | Type | Default | Description |
148
+ |------|------|---------|-------------|
149
+ | \`compositionId\` | \`"ApiOverview" \\| "SocialClip" \\| "TerminalDemo"\` | -- | Composition to play |
150
+ | \`inputProps\` | composition props type | -- | Props for the selected composition |
151
+ | \`controls\` | \`boolean\` | \`true\` | Show playback controls |
152
+ | \`autoPlay\` | \`boolean\` | \`false\` | Auto-play on mount |
153
+ | \`loop\` | \`boolean\` | \`false\` | Loop playback |
154
+ | \`width\` | \`string \\| number\` | \`"100%"\` | Player width |
155
+ | \`height\` | \`string \\| number\` | \`"auto"\` | Player height |
156
+ | \`clickToPlay\` | \`boolean\` | \`true\` | Click to toggle playback |
157
+ | \`doubleClickToFullscreen\` | \`boolean\` | \`true\` | Double-click for fullscreen |
158
+
159
+ > \`@remotion/player\` is a peer dependency. Install it in your app if you use \`DemoPlayer\`.
160
+
161
+ ## Remotion Studio
162
+
163
+ The \`@contractspec/app.video-studio\` package provides a Remotion Studio entry point for previewing compositions interactively.
164
+
165
+ \`\`\`bash
166
+ # Start Remotion Studio
167
+ bun run dev:video
168
+
169
+ # Render a specific composition
170
+ npx remotion render src/index.ts ApiOverview out/api-overview.mp4
171
+
172
+ # Render all compositions
173
+ bun run render:all
174
+ \`\`\`
175
+
176
+ ### Registered Compositions
177
+
178
+ | ID | Component | Dimensions | Duration | Description |
179
+ |----|-----------|------------|----------|-------------|
180
+ | \`ApiOverview\` | \`ApiOverview\` | 1920x1080 | 450 frames (15s) | Homepage API demo |
181
+ | \`SocialClip\` | \`SocialClip\` | 1920x1080 | 300 frames (10s) | Landscape social clip |
182
+ | \`SocialClipSquare\` | \`SocialClip\` | 1080x1080 | 300 frames (10s) | Square social clip |
183
+ | \`SocialClipPortrait\` | \`SocialClip\` | 1080x1920 | 300 frames (10s) | Portrait social clip |
184
+ | \`TerminalDemo\` | \`TerminalDemo\` | 1920x1080 | 600 frames (20s) | CLI walkthrough |
185
+
186
+ All compositions run at 30fps.
187
+
188
+ ## Guardrails
189
+
190
+ - \`LocalRenderer\` requires Node.js -- do not attempt to use it in browser or Bun environments.
191
+ - Import \`LocalRenderer\` from the \`/renderers/local\` subpath to avoid bundling \`@remotion/renderer\` in browser builds.
192
+ - The \`remotion\` entry point (\`@contractspec/lib.video-gen/remotion\`) is a **side-effect module** that calls \`registerRoot()\`. Only import it from Remotion Studio or render scripts.
193
+ - Use quality presets for consistency: \`draft\` for development, \`standard\` for CI, \`high\` for releases.
194
+ `
195
+ }
196
+ ];
197
+ registerDocBlocks(renderingDocBlocks);
@@ -0,0 +1,141 @@
1
+ // src/docs/video-gen.docblock.ts
2
+ import { registerDocBlocks } from "@contractspec/lib.contracts-spec/docs";
3
+ var videoGenDocBlocks = [
4
+ {
5
+ id: "docs.video-gen.overview",
6
+ title: "Video Generation Library",
7
+ summary: "Programmatic video generation with Remotion -- from content brief to rendered MP4 in a single pipeline.",
8
+ kind: "reference",
9
+ visibility: "public",
10
+ route: "/docs/video-gen/overview",
11
+ tags: ["video", "remotion", "generation", "content-pipeline"],
12
+ owners: ["@contractspec/lib.video-gen"],
13
+ body: `# Video Generation Library
14
+
15
+ \`@contractspec/lib.video-gen\` provides **programmatic video generation** using [Remotion](https://remotion.dev). It follows the same generator pattern as \`@contractspec/lib.content-gen\` and consumes provider contracts from \`@contractspec/lib.contracts-integrations/integrations/providers/video\`.
16
+
17
+ ## Architecture
18
+
19
+ The library is organized into five layers, each buildable and testable independently:
20
+
21
+ \`\`\`
22
+ Content Brief
23
+ |
24
+ v
25
+ Generators -----> ScenePlanner (brief -> scenes)
26
+ | ScriptGenerator (brief -> narration)
27
+ | VideoGenerator (orchestrator)
28
+ v
29
+ Compositions ---> Primitives (AnimatedText, CodeBlock, Terminal, ...)
30
+ | Full Compositions (ApiOverview, SocialClip, TerminalDemo)
31
+ v
32
+ Design ---------> Tokens, Motion, Typography, Layouts
33
+ |
34
+ v
35
+ Renderers ------> LocalRenderer (@remotion/renderer)
36
+ DemoPlayer (@remotion/player, web embedding)
37
+ \`\`\`
38
+
39
+ ### Layer Responsibilities
40
+
41
+ | Layer | Import Path | Purpose |
42
+ |-------|-------------|---------|
43
+ | **Types** | \`@contractspec/lib.video-gen/types\` | VideoBrief, ScenePlan, GeneratedVideo, re-exported contract types |
44
+ | **Design** | \`@contractspec/lib.video-gen/design\` | Video-optimized tokens, motion primitives, typography, layouts |
45
+ | **Compositions** | \`@contractspec/lib.video-gen/compositions\` | Remotion components (primitives + full compositions) |
46
+ | **Generators** | \`@contractspec/lib.video-gen/generators\` | VideoGenerator, ScenePlanner, ScriptGenerator |
47
+ | **Renderers** | \`@contractspec/lib.video-gen/renderers\` | LocalRenderer, render config, quality presets |
48
+ | **Player** | \`@contractspec/lib.video-gen/player\` | Embeddable DemoPlayer for web apps |
49
+ | **Remotion** | \`@contractspec/lib.video-gen/remotion\` | Remotion Studio entry point (registerRoot) |
50
+
51
+ ## Getting Started
52
+
53
+ ### 1. Generate a video project from a content brief
54
+
55
+ \`\`\`ts
56
+ import { VideoGenerator } from "@contractspec/lib.video-gen/generators";
57
+ import { VIDEO_FORMATS } from "@contractspec/lib.video-gen/types";
58
+ import type { VideoBrief } from "@contractspec/lib.video-gen/types";
59
+
60
+ const generator = new VideoGenerator({ fps: 30 });
61
+
62
+ const brief: VideoBrief = {
63
+ content: {
64
+ title: "Ship APIs 10x Faster",
65
+ summary: "ContractSpec generates everything from a single spec.",
66
+ problems: ["Manual API maintenance", "Inconsistent surfaces"],
67
+ solutions: ["One spec, every surface", "Safe regeneration"],
68
+ callToAction: "Try ContractSpec",
69
+ },
70
+ format: VIDEO_FORMATS.landscape,
71
+ targetDurationSeconds: 30,
72
+ };
73
+
74
+ const project = await generator.generate(brief);
75
+ \`\`\`
76
+
77
+ ### 2. Render to MP4
78
+
79
+ \`\`\`ts
80
+ import { LocalRenderer } from "@contractspec/lib.video-gen/renderers/local";
81
+
82
+ const renderer = new LocalRenderer({
83
+ entryPoint: "./src/remotion/index.ts",
84
+ });
85
+
86
+ const result = await renderer.render(project, {
87
+ outputPath: "out/video.mp4",
88
+ });
89
+ \`\`\`
90
+
91
+ ### 3. Embed in a web app
92
+
93
+ \`\`\`tsx
94
+ import { DemoPlayer } from "@contractspec/lib.video-gen/player";
95
+
96
+ <DemoPlayer
97
+ compositionId="ApiOverview"
98
+ inputProps={{ specName: "CreateUser", specCode: "..." }}
99
+ controls
100
+ autoPlay
101
+ loop
102
+ />
103
+ \`\`\`
104
+
105
+ ## Contract Bridge
106
+
107
+ The library consumes provider contracts defined in \`@contractspec/lib.contracts-integrations\`:
108
+
109
+ | Contract | Purpose |
110
+ |----------|---------|
111
+ | \`VideoProvider\` | Renderer abstraction (local, Lambda, Cloud Run) |
112
+ | \`VideoProject\` | Scene graph with format, fps, audio tracks |
113
+ | \`RenderConfig\` / \`RenderResult\` | Codec, quality, output path, dimensions |
114
+ | \`CompositionRegistry\` | Metadata for registered Remotion compositions |
115
+ | \`VideoFormat\` | Landscape / portrait / square / custom dimensions |
116
+
117
+ Types are re-exported from the main entry for convenience:
118
+
119
+ \`\`\`ts
120
+ import type { VideoProject, RenderConfig } from "@contractspec/lib.video-gen";
121
+ \`\`\`
122
+
123
+ ## Deterministic by Default
124
+
125
+ All generators support two modes:
126
+
127
+ - **Without LLM**: Fully deterministic, template-based output. Same brief always produces the same video project.
128
+ - **With LLM**: Richer scene planning and narration scripts via an optional \`LLMProvider\`. Falls back to deterministic on any failure.
129
+
130
+ This matches the content-gen pattern: \`constructor({ llm? })\` -> \`generate(brief)\`.
131
+
132
+ ## Guardrails
133
+
134
+ - Compositions must be **deterministic**: same props = same visual output.
135
+ - Design tokens bridge from \`@contractspec/lib.design-system\` -- do not duplicate brand values.
136
+ - \`LocalRenderer\` requires Node.js (\`@remotion/renderer\` is not Bun-compatible).
137
+ - The \`remotion\` entry point is a side-effect module (calls \`registerRoot\`) -- import it only from Remotion Studio or render scripts.
138
+ `
139
+ }
140
+ ];
141
+ registerDocBlocks(videoGenDocBlocks);