@mevdragon/vidfarm-devcli 0.14.0 → 0.15.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 (418) hide show
  1. package/.agents/skills/embedded-captions/CATALOG.md +93 -0
  2. package/.agents/skills/embedded-captions/SKILL.md +286 -0
  3. package/.agents/skills/embedded-captions/assets/brand/CDPR-fankit-terms.txt +35 -0
  4. package/.agents/skills/embedded-captions/assets/brand/cyberpunk-widths.json +115 -0
  5. package/.agents/skills/embedded-captions/assets/fonts/char-widths.json +2211 -0
  6. package/.agents/skills/embedded-captions/assets/strokefonts/HersheyScript1.svg +242 -0
  7. package/.agents/skills/embedded-captions/assets/strokefonts/HersheyScriptMed.svg +242 -0
  8. package/.agents/skills/embedded-captions/dna/README.md +148 -0
  9. package/.agents/skills/embedded-captions/dna/chrome.json +68 -0
  10. package/.agents/skills/embedded-captions/dna/cream.json +69 -0
  11. package/.agents/skills/embedded-captions/dna/documentary.json +62 -0
  12. package/.agents/skills/embedded-captions/dna/editorial.json +70 -0
  13. package/.agents/skills/embedded-captions/dna/glitch.json +82 -0
  14. package/.agents/skills/embedded-captions/dna/ink.json +65 -0
  15. package/.agents/skills/embedded-captions/dna/keynote.json +62 -0
  16. package/.agents/skills/embedded-captions/dna/loud.json +75 -0
  17. package/.agents/skills/embedded-captions/dna/neon.json +58 -0
  18. package/.agents/skills/embedded-captions/dna/velocity.json +89 -0
  19. package/.agents/skills/embedded-captions/modes/cinematic/README.md +48 -0
  20. package/.agents/skills/embedded-captions/modes/cinematic/_archive/champion/spec.md +98 -0
  21. package/.agents/skills/embedded-captions/modes/cinematic/_archive/champion/template.html +188 -0
  22. package/.agents/skills/embedded-captions/modes/cinematic/_archive/memory-wall/spec.md +134 -0
  23. package/.agents/skills/embedded-captions/modes/cinematic/_archive/memory-wall/template.html +179 -0
  24. package/.agents/skills/embedded-captions/modes/cinematic/_archive/portrait-header/spec.md +81 -0
  25. package/.agents/skills/embedded-captions/modes/cinematic/_archive/portrait-header/template.html +170 -0
  26. package/.agents/skills/embedded-captions/modes/cinematic/cinematic-cream/spec.md +16 -0
  27. package/.agents/skills/embedded-captions/modes/cinematic/cinematic-cream/template.html +226 -0
  28. package/.agents/skills/embedded-captions/modes/cinematic/engine.html +355 -0
  29. package/.agents/skills/embedded-captions/modes/standard/_anatomy.md +233 -0
  30. package/.agents/skills/embedded-captions/modes/standard/_motion.md +192 -0
  31. package/.agents/skills/embedded-captions/modes/standard/fonts/build-fonts-css.cjs +97 -0
  32. package/.agents/skills/embedded-captions/references/aesthetic-principles.md +168 -0
  33. package/.agents/skills/embedded-captions/references/anti-patterns.md +188 -0
  34. package/.agents/skills/embedded-captions/references/bespoke-vs-presets.md +178 -0
  35. package/.agents/skills/embedded-captions/references/caption-grouping.md +130 -0
  36. package/.agents/skills/embedded-captions/references/composition-craft.md +522 -0
  37. package/.agents/skills/embedded-captions/references/direction-catalog.md +138 -0
  38. package/.agents/skills/embedded-captions/references/example-renders/champion.html +371 -0
  39. package/.agents/skills/embedded-captions/references/example-renders/memory-wall.html +334 -0
  40. package/.agents/skills/embedded-captions/references/failure-modes.md +145 -0
  41. package/.agents/skills/embedded-captions/references/layout-heuristics.md +238 -0
  42. package/.agents/skills/embedded-captions/references/motion-vocabulary.md +148 -0
  43. package/.agents/skills/embedded-captions/references/rail.md +68 -0
  44. package/.agents/skills/embedded-captions/references/reference-bar.md +47 -0
  45. package/.agents/skills/embedded-captions/references/scene-types.md +94 -0
  46. package/.agents/skills/embedded-captions/references/test-set.md +66 -0
  47. package/.agents/skills/embedded-captions/references/typographic-moves.md +266 -0
  48. package/.agents/skills/embedded-captions/references/typography-presets.md +63 -0
  49. package/.agents/skills/embedded-captions/scripts/audio-envelope.cjs +95 -0
  50. package/.agents/skills/embedded-captions/scripts/check-occlusion.cjs +250 -0
  51. package/.agents/skills/embedded-captions/scripts/check-overflow.cjs +194 -0
  52. package/.agents/skills/embedded-captions/scripts/check-rail-climax.cjs +233 -0
  53. package/.agents/skills/embedded-captions/scripts/check-timing.cjs +173 -0
  54. package/.agents/skills/embedded-captions/scripts/fill-timings.cjs +124 -0
  55. package/.agents/skills/embedded-captions/scripts/fit-fonts.cjs +158 -0
  56. package/.agents/skills/embedded-captions/scripts/gen-stroke-path.py +46 -0
  57. package/.agents/skills/embedded-captions/scripts/inject-fonts.cjs +169 -0
  58. package/.agents/skills/embedded-captions/scripts/lib-dna.cjs +201 -0
  59. package/.agents/skills/embedded-captions/scripts/make-cinematic.cjs +1205 -0
  60. package/.agents/skills/embedded-captions/scripts/make-composition.cjs +404 -0
  61. package/.agents/skills/embedded-captions/scripts/make-theme.cjs +8781 -0
  62. package/.agents/skills/embedded-captions/scripts/matte.cjs +294 -0
  63. package/.agents/skills/embedded-captions/scripts/measure-layout.cjs +293 -0
  64. package/.agents/skills/embedded-captions/scripts/prepare.sh +39 -0
  65. package/.agents/skills/embedded-captions/scripts/preview-frames.cjs +268 -0
  66. package/.agents/skills/embedded-captions/scripts/render-and-composite.sh +509 -0
  67. package/.agents/skills/embedded-captions/scripts/render-theme.sh +34 -0
  68. package/.agents/skills/embedded-captions/scripts/safe-zones.cjs +813 -0
  69. package/.agents/skills/embedded-captions/scripts/transcribe.cjs +349 -0
  70. package/.agents/skills/embedded-captions/themes/PORTING.md +49 -0
  71. package/.agents/skills/embedded-captions/themes/README.md +244 -0
  72. package/.agents/skills/embedded-captions/themes/anchor.json +27 -0
  73. package/.agents/skills/embedded-captions/themes/arcade.json +51 -0
  74. package/.agents/skills/embedded-captions/themes/aurora.json +41 -0
  75. package/.agents/skills/embedded-captions/themes/biolume.json +35 -0
  76. package/.agents/skills/embedded-captions/themes/brush.json +74 -0
  77. package/.agents/skills/embedded-captions/themes/chalkboard.json +52 -0
  78. package/.agents/skills/embedded-captions/themes/dossier.json +56 -0
  79. package/.agents/skills/embedded-captions/themes/graffiti.json +62 -0
  80. package/.agents/skills/embedded-captions/themes/hologram.json +41 -0
  81. package/.agents/skills/embedded-captions/themes/inkwater.json +43 -0
  82. package/.agents/skills/embedded-captions/themes/laser.json +46 -0
  83. package/.agents/skills/embedded-captions/themes/lastpage.json +33 -0
  84. package/.agents/skills/embedded-captions/themes/neonsign.json +53 -0
  85. package/.agents/skills/embedded-captions/themes/nightcity.json +56 -0
  86. package/.agents/skills/embedded-captions/themes/ordnance.json +54 -0
  87. package/.agents/skills/embedded-captions/themes/papercut.json +37 -0
  88. package/.agents/skills/embedded-captions/themes/popup.json +46 -0
  89. package/.agents/skills/embedded-captions/themes/ransom.json +62 -0
  90. package/.agents/skills/embedded-captions/themes/scoreboard.json +54 -0
  91. package/.agents/skills/embedded-captions/themes/spectrum.json +46 -0
  92. package/.agents/skills/embedded-captions/themes/stardust.json +29 -0
  93. package/.agents/skills/embedded-captions/themes/stomp.json +43 -0
  94. package/.agents/skills/embedded-captions/themes/terminal.json +49 -0
  95. package/.agents/skills/embedded-captions/themes/thunder.json +44 -0
  96. package/.agents/skills/embedded-captions/themes/transit.json +44 -0
  97. package/.agents/skills/embedded-captions/themes/vhs.json +47 -0
  98. package/.agents/skills/faceless-explainer/SKILL.md +209 -0
  99. package/.agents/skills/faceless-explainer/references/cut-catalog.md +215 -0
  100. package/.agents/skills/faceless-explainer/references/motion-language.md +156 -0
  101. package/.agents/skills/faceless-explainer/references/story-design.md +248 -0
  102. package/.agents/skills/faceless-explainer/references/visual-design.md +146 -0
  103. package/.agents/skills/faceless-explainer/scripts/assemble-index.mjs +570 -0
  104. package/.agents/skills/faceless-explainer/scripts/audio.mjs +260 -0
  105. package/.agents/skills/faceless-explainer/scripts/build-frame.mjs +536 -0
  106. package/.agents/skills/faceless-explainer/scripts/captions.mjs +508 -0
  107. package/.agents/skills/faceless-explainer/scripts/lib/assets.mjs +55 -0
  108. package/.agents/skills/faceless-explainer/scripts/lib/dimensions.mjs +45 -0
  109. package/.agents/skills/faceless-explainer/scripts/lib/storyboard.mjs +249 -0
  110. package/.agents/skills/faceless-explainer/scripts/lib/tokens.mjs +204 -0
  111. package/.agents/skills/faceless-explainer/scripts/lib/transition-registry.mjs +38 -0
  112. package/.agents/skills/faceless-explainer/scripts/lib/transitions.json +71 -0
  113. package/.agents/skills/faceless-explainer/scripts/transitions.mjs +320 -0
  114. package/.agents/skills/faceless-explainer/sub-agents/frame-worker.md +75 -0
  115. package/.agents/skills/flockposter/LICENSE +17 -0
  116. package/.agents/skills/flockposter/README.md +72 -0
  117. package/.agents/skills/flockposter/SKILL.md +562 -0
  118. package/.agents/skills/flockposter/examples/cli-instagram-reel.sh +21 -0
  119. package/.agents/skills/flockposter/examples/cli-multi-platform.json +69 -0
  120. package/.agents/skills/flockposter/examples/cli-tiktok-upload-only.sh +22 -0
  121. package/.agents/skills/flockposter/examples/cli-x-thread.sh +17 -0
  122. package/.agents/skills/flockposter/examples/cli-youtube-short.sh +21 -0
  123. package/.agents/skills/flockposter/examples/public-api-instagram-reel.json +28 -0
  124. package/.agents/skills/general-video/SKILL.md +143 -0
  125. package/.agents/skills/hyperframes/SKILL.md +160 -0
  126. package/.agents/skills/hyperframes-animation/SKILL.md +84 -0
  127. package/.agents/skills/hyperframes-animation/adapters/animate-text.md +64 -0
  128. package/.agents/skills/hyperframes-animation/adapters/animejs.md +114 -0
  129. package/.agents/skills/hyperframes-animation/adapters/css-animations.md +143 -0
  130. package/.agents/skills/hyperframes-animation/adapters/gsap-easing-and-stagger.md +118 -0
  131. package/.agents/skills/hyperframes-animation/adapters/gsap-timeline-and-labels.md +96 -0
  132. package/.agents/skills/hyperframes-animation/adapters/gsap-transforms-and-perf.md +96 -0
  133. package/.agents/skills/hyperframes-animation/adapters/gsap.md +105 -0
  134. package/.agents/skills/hyperframes-animation/adapters/html-in-canvas-patterns.md +507 -0
  135. package/.agents/skills/hyperframes-animation/adapters/lottie.md +117 -0
  136. package/.agents/skills/hyperframes-animation/adapters/three.md +131 -0
  137. package/.agents/skills/hyperframes-animation/adapters/typegpu.md +178 -0
  138. package/.agents/skills/hyperframes-animation/adapters/waapi.md +101 -0
  139. package/.agents/skills/hyperframes-animation/blueprints/comparison-split.md +27 -0
  140. package/.agents/skills/hyperframes-animation/blueprints/constellation-hub.md +44 -0
  141. package/.agents/skills/hyperframes-animation/blueprints/cta-morph-press.md +28 -0
  142. package/.agents/skills/hyperframes-animation/blueprints/cursor-ui-demo.md +57 -0
  143. package/.agents/skills/hyperframes-animation/blueprints/dataviz-countup.md +46 -0
  144. package/.agents/skills/hyperframes-animation/blueprints/device-surface-showcase.md +53 -0
  145. package/.agents/skills/hyperframes-animation/blueprints/grid-card-assemble.md +66 -0
  146. package/.agents/skills/hyperframes-animation/blueprints/kinetic-type-beats.md +78 -0
  147. package/.agents/skills/hyperframes-animation/blueprints/logo-assemble-lockup.md +69 -0
  148. package/.agents/skills/hyperframes-animation/blueprints/overwhelm-surround.md +28 -0
  149. package/.agents/skills/hyperframes-animation/blueprints/spatial-pan-stations.md +37 -0
  150. package/.agents/skills/hyperframes-animation/blueprints/ticker-takeover.md +29 -0
  151. package/.agents/skills/hyperframes-animation/blueprints/titlecard-reveal.md +42 -0
  152. package/.agents/skills/hyperframes-animation/blueprints/typewriter-reveal.md +51 -0
  153. package/.agents/skills/hyperframes-animation/blueprints/video-text-pivot.md +30 -0
  154. package/.agents/skills/hyperframes-animation/blueprints-index.md +146 -0
  155. package/.agents/skills/hyperframes-animation/examples/assets/avatars/02.avif +0 -0
  156. package/.agents/skills/hyperframes-animation/examples/assets/brands/github.avif +0 -0
  157. package/.agents/skills/hyperframes-animation/examples/assets/brands/nvidia.avif +0 -0
  158. package/.agents/skills/hyperframes-animation/examples/assets/brands/visa.avif +0 -0
  159. package/.agents/skills/hyperframes-animation/examples/assets/brands/zoominfo.avif +0 -0
  160. package/.agents/skills/hyperframes-animation/examples/brand-reveal-assemble-zoom.html +382 -0
  161. package/.agents/skills/hyperframes-animation/examples/comparison-split-cards.html +649 -0
  162. package/.agents/skills/hyperframes-animation/examples/concept-demo-decode-pan.html +520 -0
  163. package/.agents/skills/hyperframes-animation/examples/cta-morph-press.html +468 -0
  164. package/.agents/skills/hyperframes-animation/examples/cta-orbit-collapse.html +1298 -0
  165. package/.agents/skills/hyperframes-animation/examples/demo-page-scroll-spotlight.html +759 -0
  166. package/.agents/skills/hyperframes-animation/examples/hook-counter-burst.html +729 -0
  167. package/.agents/skills/hyperframes-animation/examples/messaging-multi-phrase.html +352 -0
  168. package/.agents/skills/hyperframes-animation/examples/metric-video-text-pivot.html +779 -0
  169. package/.agents/skills/hyperframes-animation/examples/problem-mockup-overwhelm.html +1374 -0
  170. package/.agents/skills/hyperframes-animation/examples/proof-logo-chain.html +861 -0
  171. package/.agents/skills/hyperframes-animation/examples/takeover-ticker-displace.html +347 -0
  172. package/.agents/skills/hyperframes-animation/examples/workflow-approve-press.html +606 -0
  173. package/.agents/skills/hyperframes-animation/rules/3d-page-scroll.md +227 -0
  174. package/.agents/skills/hyperframes-animation/rules/3d-text-depth-layers.md +297 -0
  175. package/.agents/skills/hyperframes-animation/rules/ai-tracking-box.md +382 -0
  176. package/.agents/skills/hyperframes-animation/rules/ambient-glow-bloom.md +305 -0
  177. package/.agents/skills/hyperframes-animation/rules/asr-keyword-glow.md +286 -0
  178. package/.agents/skills/hyperframes-animation/rules/avatar-cloud-network.md +371 -0
  179. package/.agents/skills/hyperframes-animation/rules/camera-cursor-tracking.md +246 -0
  180. package/.agents/skills/hyperframes-animation/rules/card-morph-anchor.md +267 -0
  181. package/.agents/skills/hyperframes-animation/rules/center-outward-expansion.md +227 -0
  182. package/.agents/skills/hyperframes-animation/rules/context-sensitive-cursor.md +257 -0
  183. package/.agents/skills/hyperframes-animation/rules/coordinate-target-zoom.md +332 -0
  184. package/.agents/skills/hyperframes-animation/rules/counting-dynamic-scale.md +283 -0
  185. package/.agents/skills/hyperframes-animation/rules/css-marker-patterns.md +373 -0
  186. package/.agents/skills/hyperframes-animation/rules/cursor-click-ripple.md +262 -0
  187. package/.agents/skills/hyperframes-animation/rules/depth-of-field-blur.md +313 -0
  188. package/.agents/skills/hyperframes-animation/rules/depth-scatter-assemble.md +303 -0
  189. package/.agents/skills/hyperframes-animation/rules/discrete-text-sequence.md +273 -0
  190. package/.agents/skills/hyperframes-animation/rules/dynamic-content-sequencing.md +307 -0
  191. package/.agents/skills/hyperframes-animation/rules/gsap-effects.md +299 -0
  192. package/.agents/skills/hyperframes-animation/rules/hacker-flip-3d.md +223 -0
  193. package/.agents/skills/hyperframes-animation/rules/kinetic-beat-slam.md +183 -0
  194. package/.agents/skills/hyperframes-animation/rules/motion-blur-streak.md +328 -0
  195. package/.agents/skills/hyperframes-animation/rules/multi-phase-camera.md +273 -0
  196. package/.agents/skills/hyperframes-animation/rules/orbit-3d-entry.md +301 -0
  197. package/.agents/skills/hyperframes-animation/rules/physics-press-reaction.md +350 -0
  198. package/.agents/skills/hyperframes-animation/rules/press-release-spring.md +296 -0
  199. package/.agents/skills/hyperframes-animation/rules/reactive-displacement.md +277 -0
  200. package/.agents/skills/hyperframes-animation/rules/scale-swap-transition.md +298 -0
  201. package/.agents/skills/hyperframes-animation/rules/sine-wave-loop.md +278 -0
  202. package/.agents/skills/hyperframes-animation/rules/split-tilt-cards.md +277 -0
  203. package/.agents/skills/hyperframes-animation/rules/spring-pop-entrance.md +273 -0
  204. package/.agents/skills/hyperframes-animation/rules/stat-bars-and-fills.md +156 -0
  205. package/.agents/skills/hyperframes-animation/rules/svg-icon-enrichment.md +329 -0
  206. package/.agents/skills/hyperframes-animation/rules/svg-path-draw.md +274 -0
  207. package/.agents/skills/hyperframes-animation/rules/vertical-spring-ticker.md +239 -0
  208. package/.agents/skills/hyperframes-animation/rules/viewport-change.md +349 -0
  209. package/.agents/skills/hyperframes-animation/rules-index.md +86 -0
  210. package/.agents/skills/hyperframes-animation/scripts/animation-map.mjs +606 -0
  211. package/.agents/skills/hyperframes-animation/scripts/package-loader.mjs +288 -0
  212. package/.agents/skills/hyperframes-animation/scripts/package-loader.test.mjs +62 -0
  213. package/.agents/skills/hyperframes-animation/techniques.md +507 -0
  214. package/.agents/skills/hyperframes-animation/transitions/TRANSITION-REGISTRY.md +167 -0
  215. package/.agents/skills/hyperframes-animation/transitions/catalog.md +127 -0
  216. package/.agents/skills/hyperframes-animation/transitions/css-3d.md +12 -0
  217. package/.agents/skills/hyperframes-animation/transitions/css-blur.md +51 -0
  218. package/.agents/skills/hyperframes-animation/transitions/css-cover.md +43 -0
  219. package/.agents/skills/hyperframes-animation/transitions/css-destruction.md +95 -0
  220. package/.agents/skills/hyperframes-animation/transitions/css-dissolve.md +66 -0
  221. package/.agents/skills/hyperframes-animation/transitions/css-distortion.md +45 -0
  222. package/.agents/skills/hyperframes-animation/transitions/css-grid.md +10 -0
  223. package/.agents/skills/hyperframes-animation/transitions/css-light.md +49 -0
  224. package/.agents/skills/hyperframes-animation/transitions/css-mechanical.md +30 -0
  225. package/.agents/skills/hyperframes-animation/transitions/css-other.md +25 -0
  226. package/.agents/skills/hyperframes-animation/transitions/css-push.md +41 -0
  227. package/.agents/skills/hyperframes-animation/transitions/css-radial.md +37 -0
  228. package/.agents/skills/hyperframes-animation/transitions/css-scale.md +24 -0
  229. package/.agents/skills/hyperframes-animation/transitions/overview.md +153 -0
  230. package/.agents/skills/hyperframes-cli/SKILL.md +113 -0
  231. package/.agents/skills/hyperframes-cli/references/doctor-browser.md +45 -0
  232. package/.agents/skills/hyperframes-cli/references/init-and-scaffold.md +55 -0
  233. package/.agents/skills/hyperframes-cli/references/lambda.md +132 -0
  234. package/.agents/skills/hyperframes-cli/references/lint-validate-inspect.md +121 -0
  235. package/.agents/skills/hyperframes-cli/references/preview-render.md +149 -0
  236. package/.agents/skills/hyperframes-cli/references/upgrade-info-misc.md +75 -0
  237. package/.agents/skills/hyperframes-core/SKILL.md +78 -0
  238. package/.agents/skills/hyperframes-core/references/composition-patterns.md +263 -0
  239. package/.agents/skills/hyperframes-core/references/data-attributes.md +70 -0
  240. package/.agents/skills/hyperframes-core/references/determinism-rules.md +68 -0
  241. package/.agents/skills/hyperframes-core/references/full-screen-motion.md +62 -0
  242. package/.agents/skills/hyperframes-core/references/minimal-composition.md +66 -0
  243. package/.agents/skills/hyperframes-core/references/script-format.md +49 -0
  244. package/.agents/skills/hyperframes-core/references/storyboard-format.md +95 -0
  245. package/.agents/skills/hyperframes-core/references/sub-compositions.md +237 -0
  246. package/.agents/skills/hyperframes-core/references/subagent-dispatch.md +41 -0
  247. package/.agents/skills/hyperframes-core/references/tailwind.md +125 -0
  248. package/.agents/skills/hyperframes-core/references/tracks-and-clips.md +76 -0
  249. package/.agents/skills/hyperframes-core/references/variables-and-media.md +90 -0
  250. package/.agents/skills/hyperframes-creative/SKILL.md +70 -0
  251. package/.agents/skills/hyperframes-creative/frame-presets/biennale-yellow/FRAME.md +289 -0
  252. package/.agents/skills/hyperframes-creative/frame-presets/biennale-yellow/caption-skin.html +221 -0
  253. package/.agents/skills/hyperframes-creative/frame-presets/biennale-yellow/frame-showcase.html +1214 -0
  254. package/.agents/skills/hyperframes-creative/frame-presets/blockframe/FRAME.md +275 -0
  255. package/.agents/skills/hyperframes-creative/frame-presets/blockframe/caption-skin.html +224 -0
  256. package/.agents/skills/hyperframes-creative/frame-presets/blockframe/frame-showcase.html +1347 -0
  257. package/.agents/skills/hyperframes-creative/frame-presets/blue-professional/FRAME.md +307 -0
  258. package/.agents/skills/hyperframes-creative/frame-presets/blue-professional/caption-skin.html +223 -0
  259. package/.agents/skills/hyperframes-creative/frame-presets/blue-professional/frame-showcase.html +1372 -0
  260. package/.agents/skills/hyperframes-creative/frame-presets/bold-poster/FRAME.md +275 -0
  261. package/.agents/skills/hyperframes-creative/frame-presets/bold-poster/caption-skin.html +230 -0
  262. package/.agents/skills/hyperframes-creative/frame-presets/bold-poster/frame-showcase.html +1140 -0
  263. package/.agents/skills/hyperframes-creative/frame-presets/broadside/FRAME.md +284 -0
  264. package/.agents/skills/hyperframes-creative/frame-presets/broadside/caption-skin.html +225 -0
  265. package/.agents/skills/hyperframes-creative/frame-presets/broadside/frame-showcase.html +1166 -0
  266. package/.agents/skills/hyperframes-creative/frame-presets/capsule/FRAME.md +284 -0
  267. package/.agents/skills/hyperframes-creative/frame-presets/capsule/caption-skin.html +224 -0
  268. package/.agents/skills/hyperframes-creative/frame-presets/capsule/frame-showcase.html +1465 -0
  269. package/.agents/skills/hyperframes-creative/frame-presets/cartesian/FRAME.md +278 -0
  270. package/.agents/skills/hyperframes-creative/frame-presets/cartesian/caption-skin.html +222 -0
  271. package/.agents/skills/hyperframes-creative/frame-presets/cartesian/frame-showcase.html +1263 -0
  272. package/.agents/skills/hyperframes-creative/frame-presets/claude/FRAME.md +277 -0
  273. package/.agents/skills/hyperframes-creative/frame-presets/claude/caption-skin.html +224 -0
  274. package/.agents/skills/hyperframes-creative/frame-presets/claude/frame-showcase.html +1439 -0
  275. package/.agents/skills/hyperframes-creative/frame-presets/cobalt-grid/FRAME.md +265 -0
  276. package/.agents/skills/hyperframes-creative/frame-presets/cobalt-grid/caption-skin.html +238 -0
  277. package/.agents/skills/hyperframes-creative/frame-presets/cobalt-grid/frame-showcase.html +1468 -0
  278. package/.agents/skills/hyperframes-creative/frame-presets/coral/FRAME.md +314 -0
  279. package/.agents/skills/hyperframes-creative/frame-presets/coral/caption-skin.html +226 -0
  280. package/.agents/skills/hyperframes-creative/frame-presets/coral/frame-showcase.html +1268 -0
  281. package/.agents/skills/hyperframes-creative/frame-presets/creative-mode/FRAME.md +333 -0
  282. package/.agents/skills/hyperframes-creative/frame-presets/creative-mode/caption-skin.html +227 -0
  283. package/.agents/skills/hyperframes-creative/frame-presets/creative-mode/frame-showcase.html +1330 -0
  284. package/.agents/skills/hyperframes-creative/frame-presets/daisy-days/FRAME.md +274 -0
  285. package/.agents/skills/hyperframes-creative/frame-presets/daisy-days/caption-skin.html +230 -0
  286. package/.agents/skills/hyperframes-creative/frame-presets/daisy-days/frame-showcase.html +1444 -0
  287. package/.agents/skills/hyperframes-creative/frame-presets/editorial-forest/FRAME.md +265 -0
  288. package/.agents/skills/hyperframes-creative/frame-presets/editorial-forest/caption-skin.html +223 -0
  289. package/.agents/skills/hyperframes-creative/frame-presets/editorial-forest/frame-showcase.html +1273 -0
  290. package/.agents/skills/hyperframes-creative/palettes/bold-energetic.md +14 -0
  291. package/.agents/skills/hyperframes-creative/palettes/clean-corporate.md +14 -0
  292. package/.agents/skills/hyperframes-creative/palettes/dark-premium.md +14 -0
  293. package/.agents/skills/hyperframes-creative/palettes/jewel-rich.md +14 -0
  294. package/.agents/skills/hyperframes-creative/palettes/monochrome.md +14 -0
  295. package/.agents/skills/hyperframes-creative/palettes/nature-earth.md +14 -0
  296. package/.agents/skills/hyperframes-creative/palettes/neon-electric.md +14 -0
  297. package/.agents/skills/hyperframes-creative/palettes/pastel-soft.md +14 -0
  298. package/.agents/skills/hyperframes-creative/palettes/warm-editorial.md +14 -0
  299. package/.agents/skills/hyperframes-creative/references/audio-reactive.md +76 -0
  300. package/.agents/skills/hyperframes-creative/references/beat-direction.md +164 -0
  301. package/.agents/skills/hyperframes-creative/references/composition-patterns.md +199 -0
  302. package/.agents/skills/hyperframes-creative/references/data-in-motion.md +19 -0
  303. package/.agents/skills/hyperframes-creative/references/design-adherence.md +19 -0
  304. package/.agents/skills/hyperframes-creative/references/design-picker.md +123 -0
  305. package/.agents/skills/hyperframes-creative/references/design-spec.md +55 -0
  306. package/.agents/skills/hyperframes-creative/references/house-style.md +73 -0
  307. package/.agents/skills/hyperframes-creative/references/motion-principles.md +150 -0
  308. package/.agents/skills/hyperframes-creative/references/narration.md +92 -0
  309. package/.agents/skills/hyperframes-creative/references/prompt-expansion.md +68 -0
  310. package/.agents/skills/hyperframes-creative/references/typography.md +218 -0
  311. package/.agents/skills/hyperframes-creative/references/video-composition.md +63 -0
  312. package/.agents/skills/hyperframes-creative/references/visual-styles.md +457 -0
  313. package/.agents/skills/hyperframes-creative/scripts/contrast-report.mjs +353 -0
  314. package/.agents/skills/hyperframes-creative/scripts/extract-audio-data.py +188 -0
  315. package/.agents/skills/hyperframes-creative/scripts/package-loader.mjs +288 -0
  316. package/.agents/skills/hyperframes-creative/scripts/package-loader.test.mjs +62 -0
  317. package/.agents/skills/hyperframes-creative/templates/design-picker.html +1432 -0
  318. package/.agents/skills/hyperframes-keyframes/SKILL.md +237 -0
  319. package/.agents/skills/hyperframes-keyframes/agents/openai.yaml +4 -0
  320. package/.agents/skills/hyperframes-keyframes/references/keyframe-patterns.md +106 -0
  321. package/.agents/skills/motion-graphics/SKILL.md +172 -0
  322. package/.agents/skills/motion-graphics/agents/builder.md +40 -0
  323. package/.agents/skills/motion-graphics/agents/director.md +53 -0
  324. package/.agents/skills/motion-graphics/agents/finalize.md +17 -0
  325. package/.agents/skills/motion-graphics/catalog-map.md +40 -0
  326. package/.agents/skills/motion-graphics/categories/asset-fusion/module.md +37 -0
  327. package/.agents/skills/motion-graphics/categories/charts/module.md +21 -0
  328. package/.agents/skills/motion-graphics/categories/kinetic-type/module.md +19 -0
  329. package/.agents/skills/motion-graphics/categories/logo-reveal/module.md +17 -0
  330. package/.agents/skills/motion-graphics/categories/lower-thirds/module.md +16 -0
  331. package/.agents/skills/motion-graphics/categories/maps/bake-basemap.mjs +273 -0
  332. package/.agents/skills/motion-graphics/categories/maps/module.md +61 -0
  333. package/.agents/skills/motion-graphics/categories/news/module.md +56 -0
  334. package/.agents/skills/motion-graphics/categories/stat/module.md +21 -0
  335. package/.agents/skills/motion-graphics/categories/tweet/module.md +16 -0
  336. package/.agents/skills/motion-graphics/categories/webpage/module.md +21 -0
  337. package/.agents/skills/motion-graphics/grounding/PROTOCOL.md +64 -0
  338. package/.agents/skills/motion-graphics/grounding/locate.mjs +227 -0
  339. package/.agents/skills/motion-graphics/phases/source/guide.md +21 -0
  340. package/.agents/skills/motion-graphics/references/builder-contract.md +38 -0
  341. package/.agents/skills/motion-graphics/references/motion-vocabulary.md +43 -0
  342. package/.agents/skills/motion-graphics/references/shot-plan-ir.md +54 -0
  343. package/.agents/skills/motion-graphics/samples/asset-fusion/_ref-circle-highlight.html +306 -0
  344. package/.agents/skills/product-launch-video/SKILL.md +208 -0
  345. package/.agents/skills/product-launch-video/references/cut-catalog.md +220 -0
  346. package/.agents/skills/product-launch-video/references/motion-language.md +156 -0
  347. package/.agents/skills/product-launch-video/references/story-design.md +373 -0
  348. package/.agents/skills/product-launch-video/references/visual-design.md +126 -0
  349. package/.agents/skills/product-launch-video/scripts/assemble-index.mjs +570 -0
  350. package/.agents/skills/product-launch-video/scripts/audio.mjs +260 -0
  351. package/.agents/skills/product-launch-video/scripts/build-frame.mjs +536 -0
  352. package/.agents/skills/product-launch-video/scripts/captions.mjs +508 -0
  353. package/.agents/skills/product-launch-video/scripts/lib/assets.mjs +55 -0
  354. package/.agents/skills/product-launch-video/scripts/lib/dimensions.mjs +45 -0
  355. package/.agents/skills/product-launch-video/scripts/lib/pad-frame-duration.mjs +36 -0
  356. package/.agents/skills/product-launch-video/scripts/lib/pad-frame-duration.test.mjs +76 -0
  357. package/.agents/skills/product-launch-video/scripts/lib/storyboard.mjs +249 -0
  358. package/.agents/skills/product-launch-video/scripts/lib/tokens.mjs +204 -0
  359. package/.agents/skills/product-launch-video/scripts/lib/transition-registry.mjs +38 -0
  360. package/.agents/skills/product-launch-video/scripts/lib/transitions.json +71 -0
  361. package/.agents/skills/product-launch-video/scripts/stage-assets.mjs +39 -0
  362. package/.agents/skills/product-launch-video/scripts/transitions.mjs +327 -0
  363. package/.agents/skills/product-launch-video/sub-agents/frame-worker.md +75 -0
  364. package/.agents/skills/slideshow/SKILL.md +550 -0
  365. package/.agents/skills/slideshow/references/standalone-harness.md +1020 -0
  366. package/.agents/skills/talking-head-recut/NOTICE.md +39 -0
  367. package/.agents/skills/talking-head-recut/SKILL.md +1195 -0
  368. package/.agents/skills/talking-head-recut/assets/vendor/gsap.min.js +10 -0
  369. package/.agents/skills/talking-head-recut/references/DESIGN_INDEX.md +145 -0
  370. package/.agents/skills/talking-head-recut/references/frames/clean.html +92 -0
  371. package/.agents/skills/talking-head-recut/references/frames/hairline.html +171 -0
  372. package/.agents/skills/talking-head-recut/references/frames/polaroid.html +131 -0
  373. package/.agents/skills/talking-head-recut/references/layouts/overlay.html +164 -0
  374. package/.agents/skills/talking-head-recut/references/layouts/pip.html +143 -0
  375. package/.agents/skills/talking-head-recut/references/layouts/split.html +121 -0
  376. package/.agents/skills/talking-head-recut/references/layouts/stack.html +109 -0
  377. package/.agents/skills/talking-head-recut/references/styles/academic.html +172 -0
  378. package/.agents/skills/talking-head-recut/references/styles/audit.html +170 -0
  379. package/.agents/skills/talking-head-recut/references/styles/editorial.html +189 -0
  380. package/.agents/skills/talking-head-recut/references/styles/geom.html +181 -0
  381. package/.agents/skills/talking-head-recut/references/styles/minimal.html +130 -0
  382. package/.agents/skills/talking-head-recut/references/styles/spotlight.html +142 -0
  383. package/.agents/skills/talking-head-recut/references/styles/swiss.html +188 -0
  384. package/.agents/skills/talking-head-recut/references/styles/terminal.html +196 -0
  385. package/.agents/skills/talking-head-recut/references/styles/whiteboard.html +170 -0
  386. package/.agents/skills/talking-head-recut/references/styles/xhs.html +206 -0
  387. package/.agents/skills/vidfarm-media/SKILL.md +85 -0
  388. package/.agents/skills/vidfarm-media/references/tts.md +54 -0
  389. package/.agents/skills/vidfarm-media/scripts/audio.mjs +628 -0
  390. package/.agents/skills/vidfarm-media/scripts/wait-bgm.mjs +31 -0
  391. package/.agents/skills/website-to-video/SKILL.md +145 -0
  392. package/.agents/skills/website-to-video/assets/sfx/CREDITS.md +35 -0
  393. package/.agents/skills/website-to-video/assets/sfx/manifest.json +97 -0
  394. package/.agents/skills/website-to-video/references/beat-builder-guide.md +263 -0
  395. package/.agents/skills/website-to-video/references/capabilities.md +713 -0
  396. package/.agents/skills/website-to-video/references/step-0-capture.md +55 -0
  397. package/.agents/skills/website-to-video/references/step-1-design.md +333 -0
  398. package/.agents/skills/website-to-video/references/step-2-brief.md +178 -0
  399. package/.agents/skills/website-to-video/references/step-3-storyboard.md +572 -0
  400. package/.agents/skills/website-to-video/references/step-4-vo.md +225 -0
  401. package/.agents/skills/website-to-video/references/step-5-build.md +483 -0
  402. package/.agents/skills/website-to-video/references/step-6-validate.md +341 -0
  403. package/.agents/skills/website-to-video/scripts/w2h-verify.mjs +759 -0
  404. package/SKILL.director.md +37 -0
  405. package/SKILL.platform.md +6 -1
  406. package/demo/dist/app.js +295 -11
  407. package/dist/src/app.js +317 -133
  408. package/dist/src/cli.js +529 -12
  409. package/dist/src/composition-runtime.js +262 -3
  410. package/dist/src/devcli/doctor.js +192 -0
  411. package/dist/src/devcli/hyperframes-cli.js +118 -0
  412. package/dist/src/devcli/skills.js +476 -0
  413. package/dist/src/devcli/stills.js +249 -0
  414. package/dist/src/editor-chat.js +255 -0
  415. package/dist/src/hyperframes/composition.js +5 -5
  416. package/dist/src/services/composition-lint.js +199 -0
  417. package/dist/src/services/hyperframes.js +67 -13
  418. package/package.json +2 -1
