@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/dist/src/app.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createHash, randomBytes, randomUUID } from "node:crypto";
2
- import { createWriteStream, existsSync, mkdirSync, readFileSync, rmSync, statSync } from "node:fs";
2
+ import { createWriteStream, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync } from "node:fs";
3
3
  import path from "node:path";
4
4
  import { Readable } from "node:stream";
5
5
  import { pipeline as streamPipeline } from "node:stream/promises";
@@ -35,7 +35,7 @@ import { resolveRootFileCandidates } from "./lib/package-root.js";
35
35
  import { stripTrackingParams } from "./lib/url-clean.js";
36
36
  import { addSeconds, nowIso } from "./lib/time.js";
37
37
  import { templateRegistry } from "./registry.js";
38
- import { buildEditorChatSystemInstruction, compactEditorChatModelMessages, defaultEditorChatModel, EDITOR_CHAT_PROVIDER_PRIORITY, extractEditorChatCompositionBrief, formatEditorChatCurrentDateTime, toEditorChatModelMessages } from "./editor-chat.js";
38
+ import { buildAsyncJobHandoffText, buildEditorChatGuardrailNotice, buildEditorChatSystemInstruction, collectVerifiedHttpJobIds, compactEditorChatModelMessages, createLoadSkillTool, createStreamingJobIdRedactor, defaultEditorChatModel, EDITOR_CHAT_PROVIDER_PRIORITY, extractEditorChatCompositionBrief, formatEditorChatCurrentDateTime, lintReplaceCompositionAction, readAsyncJobHandoff, toEditorChatModelMessages } from "./editor-chat.js";
39
39
  import { apiCallHistoryStore } from "./services/api-call-history.js";
40
40
  import { AuthService } from "./services/auth.js";
41
41
  import { BillingService } from "./services/billing.js";
@@ -54,7 +54,7 @@ import { loadSpeechAudioLocally, MAX_LOCAL_TRANSCRIBE_AUDIO_BYTES } from "./devc
54
54
  import { DescribeExecutionCommand, SFNClient, StartExecutionCommand } from "@aws-sdk/client-sfn";
55
55
  import { clipRecords, makeUserPreset } from "./services/clip-records.js";
56
56
  import { matchScenesToClips, searchUserClips, vectorIndex } from "./services/clip-search.js";
57
- import { BUILTIN_PRESETS, buildEffectiveGuidance, ClipModelClient, cosineSimilarity, detectLocalAgent, effectiveHuntDurationSec, estimateScanCostFromDuration, hasFfmpeg, LocalAgentClipClient, normalizeCropFocus, normalizeHuntSpec, parseClipHuntPrompt, probeVideo, resolveDurationBand, scanVideo } from "./services/clip-curation/index.js";
57
+ import { BUILTIN_PRESETS, buildClipEmbeddingText, buildEffectiveGuidance, ClipModelClient, cosineSimilarity, detectLocalAgent, effectiveHuntDurationSec, estimateScanCostFromDuration, hasFfmpeg, LocalAgentClipClient, normalizeCropFocus, normalizeHuntSpec, parseClipHuntPrompt, probeVideo, resolveDurationBand, scanVideo } from "./services/clip-curation/index.js";
58
58
  import { analyzeCastMembers, annotateScenesFromSource, buildSmartDecomposedHtml, HyperframesService, smartDecomposeVideo, stampCompositionIdentity } from "./services/hyperframes.js";
59
59
  import { buildPendingSceneAnnotationsState } from "./services/scene-annotations.js";
60
60
  import { createPrimitiveJobContext } from "./primitive-context.js";
@@ -3609,7 +3609,12 @@ function normalizeEditorChatPath(input) {
3609
3609
  // and NEVER runs GhostCut on the long-form source — "no text" is a
3610
3610
  // scene-selection filter; caption removal stays a per-finished-clip
3611
3611
  // primitive (/api/v1/primitives/videos/remove-captions).
3612
- CLIPS_PREFIX
3612
+ CLIPS_PREFIX,
3613
+ // Public skill knowledge: the vendored skill packs (load_skill fetches
3614
+ // these too) and per-template SKILL.md manifests. Read-only markdown.
3615
+ "/skill/",
3616
+ "/skill-pack/",
3617
+ "/discover/skills/"
3613
3618
  ];
