@mevdragon/vidfarm-devcli 0.2.12 → 0.2.13

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 (199) hide show
  1. package/.env.example +37 -1
  2. package/README.md +27 -183
  3. package/SKILL.director.md +293 -0
  4. package/SKILL.platform.md +312 -0
  5. package/auto-create-hyperframe-templates/AUTO_CREATE_HYPERFRAME_TEMPLATES.md +275 -0
  6. package/auto-create-hyperframe-templates/extractor-system-prompt.md +128 -0
  7. package/auto-create-hyperframe-templates/input-manifest.schema.json +56 -0
  8. package/auto-create-hyperframe-templates/lambda-memory-estimator.md +118 -0
  9. package/auto-create-hyperframe-templates/production-graph.schema.json +314 -0
  10. package/auto-create-hyperframe-templates/runbook.md +198 -0
  11. package/auto-create-hyperframe-templates/scripts/create-hyperframe-template.mjs +368 -0
  12. package/auto-create-hyperframe-templates/template-plan.schema.json +311 -0
  13. package/auto-create-hyperframe-templates/template-planner-prompt.md +144 -0
  14. package/auto-create-templates/AUTO_CREATE_TEMPLATES.md +116 -0
  15. package/auto-create-templates/extractor-system-prompt.md +6 -1
  16. package/auto-create-templates/template-plan.schema.json +73 -2
  17. package/auto-create-templates/template-planner-prompt.md +62 -1
  18. package/dist/src/account-pages-legacy.js +361 -89
  19. package/dist/src/account-pages-legacy.js.map +1 -0
  20. package/dist/src/account-pages.js +13 -3
  21. package/dist/src/account-pages.js.map +1 -0
  22. package/dist/src/app.js +7060 -946
  23. package/dist/src/app.js.map +1 -0
  24. package/dist/src/cli.js +110 -29
  25. package/dist/src/cli.js.map +1 -0
  26. package/dist/src/composition-runtime.js +581 -0
  27. package/dist/src/composition-runtime.js.map +1 -0
  28. package/dist/src/config.js +69 -11
  29. package/dist/src/config.js.map +1 -0
  30. package/dist/src/context.js +280 -21
  31. package/dist/src/context.js.map +1 -0
  32. package/dist/src/dev-app-legacy.js +18 -17
  33. package/dist/src/dev-app-legacy.js.map +1 -0
  34. package/dist/src/dev-app.js +1 -0
  35. package/dist/src/dev-app.js.map +1 -0
  36. package/dist/src/domain.js +2 -1
  37. package/dist/src/domain.js.map +1 -0
  38. package/dist/src/editor-chat-history.js +10 -0
  39. package/dist/src/editor-chat-history.js.map +1 -0
  40. package/dist/src/editor-chat.js +133 -24
  41. package/dist/src/editor-chat.js.map +1 -0
  42. package/dist/src/frontend/flockposter-cache-store.js +10 -2
  43. package/dist/src/frontend/flockposter-cache-store.js.map +1 -0
  44. package/dist/src/frontend/homepage-client.js +6 -3
  45. package/dist/src/frontend/homepage-client.js.map +1 -0
  46. package/dist/src/frontend/homepage-shared.js +1 -0
  47. package/dist/src/frontend/homepage-shared.js.map +1 -0
  48. package/dist/src/frontend/homepage-store.js +1 -0
  49. package/dist/src/frontend/homepage-store.js.map +1 -0
  50. package/dist/src/frontend/homepage-view.js +131 -18
  51. package/dist/src/frontend/homepage-view.js.map +1 -0
  52. package/dist/src/frontend/page-runtime-client.js +5 -2
  53. package/dist/src/frontend/page-runtime-client.js.map +1 -0
  54. package/dist/src/frontend/page-runtime-store.js +1 -0
  55. package/dist/src/frontend/page-runtime-store.js.map +1 -0
  56. package/dist/src/frontend/sentry.js +42 -0
  57. package/dist/src/frontend/sentry.js.map +1 -0
  58. package/dist/src/frontend/template-editor-chat.js +1719 -213
  59. package/dist/src/frontend/template-editor-chat.js.map +1 -0
  60. package/dist/src/help-page.js +333 -0
  61. package/dist/src/help-page.js.map +1 -0
  62. package/dist/src/homepage.js +169 -47
  63. package/dist/src/homepage.js.map +1 -0
  64. package/dist/src/hyperframes/composition.js +180 -0
  65. package/dist/src/hyperframes/composition.js.map +1 -0
  66. package/dist/src/index.js +1 -0
  67. package/dist/src/index.js.map +1 -0
  68. package/dist/src/instrument.js +30 -0
  69. package/dist/src/instrument.js.map +1 -0
  70. package/dist/src/lib/crypto.js +1 -0
  71. package/dist/src/lib/crypto.js.map +1 -0
  72. package/dist/src/lib/dev-log.js +54 -0
  73. package/dist/src/lib/dev-log.js.map +1 -0
  74. package/dist/src/lib/display-name.js +11 -0
  75. package/dist/src/lib/display-name.js.map +1 -0
  76. package/dist/src/lib/ids.js +21 -1
  77. package/dist/src/lib/ids.js.map +1 -0
  78. package/dist/src/lib/images.js +1 -0
  79. package/dist/src/lib/images.js.map +1 -0
  80. package/dist/src/lib/json.js +1 -0
  81. package/dist/src/lib/json.js.map +1 -0
  82. package/dist/src/lib/template-dna.js +1 -0
  83. package/dist/src/lib/template-dna.js.map +1 -0
  84. package/dist/src/lib/template-paths.js +1 -0
  85. package/dist/src/lib/template-paths.js.map +1 -0
  86. package/dist/src/lib/template-style-options.js +29 -3
  87. package/dist/src/lib/template-style-options.js.map +1 -0
  88. package/dist/src/lib/time.js +1 -0
  89. package/dist/src/lib/time.js.map +1 -0
  90. package/dist/src/lib/video-quality-harness.js +60 -0
  91. package/dist/src/lib/video-quality-harness.js.map +1 -0
  92. package/dist/src/page-runtime.js +1 -0
  93. package/dist/src/page-runtime.js.map +1 -0
  94. package/dist/src/page-shell.js +1501 -49
  95. package/dist/src/page-shell.js.map +1 -0
  96. package/dist/src/primitive-context.js +144 -8
  97. package/dist/src/primitive-context.js.map +1 -0
  98. package/dist/src/primitive-registry.js +1919 -78
  99. package/dist/src/primitive-registry.js.map +1 -0
  100. package/dist/src/primitive-sdk.js +1 -0
  101. package/dist/src/primitive-sdk.js.map +1 -0
  102. package/dist/src/primitives/remotion/html-image.js +3 -1
  103. package/dist/src/primitives/remotion/html-image.js.map +1 -0
  104. package/dist/src/primitives/remotion/media-slideshow.js +60 -0
  105. package/dist/src/primitives/remotion/media-slideshow.js.map +1 -0
  106. package/dist/src/react-page-shell.js +1 -0
  107. package/dist/src/react-page-shell.js.map +1 -0
  108. package/dist/src/ready-post-schedule-component.js +1 -0
  109. package/dist/src/ready-post-schedule-component.js.map +1 -0
  110. package/dist/src/registry.js +237 -24
  111. package/dist/src/registry.js.map +1 -0
  112. package/dist/src/runtime.js +3 -0
  113. package/dist/src/runtime.js.map +1 -0
  114. package/dist/src/services/api-call-history.js +4 -0
  115. package/dist/src/services/api-call-history.js.map +1 -0
  116. package/dist/src/services/auth.js +40 -50
  117. package/dist/src/services/auth.js.map +1 -0
  118. package/dist/src/services/billing.js +20 -44
  119. package/dist/src/services/billing.js.map +1 -0
  120. package/dist/src/services/chat-threads.js +10 -6
  121. package/dist/src/services/chat-threads.js.map +1 -0
  122. package/dist/src/services/fork-access.js +94 -0
  123. package/dist/src/services/fork-access.js.map +1 -0
  124. package/dist/src/services/ghostcut.js +132 -0
  125. package/dist/src/services/ghostcut.js.map +1 -0
  126. package/dist/src/services/hyperframes.js +1014 -0
  127. package/dist/src/services/hyperframes.js.map +1 -0
  128. package/dist/src/services/job-capacity.js +14 -0
  129. package/dist/src/services/job-capacity.js.map +1 -0
  130. package/dist/src/services/job-logs.js +4 -0
  131. package/dist/src/services/job-logs.js.map +1 -0
  132. package/dist/src/services/jobs.js +99 -91
  133. package/dist/src/services/jobs.js.map +1 -0
  134. package/dist/src/services/media-processing.js +743 -0
  135. package/dist/src/services/media-processing.js.map +1 -0
  136. package/dist/src/services/primitive-media-lambda.js +280 -0
  137. package/dist/src/services/primitive-media-lambda.js.map +1 -0
  138. package/dist/src/services/providers.js +1560 -178
  139. package/dist/src/services/providers.js.map +1 -0
  140. package/dist/src/services/rate-limits.js +3 -2
  141. package/dist/src/services/rate-limits.js.map +1 -0
  142. package/dist/src/services/remotion.js +495 -92
  143. package/dist/src/services/remotion.js.map +1 -0
  144. package/dist/src/services/serverless-auth.js +374 -0
  145. package/dist/src/services/serverless-auth.js.map +1 -0
  146. package/dist/src/services/serverless-jobs.js +1074 -0
  147. package/dist/src/services/serverless-jobs.js.map +1 -0
  148. package/dist/src/services/serverless-provider-keys.js +401 -0
  149. package/dist/src/services/serverless-provider-keys.js.map +1 -0
  150. package/dist/src/services/serverless-records.js +1086 -0
  151. package/dist/src/services/serverless-records.js.map +1 -0
  152. package/dist/src/services/serverless-template-configs.js +67 -0
  153. package/dist/src/services/serverless-template-configs.js.map +1 -0
  154. package/dist/src/services/storage.js +170 -35
  155. package/dist/src/services/storage.js.map +1 -0
  156. package/dist/src/services/template-certification.js +295 -3
  157. package/dist/src/services/template-certification.js.map +1 -0
  158. package/dist/src/services/template-loader.js +45 -1
  159. package/dist/src/services/template-loader.js.map +1 -0
  160. package/dist/src/services/template-runtime-bundles.js +217 -0
  161. package/dist/src/services/template-runtime-bundles.js.map +1 -0
  162. package/dist/src/services/template-sources.js +452 -87
  163. package/dist/src/services/template-sources.js.map +1 -0
  164. package/dist/src/services/video-normalization.js +2 -0
  165. package/dist/src/services/video-normalization.js.map +1 -0
  166. package/dist/src/services/webhooks.js +7 -6
  167. package/dist/src/services/webhooks.js.map +1 -0
  168. package/dist/src/template-editor-pages.js +5637 -1322
  169. package/dist/src/template-editor-pages.js.map +1 -0
  170. package/dist/src/template-editor-shell.js +1376 -170
  171. package/dist/src/template-editor-shell.js.map +1 -0
  172. package/dist/src/template-sdk.js +1 -0
  173. package/dist/src/template-sdk.js.map +1 -0
  174. package/dist/src/worker.js +11 -226
  175. package/dist/src/worker.js.map +1 -0
  176. package/package.json +47 -12
  177. package/public/assets/homepage-client-app.js +34 -8
  178. package/public/assets/page-runtime-client-app.js +44 -18
  179. package/readme.secret.md +89 -0
  180. package/templates/vidfarm_template_0000/README.md +106 -0
  181. package/templates/vidfarm_template_0000/SKILL.md +266 -0
  182. package/templates/vidfarm_template_0000/assets/Abel-Regular.ttf +0 -0
  183. package/templates/vidfarm_template_0000/assets/DMSerifDisplay-Regular.ttf +0 -0
  184. package/templates/vidfarm_template_0000/assets/Montserrat[wght].ttf +0 -0
  185. package/templates/vidfarm_template_0000/assets/SourceCodePro[wght].ttf +0 -0
  186. package/templates/vidfarm_template_0000/assets/TikTokSans-SemiBold.ttf +0 -0
  187. package/templates/vidfarm_template_0000/assets/Yesteryear-Regular.ttf +0 -0
  188. package/templates/vidfarm_template_0000/composition.json +11 -0
  189. package/templates/vidfarm_template_0000/src/lib/images.js +221 -0
  190. package/templates/vidfarm_template_0000/src/remotion/Root.js +33 -0
  191. package/templates/vidfarm_template_0000/src/remotion/index.js +3 -0
  192. package/templates/vidfarm_template_0000/src/sdk.js +3 -0
  193. package/templates/vidfarm_template_0000/src/style-options.js +200 -0
  194. package/templates/vidfarm_template_0000/src/template-dna.js +9 -0
  195. package/templates/vidfarm_template_0000/src/template.js +1566 -0
  196. package/templates/vidfarm_template_0000/template.config.json +21 -0
  197. package/GETTING_STARTED.developers.md +0 -87
  198. package/SKILL.developer.md +0 -1186
  199. package/dist/src/db.js +0 -2007