package/SKILL.director.md CHANGED
@@ -550,6 +550,14 @@ Send a stable `tracer` on export so retries are traceable and filterable in job
550
550
  | `vidfarm clips scan --cloud <video\|--url <url>> [--tracer <id>]` | temp-file presign/PUT/finalize + `POST /clips/scan` + poll | BACKUP: run the hunt on the deployed pipeline (bills AWS compute only) |
551
551
  | `vidfarm clips search "…"` / `clips match "…"` / `clips list` / `clips sources` | (local library; NL→criteria via local agent or provider key) | search/reuse the clip library |
552
552
  | `vidfarm clips preset list\|run\|save` / `clips export <ids…> --to <dir>` | (local library) | saved queries; copy clip MP4s out |
553
+ | `vidfarm lint <dir\|composition.html>` | (local static validation) | pre-publish composition check: timing, overlaps, preset names, media src |
554
+ | `vidfarm stills <dir> [--at 0,2.5,…]` | (local in-process render of PNG frames) | visually verify an edit without a full render |
555
+ | `vidfarm doctor` | (local environment triage) | check ffmpeg/node/keys/agent CLI/poisoned env before debugging anything else |
556
+ | `vidfarm skills list\|add <name>\|update` | `GET /skill-pack/index.json` · `/skill-pack/:name/*` | install/refresh skill packs (see "Skill packs — import on demand") |
557
+ | `vidfarm tts "…" --engine local` / `vidfarm stt <file> --engine whisper` | (keyless LOCAL engines: Kokoro-82M TTS, whisper.cpp STT) | narration + word-timestamp transcripts with zero keys and zero accounts |
558
+ | `vidfarm remove-background <video\|image>` | (local ONNX matting — free) | transparent-subject media for occlusion captions/cutouts |
559
+ | `vidfarm capture <url>` | (local headless-Chrome capture) | website screenshots/assets for website-to-video flows |
560
+ | `vidfarm beats <audio>` | (local beat detection → JSON) | music beat timestamps to sync cuts/transitions/captions |
553
561
 