3614
3619
  const parsed = trimmed.startsWith("http://") || trimmed.startsWith("https://")
3615
3620
  ? new URL(trimmed)
@@ -4463,95 +4468,14 @@ function createEditorActionTool() {
4463
4468
  explanation: z.string().describe("One-sentence reason shown in the UI.")
4464
4469
  }),
4465
4470
  execute: async (args) => {
4471
+ const linted = lintReplaceCompositionAction(args);
4472
+ if (linted) {
4473
+ return linted;
4474
+ }
4466
4475
  return { ...args };
4467
4476
  }
4468
4477
  });
4469
4478
  }
4470
- const JOB_ID_PATTERN = /\bjob_[a-z0-9]+\b/gi;
4471
- const HTTP_TOOL_CLAIM_PATTERN = /\b(?:http_request|REST API call|API call|GET\s+https?:\/\/|POST\s+https?:\/\/|GET\s+\/api\/|POST\s+\/api\/)/i;
4472
- function collectJobIdsFromUnknown(value, output = new Set()) {
4473
- if (typeof value === "string") {
4474
- for (const match of value.matchAll(JOB_ID_PATTERN)) {
4475
- output.add(match[0]);
4476
- }
4477
- return output;
4478
- }
4479
- if (Array.isArray(value)) {
4480
- for (const entry of value) {
4481
- collectJobIdsFromUnknown(entry, output);
4482
- }
4483
- return output;
4484
- }
4485
- if (value && typeof value === "object") {
4486
- for (const entry of Object.values(value)) {
4487
- collectJobIdsFromUnknown(entry, output);
4488
- }
4489
- }
4490
- return output;
4491
- }
4492
- function collectVerifiedHttpJobIds(toolResult) {
4493
- if (!toolResult || typeof toolResult !== "object") {
4494
- return new Set();
4495
- }
4496
- const record = toolResult;
4497
- return collectJobIdsFromUnknown(record.response?.body ?? record.result?.body);
4498
- }
4499
- function readAsyncJobHandoff(output) {
4500
- if (!output || typeof output !== "object") {
4501
- return null;
4502
- }
4503
- const record = output;
4504
- const body = record.response?.body;
4505
- if (!body || typeof body !== "object") {
4506
- return null;
4507
- }
4508
- const job = body;
4509
- if (typeof job.job_id !== "string" || typeof job.status !== "string") {
4510
- return null;
4511
- }
4512
- if (job.status === "succeeded" || job.status === "failed" || job.status === "cancelled") {
4513
- return null;
4514
- }
4515
- return {
4516
- jobId: job.job_id,
4517
- tracer: typeof job.tracer === "string" ? job.tracer : null,
4518
- status: job.status,
4519
- isNewQueuedJob: record.request?.method === "POST" && record.response?.status === 202
4520
- };
4521
- }
4522
- function buildAsyncJobHandoffText(input) {
4523
- if (!input.isNewQueuedJob) {
4524
- return `Render \`${input.jobId}\` is ${input.status}.`;
4525
- }
4526
- return [
4527
- `Started render \`${input.jobId}\`${input.tracer ? ` with tracer \`${input.tracer}\`` : ""}.`,
4528
- "If it takes a while, ask for an update later and I can check it for you."
4529
- ].join("\n\n");
4530
- }
4531
- function buildEditorChatGuardrailNotice(input) {
4532
- const mentionedJobIds = collectJobIdsFromUnknown(input.assistantText);
4533
- const unverifiedJobIds = [...mentionedJobIds].filter((jobId) => !input.verifiedJobIds.has(jobId));
4534
- const notices = [];
4535
- if (input.redactedJobIds.size) {
4536
- notices.push("Guardrail: I withheld unverified job ID text because it did not come from a visible HTTP response card.");
4537
- }
4538
- else if (unverifiedJobIds.length) {
4539
- notices.push("Guardrail: I mentioned an unverified job ID. Ignore it unless it appears in a visible HTTP response card.");
4540
- }
4541
- if (!input.hasHttpRequestResult && HTTP_TOOL_CLAIM_PATTERN.test(input.assistantText)) {
4542
- notices.push("Guardrail: no `http_request` tool result was recorded for this response, so any claimed REST/API call should be treated as not executed.");
4543
- }
4544
- return notices.length ? `\n\n${notices.join("\n\n")}` : "";
4545
- }
4546
- function redactUnverifiedJobIds(input) {
4547
- return input.text.replace(JOB_ID_PATTERN, (jobId) => {
4548
- if (input.verifiedJobIds.has(jobId)) {
4549
- return jobId;
4550
- }
4551
- input.redactedJobIds.add(jobId);
4552
- return "[unverified job id]";
4553
- });
4554
- }
4555
4479
  function normalizeHistoryAttachments(attachments) {
4556
4480
  return Array.isArray(attachments)
4557
4481
  ? attachments.map((attachment) => ({
@@ -4595,6 +4519,10 @@ async function streamEditorChatAgent(input, send) {
4595
4519
  vidfarmApiKey: input.vidfarmApiKey,
4596
4520
  abortSignal: input.abortSignal
4597
4521
  }),
4522
+ load_skill: createLoadSkillTool({
4523
+ publicBaseUrl: config.PUBLIC_BASE_URL,
4524
+ abortSignal: input.abortSignal
4525
+ }),
4598
4526
  frontend_action: createEditorFrontendActionTool({
4599
4527
  tracerRegistry
4600
4528
  }),
@@ -4621,6 +4549,7 @@ async function streamEditorChatAgent(input, send) {
4621
4549
  let hasHttpRequestResult = false;
4622
4550
  const verifiedJobIds = new Set();
4623
4551
  const redactedJobIds = new Set();
4552
+ const jobIdRedactor = createStreamingJobIdRedactor({ verifiedJobIds, redactedJobIds });
4624
4553
  const toolExchangeOrder = [];
4625
4554
  const toolExchangeMap = new Map();
4626
4555
  const httpExchanges = [];
@@ -4635,16 +4564,14 @@ async function streamEditorChatAgent(input, send) {
4635
4564
  case "text-delta":
4636
4565
  assistantTextForAudit += part.text;
4637
4566
  {
4638
- const safeText = redactUnverifiedJobIds({
4639
- text: part.text,
4640
- verifiedJobIds,
4641
- redactedJobIds
4642
- });
4643
- assistantTextForUser += safeText;
4644
- send({
4645
- type: "text-delta",
4646
- delta: safeText
4647
- });
4567
+ const safeText = jobIdRedactor.push(part.text);
4568
+ if (safeText) {
4569
+ assistantTextForUser += safeText;
4570
+ send({
4571
+ type: "text-delta",
4572
+ delta: safeText
4573
+ });
4574
+ }
4648
4575
  }
4649
4576
  break;
4650
4577
  case "tool-call":
@@ -4738,6 +4665,14 @@ async function streamEditorChatAgent(input, send) {
4738
4665
  break;
4739
4666
  case "finish":
4740
4667
  {
4668
+ const heldText = jobIdRedactor.flush();
4669
+ if (heldText) {
4670
+ assistantTextForUser += heldText;
4671
+ send({
4672
+ type: "text-delta",
4673
+ delta: heldText
4674
+ });
4675
+ }
4741
4676
  const guardrailNotice = buildEditorChatGuardrailNotice({
4742
4677
  assistantText: assistantTextForAudit,
4743
4678
  verifiedJobIds,
@@ -5677,21 +5612,193 @@ const PUBLIC_SKILL_FILES = {
5677
5612
  "vidfarm-director": "SKILL.director.md",
5678
5613
  "vidfarm-platform": "SKILL.platform.md"
5679
5614
  };
5615
+ // Vendored skill packs (the heygen-scrubbed hyperframes pack + vidfarm-media)
5616
+ // mirrored from .agents/skills. Vidfarm is the distribution origin: the devcli
5617
+ // (`vidfarm skills add`) and the chat copilot's load_skill tool both pull from
5618
+ // these routes, so customers never fetch skills from an upstream vendor org.
5619
+ const SKILL_PACK_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]{0,64}$/;
5620
+ const SKILL_PACK_IGNORED_ENTRIES = new Set([".DS_Store", "node_modules", ".git"]);
5621
+ function resolveSkillPackDir(name) {
5622
+ if (!SKILL_PACK_NAME_PATTERN.test(name)) {
5623
+ return null;
5624
+ }
5625
+ for (const candidate of resolveRootFileCandidates(path.join(".agents", "skills", name))) {
5626
+ try {
5627
+ if (statSync(candidate).isDirectory()) {
5628
+ return candidate;
5629
+ }
5630
+ }
5631
+ catch {
5632
+ continue;
5633
+ }
5634
+ }
5635
+ return null;
5636
+ }
5637
+ function listSkillPackFiles(dir, prefix = "") {
5638
+ const files = [];
5639
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
5640
+ if (SKILL_PACK_IGNORED_ENTRIES.has(entry.name)) {
5641
+ continue;
5642
+ }
5643
+ const relative = prefix ? `${prefix}/${entry.name}` : entry.name;
5644
+ const absolute = path.join(dir, entry.name);
5645
+ if (entry.isDirectory()) {
5646
+ files.push(...listSkillPackFiles(absolute, relative));
5647
+ }
5648
+ else if (entry.isFile()) {
5649
+ files.push(relative);
5650
+ }
5651
+ }
5652
+ return files.sort();
5653
+ }
5654
+ function readSkillPackDescription(dir) {
5655
+ try {
5656
+ const skillMd = readFileSync(path.join(dir, "SKILL.md"), "utf8");
5657
+ const match = skillMd.match(/^description:\s*(.+)$/m);
5658
+ return match ? match[1].trim().slice(0, 300) : "";
5659
+ }
5660
+ catch {
5661
+ return "";
5662
+ }
5663
+ }
5680
5664
  app.get("/skill/:name", (c) => {
5681
5665
  const name = c.req.param("name").replace(/\.md$/i, "");
5682
5666
  const filename = PUBLIC_SKILL_FILES[name];
5683
- if (!filename) {
5684
- return c.text("Unknown skill", 404);
5685
- }
5686
- const contents = readRootSkillFile(filename);
5667
+ const contents = filename
5668
+ ? readRootSkillFile(filename)
5669
+ : (() => {
5670
+ const packDir = resolveSkillPackDir(name);
5671
+ if (!packDir) {
5672
+ return "";
5673
+ }
5674
+ try {
5675
+ return readFileSync(path.join(packDir, "SKILL.md"), "utf8");
5676
+ }
5677
+ catch {
5678
+ return "";
5679
+ }
5680
+ })();
5687
5681
  if (!contents) {
5688
- return c.text("Skill file unavailable", 404);
5682
+ return c.text(filename ? "Skill file unavailable" : "Unknown skill", 404);
5689
5683
  }
5690
5684
  return c.body(contents, 200, {
5691
5685
  "content-type": "text/markdown; charset=utf-8",
5692
5686
  "cache-control": "no-cache"
5693
5687
  });
5694
5688
  });
5689
+ app.get("/skill-pack/index.json", (c) => {
5690
+ const skills = [];
5691
+ for (const candidate of resolveRootFileCandidates(path.join(".agents", "skills"))) {
5692
+ let entries;
5693
+ try {
5694
+ entries = readdirSync(candidate);
5695
+ }
5696
+ catch {
5697
+ continue;
5698
+ }
5699
+ for (const entry of entries.sort()) {
5700
+ if (!SKILL_PACK_NAME_PATTERN.test(entry) || skills.some((skill) => skill.name === entry)) {
5701
+ continue;
5702
+ }
5703
+ const dir = path.join(candidate, entry);
5704
+ try {
5705
+ if (!statSync(dir).isDirectory()) {
5706
+ continue;
5707
+ }
5708
+ }
5709
+ catch {
5710
+ continue;
5711
+ }
5712
+ skills.push({ name: entry, description: readSkillPackDescription(dir) });
5713
+ }
5714
+ break;
5715
+ }
5716
+ return c.json({ skills });
5717
+ });
5718
+ // Manifest hashing reads every file in a pack (hyperframes-animation alone is
5719
+ // ~100 files) — memoize per pack dir, invalidated by a cheap stat signature,
5720
+ // so `vidfarm skills update` sweeps don't re-hash 5MB per request.
5721
+ const skillPackManifestCache = new Map();
5722
+ app.get("/skill-pack/:name/manifest.json", (c) => {
5723
+ const packDir = resolveSkillPackDir(c.req.param("name"));
5724
+ if (!packDir) {
5725
+ return c.json({ error: "Unknown skill pack." }, 404);
5726
+ }
5727
+ const relativePaths = listSkillPackFiles(packDir);
5728
+ const signature = relativePaths
5729
+ .map((relative) => {
5730
+ try {
5731
+ const stats = statSync(path.join(packDir, relative));
5732
+ return `${relative}:${stats.size}:${stats.mtimeMs}`;
5733
+ }
5734
+ catch {
5735
+ return `${relative}:missing`;
5736
+ }
5737
+ })
5738
+ .join("|");
5739
+ const cached = skillPackManifestCache.get(packDir);
5740
+ if (cached && cached.signature === signature) {
5741
+ return c.json(cached.manifest);
5742
+ }
5743
+ const files = relativePaths.map((relative) => {
5744
+ const bytes = readFileSync(path.join(packDir, relative));
5745
+ return {
5746
+ path: relative,
5747
+ size: bytes.length,
5748
+ sha256: createHash("sha256").update(bytes).digest("hex")
5749
+ };
5750
+ });
5751
+ const manifest = { name: path.basename(packDir), files };
5752
+ skillPackManifestCache.set(packDir, { signature, manifest });
5753
+ return c.json(manifest);
5754
+ });
5755
+ app.get("/skill-pack/:name/files/*", (c) => {
5756
+ const packDir = resolveSkillPackDir(c.req.param("name"));
5757
+ if (!packDir) {
5758
+ return c.text("Unknown skill pack.", 404);
5759
+ }
5760
+ const marker = "/files/";
5761
+ const rawPath = c.req.path.slice(c.req.path.indexOf(marker) + marker.length);
5762
+ let relative;
5763
+ try {
5764
+ relative = rawPath
5765
+ .split("/")
5766
+ .map((segment) => decodeURIComponent(segment))
5767
+ .join("/");
5768
+ }
5769
+ catch {
5770
+ return c.text("Bad file path.", 400);
5771
+ }
5772
+ const resolved = path.resolve(packDir, relative);
5773
+ if (resolved !== packDir && !resolved.startsWith(packDir + path.sep)) {
5774
+ return c.text("Bad file path.", 400);
5775
+ }
5776
+ let bytes;
5777
+ try {
5778
+ bytes = readFileSync(resolved);
5779
+ }
5780
+ catch {
5781
+ return c.text("File not found.", 404);
5782
+ }
5783
+ const ext = path.extname(resolved).toLowerCase();
5784
+ const contentType = ext === ".md" || ext === ".markdown" ? "text/markdown; charset=utf-8"
5785
+ : ext === ".json" ? "application/json; charset=utf-8"
5786
+ : ext === ".mjs" || ext === ".cjs" || ext === ".js" ? "text/javascript; charset=utf-8"
5787
+ : ext === ".html" ? "text/html; charset=utf-8"
5788
+ : ext === ".css" ? "text/css; charset=utf-8"
5789
+ : ext === ".txt" || ext === ".srt" || ext === ".vtt" || ext === ".sh" || ext === ".yaml" || ext === ".yml" ? "text/plain; charset=utf-8"
5790
+ : ext === ".png" ? "image/png"
5791
+ : ext === ".avif" ? "image/avif"
5792
+ : ext === ".webp" ? "image/webp"
5793
+ : ext === ".jpg" || ext === ".jpeg" ? "image/jpeg"
5794
+ : ext === ".mp3" ? "audio/mpeg"
5795
+ : ext === ".woff2" ? "font/woff2"
5796
+ : "application/octet-stream";
5797
+ return c.body(new Uint8Array(bytes), 200, {
5798
+ "content-type": contentType,
5799
+ "cache-control": "no-cache"
5800
+ });
5801
+ });
5695
5802
  if (config.SENTRY_DEBUG_ROUTE === "true") {
5696
5803
  app.get("/debug-sentry", () => {
5697
5804
  Sentry.logger.info("User triggered test error", {
@@ -6601,7 +6708,13 @@ app.post(`${COMPOSITIONS_PREFIX}/:forkId/captions`, async (c) => {
6601
6708
  const text = str("text");
6602
6709
  if (text) {
6603
6710
  const windowStart = Math.max(0, num("start") ?? 0);
6604
- const windowDuration = num("duration") ?? Math.max(0.4, compositionDuration - windowStart);
6711
+ const availableWindow = compositionDuration - windowStart;
6712
+ // When the composition declares no usable window (missing data-duration,
6713
+ // or windowStart at/after the end), fall back to a word-count estimate
6714
+ // (~0.32s/word, same as the /audio/captions primitive) instead of
6715
+ // cramming the whole script into a 0.4s window of overlapping cues.
6716
+ const estimatedWindow = Math.max(0.4, text.trim().split(/\s+/).filter(Boolean).length * 0.32);
6717
+ const windowDuration = num("duration") ?? (availableWindow > 0.4 ? availableWindow : estimatedWindow);
6605
6718
  cues = cuesFromText(text, windowStart + offsetSec, windowDuration, { maxWordsPerCue: maxWords });
6606
6719
  sourceNote = "text";
6607
6720
  }
@@ -14938,6 +15051,31 @@ app.get(`${USER_PREFIX}/me/generated-media`, async (c) => {
14938
15051
  next_cursor: page.nextCursor
14939
15052
  });
14940
15053
  });
15054
+ // OpenAI's embedding models are named text-embedding-3-* / text-embedding-ada-*;
15055
+ // Gemini's family INCLUDES text-embedding-004 (plus gemini-embedding-*), so a
15056
+ // bare startsWith("text-embedding") misroutes a Gemini-built library to OpenAI
15057
+ // and returns cross-space (garbage) cosine scores. Match the OpenAI naming
15058
+ // precisely; everything else is gemini.
15059
+ function inferEmbeddingProviderFromModel(model) {
15060
+ return model && /^text-embedding-(3|ada)/i.test(model) ? "openai" : "gemini";
15061
+ }
15062
+ // Embed-capable client for populating/searching a clip library. Matches the
15063
+ // library's existing embedding space when one exists (so vectors stay
15064
+ // cosine-comparable); otherwise takes the first embed-capable saved key
15065
+ // (gemini → openai; openrouter can't embed). Null → no key, keyword-only.
15066
+ async function buildClipLibraryEmbedder(customerId) {
15067
+ const existing = await clipRecords.getLibraryEmbeddingModel(customerId);
15068
+ const providers = existing ? [inferEmbeddingProviderFromModel(existing)] : ["gemini", "openai"];
15069
+ for (const provider of providers) {
15070
+ const apiKey = await resolveCustomerProviderKey(customerId, provider);
15071
+ if (!apiKey)
15072
+ continue;
15073
+ const client = new ClipModelClient({ provider, apiKey });
15074
+ if (client.canEmbed)
15075
+ return client;
15076
+ }
15077
+ return null;
15078
+ }
14941
15079
  // Embedder for My Files notes — the same BYOK seam clip search uses. Prefer the
14942
15080
  // provider matching the embedding model the file library was built with (from
14943
15081
  // the newest annotated attachment) so query vectors stay cosine-comparable; a
@@ -14946,7 +15084,7 @@ app.get(`${USER_PREFIX}/me/generated-media`, async (c) => {
14946
15084
  async function buildFileNotesEmbedder(customerId) {
14947
15085
  const attachments = await serverlessRecords.listUserAttachments(customerId);
14948
15086
  const libModel = attachments.find((a) => a.notesEmbeddingModel && Array.isArray(a.notesEmbedding) && a.notesEmbedding.length > 0)?.notesEmbeddingModel ?? null;
14949
- const providers = libModel ? [libModel.startsWith("text-embedding") ? "openai" : "gemini"] : ["gemini", "openai"];
15087
+ const providers = libModel ? [inferEmbeddingProviderFromModel(libModel)] : ["gemini", "openai"];
14950
15088
  for (const provider of providers) {
14951
15089
  const apiKey = await resolveCustomerProviderKey(customerId, provider);
14952
15090
  if (!apiKey)
@@ -16162,7 +16300,7 @@ async function pickClipProviderFromKeys(customerId) {
16162
16300
  */
16163
16301
  async function buildMatchEmbedder(customerId) {
16164
16302
  const libModel = await clipRecords.getLibraryEmbeddingModel(customerId);
16165
- const provider = libModel && libModel.startsWith("text-embedding") ? "openai" : "gemini";
16303
+ const provider = inferEmbeddingProviderFromModel(libModel);
16166
16304
  const key = await resolveCustomerProviderKey(customerId, provider);
16167
16305
  if (!key)
16168
16306
  return null;
@@ -16532,29 +16670,54 @@ app.post(`${CLIPS_PREFIX}/scan`, async (c) => {
16532
16670
  const computeEstimate = effectiveDurationSec
16533
16671
  ? estimateClipScanComputeUsd(effectiveDurationSec, huntSpec.duration_band?.target_sec)
16534
16672
  : null;
16535
- const res = await clipScanSfn.send(new StartExecutionCommand({
16536
- stateMachineArn: config.VIDFARM_CLIP_SCAN_STATE_MACHINE_ARN,
16537
- name: scanId.replace(/[^A-Za-z0-9-_]/g, "-").slice(0, 80),
16538
- input: JSON.stringify({
16539
- scan_id: scanId,
16540
- owner_id: customer.id,
16541
- source_video_id: sourceVideoId,
16542
- source_filename: filename,
16543
- raw_s3_uri: rawS3Uri ?? "",
16544
- tier,
16545
- provider,
16546
- tag_api_key: tagApiKey,
16547
- embedding_provider: client.embeddingProvider ?? "",
16548
- embedding_api_key: embeddingKey ?? "",
16549
- guidance_prompt: guidancePrompt,
16550
- frames_per_scene: framesPerScene,
16551
- include_audio: includeAudio,
16552
- hunt_spec: huntSpec,
16553
- tracer
16554
- })
16555
- }));
16556
- await putScanRecords({ scanStatus: "running", executionArn: res.executionArn });
16557
- return scanResponse({ status: "running", executionArn: res.executionArn, pipeline: "cloud", estimate, computeEstimate });
16673
+ // Records first: a Dynamo failure here aborts submission before anything
16674
+ // is billed, and the warm probe lambda's later status:"scanning" write is
16675
+ // never clobbered back to "pending" by a post-start putScanRecords.
16676
+ await putScanRecords({ scanStatus: "running" });
16677
+ let executionArn;
16678
+ try {
16679
+ const res = await clipScanSfn.send(new StartExecutionCommand({
16680
+ stateMachineArn: config.VIDFARM_CLIP_SCAN_STATE_MACHINE_ARN,
16681
+ name: scanId.replace(/[^A-Za-z0-9-_]/g, "-").slice(0, 80),
16682
+ input: JSON.stringify({
16683
+ scan_id: scanId,
16684
+ owner_id: customer.id,
16685
+ source_video_id: sourceVideoId,
16686
+ source_filename: filename,
16687
+ raw_s3_uri: rawS3Uri ?? "",
16688
+ tier,
16689
+ provider,
16690
+ tag_api_key: tagApiKey,
16691
+ embedding_provider: client.embeddingProvider ?? "",
16692
+ embedding_api_key: embeddingKey ?? "",
16693
+ guidance_prompt: guidancePrompt,
16694
+ frames_per_scene: framesPerScene,
16695
+ include_audio: includeAudio,
16696
+ hunt_spec: huntSpec,
16697
+ tracer
16698
+ })
16699
+ }));
16700
+ executionArn = res.executionArn;
16701
+ }
16702
+ catch (error) {
16703
+ // The execution never started — roll the scan (and its source) to failed
16704
+ // so pollers do not spin on a "running" record that will never progress,
16705
+ // mirroring the lazy-reconcile failure path.
16706
+ const orphan = await clipRecords.getScan(customer.id, scanId);
16707
+ if (orphan)
16708
+ await clipRecords.putScan({ ...orphan, status: "failed", error: "Failed to start the scan pipeline.", updated_at: nowIso() });
16709
+ const orphanSource = await clipRecords.getSource(customer.id, sourceVideoId);
16710
+ if (orphanSource && orphanSource.status !== "complete")
16711
+ await clipRecords.putSource({ ...orphanSource, status: "failed", updated_at: nowIso() });
16712
+ throw error;
16713
+ }
16714
+ // Attach the execution ARN for lazy SFN reconciliation (best-effort — the
16715
+ // record is already pollable; spread the current record so a runner that
16716
+ // has already advanced the status is not regressed).
16717
+ const startedScan = await clipRecords.getScan(customer.id, scanId);
16718
+ if (startedScan)
16719
+ await clipRecords.putScan({ ...startedScan, execution_arn: executionArn, updated_at: nowIso() });
16720
+ return scanResponse({ status: "running", executionArn, pipeline: "cloud", estimate, computeEstimate });
16558
16721
  }
16559
16722
  // ── vidfarm serve (no deployed pipeline): LOCAL-FIRST, cloud as backup ──
16560
16723
  // Same policy as `vidfarm clips scan`: the user's local claude/codex CLI
@@ -16856,6 +17019,11 @@ async function mirrorUpstreamClipsToLocal(input) {
16856
17019
  if (!feed.ok || !feed.json)
16857
17020
  throw new Error(`Upstream clip feed unavailable (HTTP ${feed.status}).`);
16858
17021
  let stored = 0;
17022
+ // Upstream /clips/feed strips the embedding vector, so re-embed each mirrored
17023
+ // clip on the owner's BYOK key — otherwise it lands with no embedding and is
17024
+ // permanently invisible to semantic clip search (keyword-only). Fail-soft:
17025
+ // no embed-capable key → store without embedding (keyword-only), as before.
17026
+ const embedder = await buildClipLibraryEmbedder(ownerId);
16859
17027
  for (const raw of feed.json.clips ?? []) {
16860
17028
  const clipId = typeof raw.clip_id === "string" ? raw.clip_id : null;
16861
17029
  const viewUrl = typeof raw.view_url === "string" ? raw.view_url : null;
@@ -16875,16 +17043,32 @@ async function mirrorUpstreamClipsToLocal(input) {
16875
17043
  await storage.putBuffer(thumbKey, new Uint8Array(await thumbRes.arrayBuffer()), "image/jpeg");
16876
17044
  }
16877
17045
  }
16878
- const { view_url: _v, thumbnail_url: _t, ...rest } = raw;
17046
+ const { view_url: _v, thumbnail_url: _t, embedding: _e, embedding_model: _em, ...rest } = raw;
16879
17047
  void _v;
16880
17048
  void _t;
16881
- await clipRecords.putClip({
17049
+ void _e;
17050
+ void _em;
17051
+ const clip = {
16882
17052
  ...rest,
16883
17053
  owner_id: ownerId,
16884
17054
  source_video_id: scan.source_video_id,
16885
17055
  file_path: clipKey,
16886
17056
  thumbnail_path: thumbKey
16887
- });
17057
+ };
17058
+ if (embedder?.embeddingModelId) {
17059
+ try {
17060
+ const [vector] = await embedder.embedDocuments([buildClipEmbeddingText(clip.tags, clip.description)]);
17061
+ if (vector?.length) {
17062
+ clip.embedding = vector;
17063
+ clip.embedding_model = embedder.embeddingModelId;
17064
+ }
17065
+ }
17066
+ catch (error) {
17067
+ devLog("clip_scan.upstream_mirror_embed_failed", { scan_id: scan.scan_id, clip_id: clipId, ...devErrorFields(error) }, "warn");
17068
+ }
17069
+ }
17070
+ await clipRecords.putClip(clip);
17071
+ await vectorIndex.upsert(ownerId, clip);
16888
17072
  stored++;
16889
17073
  }
16890
17074
  const source = await clipRecords.getSource(ownerId, scan.source_video_id);