@@ -0,0 +1,128 @@
1
+ # HyperFrames Production Graph Extractor Prompt
2
+
3
+ You are a HyperFrames production analyst.
4
+
5
+ Your job is to inspect one MP4, screenshot set, or PNG/JPG/WebP slideshow and extract the repeatable HyperFrames production process as structured JSON. Do not merely describe the media. Convert it into an editable composition graph that can become `composition.html`, `composition.json`, and a production Lambda site.
6
+
7
+ Return only JSON matching `production-graph.schema.json`.
8
+
9
+ ## Inputs You May Receive
10
+
11
+ - source notes
12
+ - source video or slides
13
+ - contact sheet
14
+ - representative frames
15
+ - ffprobe metadata
16
+ - scene cut list
17
+ - STT transcript with word timestamps
18
+ - OCR text from frames
19
+ - layout analysis with bounding boxes
20
+ - existing `composition.html` or `composition.json`
21
+ - desired output dimensions and fps
22
+
23
+ ## Extraction Rules
24
+
25
+ - Treat all supplied media as one reusable HyperFrames format.
26
+ - Separate source media, deterministic overlays, captions, audio, and generated assets.
27
+ - Identify which visual surfaces are editable layers and which are source-media content.
28
+ - Important readable text should default to deterministic HTML/caption layers, not baked generated media.
29
+ - Extract exact or inferred timing for scenes, slides, captions, overlays, transitions, zooms, holds, and loop points.
30
+ - Record source media slices with `media_start` when a layer uses a segment from a longer MP4.
31
+ - Preserve blank gaps as intentional timeline ranges when no layer should be visible.
32
+ - Do not depend on an always-on source video for publish correctness. Preview playback sources are allowed only as editor affordances.
33
+ - Distinguish `mode: "both"`, `mode: "editor"`, and `mode: "publish"`.
34
+ - Use percent geometry for layer placement: `x`, `y`, `width`, `height`.
35
+ - Use seconds for `start`, `duration`, `media_start`, and `media_end`.
36
+ - Track source audio separately from source video if audio should continue across scene cuts.
37
+ - Keep one editable timeline track collision-free unless the track is explicitly marked as composited.
38
+ - Identify caption safe areas and collisions with TikTok/Reels chrome.
39
+ - Record Lambda memory estimate inputs: resolution, duration, active video streams, source resolution, layer count, DOM complexity, effects, audio mixing, and known risk flags.
40
+
41
+ ## Required Analysis Dimensions
42
+
43
+ Extract:
44
+
45
+ - format summary and source mode
46
+ - output dimensions, fps, and total duration
47
+ - source asset inventory
48
+ - scene or slide timeline
49
+ - layer decomposition
50
+ - deterministic caption and text surfaces
51
+ - HTML overlay surfaces
52
+ - media replacement slots
53
+ - audio plan
54
+ - safe areas and subject bounds
55
+ - caption positioning and wrapping rules
56
+ - visual rules that must survive adaptation
57
+ - editable controls
58
+ - generated asset needs, if any
59
+ - Lambda memory estimate
60
+ - production Lambda site readiness
61
+ - validation checklist
62
+
63
+ ## Layer Classification
64
+
65
+ For every meaningful visual or audio element choose one kind:
66
+
67
+ - `video`: timed video layer or scene slice
68
+ - `image`: timed image/slide layer
69
+ - `audio`: timed audio layer
70
+ - `caption`: text intended as subtitle/creator caption
71
+ - `html`: custom deterministic HTML overlay, UI card, comment, notification, or app shell
72
+ - `shape`: non-text geometric layer
73
+ - `effect`: deterministic transform/filter/mask/highlight
74
+
75
+ For every layer choose one source of truth:
76
+
77
+ - `source_media`: the original media asset is the visual/audio content
78
+ - `deterministic_html`: HTML/CSS/text is the source of truth
79
+ - `generated_asset`: AI/generated media is the source of truth
80
+ - `user_asset`: caller-provided replacement asset is required
81
+ - `computed_effect`: derived motion, mask, crop, zoom, or highlight
82
+
83
+ ## Caption Rules
84
+
85
+ Strongly identify typography:
86
+
87
+ - font family match
88
+ - fallback font stack
89
+ - font weight
90
+ - case
91
+ - color
92
+ - outline, stroke, radial halo, shadow
93
+ - background chip style
94
+ - line wrapping
95
+ - line height
96
+ - alignment
97
+ - safe area
98
+ - phone-size legibility
99
+
100
+ When captions have colored backgrounds, classify them as inline highlight chips unless the source clearly uses a panel. Chips must hug measured wrapped lines.
101
+
102
+ When captions are white TikTok-native captions, distinguish radial black halo/outline from a web-style directional shadow.
103
+
104
+ For multiline captions, require one shared font size and line height for the block. Do not recommend per-line rendered images.
105
+
106
+ ## Lambda Memory Estimate Rules
107
+
108
+ Estimate memory from composition complexity, not vibes.
109
+
110
+ Use these defaults:
111
+
112
+ - `2048` MB for static/slideshow/simple image compositions with low DOM complexity.
113
+ - `3072` MB for standard 720x1280 or 1080x1920 social video with one active video stream and deterministic overlays.
114
+ - `4096` MB for 1080p video, multiple active videos, heavy captions, masks, filters, or long audio.
115
+ - `6144` MB or higher only when high resolution, many simultaneous layers, or prior failures justify it.
116
+
117
+ Return both a recommendation and a confidence. Include benchmark guidance only when the source sits near a threshold.
118
+
119
+ ## Output Bias
120
+
121
+ Be concrete. A production graph should be implementable.
122
+
123
+ Bad: "Add captions around the video."
124
+
125
+ Good: "Render a 2-line white TikTok Sans Semibold caption block at x=8, y=42, width=84, height=14, fontSize=46, lineHeight=1.08, black radial halo, max 18 chars per line, timed 0.0-2.4s."
126
+
127
+ Publish correctness bias: if a source video is split into scenes, every scene must be its own timed layer or publish proxy. Deleting scene 2 must delete scene 2 from the final render.
128
+
@@ -0,0 +1,56 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "Auto-Create HyperFrame Input Manifest",
4
+ "type": "object",
5
+ "required": [
6
+ "mode",
7
+ "input_path",
8
+ "output_path",
9
+ "slug_id",
10
+ "source_mode",
11
+ "render_defaults",
12
+ "lambda",
13
+ "publish"
14
+ ],
15
+ "properties": {
16
+ "mode": { "const": "autocreate-hyperframe-template" },
17
+ "harness_entry": { "type": "string" },
18
+ "input_path": { "type": "string" },
19
+ "output_path": { "type": "string" },
20
+ "slug_id": { "type": "string" },
21
+ "source_mode": { "enum": ["auto", "single_video", "scene_split_video", "slideshow", "mixed_media"] },
22
+ "source_notes_path": { "type": "string" },
23
+ "render_defaults": {
24
+ "type": "object",
25
+ "required": ["width", "height", "fps"],
26
+ "properties": {
27
+ "width": { "type": "integer", "minimum": 1 },
28
+ "height": { "type": "integer", "minimum": 1 },
29
+ "fps": { "type": "number", "minimum": 1 }
30
+ },
31
+ "additionalProperties": false
32
+ },
33
+ "lambda": {
34
+ "type": "object",
35
+ "required": ["stack_name", "region", "memory_strategy"],
36
+ "properties": {
37
+ "stack_name": { "type": "string" },
38
+ "region": { "type": "string" },
39
+ "memory_strategy": { "enum": ["estimate", "fixed"] },
40
+ "fixed_memory_mb": { "enum": [2048, 3072, 4096, 6144, 8192, 10240] }
41
+ },
42
+ "additionalProperties": false
43
+ },
44
+ "publish": {
45
+ "type": "object",
46
+ "required": ["prestage_site", "output_url_policy"],
47
+ "properties": {
48
+ "prestage_site": { "type": "boolean" },
49
+ "output_url_policy": { "enum": ["signed_https_final_output_only"] }
50
+ },
51
+ "additionalProperties": false
52
+ }
53
+ },
54
+ "additionalProperties": false
55
+ }
56
+
@@ -0,0 +1,118 @@
1
+ # HyperFrames Lambda Memory Estimator
2
+
3
+ Use this rubric to estimate Lambda memory before benchmarking.
4
+
5
+ The goal is not perfect prediction. The goal is a sane first render configuration that avoids the historical overpowered default while keeping publish reliable.
6
+
7
+ ## Recommended Buckets
8
+
9
+ | Memory | Use For |
10
+ | --- | --- |
11
+ | `2048` MB | Static image, simple slideshow, low DOM, no video decode pressure, 720p target. |
12
+ | `3072` MB | Default vertical social video: one active video stream, 720x1280 or 1080x1920, deterministic captions/HTML overlays. |
13
+ | `4096` MB | 1080p video with heavy overlays, multiple active video streams, masks/filters, large shadows, long audio, or >30s timelines. |
14
+ | `6144` MB | High-resolution outputs, many simultaneous media layers, complex CSS filters/masks, prior 3GB/4GB failure, or large generated assets. |
15
+ | `8192` MB+ | Exceptional cases only. Use after measured failure or very high complexity. |
16
+ | `10240` MB | Last resort, not a default. |
17
+
18
+ ## Scoring
19
+
20
+ Start at `1536` MB.
21
+
22
+ Add output pixel score:
23
+
24
+ - `0` MB for <= 1.0 megapixel output
25
+ - `512` MB for <= 2.1 megapixel output
26
+ - `1024` MB for <= 4.0 megapixel output
27
+ - `2048` MB for > 4.0 megapixel output
28
+
29
+ Add media score:
30
+
31
+ - `0` MB for no video layers
32
+ - `768` MB for one active video stream
33
+ - `512` MB for each additional simultaneous active video stream
34
+ - `256` MB for each additional unique source video decoded across the timeline
35
+ - `512` MB if source media is much larger than output resolution
36
+
37
+ Add DOM/caption score:
38
+
39
+ - `0` MB for <= 10 simple layers
40
+ - `256` MB for 11-30 layers
41
+ - `512` MB for > 30 layers
42
+ - `256` MB for frequent timed captions
43
+ - `512` MB for word-level caption highlighting or many HTML overlays
44
+
45
+ Add effect score:
46
+
47
+ - `256` MB for large text shadows, outlines, or chips on many layers
48
+ - `512` MB for masks, blend modes, blur, filter chains, or large CSS transforms
49
+ - `1024` MB for several effects active over video at once
50
+
51
+ Add duration/audio score:
52
+
53
+ - `0` MB for <= 30 seconds
54
+ - `256` MB for 31-60 seconds
55
+ - `512` MB for 61-180 seconds
56
+ - `1024` MB for > 180 seconds
57
+ - `256` MB for continuous audio mix
58
+ - `512` MB for multiple audio streams or heavy audio processing
59
+
60
+ Round up to the next bucket: `2048`, `3072`, `4096`, `6144`, `8192`, or `10240`.
61
+
62
+ Clamp ordinary compositions to `2048`-`4096` unless risk flags justify more.
63
+
64
+ ## Fast Rules
65
+
66
+ - If there is no video and the output is <= 1080x1920, start at `2048`.
67
+ - If there is exactly one active video stream and ordinary captions, start at `3072`.
68
+ - If there are two or more simultaneous videos, start at `4096`.
69
+ - If output is 4K or the source is 4K and actively decoded, start at `6144`.
70
+ - If 3GB succeeds with similar wall time to 4GB, keep 3GB.
71
+ - If 2GB succeeds but wall time grows enough to erase savings, keep 3GB.
72
+
73
+ ## Output Shape
74
+
75
+ ```json
76
+ {
77
+ "recommended_memory_mb": 3072,
78
+ "confidence": "medium",
79
+ "complexity_scores": {
80
+ "output_pixels": 921600,
81
+ "output_pixel_score_mb": 0,
82
+ "max_simultaneous_video_streams": 1,
83
+ "media_score_mb": 768,
84
+ "layer_count": 8,
85
+ "dom_caption_score_mb": 256,
86
+ "effect_score_mb": 0,
87
+ "duration_seconds": 12.7,
88
+ "duration_audio_score_mb": 256,
89
+ "raw_estimate_mb": 2816,
90
+ "rounded_bucket_mb": 3072
91
+ },
92
+ "risk_flags": [
93
+ "source_video_decode",
94
+ "continuous_audio"
95
+ ],
96
+ "rationale": "One active 720x1280 video stream with a small deterministic HTML overlay and continuous source audio fits the 3GB baseline.",
97
+ "benchmark_override": null
98
+ }
99
+ ```
100
+
101
+ ## Cost Estimate
102
+
103
+ Use this rough formula:
104
+
105
+ ```txt
106
+ lambda_cost = memory_gb * billed_seconds_total * 0.0000166667
107
+ step_functions_cost = state_transitions * 0.000025
108
+ estimated_cost = lambda_cost + step_functions_cost
109
+ ```
110
+
111
+ For planning, estimate billed seconds from similar templates:
112
+
113
+ - static/slideshow: 20-60 billed seconds
114
+ - 10-20s social video: 90-180 billed seconds at 3GB
115
+ - 30-60s social video: 180-420 billed seconds at 3GB
116
+
117
+ Record the estimate, but treat the first production render as the real calibration.
118
+
@@ -0,0 +1,314 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "HyperFrames Production Graph",
4
+ "type": "object",
5
+ "required": [
6
+ "format_summary",
7
+ "input_contract",
8
+ "visual_system",
9
+ "timeline",
10
+ "layer_decomposition",
11
+ "caption_system",
12
+ "lambda_memory_estimate",
13
+ "deployment",
14
+ "validation"
15
+ ],
16
+ "properties": {
17
+ "format_summary": {
18
+ "type": "object",
19
+ "required": ["slug_id", "title", "source_type", "summary", "width", "height", "duration_seconds"],
20
+ "properties": {
21
+ "slug_id": { "type": "string" },
22
+ "title": { "type": "string" },
23
+ "source_type": { "enum": ["single_video", "scene_split_video", "slideshow", "mixed_media"] },
24
+ "summary": { "type": "string" },
25
+ "width": { "type": "integer", "minimum": 1 },
26
+ "height": { "type": "integer", "minimum": 1 },
27
+ "fps": { "type": "number", "minimum": 1 },
28
+ "duration_seconds": { "type": "number", "minimum": 0 }
29
+ },
30
+ "additionalProperties": false
31
+ },
32
+ "input_contract": {
33
+ "type": "object",
34
+ "required": ["source_assets", "replaceable_slots"],
35
+ "properties": {
36
+ "source_assets": {
37
+ "type": "array",
38
+ "items": { "$ref": "#/$defs/sourceAsset" }
39
+ },
40
+ "replaceable_slots": {
41
+ "type": "array",
42
+ "items": {
43
+ "type": "object",
44
+ "required": ["name", "kind", "required", "description"],
45
+ "properties": {
46
+ "name": { "type": "string" },
47
+ "kind": { "enum": ["text", "image", "video", "audio", "html", "style", "duration", "cta"] },
48
+ "required": { "type": "boolean" },
49
+ "description": { "type": "string" },
50
+ "constraints": { "type": "array", "items": { "type": "string" } }
51
+ },
52
+ "additionalProperties": false
53
+ }
54
+ }
55
+ },
56
+ "additionalProperties": false
57
+ },
58
+ "viral_mechanics": {
59
+ "type": "object",
60
+ "properties": {
61
+ "hook_mechanic": { "type": "string" },
62
+ "retention_mechanic": { "type": "string" },
63
+ "payoff": { "type": "string" },
64
+ "must_preserve": { "type": "array", "items": { "type": "string" } },
65
+ "must_not_dilute": { "type": "array", "items": { "type": "string" } }
66
+ },
67
+ "additionalProperties": false
68
+ },
69
+ "visual_system": {
70
+ "type": "object",
71
+ "required": ["safe_areas", "layout_rules", "style_rules"],
72
+ "properties": {
73
+ "safe_areas": { "$ref": "#/$defs/safeAreas" },
74
+ "layout_rules": { "type": "array", "items": { "type": "string" } },
75
+ "style_rules": { "type": "array", "items": { "type": "string" } },
76
+ "subject_regions": {
77
+ "type": "array",
78
+ "items": {
79
+ "type": "object",
80
+ "required": ["id", "role", "geometry"],
81
+ "properties": {
82
+ "id": { "type": "string" },
83
+ "role": { "type": "string" },
84
+ "geometry": { "$ref": "#/$defs/geometry" }
85
+ },
86
+ "additionalProperties": false
87
+ }
88
+ }
89
+ },
90
+ "additionalProperties": false
91
+ },
92
+ "timeline": {
93
+ "type": "object",
94
+ "required": ["total_duration_seconds", "beats"],
95
+ "properties": {
96
+ "total_duration_seconds": { "type": "number", "minimum": 0 },
97
+ "beats": {
98
+ "type": "array",
99
+ "items": {
100
+ "type": "object",
101
+ "required": ["id", "start", "duration", "role", "coverage"],
102
+ "properties": {
103
+ "id": { "type": "string" },
104
+ "start": { "type": "number", "minimum": 0 },
105
+ "duration": { "type": "number", "exclusiveMinimum": 0 },
106
+ "role": { "type": "string" },
107
+ "coverage": { "enum": ["media", "html_overlay", "caption_only", "blank_background", "audio_only"] },
108
+ "notes": { "type": "string" }
109
+ },
110
+ "additionalProperties": false
111
+ }
112
+ }
113
+ },
114
+ "additionalProperties": false
115
+ },
116
+ "layer_decomposition": {
117
+ "type": "object",
118
+ "required": ["composition_id", "background_color", "layers"],
119
+ "properties": {
120
+ "composition_id": { "type": "string" },
121
+ "background_color": { "type": "string" },
122
+ "layers": {
123
+ "type": "array",
124
+ "items": { "$ref": "#/$defs/layer" }
125
+ },
126
+ "track_policy": {
127
+ "type": "object",
128
+ "properties": {
129
+ "collision_free_by_default": { "type": "boolean" },
130
+ "composited_tracks": { "type": "array", "items": { "type": "integer" } }
131
+ },
132
+ "additionalProperties": false
133
+ }
134
+ },
135
+ "additionalProperties": false
136
+ },
137
+ "caption_system": {
138
+ "type": "object",
139
+ "required": ["surfaces", "default_style"],
140
+ "properties": {
141
+ "surfaces": {
142
+ "type": "array",
143
+ "items": {
144
+ "type": "object",
145
+ "required": ["id", "layer_ids", "placement", "safe_area_notes"],
146
+ "properties": {
147
+ "id": { "type": "string" },
148
+ "layer_ids": { "type": "array", "items": { "type": "string" } },
149
+ "placement": { "$ref": "#/$defs/geometry" },
150
+ "safe_area_notes": { "type": "string" },
151
+ "wrap_rules": { "type": "array", "items": { "type": "string" } }
152
+ },
153
+ "additionalProperties": false
154
+ }
155
+ },
156
+ "default_style": { "$ref": "#/$defs/textStyle" }
157
+ },
158
+ "additionalProperties": false
159
+ },
160
+ "lambda_memory_estimate": { "$ref": "#/$defs/lambdaMemoryEstimate" },
161
+ "deployment": {
162
+ "type": "object",
163
+ "required": ["stack_name", "region", "site_strategy", "output_url_policy"],
164
+ "properties": {
165
+ "stack_name": { "type": "string" },
166
+ "region": { "type": "string" },
167
+ "site_strategy": { "enum": ["pre_stage_site", "stage_on_publish", "manual"] },
168
+ "output_url_policy": { "enum": ["signed_https_final_output_only"] },
169
+ "render_defaults": {
170
+ "type": "object",
171
+ "properties": {
172
+ "width": { "type": "integer", "minimum": 1 },
173
+ "height": { "type": "integer", "minimum": 1 },
174
+ "fps": { "type": "number", "minimum": 1 }
175
+ },
176
+ "additionalProperties": false
177
+ }
178
+ },
179
+ "additionalProperties": false
180
+ },
181
+ "validation": {
182
+ "type": "object",
183
+ "required": ["checks"],
184
+ "properties": {
185
+ "checks": { "type": "array", "items": { "type": "string" } },
186
+ "known_risks": { "type": "array", "items": { "type": "string" } }
187
+ },
188
+ "additionalProperties": false
189
+ }
190
+ },
191
+ "additionalProperties": false,
192
+ "$defs": {
193
+ "sourceAsset": {
194
+ "type": "object",
195
+ "required": ["id", "type", "path"],
196
+ "properties": {
197
+ "id": { "type": "string" },
198
+ "type": { "enum": ["video", "image", "audio", "font", "json", "html"] },
199
+ "path": { "type": "string" },
200
+ "width": { "type": "integer", "minimum": 0 },
201
+ "height": { "type": "integer", "minimum": 0 },
202
+ "duration_seconds": { "type": "number", "minimum": 0 },
203
+ "role": { "type": "string" }
204
+ },
205
+ "additionalProperties": false
206
+ },
207
+ "geometry": {
208
+ "type": "object",
209
+ "required": ["x", "y", "width", "height"],
210
+ "properties": {
211
+ "x": { "type": "number" },
212
+ "y": { "type": "number" },
213
+ "width": { "type": "number", "exclusiveMinimum": 0 },
214
+ "height": { "type": "number", "exclusiveMinimum": 0 },
215
+ "unit": { "const": "percent" }
216
+ },
217
+ "additionalProperties": false
218
+ },
219
+ "safeAreas": {
220
+ "type": "object",
221
+ "properties": {
222
+ "top_percent": { "type": "number", "minimum": 0 },
223
+ "right_percent": { "type": "number", "minimum": 0 },
224
+ "bottom_percent": { "type": "number", "minimum": 0 },
225
+ "left_percent": { "type": "number", "minimum": 0 },
226
+ "notes": { "type": "array", "items": { "type": "string" } }
227
+ },
228
+ "additionalProperties": false
229
+ },
230
+ "textStyle": {
231
+ "type": "object",
232
+ "properties": {
233
+ "font_family": { "type": "string" },
234
+ "font_weight": { "type": "integer" },
235
+ "font_size_px": { "type": "number" },
236
+ "line_height": { "type": "number" },
237
+ "color": { "type": "string" },
238
+ "background": { "type": "string" },
239
+ "background_style": { "enum": ["plain", "outline", "radial_halo", "highlight_solid", "highlight_translucent", "panel"] },
240
+ "text_align": { "enum": ["left", "center", "right"] },
241
+ "max_lines": { "type": "integer", "minimum": 1 }
242
+ },
243
+ "additionalProperties": false
244
+ },
245
+ "layer": {
246
+ "type": "object",
247
+ "required": ["id", "kind", "start", "duration", "track", "z", "mode", "source_of_truth", "geometry", "viral_alignment"],
248
+ "properties": {
249
+ "id": { "type": "string" },
250
+ "kind": { "enum": ["video", "image", "audio", "caption", "html", "shape", "effect"] },
251
+ "start": { "type": "number", "minimum": 0 },
252
+ "duration": { "type": "number", "exclusiveMinimum": 0 },
253
+ "track": { "type": "integer", "minimum": 0 },
254
+ "z": { "type": "integer" },
255
+ "mode": { "enum": ["both", "editor", "publish"] },
256
+ "source_of_truth": { "enum": ["source_media", "deterministic_html", "generated_asset", "user_asset", "computed_effect"] },
257
+ "geometry": { "$ref": "#/$defs/geometry" },
258
+ "media": {
259
+ "type": "object",
260
+ "properties": {
261
+ "src": { "type": "string" },
262
+ "asset_id": { "type": "string" },
263
+ "media_start": { "type": "number", "minimum": 0 },
264
+ "media_end": { "type": "number", "minimum": 0 },
265
+ "fit": { "enum": ["cover", "contain", "fill", "none"] },
266
+ "muted": { "type": "boolean" },
267
+ "volume": { "type": "number", "minimum": 0 }
268
+ },
269
+ "additionalProperties": false
270
+ },
271
+ "text": {
272
+ "type": "object",
273
+ "properties": {
274
+ "content": { "type": "string" },
275
+ "style": { "$ref": "#/$defs/textStyle" }
276
+ },
277
+ "additionalProperties": false
278
+ },
279
+ "html_contract": {
280
+ "type": "object",
281
+ "properties": {
282
+ "description": { "type": "string" },
283
+ "required_classes": { "type": "array", "items": { "type": "string" } },
284
+ "editable_fields": { "type": "array", "items": { "type": "string" } }
285
+ },
286
+ "additionalProperties": false
287
+ },
288
+ "viral_alignment": { "type": "string" },
289
+ "publish_notes": { "type": "string" }
290
+ },
291
+ "additionalProperties": false
292
+ },
293
+ "lambdaMemoryEstimate": {
294
+ "type": "object",
295
+ "required": ["recommended_memory_mb", "confidence", "complexity_scores", "rationale", "risk_flags"],
296
+ "properties": {
297
+ "recommended_memory_mb": { "enum": [2048, 3072, 4096, 6144, 8192, 10240] },
298
+ "confidence": { "enum": ["low", "medium", "high"] },
299
+ "complexity_scores": { "type": "object", "additionalProperties": { "type": ["number", "integer", "string", "boolean"] } },
300
+ "rationale": { "type": "string" },
301
+ "risk_flags": { "type": "array", "items": { "type": "string" } },
302
+ "benchmark_override": {
303
+ "type": ["object", "null"],
304
+ "properties": {
305
+ "memory_mb": { "enum": [2048, 3072, 4096, 6144, 8192, 10240] },
306
+ "reason": { "type": "string" }
307
+ },
308
+ "additionalProperties": false
309
+ }
310
+ },
311
+ "additionalProperties": false
312
+ }
313
+ }
314
+ }