554
562
  **Frontend URLs are first-class output.** Every command that has a human-openable page (editor, discover, approved-post preview, share link) prints that prod frontend URL as a highlighted line. `render --wait` polls to completion and prints the final MP4 URL; `approve` prints the approved-post `share_url`. Add `--json` to any command for pure JSON (agent-friendly, no banners).
555
563
 
@@ -611,6 +619,35 @@ Flags: `--port` (default 3000), `--dir` (default `./.vidfarm-local`), `--key` (b
611
619
 
612
620
  To *analyze* the source media locally (videos, transcript, recurring cast), read the `video-context.json` / `cast.json` routes, or pull a media URL with `vidfarm download <url>`.
613
621
 
622
+ ## Skill packs — import on demand (HyperFrames-grade authoring power)
623
+
624
+ This skill stays lean on purpose. Deep authoring craft lives in **skill packs** — vidfarm-scrubbed snapshots of the HyperFrames skill suite plus vidfarm's own media pack — vendored on the Vidfarm host and installed only when a task needs them. Never install skills from upstream vendor orgs or third-party registries; the vidfarm mirror is the source (`vidfarm skills add <name>` fetches `GET /skill-pack/:name/*` with hash verification into `.agents/skills/` + a `.claude/skills/` link, pinned in `skills-lock.json`; `vidfarm skills list` shows what is available/installed; `vidfarm skills update` refreshes pins).
625
+
626
+ Import by task:
627
+
628
+ | When the task needs… | Install |
629
+ |---|---|
630
+ | the raw composition HTML contract (data-* attrs, tracks, clips, sub-compositions, determinism rules) | `vidfarm skills add hyperframes-core` |
631
+ | motion design: animation rules, multi-phase scene blueprints, transition doctrine, runtime adapters (GSAP/Lottie/Three/Anime/CSS/WAAPI/TypeGPU) | `vidfarm skills add hyperframes-animation` |
632
+ | seek-safe keyframe patterns (FLIP, paths, masks, SVG draw/morph, 3D depth) | `vidfarm skills add hyperframes-keyframes` |
633
+ | creative direction: design specs, palettes, typography, house style, narration craft | `vidfarm skills add hyperframes-creative` |
634
+ | the HyperFrames CLI dev loop (init/lint/validate/inspect/snapshot/preview/render) | `vidfarm skills add hyperframes-cli` |
635
+ | narration/BGM/SFX/media resolution (the shared audio engine) | `vidfarm skills add vidfarm-media` |
636
+ | embedded/cinematic captions with subject occlusion (32-identity catalog) | `vidfarm skills add embedded-captions` |
637
+ | graphic overlay cards on existing talking-head footage | `vidfarm skills add talking-head-recut` |
638
+ | a product launch/promo video end-to-end | `vidfarm skills add product-launch-video` |
639
+ | a faceless topic explainer end-to-end | `vidfarm skills add faceless-explainer` |
640
+ | a website tour/showcase video end-to-end | `vidfarm skills add website-to-video` |
641
+ | a short motion graphic (kinetic type, stat hit, logo sting, lower-third) | `vidfarm skills add motion-graphics` |
642
+ | an interactive slideshow/deck | `vidfarm skills add slideshow` |
643
+ | any other multi-scene composition (fallback workflow) | `vidfarm skills add general-video` |
644
+
645
+ Ground rules:
646
+
647
+ - **Local coding agents** (Claude Code / Codex on a `vidfarm serve` box or a pulled fork) get the FULL packs — install, read, and follow them. Scripted/GSAP compositions authored this way render correctly through `vidfarm render` (local and cloud); note that the **web editor strips `<script>` on save**, so keep compositions that must round-trip through the browser editor declarative (the built-in Ken Burns / transitions / animated-captions vocabulary).
648
+ - **The web copilot** never installs packs — it has a `load_skill` tool that reads the same content on demand from the vidfarm mirror. Nothing to do there; it is already wired.
649
+ - Vidfarm-managed environments set `HYPERFRAMES_SKIP_SKILLS=1` and `HYPERFRAMES_NO_TELEMETRY=1`, so `npx hyperframes init` never overwrites the vidfarm-scrubbed packs and the bundled CLI never phones home. Do not run `hyperframes auth`, `hyperframes cloud`, `hyperframes publish`, `hyperframes play`, or `hyperframes feedback` — vidfarm's own render/share/telemetry surfaces cover all of them.
650
+
614
651
  ## What NOT to do
615
652
 
616
653
  - Do **not** manipulate composition HTML by string concatenation. Always parse, edit, and re-serialize the DOM. The editor and runtime rely on `data-start`, `data-duration`, `data-track-index`, `data-hf-id`, `data-composition-id` attributes being well-formed.
package/SKILL.platform.md CHANGED
@@ -266,7 +266,7 @@ Configuration: `GHOSTCUT_KEY` and `GHOSTCUT_SECRET` env vars per stage. Pass-thr
266
266
 
267
267
  The chat model uses the **caller's provider keys**. No Vidfarm-owned model calls happen in this path.
268
268
 
269
- Beyond the Editor Action API, the chat harness registers shared tools defined in **two synced copies** (`src/app.ts` for the in-process dev server and `infra/lambda/editor-chat.ts` for the deployed Lambda — keep them in lockstep): `http_request` (allowlisted REST/primitive calls), `frontend_action` (tracer/thread state), `video_context`, and `browse_files`. `browse_files` reads **and writes** the caller's My Files library — `action=list`/`search`/`read`/`write`/`annotate`. `write` saves a text file (md/txt/csv/json/srt/vtt) via `POST /me/attachments/upload`, or **imports a durable media URL** into the library when `source_url` is passed (how a generated `character_sprite_card.png` gets persisted instead of stranding in a job result). `annotate` sets free-form metadata `notes` on any entry (`PATCH /me/attachments/:id`); notes are **vector-embedded server-side** (BYOK, same gemini→openai auto-pick seam as clip search; no key fail-softs to keyword-only) and `search` runs the hybrid keyword+semantic lookup over every file's name/folder/notes via `POST /me/attachments/search` — the My Files mirror of `/clips/search`. Write+annotate are what let the copilot persist Getting Started context (About.md, awareness-levels.md, persuasive-angles.md, ad-hooks.md) and character-consistency pairs (`about_character.md` + `character_sprite_card.png`) namescoped under a product/offer folder; the system prompt in `src/editor-chat.ts` drives when to save and annotate. The devcli mirrors are `vidfarm put-file [--notes]`, `annotate-file`, and `files --search`.
269
+ Beyond the Editor Action API, the chat harness registers shared tools defined in **two synced copies** (`src/app.ts` for the in-process dev server and `infra/lambda/editor-chat.ts` for the deployed Lambda — keep them in lockstep): `http_request` (allowlisted REST/primitive calls), `frontend_action` (tracer/thread state), `video_context`, `load_skill`, and `browse_files`. `load_skill` is the copilot's knowledge-on-demand seam: it fetches vendored skill-pack content (SKILL.md or a reference file) from the host's public `/skill/:name` + `/skill-pack/:name/files/*` mirror routes (backed by `.agents/skills/`, shipped in the api Docker image), size-capped, with the pack catalog + one-liners defined once in `EDITOR_CHAT_SKILL_PACKS` (`src/editor-chat.ts`) and shared by both copies. The stream-loop guardrails (`redactUnverifiedJobIds`, `buildEditorChatGuardrailNotice`, async-job handoff text) also live in `src/editor-chat.ts` and are imported by both copies — never re-implement them locally. `editor_action`'s `replace_composition_html` is lint-gated in the tool `execute` via `src/services/composition-lint.ts` (a rejected result carries `rejected: true` + `lint_errors` and omits `action_type`, so the browser never applies it). `browse_files` reads **and writes** the caller's My Files library — `action=list`/`search`/`read`/`write`/`annotate`. `write` saves a text file (md/txt/csv/json/srt/vtt) via `POST /me/attachments/upload`, or **imports a durable media URL** into the library when `source_url` is passed (how a generated `character_sprite_card.png` gets persisted instead of stranding in a job result). `annotate` sets free-form metadata `notes` on any entry (`PATCH /me/attachments/:id`); notes are **vector-embedded server-side** (BYOK, same gemini→openai auto-pick seam as clip search; no key fail-softs to keyword-only) and `search` runs the hybrid keyword+semantic lookup over every file's name/folder/notes via `POST /me/attachments/search` — the My Files mirror of `/clips/search`. Write+annotate are what let the copilot persist Getting Started context (About.md, awareness-levels.md, persuasive-angles.md, ad-hooks.md) and character-consistency pairs (`about_character.md` + `character_sprite_card.png`) namescoped under a product/offer folder; the system prompt in `src/editor-chat.ts` drives when to save and annotate. The devcli mirrors are `vidfarm put-file [--notes]`, `annotate-file`, and `files --search`.
270
270
 
271
271
  ## Primitives
272
272
 
@@ -322,9 +322,14 @@ Per-stage config is loaded via `.env.<stage>`. Critical variables:
322
322
  - `GHOSTCUT_KEY`, `GHOSTCUT_SECRET` — GhostCut credentials
323
323
  - `RAPIDAPI_KEY` — shared RapidAPI credential used by the `video_download` and `image_remove_background` primitives. Same key is set in both `.env.staging` and `.env.production`.
324
324
  - Provider fallback keys for platform-owned features that don't have a caller yet (bootstrap only)
325
+ - `HYPERFRAMES_NO_TELEMETRY=1` + `HYPERFRAMES_SKIP_SKILLS=1` — baked into every vidfarm-managed environment (api Docker image, CDK `hyperframesLambdaEnvironment`, devcli serve/spawns). The bundled hyperframes CLI defaults telemetry ON and auto-refreshes skills from its upstream GitHub org; these kill both. Never unset them, and never run `hyperframes auth`/`cloud`/`publish`/`play`/`feedback` — those are third-party account/hosting surfaces vidfarm replaces.
325
326
 
326
327
  Never commit `.env.staging` or `.env.production` — both are gitignored.
327
328
 
329
+ ## Skill packs (vendored mirror)
330
+
331
+ `.agents/skills/` holds the vidfarm-scrubbed skill packs (the HyperFrames suite with every upstream-vendor dependency replaced by vidfarm primitives, plus `vidfarm-media` — the shared audio engine implementing the neutral `audio_request.json` → `audio_engine_meta.json` contract). `.claude/skills/*` are symlinks into it. The api serves the packs publicly: `GET /skill/:name` (SKILL.md), `GET /skill-pack/index.json` (catalog), `GET /skill-pack/:name/manifest.json` (file list + sha256), `GET /skill-pack/:name/files/<path>` (bytes, path-guarded) — `src/app.ts` next to `PUBLIC_SKILL_FILES`. Consumers: `vidfarm skills list|add|update` (devcli installer, writes `skills-lock.json` with reproducible folder hashes) and the web copilot's `load_skill` tool. When editing a pack, edit `.agents/skills/<name>` directly (the canonical copy), keep it free of upstream vendor accounts/endpoints, and re-run `vidfarm skills update`-side hash pinning as needed.
332
+
328
333
  ## Deployment
329
334
 
330
335
  CDK stacks are under `infra/cdk/`:
package/demo/dist/app.js CHANGED
@@ -704,7 +704,8 @@ for myself`,y:43},{text:`1/10 when I chose
704
704
  myself`,y:22}];return[...U1(t,e,r.map((o,i)=>`${10-i}/10 scene`)),{id:`${t.id}-audio`,label:"Original audio",kind:"audio",mode:"both",start:0,duration:t.duration,track:1,z:1,viralNote:"Continuous source audio across scene cuts.",src:t.media.src,playbackStart:0,volume:1,muted:!1},...r.map((o,i)=>({...n,id:`${t.id}-caption-${10-i}`,label:`${10-i}/10 caption`,text:o.text,start:e[i],duration:e[i+1]-e[i],y:o.y}))]}function WX(t){if(t.media.type!=="video")return[];let e=T6(t.media.src);return[{id:`${t.id}-video`,label:e,kind:"video",mode:"both",start:0,duration:t.duration,track:0,z:0,viralNote:"Editable source visual track.",src:t.media.src},{id:`${t.id}-audio`,label:"Original audio",kind:"audio",mode:"both",start:0,duration:t.duration,track:1,z:1,viralNote:"Editable source audio track.",src:t.media.src,volume:1,muted:!1}]}function B1(t){return t.id==="slides"?GX():t.id==="simple-video"?qm.filter(e=>e.mode==="both"||e.mode==="publish"):t.id==="hard-video"?$X(t):t.id==="medium-easy-video"?qX(t):t.id==="medium-video-loop-split"?jX(t):t.id==="medium-video"?VX(t):WX(t)}function w6(t){return B1(t).reduce((e,n)=>Math.max(e,n.start+n.duration),t.duration)}function YX(t){let e=t.filter(n=>n.duration>0);for(let n=0;n<e.length;n+=1){let r=e[n];for(let o of e.slice(n+1))if(Yd(r,o))throw new Error(`Track collision: ${r.id} overlaps ${o.id} on track ${r.track}.`)}}function x6(t){return t.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;")}function He(t){return x6(String(t))}function Vt(t){return Number(t.toFixed(3)).toString()}function Lm(t){let e=t.fontSize??18,n=t.fontFamily??"TikTok Sans",r=t.fontWeight??Fs(n),o=["position:absolute",`left:${t.x??0}%`,`top:${t.y??0}%`,`width:${t.width??100}%`,`height:${t.height??100}%`,`z-index:${t.z}`,"opacity:1",`border-radius:${t.radius??0}px`,"overflow:hidden"];return(t.kind==="video"||t.kind==="image")&&o.push("object-fit:cover"),(t.kind==="text"||t.kind==="caption"||t.kind==="shape")&&o.push("display:flex","align-items:center","justify-content:center","padding:3px",`font-family:${zs(n)}, 'TikTok Sans', Montserrat, Abel`,`font-weight:${r}`,"line-height:1.48","text-align:center","text-transform:none",`font-size:${e}px`,`color:${t.color??"#ffffff"}`,"background:transparent"),o.join(";")}function KX(t){let e=[`id="${He(t.id)}"`,`data-hf-id="${He(t.id)}"`,`data-layer-mode="${He(t.mode)}"`,`data-layer-kind="${He(t.kind)}"`,`data-viral-note="${He(t.viralNote)}"`,`data-start="${Vt(t.start)}"`,`data-duration="${Vt(t.duration)}"`,`data-track-index="${t.track}"`,`data-label="${He(t.label)}"`];return(t.kind==="text"||t.kind==="caption"||t.kind==="shape")&&e.push(`data-text-background-style="${He(t.textBackgroundStyle??"highlight-solid")}"`,`data-text-background-color="${He(t.background??"#000000")}"`,`data-font-family="${He(t.fontFamily??"TikTok Sans")}"`),t.customHtml&&e.push('data-layer-format="html"'),(t.kind==="video"||t.kind==="audio")&&t.playbackStart!==void 0&&e.push(`data-media-start="${Vt(t.playbackStart)}"`,`data-playback-start="${Vt(t.playbackStart)}"`),e.join(" ")}function XX(t){let e=KX(t);if(t.kind==="video")return t.playbackStart!==void 0?`<div ${e} data-vf-timeline-proxy="video" data-src="${He(t.src??"")}" style="${He(Lm({...t,x:0,y:0,width:1,height:1}))};display:none;pointer-events:none;"></div>`:`<video ${e} src="${He(t.src??"")}" muted playsinline preload="auto" style="${He(Lm(t))}"></video>`;if(t.kind==="audio")return`<audio ${e} src="${He(t.src??"")}" data-timeline-role="music" data-volume="${Vt(t.volume??1)}" ${t.muted?"muted":""} preload="metadata"></audio>`;if(t.kind==="image")return`<img ${e} src="${He(t.src??"")}" alt="" style="${He(Lm(t))}" />`;if(t.customHtml)return`<div ${e} style="${He(Lm(t))}">${t.customHtml}</div>`;let n=t.text??t.label,r=S6(t.textBackgroundStyle??"highlight-solid",t.color??"#ffffff",t.background??"#000000",t.fontFamily??"TikTok Sans",t.fontWeight??Fs(t.fontFamily??"TikTok Sans")),o=E6(t.textBackgroundStyle??"highlight-solid");return`<div ${e} style="${He(Lm(t))}"><span data-vf-text-lines="true" style="${He(o)}"><span data-vf-text-inline="true" style="${He(r)}">${x6(n)}</span></span></div>`}function JX(t,e){return t==="shape"&&e?"HTML":t}function QX(t,e){return t==="shape"&&e?"HTML":t.slice(0,3).toUpperCase()}function ZX(t,e){if(t.media.type!=="video"||!e.some(o=>o.kind==="video"&&o.playbackStart!==void 0))return"";let r=["position:absolute","left:0%","top:0%","width:100%","height:100%","z-index:0","object-fit:cover","background:#050604"].join(";");return`<video data-vf-playback-source="true" src="${He(t.media.src)}" muted playsinline preload="auto" style="${He(r)}"></video>`}function A6(){return`<script>
705
705
  (() => {
706
706
  const root = document.querySelector("[data-composition-id]");
707
- let duration = Number(root?.getAttribute("data-duration") || 0);
707
+ let declaredDuration = Number(root?.getAttribute("data-duration") || 0);
708
+ let duration = declaredDuration;
708
709
  let time = 0;
709
710
  let playing = false;
710
711
  let playbackRate = 1;
@@ -752,8 +753,8 @@ myself`,y:22}];return[...U1(t,e,r.map((o,i)=>`${10-i}/10 scene`)),{id:`${t.id}-a
752
753
  // The parent editor can live-swap the composition DOM (undo/redo). Re-read
753
754
  // everything derivable from the document so a swap never leaves the player
754
755
  // clamped to a stale duration or a stale authored-mute state.
755
- duration = Number(root?.getAttribute("data-duration") || 0);
756
- time = clampTime(time);
756
+ declaredDuration = Number(root?.getAttribute("data-duration") || 0);
757
+ duration = declaredDuration;
757
758
  clips = Array.from(document.querySelectorAll("[data-start]")).filter((node) => node !== root);
758
759
  for (const clip of clips) {
759
760
  if (clip instanceof HTMLMediaElement) {
@@ -776,6 +777,9 @@ myself`,y:22}];return[...U1(t,e,r.map((o,i)=>`${10-i}/10 scene`)),{id:`${t.id}-a
776
777
  activeVideoProxyKey = null;
777
778
  activeVideoProxyNode = null;
778
779
  hasVideoProxies = clips.some((clip) => clip instanceof Element && clip.getAttribute("data-vf-timeline-proxy") === "video");
780
+ ensureDuration();
781
+ time = clampTime(time);
782
+ discoverGeneralCssAnimations();
779
783
  apply(time, { forceSeek: true });
780
784
  }
781
785
 
@@ -848,6 +852,130 @@ myself`,y:22}];return[...U1(t,e,r.map((o,i)=>`${10-i}/10 scene`)),{id:`${t.id}-a
848
852
  }
849
853
  }
850
854
 
855
+ // Runtime-adapter bridge \u2014 mirrors the official @hyperframes/producer
856
+ // deterministic adapters so compositions driven by a registered GSAP
857
+ // timeline (window.__timelines), Anime.js (window.__hfAnime), Lottie
858
+ // (window.__hfLottie), or Three.js/TypeGPU (window.__hfThreeTime/
859
+ // __hfTypegpuTime + the hf-seek CustomEvent) scrub with the player instead
860
+ // of running on the wall clock. Everything is duck-typed and try/caught so
861
+ // a broken composition script never kills the apply loop.
862
+ function compositionTimeline() {
863
+ let registry = null;
864
+ try { registry = window.__timelines; } catch { return null; }
865
+ if (!registry || typeof registry !== "object") return null;
866
+ const compId = root?.getAttribute("data-composition-id") || "";
867
+ let timeline = compId ? registry[compId] : null;
868
+ if (!timeline) {
869
+ const keys = Object.keys(registry);
870
+ if (keys.length === 1) timeline = registry[keys[0]];
871
+ }
872
+ if (!timeline || typeof timeline.pause !== "function") return null;
873
+ if (typeof timeline.totalTime !== "function" && typeof timeline.seek !== "function") return null;
874
+ return timeline;
875
+ }
876
+
877
+ function timelineDuration(timeline) {
878
+ try {
879
+ const value = typeof timeline.duration === "function" ? Number(timeline.duration()) : Number(timeline.duration);
880
+ if (Number.isFinite(value) && value > 0) return value;
881
+ } catch {}
882
+ return 0;
883
+ }
884
+
885
+ function syncTimeline() {
886
+ const timeline = compositionTimeline();
887
+ if (!timeline) return;
888
+ try {
889
+ timeline.pause();
890
+ // Official gsap adapter seek: nudge to time+1ms with suppressed events,
891
+ // then land exactly, so gsap re-renders even when the target equals the
892
+ // timeline's current time.
893
+ if (typeof timeline.totalTime === "function") {
894
+ timeline.totalTime(time + 0.001, true);
895
+ timeline.totalTime(time, false);
896
+ } else {
897
+ timeline.seek(time, false);
898
+ }
899
+ } catch {}
900
+ }
901
+
902
+ function syncAnimeInstances() {
903
+ let instances = null;
904
+ try { instances = window.__hfAnime; } catch { return; }
905
+ if (!Array.isArray(instances) || instances.length === 0) return;
906
+ const ms = Math.max(0, time) * 1000;
907
+ for (const instance of instances) {
908
+ try {
909
+ if (instance && typeof instance.seek === "function") instance.seek(ms);
910
+ } catch {}
911
+ }
912
+ }
913
+
914
+ function syncLottiePlayers() {
915
+ let players = null;
916
+ try { players = window.__hfLottie; } catch { return; }
917
+ if (!Array.isArray(players) || players.length === 0) return;
918
+ const safe = Math.max(0, time);
919
+ for (const player of players) {
920
+ try {
921
+ if (!player || typeof player !== "object") continue;
922
+ if (typeof player.goToAndStop === "function") {
923
+ player.goToAndStop(safe * 1000, false);
924
+ } else if (typeof player.pause === "function" && ("totalFrames" in player || "duration" in player)) {
925
+ if (typeof player.setCurrentRawFrameValue === "function") {
926
+ const totalFrames = player.totalFrames ?? 0;
927
+ const frameRate = player.frameRate ?? 30;
928
+ if (totalFrames > 0) player.setCurrentRawFrameValue(Math.min(safe * frameRate, totalFrames - 1));
929
+ } else if (typeof player.seek === "function") {
930
+ player.seek(Math.min(100, (safe / (player.duration ?? 1)) * 100));
931
+ }
932
+ }
933
+ } catch {}
934
+ }
935
+ }
936
+
937
+ let lastDispatchedSeekTime = -1;
938
+ function syncSeekGlobals() {
939
+ const safe = Math.max(0, time);
940
+ try { window.__hfThreeTime = safe; } catch {}
941
+ try { window.__hfTypegpuTime = safe; } catch {}
942
+ // The official three/typegpu adapters dedupe the hf-seek dispatch on the
943
+ // last dispatched time.
944
+ if (safe === lastDispatchedSeekTime) return;
945
+ lastDispatchedSeekTime = safe;
946
+ try { window.dispatchEvent(new CustomEvent("hf-seek", { detail: { time: safe } })); } catch {}
947
+ }
948
+
949
+ function syncRuntimeAdapters() {
950
+ syncTimeline();
951
+ syncAnimeInstances();
952
+ syncLottiePlayers();
953
+ syncSeekGlobals();
954
+ }
955
+
956
+ // data-duration on the root is authoritative when present. Arbitrary
957
+ // compositions may omit it, so infer the duration from clip extents,
958
+ // preferring a registered GSAP timeline that reports a longer duration.
959
+ // Recomputed on every apply so a timeline registered after load still
960
+ // corrects the duration (and seek clamping) lazily.
961
+ function ensureDuration() {
962
+ if (declaredDuration > 0) {
963
+ duration = declaredDuration;
964
+ return;
965
+ }
966
+ let inferred = 0;
967
+ for (const clip of clips) {
968
+ const timing = readTiming(clip);
969
+ if (timing.end > inferred) inferred = timing.end;
970
+ }
971
+ const timeline = compositionTimeline();
972
+ if (timeline) {
973
+ const reported = timelineDuration(timeline);
974
+ if (reported > inferred) inferred = reported;
975
+ }
976
+ duration = inferred;
977
+ }
978
+
851
979
  function deriveTimelineTimeFromBackingVideo() {
852
980
  if (!(backingVideo instanceof HTMLVideoElement)) return null;
853
981
  if (activeVideoProxyNode instanceof Element && !activeVideoProxyNode.isConnected) {
@@ -1017,19 +1145,138 @@ myself`,y:22}];return[...U1(t,e,r.map((o,i)=>`${10-i}/10 scene`)),{id:`${t.id}-a
1017
1145
  }
1018
1146
  }
1019
1147
 
1148
+ // Generalized CSS keyframe scrub \u2014 the preview twin of the official
1149
+ // producer CSS adapter: every element whose computed animation-name is set
1150
+ // gets its animations paused and scrubbed to the player time relative to
1151
+ // the nearest ancestor-or-self [data-start] (0 when none). vf-* animations
1152
+ // (Ken Burns, transitions, captions) keep their dedicated machinery above.
1153
+ // Discovery is cached per refreshClips like the official adapter's discover
1154
+ // pass; elements added by live patches are picked up on the next refresh.
1155
+ // Each entry also caches its clip-relative start at discovery so the
1156
+ // per-frame sync skips the ancestor walk; a re-parented or retimed element
1157
+ // is likewise re-resolved on the next refreshClips discovery.
1158
+ let generalCssEntries = [];
1159
+
1160
+ function discoverGeneralCssAnimations() {
1161
+ generalCssEntries = [];
1162
+ let nodes = [];
1163
+ try { nodes = document.querySelectorAll("*"); } catch { return; }
1164
+ for (const node of nodes) {
1165
+ if (!(node instanceof HTMLElement) || typeof node.getAnimations !== "function") continue;
1166
+ let names = "";
1167
+ try { names = getComputedStyle(node).animationName || ""; } catch { continue; }
1168
+ if (!names || names === "none") continue;
1169
+ const expected = [];
1170
+ for (const name of names.split(",")) {
1171
+ const trimmed = name.trim();
1172
+ if (!trimmed || trimmed === "none" || trimmed.indexOf("vf-") === 0) continue;
1173
+ expected.push(trimmed);
1174
+ }
1175
+ if (expected.length) generalCssEntries.push({ el: node, names: expected, start: generalClipStartFor(node) });
1176
+ }
1177
+ }
1178
+
1179
+ function hasAnimationNamed(anims, name) {
1180
+ for (const anim of anims) {
1181
+ if (anim.animationName === name) return true;
1182
+ }
1183
+ return false;
1184
+ }
1185
+
1186
+ function generalClipStartFor(node) {
1187
+ const holder = node.closest("[data-start]");
1188
+ return holder ? readNumberAttr(holder, ["data-start"], 0) : 0;
1189
+ }
1190
+
1191
+ // Cycling animation-name through none re-creates dropped CSS animations
1192
+ // declaratively (same trick as the caption resurrection above), preserving
1193
+ // any authored inline animation-name.
1194
+ function resurrectCssAnimations(node) {
1195
+ try {
1196
+ const inline = node.style.animationName;
1197
+ node.style.animationName = "none";
1198
+ void node.offsetWidth;
1199
+ if (inline && inline !== "none") {
1200
+ node.style.animationName = inline;
1201
+ } else {
1202
+ node.style.removeProperty("animation-name");
1203
+ }
1204
+ } catch {}
1205
+ }
1206
+
1207
+ function scrubGeneralAnimation(anim, offsetMs) {
1208
+ let target = offsetMs;
1209
+ try {
1210
+ const computed = anim.effect && typeof anim.effect.getComputedTiming === "function"
1211
+ ? anim.effect.getComputedTiming()
1212
+ : null;
1213
+ const endTime = computed && typeof computed.endTime === "number" ? computed.endTime : NaN;
1214
+ if (Number.isFinite(endTime) && offsetMs >= endTime) {
1215
+ // Same Chrome guard as the caption scrub: paused fill:none/backwards
1216
+ // animations pushed past their effect end are destroyed permanently,
1217
+ // so park them at 0; fill:forwards/both hold their final keyframe at
1218
+ // the clamped end. Infinite-iteration animations (endTime Infinity)
1219
+ // take the raw clip-relative offset like the official CSS adapter \u2014
1220
+ // the browser resolves the iteration phase.
1221
+ target = computed.fill === "forwards" || computed.fill === "both" ? endTime : 0;
1222
+ }
1223
+ } catch {}
1224
+ try {
1225
+ anim.pause();
1226
+ anim.currentTime = target;
1227
+ } catch {}
1228
+ }
1229
+
1230
+ function syncGeneralCssAnimations() {
1231
+ for (const entry of generalCssEntries) {
1232
+ const node = entry.el;
1233
+ if (!node.isConnected) continue;
1234
+ const offsetMs = Math.max(0, time - entry.start) * 1000;
1235
+ let anims = [];
1236
+ try { anims = node.getAnimations(); } catch { continue; }
1237
+ let missing = null;
1238
+ for (const name of entry.names) {
1239
+ if (!hasAnimationNamed(anims, name)) (missing || (missing = [])).push(name);
1240
+ }
1241
+ if (missing) {
1242
+ resurrectCssAnimations(node);
1243
+ try { anims = node.getAnimations(); } catch { anims = []; }
1244
+ // Names that still have no live animation (e.g. a display:none
1245
+ // subtree) are dropped until the next discovery so a hidden element
1246
+ // is not forced through a reflow every frame.
1247
+ entry.names = entry.names.filter((name) => missing.indexOf(name) === -1 || hasAnimationNamed(anims, name));
1248
+ }
1249
+ for (const anim of anims) {
1250
+ if (typeof anim.animationName !== "string" || anim.animationName.indexOf("vf-") === 0) continue;
1251
+ scrubGeneralAnimation(anim, offsetMs);
1252
+ }
1253
+ }
1254
+ }
1255
+
1020
1256
  function apply(nextTime, options = {}) {
1021
1257
  const forceSeek = Boolean(options.forceSeek);
1022
1258
  const fromClock = Boolean(options.fromClock);
1259
+ ensureDuration();
1023
1260
  time = clampTime(nextTime);
1024
1261
  let activeVideoProxy = null;
1262
+ let activeVideoProxyStart = -Infinity;
1025
1263
  const transitionWindows = collectTransitionWindows();
1026
1264
  for (const clip of clips) {
1027
1265
  const timing = readTiming(clip);
1028
1266
  const hold = transitionHoldFor(clip, timing, transitionWindows);
1029
- const active = time >= timing.start && time < timing.end + hold;
1267
+ // hyperframes-core clip windows are inclusive of both ends \u2014 the final
1268
+ // frame holds.
1269
+ const active = time >= timing.start && time <= timing.end + hold;
1030
1270
  if (clip instanceof HTMLElement && !(clip instanceof HTMLAudioElement)) {
1031
1271
  if (clip.getAttribute("data-vf-timeline-proxy") === "video") {
1032
- if (active) activeVideoProxy = clip;
1272
+ // Clip windows are inclusive of both ends, so at an exact butt-cut
1273
+ // the outgoing AND incoming proxies are both active. Prefer the
1274
+ // greatest data-start (timeline order \u2014 the incoming clip wins);
1275
+ // DOM order only breaks ties between equal starts.
1276
+ if (active && timing.start >= activeVideoProxyStart) {
1277
+ activeVideoProxy = clip;
1278
+ activeVideoProxyStart = timing.start;
1279
+ }
1033
1280
  } else {
1034
1281
  setVisibility(clip, active);
1035
1282
  }
@@ -1053,6 +1300,8 @@ myself`,y:22}];return[...U1(t,e,r.map((o,i)=>`${10-i}/10 scene`)),{id:`${t.id}-a
1053
1300
  }
1054
1301
  }
1055
1302
  }
1303
+ syncGeneralCssAnimations();
1304
+ syncRuntimeAdapters();
1056
1305
  if (backingVideo instanceof HTMLVideoElement) {
1057
1306
  applyMediaState(backingVideo);
1058
1307
  const shouldShowBackingVideo = !hasVideoProxies || Boolean(activeVideoProxy);
@@ -1161,10 +1410,45 @@ myself`,y:22}];return[...U1(t,e,r.map((o,i)=>`${10-i}/10 scene`)),{id:`${t.id}-a
1161
1410
  if (!playing) apply(time, { forceSeek: true });
1162
1411
  });
1163
1412
  }
1413
+ window.addEventListener("load", () => {
1414
+ // Composition scripts may register adapter instances (GSAP timelines,
1415
+ // Lottie players, ...) or start CSS animations on the load event \u2014
1416
+ // re-discover and re-scrub so late registrations preview correctly.
1417
+ discoverGeneralCssAnimations();
1418
+ if (!playing) apply(time, { forceSeek: true });
1419
+ });
1420
+
1421
+ // Cache the parent frame's origin from the first accepted control message
1422
+ // and pin all outbound postMessages to it. Falls back to document.referrer's
1423
+ // origin so drag/select events still reach the editor before any control
1424
+ // message has been received. Without pinning, sending "*" leaks preview
1425
+ // frame coordinates and layer ids to any embedding third-party page.
1426
+ let trustedParentOrigin = null;
1427
+ try {
1428
+ if (document.referrer) {
1429
+ trustedParentOrigin = new URL(document.referrer).origin;
1430
+ }
1431
+ } catch {}
1432
+ function parentTargetOrigin() {
1433
+ return trustedParentOrigin || "*";
1434
+ }
1435
+ function postToParent(payload) {
1436
+ if (!window.parent || window.parent === window) return;
1437
+ try {
1438
+ window.parent.postMessage(payload, parentTargetOrigin());
1439
+ } catch {}
1440
+ }
1164
1441
 
1165
1442
  window.addEventListener("message", (event) => {
1443
+ // Only accept messages from the direct parent frame. Blocks sibling
1444
+ // iframes and popups that could otherwise spoof play/pause/seek by
1445
+ // forging data.source.
1446
+ if (event.source !== window.parent) return;
1166
1447
  const data = event.data || {};
1167
1448
  if (data.type !== "control" && data.source !== "hf-parent") return;
1449
+ if (event.origin && event.origin !== "null") {
1450
+ trustedParentOrigin = event.origin;
1451
+ }
1168
1452
  if (data.action === "play") {
1169
1453
  window.__player.play();
1170
1454
  }
@@ -1206,11 +1490,11 @@ myself`,y:22}];return[...U1(t,e,r.map((o,i)=>`${10-i}/10 scene`)),{id:`${t.id}-a
1206
1490
  const target = selectTargetFromEvent(event);
1207
1491
  const rawId = target?.getAttribute("data-hf-id") || target?.id || null;
1208
1492
  const id = rawId === "source-video" ? null : rawId;
1209
- window.parent?.postMessage({
1493
+ postToParent({
1210
1494
  source: "vidfarm-composition",
1211
1495
  action: "select-layer",
1212
1496
  id
1213
- }, "*");
1497
+ });
1214
1498
  }
1215
1499
 
1216
1500
  function postPreviewContextMenu(event) {
@@ -1222,7 +1506,7 @@ myself`,y:22}];return[...U1(t,e,r.map((o,i)=>`${10-i}/10 scene`)),{id:`${t.id}-a
1222
1506
  const id = rawId === "source-video" ? null : rawId;
1223
1507
  const x = rect ? ((event.clientX - rect.left) / Math.max(1, rect.width)) * 100 : 12;
1224
1508
  const y = rect ? ((event.clientY - rect.top) / Math.max(1, rect.height)) * 100 : 70;
1225
- window.parent?.postMessage({
1509
+ postToParent({
1226
1510
  source: "vidfarm-composition",
1227
1511
  action: "preview-context-menu",
1228
1512
  id,
@@ -1235,7 +1519,7 @@ myself`,y:22}];return[...U1(t,e,r.map((o,i)=>`${10-i}/10 scene`)),{id:`${t.id}-a
1235
1519
  width: 42,
1236
1520
  height: 12
1237
1521
  }
1238
- }, "*");
1522
+ });
1239
1523
  }
1240
1524
 
1241
1525
  function frameFromNode(node) {
@@ -1338,13 +1622,13 @@ myself`,y:22}];return[...U1(t,e,r.map((o,i)=>`${10-i}/10 scene`)),{id:`${t.id}-a
1338
1622
  function postFrameDraft(node, phase) {
1339
1623
  const id = node.getAttribute("data-hf-id") || node.id || null;
1340
1624
  if (!id) return;
1341
- window.parent?.postMessage({
1625
+ postToParent({
1342
1626
  source: "vidfarm-composition",
1343
1627
  action: "visual-frame-draft",
1344
1628
  phase,
1345
1629
  id,
1346
1630
  frame: frameFromNode(node)
1347
- }, "*");
1631
+ });
1348
1632
  }
1349
1633
 
1350
1634
  let visualFrameDrag = null;