dsh-hyperframes 0.1.1 → 0.3.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 (916) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +34 -5
  3. package/README.md +34 -8
  4. package/lib/index.d.ts +11 -1
  5. package/lib/index.js +57 -3
  6. package/package.json +63 -64
  7. package/skills/embedded-captions/CATALOG.md +91 -0
  8. package/skills/embedded-captions/SKILL.md +258 -0
  9. package/skills/embedded-captions/assets/fonts/char-widths.json +2211 -0
  10. package/skills/embedded-captions/assets/strokefonts/HersheyScript1.svg +242 -0
  11. package/skills/embedded-captions/assets/strokefonts/HersheyScriptMed.svg +242 -0
  12. package/skills/embedded-captions/dna/README.md +148 -0
  13. package/skills/embedded-captions/dna/chrome.json +68 -0
  14. package/skills/embedded-captions/dna/cream.json +69 -0
  15. package/skills/embedded-captions/dna/documentary.json +62 -0
  16. package/skills/embedded-captions/dna/editorial.json +70 -0
  17. package/skills/embedded-captions/dna/glitch.json +82 -0
  18. package/skills/embedded-captions/dna/ink.json +65 -0
  19. package/skills/embedded-captions/dna/keynote.json +62 -0
  20. package/skills/embedded-captions/dna/loud.json +75 -0
  21. package/skills/embedded-captions/dna/neon.json +58 -0
  22. package/skills/embedded-captions/dna/velocity.json +89 -0
  23. package/skills/embedded-captions/modes/cinematic/README.md +48 -0
  24. package/skills/embedded-captions/modes/cinematic/_archive/champion/spec.md +98 -0
  25. package/skills/embedded-captions/modes/cinematic/_archive/champion/template.html +188 -0
  26. package/skills/embedded-captions/modes/cinematic/_archive/memory-wall/spec.md +134 -0
  27. package/skills/embedded-captions/modes/cinematic/_archive/memory-wall/template.html +179 -0
  28. package/skills/embedded-captions/modes/cinematic/_archive/portrait-header/spec.md +81 -0
  29. package/skills/embedded-captions/modes/cinematic/_archive/portrait-header/template.html +170 -0
  30. package/skills/embedded-captions/modes/cinematic/cinematic-cream/spec.md +16 -0
  31. package/skills/embedded-captions/modes/cinematic/cinematic-cream/template.html +226 -0
  32. package/skills/embedded-captions/modes/cinematic/engine.html +355 -0
  33. package/skills/embedded-captions/modes/standard/_anatomy.md +233 -0
  34. package/skills/embedded-captions/modes/standard/_motion.md +192 -0
  35. package/skills/embedded-captions/modes/standard/fonts/build-fonts-css.cjs +97 -0
  36. package/skills/embedded-captions/modes/standard/fonts/files/anton-latin-400-normal.woff2 +0 -0
  37. package/skills/embedded-captions/modes/standard/fonts/files/audiowide-latin-400-normal.woff2 +0 -0
  38. package/skills/embedded-captions/modes/standard/fonts/files/baloo-2-latin-400-normal.woff2 +0 -0
  39. package/skills/embedded-captions/modes/standard/fonts/files/baloo-2-latin-700-normal.woff2 +0 -0
  40. package/skills/embedded-captions/modes/standard/fonts/files/bangers-latin-400-normal.woff2 +0 -0
  41. package/skills/embedded-captions/modes/standard/fonts/files/bodoni-moda-latin-400-normal.woff2 +0 -0
  42. package/skills/embedded-captions/modes/standard/fonts/files/bodoni-moda-latin-700-normal.woff2 +0 -0
  43. package/skills/embedded-captions/modes/standard/fonts/files/caveat-latin-400-normal.woff2 +0 -0
  44. package/skills/embedded-captions/modes/standard/fonts/files/caveat-latin-700-normal.woff2 +0 -0
  45. package/skills/embedded-captions/modes/standard/fonts/files/chakra-petch-latin-500-normal.woff2 +0 -0
  46. package/skills/embedded-captions/modes/standard/fonts/files/chakra-petch-latin-700-normal.woff2 +0 -0
  47. package/skills/embedded-captions/modes/standard/fonts/files/cinzel-latin-400-normal.woff2 +0 -0
  48. package/skills/embedded-captions/modes/standard/fonts/files/cinzel-latin-700-normal.woff2 +0 -0
  49. package/skills/embedded-captions/modes/standard/fonts/files/cormorant-garamond-latin-400-normal.woff2 +0 -0
  50. package/skills/embedded-captions/modes/standard/fonts/files/cormorant-garamond-latin-700-normal.woff2 +0 -0
  51. package/skills/embedded-captions/modes/standard/fonts/files/creepster-latin-400-normal.woff2 +0 -0
  52. package/skills/embedded-captions/modes/standard/fonts/files/fredoka-latin-400-normal.woff2 +0 -0
  53. package/skills/embedded-captions/modes/standard/fonts/files/fredoka-latin-700-normal.woff2 +0 -0
  54. package/skills/embedded-captions/modes/standard/fonts/files/inter-latin-400-normal.woff2 +0 -0
  55. package/skills/embedded-captions/modes/standard/fonts/files/inter-latin-500-italic.woff2 +0 -0
  56. package/skills/embedded-captions/modes/standard/fonts/files/inter-latin-500-normal.woff2 +0 -0
  57. package/skills/embedded-captions/modes/standard/fonts/files/inter-latin-600-italic.woff2 +0 -0
  58. package/skills/embedded-captions/modes/standard/fonts/files/inter-latin-600-normal.woff2 +0 -0
  59. package/skills/embedded-captions/modes/standard/fonts/files/inter-latin-700-normal.woff2 +0 -0
  60. package/skills/embedded-captions/modes/standard/fonts/files/inter-latin-800-normal.woff2 +0 -0
  61. package/skills/embedded-captions/modes/standard/fonts/files/inter-latin-900-normal.woff2 +0 -0
  62. package/skills/embedded-captions/modes/standard/fonts/files/monoton-latin-400-normal.woff2 +0 -0
  63. package/skills/embedded-captions/modes/standard/fonts/files/orbitron-latin-400-normal.woff2 +0 -0
  64. package/skills/embedded-captions/modes/standard/fonts/files/orbitron-latin-700-normal.woff2 +0 -0
  65. package/skills/embedded-captions/modes/standard/fonts/files/permanent-marker-latin-400-normal.woff2 +0 -0
  66. package/skills/embedded-captions/modes/standard/fonts/files/press-start-2p-latin-400-normal.woff2 +0 -0
  67. package/skills/embedded-captions/modes/standard/fonts/files/rajdhani-latin-500-normal.woff2 +0 -0
  68. package/skills/embedded-captions/modes/standard/fonts/files/rajdhani-latin-700-normal.woff2 +0 -0
  69. package/skills/embedded-captions/modes/standard/fonts/files/saira-stencil-one-latin-400-normal.woff2 +0 -0
  70. package/skills/embedded-captions/modes/standard/fonts/files/shippori-mincho-latin-400-normal.woff2 +0 -0
  71. package/skills/embedded-captions/modes/standard/fonts/files/shippori-mincho-latin-700-normal.woff2 +0 -0
  72. package/skills/embedded-captions/modes/standard/fonts/files/sora-latin-400-normal.woff2 +0 -0
  73. package/skills/embedded-captions/modes/standard/fonts/files/sora-latin-700-normal.woff2 +0 -0
  74. package/skills/embedded-captions/modes/standard/fonts/files/space-grotesk-latin-400-normal.woff2 +0 -0
  75. package/skills/embedded-captions/modes/standard/fonts/files/space-grotesk-latin-700-normal.woff2 +0 -0
  76. package/skills/embedded-captions/modes/standard/fonts/files/special-elite-latin-400-normal.woff2 +0 -0
  77. package/skills/embedded-captions/modes/standard/fonts/files/teko-latin-400-normal.woff2 +0 -0
  78. package/skills/embedded-captions/modes/standard/fonts/files/teko-latin-700-normal.woff2 +0 -0
  79. package/skills/embedded-captions/modes/standard/fonts/files/vt323-latin-400-normal.woff2 +0 -0
  80. package/skills/embedded-captions/modes/standard/fonts/fonts.css +401 -0
  81. package/skills/embedded-captions/references/aesthetic-principles.md +168 -0
  82. package/skills/embedded-captions/references/anti-patterns.md +188 -0
  83. package/skills/embedded-captions/references/bespoke-vs-presets.md +178 -0
  84. package/skills/embedded-captions/references/caption-grouping.md +130 -0
  85. package/skills/embedded-captions/references/composition-craft.md +522 -0
  86. package/skills/embedded-captions/references/direction-catalog.md +138 -0
  87. package/skills/embedded-captions/references/example-renders/champion.html +371 -0
  88. package/skills/embedded-captions/references/example-renders/memory-wall.html +334 -0
  89. package/skills/embedded-captions/references/failure-modes.md +145 -0
  90. package/skills/embedded-captions/references/layout-heuristics.md +238 -0
  91. package/skills/embedded-captions/references/motion-vocabulary.md +148 -0
  92. package/skills/embedded-captions/references/rail.md +68 -0
  93. package/skills/embedded-captions/references/reference-bar.md +47 -0
  94. package/skills/embedded-captions/references/scene-types.md +94 -0
  95. package/skills/embedded-captions/references/typographic-moves.md +266 -0
  96. package/skills/embedded-captions/references/typography-presets.md +63 -0
  97. package/skills/embedded-captions/scripts/audio-envelope.cjs +95 -0
  98. package/skills/embedded-captions/scripts/check-occlusion.cjs +250 -0
  99. package/skills/embedded-captions/scripts/check-overflow.cjs +194 -0
  100. package/skills/embedded-captions/scripts/check-rail-climax.cjs +233 -0
  101. package/skills/embedded-captions/scripts/check-timing.cjs +173 -0
  102. package/skills/embedded-captions/scripts/fill-timings.cjs +124 -0
  103. package/skills/embedded-captions/scripts/fit-fonts.cjs +158 -0
  104. package/skills/embedded-captions/scripts/gen-stroke-path.py +57 -0
  105. package/skills/embedded-captions/scripts/inject-fonts.cjs +169 -0
  106. package/skills/embedded-captions/scripts/lib-dna.cjs +201 -0
  107. package/skills/embedded-captions/scripts/make-cinematic.cjs +1206 -0
  108. package/skills/embedded-captions/scripts/make-composition.cjs +405 -0
  109. package/skills/embedded-captions/scripts/make-theme.cjs +8585 -0
  110. package/skills/embedded-captions/scripts/matte.cjs +280 -0
  111. package/skills/embedded-captions/scripts/measure-layout.cjs +293 -0
  112. package/skills/embedded-captions/scripts/prepare.sh +39 -0
  113. package/skills/embedded-captions/scripts/preview-frames.cjs +268 -0
  114. package/skills/embedded-captions/scripts/render-and-composite.sh +469 -0
  115. package/skills/embedded-captions/scripts/render-theme.sh +34 -0
  116. package/skills/embedded-captions/scripts/safe-zones.cjs +813 -0
  117. package/skills/embedded-captions/scripts/transcribe.cjs +332 -0
  118. package/skills/embedded-captions/themes/README.md +243 -0
  119. package/skills/embedded-captions/themes/anchor.json +27 -0
  120. package/skills/embedded-captions/themes/arcade.json +51 -0
  121. package/skills/embedded-captions/themes/aurora.json +41 -0
  122. package/skills/embedded-captions/themes/biolume.json +35 -0
  123. package/skills/embedded-captions/themes/brush.json +74 -0
  124. package/skills/embedded-captions/themes/chalkboard.json +52 -0
  125. package/skills/embedded-captions/themes/dossier.json +56 -0
  126. package/skills/embedded-captions/themes/graffiti.json +62 -0
  127. package/skills/embedded-captions/themes/hologram.json +41 -0
  128. package/skills/embedded-captions/themes/inkwater.json +43 -0
  129. package/skills/embedded-captions/themes/laser.json +46 -0
  130. package/skills/embedded-captions/themes/lastpage.json +33 -0
  131. package/skills/embedded-captions/themes/neonsign.json +53 -0
  132. package/skills/embedded-captions/themes/ordnance.json +54 -0
  133. package/skills/embedded-captions/themes/papercut.json +37 -0
  134. package/skills/embedded-captions/themes/popup.json +46 -0
  135. package/skills/embedded-captions/themes/ransom.json +62 -0
  136. package/skills/embedded-captions/themes/scoreboard.json +54 -0
  137. package/skills/embedded-captions/themes/spectrum.json +46 -0
  138. package/skills/embedded-captions/themes/stardust.json +29 -0
  139. package/skills/embedded-captions/themes/stomp.json +43 -0
  140. package/skills/embedded-captions/themes/terminal.json +49 -0
  141. package/skills/embedded-captions/themes/thunder.json +44 -0
  142. package/skills/embedded-captions/themes/transit.json +44 -0
  143. package/skills/embedded-captions/themes/vhs.json +47 -0
  144. package/skills/faceless-explainer/SKILL.md +233 -0
  145. package/skills/faceless-explainer/references/cut-catalog.md +215 -0
  146. package/skills/faceless-explainer/references/motion-language.md +156 -0
  147. package/skills/faceless-explainer/references/story-design.md +255 -0
  148. package/skills/faceless-explainer/references/visual-design.md +146 -0
  149. package/skills/faceless-explainer/scripts/assemble-index.mjs +623 -0
  150. package/skills/faceless-explainer/scripts/assemble-index.test.mjs +72 -0
  151. package/skills/faceless-explainer/scripts/audio.mjs +291 -0
  152. package/skills/faceless-explainer/scripts/audio.test.mjs +176 -0
  153. package/skills/faceless-explainer/scripts/build-frame.mjs +551 -0
  154. package/skills/faceless-explainer/scripts/captions.mjs +521 -0
  155. package/skills/faceless-explainer/scripts/captions.test.mjs +219 -0
  156. package/skills/faceless-explainer/scripts/frame-packets.mjs +27 -0
  157. package/skills/faceless-explainer/scripts/frame-packets.test.mjs +66 -0
  158. package/skills/faceless-explainer/scripts/lib/assets.mjs +56 -0
  159. package/skills/faceless-explainer/scripts/lib/dimensions.mjs +45 -0
  160. package/skills/faceless-explainer/scripts/lib/pad-frame-duration.mjs +36 -0
  161. package/skills/faceless-explainer/scripts/lib/storyboard.mjs +249 -0
  162. package/skills/faceless-explainer/scripts/lib/tokens.mjs +211 -0
  163. package/skills/faceless-explainer/scripts/lib/transition-registry.mjs +38 -0
  164. package/skills/faceless-explainer/scripts/lib/transitions.json +71 -0
  165. package/skills/faceless-explainer/scripts/transitions.mjs +383 -0
  166. package/skills/faceless-explainer/scripts/transitions.test.mjs +68 -0
  167. package/skills/faceless-explainer/sub-agents/frame-worker.md +12 -0
  168. package/skills/figma/SKILL.md +132 -0
  169. package/skills/figma/scripts/verify-motion.mjs +153 -0
  170. package/skills/general-video/SKILL.md +165 -0
  171. package/skills/general-video/scripts/frame-packets.mjs +38 -0
  172. package/skills/general-video/scripts/frame-packets.test.mjs +80 -0
  173. package/skills/general-video/sub-agents/frame-worker.md +34 -0
  174. package/skills/hyperframes/SKILL.md +98 -337
  175. package/skills/hyperframes/references/capability-menu.md +47 -0
  176. package/skills/hyperframes/references/intent-interview.md +71 -0
  177. package/skills/hyperframes/references/pitch-round.md +40 -0
  178. package/skills/hyperframes/references/route-briefs.md +11 -0
  179. package/skills/hyperframes/references/routes/embedded-captions.md +11 -0
  180. package/skills/hyperframes/references/routes/faceless-explainer.md +12 -0
  181. package/skills/hyperframes/references/routes/general-video.md +12 -0
  182. package/skills/hyperframes/references/routes/motion-graphics.md +11 -0
  183. package/skills/hyperframes/references/routes/music-to-video.md +12 -0
  184. package/skills/hyperframes/references/routes/pr-to-video.md +28 -0
  185. package/skills/hyperframes/references/routes/product-launch-video.md +13 -0
  186. package/skills/hyperframes/references/routes/remotion-to-hyperframes.md +9 -0
  187. package/skills/hyperframes/references/routes/slideshow.md +11 -0
  188. package/skills/hyperframes/references/routes/talking-head-recut.md +11 -0
  189. package/skills/hyperframes/references/skill-lifecycle.md +33 -0
  190. package/skills/hyperframes/references/workflow-catalog.md +10 -0
  191. package/skills/hyperframes-animation/SKILL.md +84 -0
  192. package/skills/hyperframes-animation/adapters/animate-text.md +64 -0
  193. package/skills/hyperframes-animation/adapters/animejs.md +130 -0
  194. package/skills/hyperframes-animation/adapters/css-animations.md +143 -0
  195. package/skills/hyperframes-animation/adapters/gsap-easing-and-stagger.md +199 -0
  196. package/skills/hyperframes-animation/adapters/gsap-timeline-and-labels.md +96 -0
  197. package/skills/hyperframes-animation/adapters/gsap-transforms-and-perf.md +129 -0
  198. package/skills/hyperframes-animation/adapters/gsap.md +105 -0
  199. package/skills/hyperframes-animation/adapters/html-in-canvas-patterns.md +507 -0
  200. package/skills/hyperframes-animation/adapters/lottie.md +117 -0
  201. package/skills/hyperframes-animation/adapters/three.md +131 -0
  202. package/skills/hyperframes-animation/adapters/typegpu.md +182 -0
  203. package/skills/hyperframes-animation/adapters/waapi.md +101 -0
  204. package/skills/hyperframes-animation/blueprints/agent-progress-theater.md +76 -0
  205. package/skills/hyperframes-animation/blueprints/camera-journey.md +61 -0
  206. package/skills/hyperframes-animation/blueprints/comparison-split.md +27 -0
  207. package/skills/hyperframes-animation/blueprints/constellation-hub.md +63 -0
  208. package/skills/hyperframes-animation/blueprints/cta-morph-press.md +63 -0
  209. package/skills/hyperframes-animation/blueprints/cursor-ui-demo.md +89 -0
  210. package/skills/hyperframes-animation/blueprints/dataviz-countup.md +59 -0
  211. package/skills/hyperframes-animation/blueprints/device-surface-showcase.md +68 -0
  212. package/skills/hyperframes-animation/blueprints/fixed-anchor-cycle.md +46 -0
  213. package/skills/hyperframes-animation/blueprints/grid-card-assemble.md +81 -0
  214. package/skills/hyperframes-animation/blueprints/kinetic-type-beats.md +133 -0
  215. package/skills/hyperframes-animation/blueprints/logo-assemble-lockup.md +121 -0
  216. package/skills/hyperframes-animation/blueprints/overwhelm-surround.md +58 -0
  217. package/skills/hyperframes-animation/blueprints/panel-edit-live-sync.md +73 -0
  218. package/skills/hyperframes-animation/blueprints/prompt-type-submit-generate.md +85 -0
  219. package/skills/hyperframes-animation/blueprints/spatial-pan-stations.md +37 -0
  220. package/skills/hyperframes-animation/blueprints/ticker-takeover.md +29 -0
  221. package/skills/hyperframes-animation/blueprints/titlecard-reveal.md +80 -0
  222. package/skills/hyperframes-animation/blueprints/transcript-scroll-artifact-reveal.md +45 -0
  223. package/skills/hyperframes-animation/blueprints/typewriter-reveal.md +51 -0
  224. package/skills/hyperframes-animation/blueprints/video-text-pivot.md +30 -0
  225. package/skills/hyperframes-animation/blueprints/zoom-out-workspace-reveal.md +68 -0
  226. package/skills/hyperframes-animation/blueprints-index.md +202 -0
  227. package/skills/hyperframes-animation/examples/brand-reveal-assemble-zoom.html +382 -0
  228. package/skills/hyperframes-animation/examples/comparison-split-cards.html +649 -0
  229. package/skills/hyperframes-animation/examples/concept-demo-decode-pan.html +520 -0
  230. package/skills/hyperframes-animation/examples/cta-morph-press.html +468 -0
  231. package/skills/hyperframes-animation/examples/cta-orbit-collapse.html +1298 -0
  232. package/skills/hyperframes-animation/examples/demo-page-scroll-spotlight.html +759 -0
  233. package/skills/hyperframes-animation/examples/hook-counter-burst.html +729 -0
  234. package/skills/hyperframes-animation/examples/messaging-multi-phrase.html +352 -0
  235. package/skills/hyperframes-animation/examples/metric-video-text-pivot.html +779 -0
  236. package/skills/hyperframes-animation/examples/problem-mockup-overwhelm.html +1374 -0
  237. package/skills/hyperframes-animation/examples/proof-logo-chain.html +861 -0
  238. package/skills/hyperframes-animation/examples/takeover-ticker-displace.html +347 -0
  239. package/skills/hyperframes-animation/examples/workflow-approve-press.html +606 -0
  240. package/skills/hyperframes-animation/rules/3d-camera-flight.md +180 -0
  241. package/skills/hyperframes-animation/rules/3d-page-scroll.md +135 -0
  242. package/skills/hyperframes-animation/rules/3d-text-depth-layers.md +128 -0
  243. package/skills/hyperframes-animation/rules/ai-tracking-box.md +139 -0
  244. package/skills/hyperframes-animation/rules/ambient-glow-bloom.md +133 -0
  245. package/skills/hyperframes-animation/rules/anchored-layout-expand.md +148 -0
  246. package/skills/hyperframes-animation/rules/asr-keyword-glow.md +128 -0
  247. package/skills/hyperframes-animation/rules/avatar-cloud-network.md +145 -0
  248. package/skills/hyperframes-animation/rules/camera-cursor-tracking.md +133 -0
  249. package/skills/hyperframes-animation/rules/card-morph-anchor.md +134 -0
  250. package/skills/hyperframes-animation/rules/center-outward-expansion.md +88 -0
  251. package/skills/hyperframes-animation/rules/chart-scrub-readout.md +151 -0
  252. package/skills/hyperframes-animation/rules/chromatic-glitch.md +150 -0
  253. package/skills/hyperframes-animation/rules/context-sensitive-cursor.md +140 -0
  254. package/skills/hyperframes-animation/rules/control-target-sync.md +131 -0
  255. package/skills/hyperframes-animation/rules/coordinate-target-zoom.md +138 -0
  256. package/skills/hyperframes-animation/rules/counting-dynamic-scale.md +115 -0
  257. package/skills/hyperframes-animation/rules/css-marker-patterns.md +208 -0
  258. package/skills/hyperframes-animation/rules/cursor-click-ripple.md +104 -0
  259. package/skills/hyperframes-animation/rules/cursor-drag.md +141 -0
  260. package/skills/hyperframes-animation/rules/depth-of-field-blur.md +112 -0
  261. package/skills/hyperframes-animation/rules/depth-scatter-assemble.md +139 -0
  262. package/skills/hyperframes-animation/rules/discrete-text-sequence.md +146 -0
  263. package/skills/hyperframes-animation/rules/dynamic-content-sequencing.md +149 -0
  264. package/skills/hyperframes-animation/rules/gradient-text-sweep.md +136 -0
  265. package/skills/hyperframes-animation/rules/gsap-effects.md +196 -0
  266. package/skills/hyperframes-animation/rules/hacker-flip-3d.md +123 -0
  267. package/skills/hyperframes-animation/rules/kinetic-beat-slam.md +137 -0
  268. package/skills/hyperframes-animation/rules/motion-blur-streak.md +130 -0
  269. package/skills/hyperframes-animation/rules/multi-cursor-choreography.md +133 -0
  270. package/skills/hyperframes-animation/rules/multi-phase-camera.md +129 -0
  271. package/skills/hyperframes-animation/rules/nudge-curve.md +47 -0
  272. package/skills/hyperframes-animation/rules/orbit-3d-entry.md +148 -0
  273. package/skills/hyperframes-animation/rules/particle-burst.md +149 -0
  274. package/skills/hyperframes-animation/rules/physics-press-reaction.md +101 -0
  275. package/skills/hyperframes-animation/rules/press-release-spring.md +108 -0
  276. package/skills/hyperframes-animation/rules/reactive-displacement.md +92 -0
  277. package/skills/hyperframes-animation/rules/scale-swap-transition.md +88 -0
  278. package/skills/hyperframes-animation/rules/sine-wave-loop.md +85 -0
  279. package/skills/hyperframes-animation/rules/split-tilt-cards.md +123 -0
  280. package/skills/hyperframes-animation/rules/spring-pop-entrance.md +107 -0
  281. package/skills/hyperframes-animation/rules/stat-bars-and-fills.md +145 -0
  282. package/skills/hyperframes-animation/rules/svg-icon-enrichment.md +141 -0
  283. package/skills/hyperframes-animation/rules/svg-path-draw.md +122 -0
  284. package/skills/hyperframes-animation/rules/theme-crossfade-morph.md +126 -0
  285. package/skills/hyperframes-animation/rules/vertical-spring-ticker.md +104 -0
  286. package/skills/hyperframes-animation/rules/viewport-change.md +148 -0
  287. package/skills/hyperframes-animation/rules/waterfall-entry.md +81 -0
  288. package/skills/hyperframes-animation/rules-index.md +113 -0
  289. package/skills/hyperframes-animation/scripts/animation-map-sampling.mjs +40 -0
  290. package/skills/hyperframes-animation/scripts/animation-map-sampling.test.mjs +48 -0
  291. package/skills/{hyperframes → hyperframes-animation}/scripts/animation-map.mjs +116 -53
  292. package/skills/hyperframes-animation/scripts/animation-map.test.mjs +444 -0
  293. package/skills/hyperframes-animation/scripts/package-loader.mjs +384 -0
  294. package/skills/hyperframes-animation/scripts/package-loader.test.mjs +62 -0
  295. package/skills/{website-to-hyperframes/references → hyperframes-animation}/techniques.md +146 -26
  296. package/skills/hyperframes-animation/transitions/TRANSITION-REGISTRY.md +168 -0
  297. package/skills/{hyperframes/references → hyperframes-animation}/transitions/catalog.md +26 -16
  298. package/skills/{hyperframes/references → hyperframes-animation}/transitions/css-destruction.md +1 -1
  299. package/skills/{hyperframes/references/transitions.md → hyperframes-animation/transitions/overview.md} +44 -3
  300. package/skills/hyperframes-audio/SKILL.md +470 -0
  301. package/skills/hyperframes-audio/references/attributes.md +138 -0
  302. package/skills/hyperframes-audio/references/diagnosis.md +276 -0
  303. package/skills/hyperframes-audio/references/fx-registry.md +84 -0
  304. package/skills/hyperframes-audio/references/presets.md +216 -0
  305. package/skills/hyperframes-audio/scripts/carve.mjs +569 -0
  306. package/skills/hyperframes-audio/scripts/carve.test.mjs +239 -0
  307. package/skills/hyperframes-cli/SKILL.md +121 -103
  308. package/skills/hyperframes-cli/references/beats.md +19 -0
  309. package/skills/hyperframes-cli/references/cloud.md +163 -0
  310. package/skills/hyperframes-cli/references/cloudrun.md +62 -0
  311. package/skills/hyperframes-cli/references/compare-and-batch.md +105 -0
  312. package/skills/hyperframes-cli/references/doctor-browser.md +57 -0
  313. package/skills/hyperframes-cli/references/init-and-scaffold.md +72 -0
  314. package/skills/hyperframes-cli/references/lambda.md +185 -0
  315. package/skills/hyperframes-cli/references/lint-validate-inspect.md +132 -0
  316. package/skills/hyperframes-cli/references/preview-render.md +190 -0
  317. package/skills/hyperframes-cli/references/upgrade-info-misc.md +77 -0
  318. package/skills/hyperframes-core/SKILL.md +94 -0
  319. package/skills/hyperframes-core/references/brief-contract.md +108 -0
  320. package/skills/hyperframes-core/references/brief-format.md +72 -0
  321. package/skills/hyperframes-core/references/composition-patterns.md +263 -0
  322. package/skills/hyperframes-core/references/creator-editing-recipes.md +367 -0
  323. package/skills/hyperframes-core/references/data-attributes.md +78 -0
  324. package/skills/hyperframes-core/references/determinism-rules.md +70 -0
  325. package/skills/hyperframes-core/references/frame-worker-core.md +80 -0
  326. package/skills/hyperframes-core/references/full-screen-motion.md +76 -0
  327. package/skills/hyperframes-core/references/minimal-composition.md +69 -0
  328. package/skills/hyperframes-core/references/production-loop.md +26 -0
  329. package/skills/hyperframes-core/references/review-loop.md +41 -0
  330. package/skills/hyperframes-core/references/script-format.md +52 -0
  331. package/skills/hyperframes-core/references/storyboard-format.md +130 -0
  332. package/skills/hyperframes-core/references/sub-compositions.md +239 -0
  333. package/skills/hyperframes-core/references/subagent-dispatch.md +35 -0
  334. package/skills/hyperframes-core/references/tailwind.md +123 -0
  335. package/skills/hyperframes-core/references/tracks-and-clips.md +91 -0
  336. package/skills/hyperframes-core/references/variables-and-media.md +107 -0
  337. package/skills/hyperframes-core/scripts/lib/frame-packets-core.mjs +212 -0
  338. package/skills/hyperframes-creative/SKILL.md +71 -0
  339. package/skills/hyperframes-creative/frame-presets/biennale-yellow/FRAME.md +289 -0
  340. package/skills/hyperframes-creative/frame-presets/biennale-yellow/caption-skin.html +221 -0
  341. package/skills/hyperframes-creative/frame-presets/biennale-yellow/frame-showcase.html +1214 -0
  342. package/skills/hyperframes-creative/frame-presets/blockframe/FRAME.md +275 -0
  343. package/skills/hyperframes-creative/frame-presets/blockframe/caption-skin.html +224 -0
  344. package/skills/hyperframes-creative/frame-presets/blockframe/frame-showcase.html +1347 -0
  345. package/skills/hyperframes-creative/frame-presets/blue-professional/FRAME.md +307 -0
  346. package/skills/hyperframes-creative/frame-presets/blue-professional/caption-skin.html +223 -0
  347. package/skills/hyperframes-creative/frame-presets/blue-professional/frame-showcase.html +1372 -0
  348. package/skills/hyperframes-creative/frame-presets/bold-poster/FRAME.md +275 -0
  349. package/skills/hyperframes-creative/frame-presets/bold-poster/caption-skin.html +230 -0
  350. package/skills/hyperframes-creative/frame-presets/bold-poster/frame-showcase.html +1140 -0
  351. package/skills/hyperframes-creative/frame-presets/broadside/FRAME.md +284 -0
  352. package/skills/hyperframes-creative/frame-presets/broadside/caption-skin.html +225 -0
  353. package/skills/hyperframes-creative/frame-presets/broadside/frame-showcase.html +1166 -0
  354. package/skills/hyperframes-creative/frame-presets/capsule/FRAME.md +284 -0
  355. package/skills/hyperframes-creative/frame-presets/capsule/caption-skin.html +224 -0
  356. package/skills/hyperframes-creative/frame-presets/capsule/frame-showcase.html +1465 -0
  357. package/skills/hyperframes-creative/frame-presets/cartesian/FRAME.md +278 -0
  358. package/skills/hyperframes-creative/frame-presets/cartesian/caption-skin.html +222 -0
  359. package/skills/hyperframes-creative/frame-presets/cartesian/frame-showcase.html +1263 -0
  360. package/skills/hyperframes-creative/frame-presets/cobalt-grid/FRAME.md +265 -0
  361. package/skills/hyperframes-creative/frame-presets/cobalt-grid/caption-skin.html +238 -0
  362. package/skills/hyperframes-creative/frame-presets/cobalt-grid/frame-showcase.html +1468 -0
  363. package/skills/hyperframes-creative/frame-presets/code-editorial/FRAME.md +277 -0
  364. package/skills/hyperframes-creative/frame-presets/code-editorial/caption-skin.html +224 -0
  365. package/skills/hyperframes-creative/frame-presets/code-editorial/fonts/EBGaramond-400.woff2 +0 -0
  366. package/skills/hyperframes-creative/frame-presets/code-editorial/fonts/EBGaramond-700.woff2 +0 -0
  367. package/skills/hyperframes-creative/frame-presets/code-editorial/fonts/Inter-400.woff2 +0 -0
  368. package/skills/hyperframes-creative/frame-presets/code-editorial/fonts/Inter-700.woff2 +0 -0
  369. package/skills/hyperframes-creative/frame-presets/code-editorial/fonts/JetBrainsMono-400.woff2 +0 -0
  370. package/skills/hyperframes-creative/frame-presets/code-editorial/fonts/JetBrainsMono-700.woff2 +0 -0
  371. package/skills/hyperframes-creative/frame-presets/code-editorial/fonts/OFL-eb-garamond.txt +93 -0
  372. package/skills/hyperframes-creative/frame-presets/code-editorial/fonts/OFL-inter.txt +93 -0
  373. package/skills/hyperframes-creative/frame-presets/code-editorial/fonts/OFL-jetbrains-mono.txt +93 -0
  374. package/skills/hyperframes-creative/frame-presets/code-editorial/frame-showcase.html +1438 -0
  375. package/skills/hyperframes-creative/frame-presets/coral/FRAME.md +314 -0
  376. package/skills/hyperframes-creative/frame-presets/coral/caption-skin.html +226 -0
  377. package/skills/hyperframes-creative/frame-presets/coral/frame-showcase.html +1268 -0
  378. package/skills/hyperframes-creative/frame-presets/creative-mode/FRAME.md +333 -0
  379. package/skills/hyperframes-creative/frame-presets/creative-mode/caption-skin.html +227 -0
  380. package/skills/hyperframes-creative/frame-presets/creative-mode/frame-showcase.html +1330 -0
  381. package/skills/hyperframes-creative/frame-presets/daisy-days/FRAME.md +274 -0
  382. package/skills/hyperframes-creative/frame-presets/daisy-days/caption-skin.html +230 -0
  383. package/skills/hyperframes-creative/frame-presets/daisy-days/frame-showcase.html +1444 -0
  384. package/skills/hyperframes-creative/frame-presets/editorial-forest/FRAME.md +265 -0
  385. package/skills/hyperframes-creative/frame-presets/editorial-forest/caption-skin.html +223 -0
  386. package/skills/hyperframes-creative/frame-presets/editorial-forest/frame-showcase.html +1273 -0
  387. package/skills/{hyperframes → hyperframes-creative}/references/audio-reactive.md +1 -1
  388. package/skills/hyperframes-creative/references/beat-direction.md +164 -0
  389. package/skills/hyperframes-creative/references/composition-patterns.md +199 -0
  390. package/skills/{hyperframes → hyperframes-creative/references}/data-in-motion.md +1 -1
  391. package/skills/hyperframes-creative/references/design-adherence.md +19 -0
  392. package/skills/hyperframes-creative/references/design-picker.md +123 -0
  393. package/skills/hyperframes-creative/references/design-spec.md +55 -0
  394. package/skills/{hyperframes → hyperframes-creative/references}/house-style.md +4 -2
  395. package/skills/hyperframes-creative/references/motion-principles.md +151 -0
  396. package/skills/{website-to-hyperframes/references/step-3-script.md → hyperframes-creative/references/narration.md} +5 -9
  397. package/skills/hyperframes-creative/references/prompt-expansion.md +68 -0
  398. package/skills/hyperframes-creative/references/story-spine.md +43 -0
  399. package/skills/{hyperframes → hyperframes-creative}/references/typography.md +45 -2
  400. package/skills/hyperframes-creative/references/video-composition.md +63 -0
  401. package/skills/hyperframes-creative/references/visual-styles.md +457 -0
  402. package/skills/hyperframes-creative/scripts/contrast-report.mjs +538 -0
  403. package/skills/{gsap → hyperframes-creative}/scripts/extract-audio-data.py +13 -2
  404. package/skills/hyperframes-creative/scripts/package-loader.mjs +384 -0
  405. package/skills/hyperframes-creative/scripts/package-loader.test.mjs +62 -0
  406. package/skills/hyperframes-creative/templates/design-picker.html +1432 -0
  407. package/skills/hyperframes-keyframes/SKILL.md +262 -0
  408. package/skills/hyperframes-keyframes/agents/openai.yaml +4 -0
  409. package/skills/hyperframes-keyframes/references/keyframe-patterns.md +108 -0
  410. package/skills/hyperframes-registry/SKILL.md +55 -16
  411. package/skills/hyperframes-registry/references/component-quality-bar.md +250 -0
  412. package/skills/hyperframes-registry/references/contributing.md +174 -0
  413. package/skills/hyperframes-registry/references/discovery.md +191 -13
  414. package/skills/hyperframes-registry/references/placeholder-material.md +149 -0
  415. package/skills/hyperframes-registry/references/templates.md +417 -0
  416. package/skills/hyperframes-registry/references/wiring-blocks.md +1 -31
  417. package/skills/hyperframes-registry/references/wiring-components.md +1 -39
  418. package/skills/media-use/SKILL.md +96 -0
  419. package/skills/media-use/audio/assets/sfx/CREDITS.md +35 -0
  420. package/skills/media-use/audio/assets/sfx/chime.mp3 +0 -0
  421. package/skills/media-use/audio/assets/sfx/click-soft.mp3 +0 -0
  422. package/skills/media-use/audio/assets/sfx/click.mp3 +0 -0
  423. package/skills/media-use/audio/assets/sfx/error.mp3 +0 -0
  424. package/skills/media-use/audio/assets/sfx/glitch-1.mp3 +0 -0
  425. package/skills/media-use/audio/assets/sfx/glitch-2.mp3 +0 -0
  426. package/skills/media-use/audio/assets/sfx/glitch-3.mp3 +0 -0
  427. package/skills/media-use/audio/assets/sfx/impact-bass-1.mp3 +0 -0
  428. package/skills/media-use/audio/assets/sfx/impact-bass-2.mp3 +0 -0
  429. package/skills/media-use/audio/assets/sfx/key-press.mp3 +0 -0
  430. package/skills/media-use/audio/assets/sfx/manifest.json +97 -0
  431. package/skills/media-use/audio/assets/sfx/notification.mp3 +0 -0
  432. package/skills/media-use/audio/assets/sfx/ping.mp3 +0 -0
  433. package/skills/media-use/audio/assets/sfx/pop.mp3 +0 -0
  434. package/skills/media-use/audio/assets/sfx/riser.mp3 +0 -0
  435. package/skills/media-use/audio/assets/sfx/sparkle.mp3 +0 -0
  436. package/skills/media-use/audio/assets/sfx/typing.mp3 +0 -0
  437. package/skills/media-use/audio/assets/sfx/whoosh-cinematic.mp3 +0 -0
  438. package/skills/media-use/audio/assets/sfx/whoosh-short.mp3 +0 -0
  439. package/skills/media-use/audio/assets/sfx/whoosh.mp3 +0 -0
  440. package/skills/media-use/audio/references/bgm.md +74 -0
  441. package/skills/media-use/audio/references/captions/authoring.md +159 -0
  442. package/skills/{hyperframes/references/dynamic-techniques.md → media-use/audio/references/captions/motion.md} +8 -11
  443. package/skills/{hyperframes/references/transcript-guide.md → media-use/audio/references/captions/transcript-handling.md} +5 -59
  444. package/skills/media-use/audio/references/remove-background.md +143 -0
  445. package/skills/media-use/audio/references/requirements.md +29 -0
  446. package/skills/media-use/audio/references/sfx.md +42 -0
  447. package/skills/media-use/audio/references/transcribe.md +52 -0
  448. package/skills/media-use/audio/references/tts-to-captions.md +26 -0
  449. package/skills/media-use/audio/references/tts.md +165 -0
  450. package/skills/media-use/audio/scripts/audio.mjs +293 -0
  451. package/skills/media-use/audio/scripts/audio.test.mjs +49 -0
  452. package/skills/media-use/audio/scripts/heygen-tts.mjs +121 -0
  453. package/skills/media-use/audio/scripts/lib/bgm.mjs +257 -0
  454. package/skills/media-use/audio/scripts/lib/bgm.test.mjs +30 -0
  455. package/skills/media-use/audio/scripts/lib/concurrency.mjs +14 -0
  456. package/skills/media-use/audio/scripts/lib/concurrency.test.mjs +41 -0
  457. package/skills/media-use/audio/scripts/lib/heygen.mjs +155 -0
  458. package/skills/media-use/audio/scripts/lib/heygen.test.mjs +103 -0
  459. package/skills/media-use/audio/scripts/lib/python.mjs +63 -0
  460. package/skills/media-use/audio/scripts/lib/python.test.mjs +68 -0
  461. package/skills/media-use/audio/scripts/lib/sfx.mjs +143 -0
  462. package/skills/media-use/audio/scripts/lib/sfx.test.mjs +69 -0
  463. package/skills/media-use/audio/scripts/lib/tts.mjs +378 -0
  464. package/skills/media-use/audio/scripts/lib/tts.spawn.test.mjs +158 -0
  465. package/skills/media-use/audio/scripts/lib/tts.test.mjs +157 -0
  466. package/skills/media-use/audio/scripts/lyria-recipe.py +136 -0
  467. package/skills/media-use/audio/scripts/wait-bgm.mjs +167 -0
  468. package/skills/media-use/luts/README.md +28 -0
  469. package/skills/media-use/luts/index.json +57 -0
  470. package/skills/media-use/references/audio.md +19 -0
  471. package/skills/media-use/references/grading.md +160 -0
  472. package/skills/media-use/references/media-treatment-recipes.md +929 -0
  473. package/skills/media-use/references/media-treatments.md +202 -0
  474. package/skills/media-use/references/memory.md +36 -0
  475. package/skills/media-use/references/meta.md +61 -0
  476. package/skills/media-use/references/operations.md +325 -0
  477. package/skills/media-use/references/resolve.md +139 -0
  478. package/skills/media-use/references/setup-providers.md +80 -0
  479. package/skills/media-use/references/telemetry-dashboard.md +49 -0
  480. package/skills/media-use/scripts/audio-duck.mjs +121 -0
  481. package/skills/media-use/scripts/dither.mjs +328 -0
  482. package/skills/media-use/scripts/dither.test.mjs +176 -0
  483. package/skills/media-use/scripts/eval.mjs +369 -0
  484. package/skills/media-use/scripts/lib/adopt.mjs +128 -0
  485. package/skills/media-use/scripts/lib/adopt.test.mjs +95 -0
  486. package/skills/media-use/scripts/lib/bgm-provider.mjs +20 -0
  487. package/skills/media-use/scripts/lib/brand-provider.mjs +59 -0
  488. package/skills/media-use/scripts/lib/bundled-sfx-provider.mjs +108 -0
  489. package/skills/media-use/scripts/lib/bundled-sfx-provider.test.mjs +85 -0
  490. package/skills/media-use/scripts/lib/cache.mjs +150 -0
  491. package/skills/media-use/scripts/lib/candidates.mjs +91 -0
  492. package/skills/media-use/scripts/lib/candidates.test.mjs +155 -0
  493. package/skills/media-use/scripts/lib/codex-provider.mjs +161 -0
  494. package/skills/media-use/scripts/lib/codex-provider.test.mjs +34 -0
  495. package/skills/media-use/scripts/lib/coverage.test.mjs +117 -0
  496. package/skills/media-use/scripts/lib/cube-build.mjs +181 -0
  497. package/skills/media-use/scripts/lib/cube-build.test.mjs +80 -0
  498. package/skills/media-use/scripts/lib/cube-validate.mjs +198 -0
  499. package/skills/media-use/scripts/lib/cube-validate.test.mjs +125 -0
  500. package/skills/media-use/scripts/lib/cutlist.mjs +184 -0
  501. package/skills/media-use/scripts/lib/cutlist.test.mjs +148 -0
  502. package/skills/media-use/scripts/lib/duck.mjs +89 -0
  503. package/skills/media-use/scripts/lib/duck.test.mjs +118 -0
  504. package/skills/media-use/scripts/lib/error-diffusion.mjs +230 -0
  505. package/skills/media-use/scripts/lib/error-diffusion.test.mjs +102 -0
  506. package/skills/media-use/scripts/lib/freeze.mjs +70 -0
  507. package/skills/media-use/scripts/lib/freeze.test.mjs +46 -0
  508. package/skills/media-use/scripts/lib/grade-analyzer.mjs +264 -0
  509. package/skills/media-use/scripts/lib/grade-analyzer.test.mjs +285 -0
  510. package/skills/media-use/scripts/lib/heygen-cli.mjs +191 -0
  511. package/skills/media-use/scripts/lib/heygen-cli.test.mjs +301 -0
  512. package/skills/media-use/scripts/lib/heygen-search.mjs +45 -0
  513. package/skills/media-use/scripts/lib/heygen-search.test.mjs +49 -0
  514. package/skills/media-use/scripts/lib/heygen-video-provider.mjs +127 -0
  515. package/skills/media-use/scripts/lib/heygen-video-provider.test.mjs +344 -0
  516. package/skills/media-use/scripts/lib/image-provider.mjs +44 -0
  517. package/skills/media-use/scripts/lib/index-gen.mjs +63 -0
  518. package/skills/media-use/scripts/lib/local-models.mjs +318 -0
  519. package/skills/media-use/scripts/lib/local-models.test.mjs +220 -0
  520. package/skills/media-use/scripts/lib/local-run.mjs +78 -0
  521. package/skills/media-use/scripts/lib/local-run.test.mjs +121 -0
  522. package/skills/media-use/scripts/lib/logo-provider.mjs +222 -0
  523. package/skills/media-use/scripts/lib/logo-provider.test.mjs +137 -0
  524. package/skills/media-use/scripts/lib/ltx-video-provider.mjs +94 -0
  525. package/skills/media-use/scripts/lib/ltx-video-provider.test.mjs +316 -0
  526. package/skills/media-use/scripts/lib/lut-preset-provider.mjs +266 -0
  527. package/skills/media-use/scripts/lib/lut-preset-provider.test.mjs +176 -0
  528. package/skills/media-use/scripts/lib/manifest.mjs +229 -0
  529. package/skills/media-use/scripts/lib/manifest.test.mjs +388 -0
  530. package/skills/media-use/scripts/lib/match.mjs +47 -0
  531. package/skills/media-use/scripts/lib/mflux-provider.mjs +128 -0
  532. package/skills/media-use/scripts/lib/mflux-provider.test.mjs +174 -0
  533. package/skills/media-use/scripts/lib/misses.mjs +49 -0
  534. package/skills/media-use/scripts/lib/misses.test.mjs +78 -0
  535. package/skills/media-use/scripts/lib/npx-sync.mjs +31 -0
  536. package/skills/media-use/scripts/lib/npx-sync.test.mjs +50 -0
  537. package/skills/media-use/scripts/lib/parakeet-words.mjs +27 -0
  538. package/skills/media-use/scripts/lib/parakeet-words.test.mjs +44 -0
  539. package/skills/media-use/scripts/lib/prefs-store.mjs +180 -0
  540. package/skills/media-use/scripts/lib/prefs-store.test.mjs +189 -0
  541. package/skills/media-use/scripts/lib/probe.mjs +39 -0
  542. package/skills/media-use/scripts/lib/probe.test.mjs +31 -0
  543. package/skills/media-use/scripts/lib/providers.mjs +5 -0
  544. package/skills/media-use/scripts/lib/recipe-store.mjs +367 -0
  545. package/skills/media-use/scripts/lib/recipe-store.test.mjs +367 -0
  546. package/skills/media-use/scripts/lib/registry.mjs +218 -0
  547. package/skills/media-use/scripts/lib/registry.test.mjs +261 -0
  548. package/skills/media-use/scripts/lib/search.mjs +24 -0
  549. package/skills/media-use/scripts/lib/search.test.mjs +32 -0
  550. package/skills/media-use/scripts/lib/sfx-provider.mjs +23 -0
  551. package/skills/media-use/scripts/lib/specs.mjs +132 -0
  552. package/skills/media-use/scripts/lib/specs.test.mjs +157 -0
  553. package/skills/media-use/scripts/lib/stats.mjs +117 -0
  554. package/skills/media-use/scripts/lib/stats.test.mjs +165 -0
  555. package/skills/media-use/scripts/lib/telemetry.mjs +222 -0
  556. package/skills/media-use/scripts/lib/telemetry.test.mjs +373 -0
  557. package/skills/media-use/scripts/lib/tts-local-provider.mjs +92 -0
  558. package/skills/media-use/scripts/lib/tts-local-provider.test.mjs +72 -0
  559. package/skills/media-use/scripts/lib/usage.mjs +57 -0
  560. package/skills/media-use/scripts/lib/usage.test.mjs +54 -0
  561. package/skills/media-use/scripts/lib/voice-provider.mjs +57 -0
  562. package/skills/media-use/scripts/lib/voice-provider.test.mjs +46 -0
  563. package/skills/media-use/scripts/lib/words.mjs +18 -0
  564. package/skills/media-use/scripts/prefs.mjs +70 -0
  565. package/skills/media-use/scripts/recipe.mjs +103 -0
  566. package/skills/media-use/scripts/resolve.mjs +1271 -0
  567. package/skills/media-use/scripts/resolve.test.mjs +1120 -0
  568. package/skills/media-use/scripts/transcribe.mjs +180 -0
  569. package/skills/media-use/scripts/transcript-cut.mjs +239 -0
  570. package/skills/motion-graphics/SKILL.md +176 -0
  571. package/skills/motion-graphics/agents/builder.md +40 -0
  572. package/skills/motion-graphics/agents/director.md +53 -0
  573. package/skills/motion-graphics/agents/finalize.md +17 -0
  574. package/skills/motion-graphics/catalog-map.md +40 -0
  575. package/skills/motion-graphics/categories/asset-fusion/module.md +37 -0
  576. package/skills/motion-graphics/categories/charts/module.md +21 -0
  577. package/skills/motion-graphics/categories/kinetic-type/module.md +19 -0
  578. package/skills/motion-graphics/categories/logo-reveal/module.md +17 -0
  579. package/skills/motion-graphics/categories/lower-thirds/module.md +16 -0
  580. package/skills/motion-graphics/categories/maps/bake-basemap.mjs +273 -0
  581. package/skills/motion-graphics/categories/maps/module.md +61 -0
  582. package/skills/motion-graphics/categories/news/module.md +56 -0
  583. package/skills/motion-graphics/categories/stat/module.md +21 -0
  584. package/skills/motion-graphics/categories/tweet/module.md +16 -0
  585. package/skills/motion-graphics/categories/webpage/module.md +30 -0
  586. package/skills/motion-graphics/grounding/PROTOCOL.md +64 -0
  587. package/skills/motion-graphics/grounding/locate.mjs +228 -0
  588. package/skills/motion-graphics/phases/source/guide.md +21 -0
  589. package/skills/motion-graphics/references/builder-contract.md +38 -0
  590. package/skills/motion-graphics/references/motion-vocabulary.md +43 -0
  591. package/skills/motion-graphics/references/shot-plan-ir.md +54 -0
  592. package/skills/motion-graphics/samples/asset-fusion/_ref-circle-highlight.html +306 -0
  593. package/skills/music-to-video/SKILL.md +208 -0
  594. package/skills/music-to-video/references/frame-skeleton.md +100 -0
  595. package/skills/music-to-video/references/montage.md +58 -0
  596. package/skills/music-to-video/references/motion-primitive-catalog.md +75 -0
  597. package/skills/music-to-video/references/motion-primitives/3d-card-flip/index.html +154 -0
  598. package/skills/music-to-video/references/motion-primitives/assets/gsap.min.js +11 -0
  599. package/skills/music-to-video/references/motion-primitives/bg-flow-field/index.html +326 -0
  600. package/skills/music-to-video/references/motion-primitives/binary-decrypt/index.html +120 -0
  601. package/skills/music-to-video/references/motion-primitives/blur-resolve/index.html +95 -0
  602. package/skills/music-to-video/references/motion-primitives/braam-punch/index.html +135 -0
  603. package/skills/music-to-video/references/motion-primitives/chromatic-split/index.html +146 -0
  604. package/skills/music-to-video/references/motion-primitives/chrome-sweep/index.html +103 -0
  605. package/skills/music-to-video/references/motion-primitives/counting-punch/index.html +154 -0
  606. package/skills/music-to-video/references/motion-primitives/crash-zoom-in/index.html +155 -0
  607. package/skills/music-to-video/references/motion-primitives/datamosh-smear/index.html +166 -0
  608. package/skills/music-to-video/references/motion-primitives/directional-fill/index.html +133 -0
  609. package/skills/music-to-video/references/motion-primitives/dolly-zoom/index.html +137 -0
  610. package/skills/music-to-video/references/motion-primitives/electric-arc/index.html +144 -0
  611. package/skills/music-to-video/references/motion-primitives/flash-cut/index.html +132 -0
  612. package/skills/music-to-video/references/motion-primitives/gooey-metaball/index.html +241 -0
  613. package/skills/music-to-video/references/motion-primitives/hard-cut/index.html +117 -0
  614. package/skills/music-to-video/references/motion-primitives/hypercut-whip/index.html +79 -0
  615. package/skills/music-to-video/references/motion-primitives/iris-open/index.html +104 -0
  616. package/skills/music-to-video/references/motion-primitives/kinetic-letter-in/index.html +98 -0
  617. package/skills/music-to-video/references/motion-primitives/liquid-morph/index.html +131 -0
  618. package/skills/music-to-video/references/motion-primitives/mask-reveal/index.html +109 -0
  619. package/skills/music-to-video/references/motion-primitives/mosaic-pack/index.html +124 -0
  620. package/skills/music-to-video/references/motion-primitives/neon-flicker/index.html +108 -0
  621. package/skills/music-to-video/references/motion-primitives/outline-to-fill/index.html +117 -0
  622. package/skills/music-to-video/references/motion-primitives/palette-flip/index.html +132 -0
  623. package/skills/music-to-video/references/motion-primitives/particle-burst/index.html +141 -0
  624. package/skills/music-to-video/references/motion-primitives/pixel-dissolve/index.html +121 -0
  625. package/skills/music-to-video/references/motion-primitives/radial-burst-lines/index.html +160 -0
  626. package/skills/music-to-video/references/motion-primitives/screen-shake/index.html +113 -0
  627. package/skills/music-to-video/references/motion-primitives/slot-machine-reveal/index.html +130 -0
  628. package/skills/music-to-video/references/motion-primitives/spotlight-sweep/index.html +137 -0
  629. package/skills/music-to-video/references/motion-primitives/staggered-exit/index.html +117 -0
  630. package/skills/music-to-video/references/motion-primitives/text-spectral-rays/USAGE.md +42 -0
  631. package/skills/music-to-video/references/motion-primitives/text-spectral-rays/index.html +313 -0
  632. package/skills/music-to-video/references/motion-primitives/text-wave-distort/index.html +136 -0
  633. package/skills/music-to-video/references/motion-primitives/tile-mosaic/index.html +144 -0
  634. package/skills/music-to-video/references/motion-primitives/typewriter-reveal/index.html +122 -0
  635. package/skills/music-to-video/references/motion-primitives/word-grid-burst/index.html +126 -0
  636. package/skills/music-to-video/references/planning.md +104 -0
  637. package/skills/music-to-video/references/storyboard-format.md +94 -0
  638. package/skills/music-to-video/references/template-catalog.md +106 -0
  639. package/skills/music-to-video/references/templates/card-flyby/index.html +527 -0
  640. package/skills/music-to-video/references/templates/card-flyby/program.json +13 -0
  641. package/skills/music-to-video/references/templates/held-message-living-field/index.html +485 -0
  642. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/asphalt-031.png +0 -0
  643. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/bark-014.png +0 -0
  644. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/brick.png +0 -0
  645. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/bricks-075-a.png +0 -0
  646. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/bricks-101.png +0 -0
  647. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/bricks-102.png +0 -0
  648. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/bricks-104.png +0 -0
  649. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/carpet.png +0 -0
  650. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/concrete-034.png +0 -0
  651. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/concrete-042-a.png +0 -0
  652. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/concrete-046.png +0 -0
  653. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/concrete-047-a.png +0 -0
  654. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/concrete.png +0 -0
  655. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/diamond-plate-009.png +0 -0
  656. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/fabric-080.png +0 -0
  657. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/fabric-083.png +0 -0
  658. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/grass-001.png +0 -0
  659. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/grass-004.png +0 -0
  660. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/grass-005.png +0 -0
  661. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/ground-037.png +0 -0
  662. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/ground-054.png +0 -0
  663. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/ground-068.png +0 -0
  664. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/ground-080.png +0 -0
  665. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/ground-103.png +0 -0
  666. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/ground-104.png +0 -0
  667. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/lava.png +0 -0
  668. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/leather-037.png +0 -0
  669. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/marble-012.png +0 -0
  670. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/marble-016.png +0 -0
  671. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/metal-032.png +0 -0
  672. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/metal-038.png +0 -0
  673. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/metal-041-a.png +0 -0
  674. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/metal-046-b.png +0 -0
  675. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/metal-048-a.png +0 -0
  676. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/metal-049-a.png +0 -0
  677. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/metal-055-a.png +0 -0
  678. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/metal-061-b.png +0 -0
  679. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/metal.png +0 -0
  680. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/onyx.png +0 -0
  681. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/painted-plaster-017.png +0 -0
  682. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/paving-stones-138.png +0 -0
  683. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/paving-stones-150.png +0 -0
  684. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/plaster-001.png +0 -0
  685. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/road-007.png +0 -0
  686. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/road-008-a.png +0 -0
  687. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/road-009-c.png +0 -0
  688. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/road-012-a.png +0 -0
  689. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/road-012-b.png +0 -0
  690. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/road-013-a.png +0 -0
  691. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/rock-058.png +0 -0
  692. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/rock-063.png +0 -0
  693. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/rock.png +0 -0
  694. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/snow-015.png +0 -0
  695. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/snow.png +0 -0
  696. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/tiles-138.png +0 -0
  697. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/travertine-009.png +0 -0
  698. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/wood-049.png +0 -0
  699. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/wood-051.png +0 -0
  700. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/wood-058.png +0 -0
  701. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/wood-066.png +0 -0
  702. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/wood-092.png +0 -0
  703. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/wood-094.png +0 -0
  704. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/wood-floor-051.png +0 -0
  705. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/wood-floor-064.png +0 -0
  706. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/wood-floor-070.png +0 -0
  707. package/skills/music-to-video/references/templates/held-text-strobe-burst/assets/texture-mask-text/masks/wood.png +0 -0
  708. package/skills/music-to-video/references/templates/held-text-strobe-burst/index.html +302 -0
  709. package/skills/music-to-video/references/templates/intro-kinetic-cascade/index.html +610 -0
  710. package/skills/music-to-video/references/templates/intro-kinetic-cascade/program.json +41 -0
  711. package/skills/music-to-video/references/templates/logo-split-lockup-pulse/assets/fredoka-700.woff2 +0 -0
  712. package/skills/music-to-video/references/templates/logo-split-lockup-pulse/index.html +596 -0
  713. package/skills/music-to-video/references/templates/poster-tile-mosaic/index.html +589 -0
  714. package/skills/music-to-video/references/templates/poster-tile-mosaic/program.json +25 -0
  715. package/skills/music-to-video/references/templates/roll-flipbook-word-cycle/index.html +267 -0
  716. package/skills/music-to-video/references/templates/split-anchor-word-slot/index.html +594 -0
  717. package/skills/music-to-video/references/templates/split-anchor-word-slot/program.json +39 -0
  718. package/skills/music-to-video/references/templates/typewriter-phrase-keyword-shuffle/index.html +238 -0
  719. package/skills/music-to-video/scripts/analyze-beatgrid.py +542 -0
  720. package/skills/music-to-video/scripts/assemble-index.mjs +220 -0
  721. package/skills/music-to-video/scripts/lib/storyboard.mjs +249 -0
  722. package/skills/music-to-video/scripts/stage-assets.mjs +58 -0
  723. package/skills/music-to-video/scripts/validate-plan.mjs +161 -0
  724. package/skills/music-to-video/sub-agents/frame-worker.md +49 -0
  725. package/skills/pr-to-video/SKILL.md +269 -0
  726. package/skills/pr-to-video/references/code-vocabulary.md +111 -0
  727. package/skills/pr-to-video/references/cut-catalog.md +215 -0
  728. package/skills/pr-to-video/references/motion-language.md +156 -0
  729. package/skills/pr-to-video/references/story-design.md +230 -0
  730. package/skills/pr-to-video/references/visual-design.md +164 -0
  731. package/skills/pr-to-video/scripts/assemble-index.mjs +629 -0
  732. package/skills/pr-to-video/scripts/assemble-index.test.mjs +75 -0
  733. package/skills/pr-to-video/scripts/audio.mjs +291 -0
  734. package/skills/pr-to-video/scripts/build-frame.mjs +586 -0
  735. package/skills/pr-to-video/scripts/captions.mjs +521 -0
  736. package/skills/pr-to-video/scripts/captions.test.mjs +219 -0
  737. package/skills/pr-to-video/scripts/fetch-people-avatars.mjs +157 -0
  738. package/skills/pr-to-video/scripts/fetch-pr.mjs +234 -0
  739. package/skills/pr-to-video/scripts/frame-contract.test.mjs +209 -0
  740. package/skills/pr-to-video/scripts/frame-packets.mjs +62 -0
  741. package/skills/pr-to-video/scripts/ingest.mjs +561 -0
  742. package/skills/pr-to-video/scripts/lib/assets.mjs +56 -0
  743. package/skills/pr-to-video/scripts/lib/dimensions.mjs +45 -0
  744. package/skills/pr-to-video/scripts/lib/frame-contract.mjs +54 -0
  745. package/skills/pr-to-video/scripts/lib/pad-frame-duration.mjs +36 -0
  746. package/skills/pr-to-video/scripts/lib/storyboard.mjs +249 -0
  747. package/skills/pr-to-video/scripts/lib/tokens.mjs +211 -0
  748. package/skills/pr-to-video/scripts/lib/transition-registry.mjs +38 -0
  749. package/skills/pr-to-video/scripts/lib/transitions.json +71 -0
  750. package/skills/pr-to-video/scripts/preflight.mjs +51 -0
  751. package/skills/pr-to-video/scripts/project-dir.mjs +92 -0
  752. package/skills/pr-to-video/scripts/transitions.mjs +381 -0
  753. package/skills/pr-to-video/scripts/workflow-guardrails.test.mjs +198 -0
  754. package/skills/pr-to-video/sub-agents/frame-worker.md +38 -0
  755. package/skills/product-launch-video/SKILL.md +260 -0
  756. package/skills/product-launch-video/references/cut-catalog.md +220 -0
  757. package/skills/product-launch-video/references/motion-language.md +156 -0
  758. package/skills/product-launch-video/references/story-design.md +508 -0
  759. package/skills/product-launch-video/references/visual-design.md +126 -0
  760. package/skills/product-launch-video/scripts/assemble-index.mjs +771 -0
  761. package/skills/product-launch-video/scripts/assemble-index.test.mjs +72 -0
  762. package/skills/product-launch-video/scripts/audio.mjs +291 -0
  763. package/skills/product-launch-video/scripts/audio.test.mjs +218 -0
  764. package/skills/product-launch-video/scripts/build-frame.mjs +549 -0
  765. package/skills/product-launch-video/scripts/captions.mjs +521 -0
  766. package/skills/product-launch-video/scripts/captions.test.mjs +219 -0
  767. package/skills/product-launch-video/scripts/capture-skill-guardrails.test.mjs +39 -0
  768. package/skills/product-launch-video/scripts/frame-packets.mjs +27 -0
  769. package/skills/product-launch-video/scripts/frame-packets.test.mjs +144 -0
  770. package/skills/product-launch-video/scripts/lib/assets.mjs +56 -0
  771. package/skills/product-launch-video/scripts/lib/dimensions.mjs +45 -0
  772. package/skills/product-launch-video/scripts/lib/pad-frame-duration.mjs +36 -0
  773. package/skills/product-launch-video/scripts/lib/pad-frame-duration.test.mjs +76 -0
  774. package/skills/product-launch-video/scripts/lib/storyboard.mjs +249 -0
  775. package/skills/product-launch-video/scripts/lib/tokens.mjs +218 -0
  776. package/skills/product-launch-video/scripts/lib/tokens.test.mjs +57 -0
  777. package/skills/product-launch-video/scripts/lib/transition-registry.mjs +38 -0
  778. package/skills/product-launch-video/scripts/lib/transitions.json +71 -0
  779. package/skills/product-launch-video/scripts/media-contract.test.mjs +200 -0
  780. package/skills/product-launch-video/scripts/stage-assets.mjs +39 -0
  781. package/skills/product-launch-video/scripts/stage-assets.test.mjs +52 -0
  782. package/skills/product-launch-video/scripts/transitions.mjs +381 -0
  783. package/skills/product-launch-video/sub-agents/frame-worker.md +21 -0
  784. package/skills/remotion-to-hyperframes/SKILL.md +129 -0
  785. package/skills/remotion-to-hyperframes/assets/.gitkeep +0 -0
  786. package/skills/remotion-to-hyperframes/assets/test-corpus/run.sh +249 -0
  787. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/README.md +41 -0
  788. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/expected.json +26 -0
  789. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/hf-src/index.html +61 -0
  790. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/package.json +14 -0
  791. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/remotion.config.ts +13 -0
  792. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/src/Root.tsx +13 -0
  793. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/src/TitleCard.tsx +34 -0
  794. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/src/index.ts +4 -0
  795. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/remotion-src/tsconfig.json +15 -0
  796. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/README.md +54 -0
  797. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/expected.json +29 -0
  798. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/hf-src/index.html +118 -0
  799. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/package.json +14 -0
  800. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/remotion.config.ts +13 -0
  801. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/src/MultiScene.tsx +105 -0
  802. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/src/Root.tsx +13 -0
  803. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/src/index.ts +4 -0
  804. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/remotion-src/tsconfig.json +15 -0
  805. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/setup.sh +34 -0
  806. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/README.md +85 -0
  807. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/expected.json +41 -0
  808. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/hf-src/index.html +269 -0
  809. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/package.json +15 -0
  810. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/remotion.config.ts +13 -0
  811. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/Root.tsx +27 -0
  812. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/Stargazed.tsx +37 -0
  813. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/components/AnimatedNumber.tsx +23 -0
  814. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/components/StatCard.tsx +59 -0
  815. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/components/UnderlinedText.tsx +47 -0
  816. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/index.ts +4 -0
  817. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/scenes/OutroScene.tsx +18 -0
  818. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/scenes/StatsScene.tsx +34 -0
  819. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/src/scenes/TitleScene.tsx +55 -0
  820. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/remotion-src/tsconfig.json +15 -0
  821. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/README.md +51 -0
  822. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/01-use-state.tsx +29 -0
  823. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/02-use-effect-deps.tsx +29 -0
  824. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/03-async-metadata.tsx +39 -0
  825. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/04-third-party-react.tsx +30 -0
  826. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/05-lambda-config.tsx +38 -0
  827. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/06-warnings-only.tsx +36 -0
  828. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/07-custom-hook.tsx +28 -0
  829. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/cases/08-mixed.tsx +41 -0
  830. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/expected.json +85 -0
  831. package/skills/remotion-to-hyperframes/assets/test-corpus/tier-4-escape-hatch/validate.sh +110 -0
  832. package/skills/remotion-to-hyperframes/references/api-map.md +142 -0
  833. package/skills/remotion-to-hyperframes/references/escape-hatch.md +115 -0
  834. package/skills/remotion-to-hyperframes/references/eval.md +140 -0
  835. package/skills/remotion-to-hyperframes/references/fonts.md +112 -0
  836. package/skills/remotion-to-hyperframes/references/limitations.md +136 -0
  837. package/skills/remotion-to-hyperframes/references/lottie.md +121 -0
  838. package/skills/remotion-to-hyperframes/references/media.md +149 -0
  839. package/skills/remotion-to-hyperframes/references/parameters.md +167 -0
  840. package/skills/remotion-to-hyperframes/references/sequencing.md +198 -0
  841. package/skills/remotion-to-hyperframes/references/timing.md +165 -0
  842. package/skills/remotion-to-hyperframes/references/transitions.md +114 -0
  843. package/skills/remotion-to-hyperframes/scripts/.gitkeep +0 -0
  844. package/skills/remotion-to-hyperframes/scripts/frame_strip.sh +107 -0
  845. package/skills/remotion-to-hyperframes/scripts/lint_source.py +370 -0
  846. package/skills/remotion-to-hyperframes/scripts/render_diff.sh +103 -0
  847. package/skills/remotion-to-hyperframes/scripts/tests/fixtures/blocker.tsx +50 -0
  848. package/skills/remotion-to-hyperframes/scripts/tests/fixtures/clean.tsx +46 -0
  849. package/skills/remotion-to-hyperframes/scripts/tests/smoke.sh +90 -0
  850. package/skills/slideshow/SKILL.md +529 -0
  851. package/skills/slideshow/references/standalone-harness.md +1020 -0
  852. package/skills/talking-head-recut/NOTICE.md +39 -0
  853. package/skills/talking-head-recut/SKILL.md +1211 -0
  854. package/skills/talking-head-recut/assets/fonts/Caveat-400-latin.woff2 +0 -0
  855. package/skills/talking-head-recut/assets/fonts/Caveat-700-latin.woff2 +0 -0
  856. package/skills/talking-head-recut/assets/fonts/Inter-400-latin.woff2 +0 -0
  857. package/skills/talking-head-recut/assets/fonts/Inter-700-latin.woff2 +0 -0
  858. package/skills/talking-head-recut/assets/fonts/LXGWWenKaiTC-400-latin.woff2 +0 -0
  859. package/skills/talking-head-recut/assets/fonts/Virgil.woff2 +0 -0
  860. package/skills/talking-head-recut/assets/vendor/gsap.min.js +10 -0
  861. package/skills/talking-head-recut/media-contract.test.mjs +35 -0
  862. package/skills/talking-head-recut/references/DESIGN_INDEX.md +145 -0
  863. package/skills/talking-head-recut/references/frames/clean.html +92 -0
  864. package/skills/talking-head-recut/references/frames/hairline.html +171 -0
  865. package/skills/talking-head-recut/references/frames/polaroid.html +131 -0
  866. package/skills/talking-head-recut/references/layouts/overlay.html +164 -0
  867. package/skills/talking-head-recut/references/layouts/pip.html +143 -0
  868. package/skills/talking-head-recut/references/layouts/split.html +121 -0
  869. package/skills/talking-head-recut/references/layouts/stack.html +109 -0
  870. package/skills/talking-head-recut/references/styles/academic.html +172 -0
  871. package/skills/talking-head-recut/references/styles/audit.html +170 -0
  872. package/skills/talking-head-recut/references/styles/editorial.html +189 -0
  873. package/skills/talking-head-recut/references/styles/geom.html +181 -0
  874. package/skills/talking-head-recut/references/styles/minimal.html +130 -0
  875. package/skills/talking-head-recut/references/styles/spotlight.html +142 -0
  876. package/skills/talking-head-recut/references/styles/swiss.html +188 -0
  877. package/skills/talking-head-recut/references/styles/terminal.html +196 -0
  878. package/skills/talking-head-recut/references/styles/whiteboard.html +170 -0
  879. package/skills/talking-head-recut/references/styles/xhs.html +206 -0
  880. package/skills/gsap/SKILL.md +0 -213
  881. package/skills/gsap/references/effects.md +0 -297
  882. package/skills/hyperframes/patterns.md +0 -118
  883. package/skills/hyperframes/references/captions.md +0 -132
  884. package/skills/hyperframes/references/css-patterns.md +0 -373
  885. package/skills/hyperframes/references/motion-principles.md +0 -69
  886. package/skills/hyperframes/references/tts.md +0 -75
  887. package/skills/hyperframes/scripts/contrast-report.mjs +0 -335
  888. package/skills/hyperframes/visual-styles.md +0 -211
  889. package/skills/website-to-hyperframes/SKILL.md +0 -125
  890. package/skills/website-to-hyperframes/references/step-1-capture.md +0 -74
  891. package/skills/website-to-hyperframes/references/step-2-design.md +0 -178
  892. package/skills/website-to-hyperframes/references/step-4-storyboard.md +0 -246
  893. package/skills/website-to-hyperframes/references/step-5-vo.md +0 -42
  894. package/skills/website-to-hyperframes/references/step-6-build.md +0 -229
  895. package/skills/website-to-hyperframes/references/step-7-validate.md +0 -114
  896. /package/skills/{hyperframes/references → hyperframes-animation}/transitions/css-3d.md +0 -0
  897. /package/skills/{hyperframes/references → hyperframes-animation}/transitions/css-blur.md +0 -0
  898. /package/skills/{hyperframes/references → hyperframes-animation}/transitions/css-cover.md +0 -0
  899. /package/skills/{hyperframes/references → hyperframes-animation}/transitions/css-dissolve.md +0 -0
  900. /package/skills/{hyperframes/references → hyperframes-animation}/transitions/css-distortion.md +0 -0
  901. /package/skills/{hyperframes/references → hyperframes-animation}/transitions/css-grid.md +0 -0
  902. /package/skills/{hyperframes/references → hyperframes-animation}/transitions/css-light.md +0 -0
  903. /package/skills/{hyperframes/references → hyperframes-animation}/transitions/css-mechanical.md +0 -0
  904. /package/skills/{hyperframes/references → hyperframes-animation}/transitions/css-other.md +0 -0
  905. /package/skills/{hyperframes/references → hyperframes-animation}/transitions/css-push.md +0 -0
  906. /package/skills/{hyperframes/references → hyperframes-animation}/transitions/css-radial.md +0 -0
  907. /package/skills/{hyperframes/references → hyperframes-animation}/transitions/css-scale.md +0 -0
  908. /package/skills/{hyperframes → hyperframes-creative}/palettes/bold-energetic.md +0 -0
  909. /package/skills/{hyperframes → hyperframes-creative}/palettes/clean-corporate.md +0 -0
  910. /package/skills/{hyperframes → hyperframes-creative}/palettes/dark-premium.md +0 -0
  911. /package/skills/{hyperframes → hyperframes-creative}/palettes/jewel-rich.md +0 -0
  912. /package/skills/{hyperframes → hyperframes-creative}/palettes/monochrome.md +0 -0
  913. /package/skills/{hyperframes → hyperframes-creative}/palettes/nature-earth.md +0 -0
  914. /package/skills/{hyperframes → hyperframes-creative}/palettes/neon-electric.md +0 -0
  915. /package/skills/{hyperframes → hyperframes-creative}/palettes/pastel-soft.md +0 -0
  916. /package/skills/{hyperframes → hyperframes-creative}/palettes/warm-editorial.md +0 -0
@@ -0,0 +1,1271 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawnSync } from "node:child_process";
4
+ import { existsSync, statSync, writeFileSync, renameSync, rmSync } from "node:fs";
5
+ import { resolve, join, extname, basename } from "node:path";
6
+ import { parseArgs } from "node:util";
7
+ import {
8
+ appendRecord,
9
+ findByPrompt,
10
+ findByEntity,
11
+ nextId,
12
+ withReservedFile,
13
+ withReservedFileSync,
14
+ } from "./lib/manifest.mjs";
15
+ import { regenerateIndex } from "./lib/index-gen.mjs";
16
+ import { cacheGet, cacheGetByEntity, importFromCache, cachePut } from "./lib/cache.mjs";
17
+ import {
18
+ runCapability,
19
+ listTypes,
20
+ providerMatches,
21
+ providerNamesFor,
22
+ providerTierFor,
23
+ } from "./lib/registry.mjs";
24
+ import { freezeUrl, freezeLocalFile, isDirectMediaUrl } from "./lib/freeze.mjs";
25
+ import { findExistingAsset } from "./lib/adopt.mjs";
26
+ import { track } from "./lib/telemetry.mjs";
27
+ import { recordMiss } from "./lib/misses.mjs";
28
+ import { buildStats } from "./lib/stats.mjs";
29
+ import { typesMatch } from "./lib/match.mjs";
30
+ import { listCandidates, formatCandidates, CANDIDATE_CAP } from "./lib/candidates.mjs";
31
+ import { findGlobalBySha } from "./lib/cache.mjs";
32
+ import { heygenAuthMethod } from "../audio/scripts/lib/heygen.mjs";
33
+ import { buildCube, paramsFromIntent } from "./lib/cube-build.mjs";
34
+ import { validateCubeFile } from "./lib/cube-validate.mjs";
35
+ import { analyzeMediaGrade, formatMeasuredNote } from "./lib/grade-analyzer.mjs";
36
+ import {
37
+ freezeLibraryLut,
38
+ isLibraryLutOfflineMiss,
39
+ matchColorLook,
40
+ } from "./lib/lut-preset-provider.mjs";
41
+ import {
42
+ HEYGEN_AUTH_COMMAND,
43
+ HEYGEN_INSTALL_COMMAND,
44
+ HEYGEN_MIN_VERSION,
45
+ HEYGEN_UPDATE_COMMAND,
46
+ consumeHeygenRemediation,
47
+ firstSemver,
48
+ flushHeygenFailureTracking,
49
+ versionLessThan,
50
+ } from "./lib/heygen-cli.mjs";
51
+ import { BundledSfxAssetsError, inspectBundledSfxAssets } from "./lib/bundled-sfx-provider.mjs";
52
+
53
+ const INGEST_TYPES = listTypes();
54
+ const DEFAULT_EXT = {
55
+ bgm: ".wav",
56
+ sfx: ".mp3",
57
+ voice: ".wav",
58
+ image: ".jpg",
59
+ icon: ".svg",
60
+ logo: ".svg",
61
+ brand: ".png",
62
+ video: ".mp4",
63
+ grade: ".cube",
64
+ lut: ".cube",
65
+ };
66
+
67
+ // resolve shells `fetch`/`freezeUrl` and modern ESM; 18 is the floor where those
68
+ // exist without flags. Named so the --doctor node check verifies something real
69
+ // (O2). Declared before the top-level `--doctor` branch that calls runDoctor().
70
+ const MIN_NODE_VERSION = "18.0.0";
71
+
72
+ const { values: args } = parseArgs({
73
+ options: {
74
+ type: { type: "string", short: "t" },
75
+ intent: { type: "string", short: "i" },
76
+ entity: { type: "string", short: "e" },
77
+ project: { type: "string", short: "p", default: "." },
78
+ adopt: { type: "boolean", default: false },
79
+ candidates: { type: "boolean", default: false },
80
+ doctor: { type: "boolean", default: false },
81
+ stats: { type: "boolean", default: false },
82
+ days: { type: "string" },
83
+ "dry-run": { type: "boolean", default: false },
84
+ reuse: { type: "string" },
85
+ from: { type: "string" },
86
+ params: { type: "string" },
87
+ for: { type: "string" },
88
+ analyze: { type: "boolean", default: false },
89
+ "local-only": { type: "boolean", default: false },
90
+ provider: { type: "string" },
91
+ "avatar-id": { type: "string" },
92
+ "voice-id": { type: "string" },
93
+ json: { type: "boolean", default: false },
94
+ help: { type: "boolean", short: "h", default: false },
95
+ },
96
+ strict: true,
97
+ });
98
+
99
+ if (args.help) {
100
+ console.log(`media-use resolve — turn a media need into a frozen local file
101
+
102
+ Usage:
103
+ node resolve.mjs --type <type> --intent "<description>" [--project <dir>]
104
+
105
+ Types: ${listTypes().join(", ")}
106
+
107
+ Options:
108
+ --type, -t Media type (required)
109
+ --intent, -i What you need (required)
110
+ --entity, -e Entity name for cache matching (optional)
111
+ --project, -p Project directory (default: .)
112
+ --adopt Adopt all existing assets/ files into the manifest
113
+ --candidates List reusable assets (project + global cache) for --type; no
114
+ download, no mutation. Read them and decide reuse yourself.
115
+ --doctor Check local CLI dependencies; no manifest changes.
116
+ --stats Print local usage stats from .media and ~/.media; no mutation.
117
+ --days <N> Limit --stats to records/misses from the last N days when
118
+ timestamps are available.
119
+ --reuse <sha> Import a specific global-cache asset (by content sha/prefix,
120
+ from --candidates) into this project
121
+ --from <file> Freeze a local file or direct public URL (ingest)
122
+ --params <json> Build an explicit parametric LUT (lut/grade only)
123
+ --for <media> Analyze a local image/video and add measured grade adjust
124
+ suggestions (grade only)
125
+ --analyze Return --for grade evidence without recording a candidate
126
+ --local-only Offline: skip every network provider
127
+ --provider Force one generator (e.g. codex, mflux, kokoro, heygen)
128
+ --avatar-id Override the default avatar for heygen.video generation
129
+ --voice-id Override the default voice for voice/heygen.video generation
130
+ --json Output JSON instead of one-line result
131
+ --help, -h Show this help`);
132
+ process.exit(0);
133
+ }
134
+
135
+ const projectDir = resolve(args.project);
136
+ const type = args.type;
137
+ const intent = args.intent;
138
+ const entity = args.entity || null;
139
+
140
+ if (args.adopt) {
141
+ const { adoptExistingAssets } = await import("./lib/adopt.mjs");
142
+ const adopted = adoptExistingAssets(projectDir);
143
+ if (args.json) {
144
+ console.log(JSON.stringify({ ok: true, adopted: adopted.length, assets: adopted }));
145
+ } else if (adopted.length === 0) {
146
+ console.log("no new assets to adopt (assets/ empty or already registered)");
147
+ } else {
148
+ console.log(`adopted ${adopted.length} asset${adopted.length === 1 ? "" : "s"} from assets/`);
149
+ for (const r of adopted) console.log(` ${r.id} → ${r.path} (${r.type})`);
150
+ }
151
+ process.exit(0);
152
+ }
153
+
154
+ // Candidates: side-effect-free listing of reusable assets (project + global
155
+ // cache) for --type. No download, no provider, no mutation. The agent reads
156
+ // these and decides semantic fit itself.
157
+ if (args.candidates || args["dry-run"]) {
158
+ await showCandidates();
159
+ process.exit(0);
160
+ }
161
+
162
+ if (args.doctor) {
163
+ const doctor = runDoctor();
164
+ const failed = doctor.checks.filter((check) => !check.ok);
165
+ // Non-PII: instrument the exact question the feature exists to answer — how
166
+ // often is --doctor run and which check fails most. Awaited so a short-lived
167
+ // run flushes before exit.
168
+ await track("media_use_doctor_run", {
169
+ ok: doctor.ok,
170
+ checks_failed: failed.length,
171
+ failed: failed.map((check) => check.name),
172
+ });
173
+ if (args.json) {
174
+ console.log(JSON.stringify({ ok: doctor.ok, checks: doctor.checks }));
175
+ } else {
176
+ printDoctor(doctor.checks);
177
+ }
178
+ process.exit(doctor.ok ? 0 : 1);
179
+ }
180
+
181
+ if (args.stats) {
182
+ const report = buildStats({
183
+ projectDir,
184
+ days: args.days ? Number(args.days) : undefined,
185
+ });
186
+ if (args.json) {
187
+ console.log(JSON.stringify(report));
188
+ } else {
189
+ printStats(report);
190
+ }
191
+ process.exit(0);
192
+ }
193
+
194
+ // Reuse: import a specific global-cache asset (by content sha/prefix, taken
195
+ // from --candidates) into this project. `!== undefined` so an empty --reuse ""
196
+ // still routes here (and gets a clear empty-sha error) instead of falling
197
+ // through to the misleading "--type and --intent are required".
198
+ if (args.reuse !== undefined) {
199
+ await reuseGlobal(args.reuse);
200
+ process.exit(0);
201
+ }
202
+
203
+ // Ingest: freeze a user-supplied local file or direct public URL (no search).
204
+ if (args.from) {
205
+ await ingest(args.from);
206
+ process.exit(0);
207
+ }
208
+
209
+ if (args.analyze) {
210
+ if (type !== "grade" || !args.for) {
211
+ console.error("error: --analyze requires --type grade and --for <media>");
212
+ process.exit(2);
213
+ }
214
+ const mediaPath = resolve(args.for);
215
+ if (!existsSync(mediaPath)) {
216
+ console.error(`error: --for file not found: ${mediaPath}`);
217
+ process.exit(2);
218
+ }
219
+ const analysis = analyzeMediaGrade(mediaPath);
220
+ if (args.json) {
221
+ console.log(JSON.stringify({ ok: true, type: "grade-analysis", ...analysis }));
222
+ } else {
223
+ console.log(formatMeasuredNote(mediaPath, analysis.measured));
224
+ console.log(`suggested adjust: ${JSON.stringify(analysis.adjust)}`);
225
+ }
226
+ process.exit(0);
227
+ }
228
+
229
+ // Recipes: folder-based named bundles resolved by entity name — no providers,
230
+ // no content hashing (an evolving versioned bundle, not an immutable file).
231
+ // Delegates to lib/recipe-store.mjs the way grade/lut delegate to resolveColor;
232
+ // freeze/list live in scripts/recipe.mjs.
233
+ if (type === "recipe") {
234
+ const { useRecipe } = await import("./lib/recipe-store.mjs");
235
+ const name = (entity || intent || "").trim();
236
+ if (!name) exitError("--type recipe needs --entity <name> (or --intent <name>)", 2);
237
+ try {
238
+ const used = useRecipe({ projectDir, name });
239
+ if (args.json) {
240
+ console.log(JSON.stringify({ ok: true, ...used }));
241
+ } else {
242
+ console.log(
243
+ `resolved recipe ${used.recipe.name} (v${used.recipe.version}, ${used.recipe.workflow})`,
244
+ );
245
+ console.log(` frame spec → ${used.frameSpecPath} (copied over)`);
246
+ console.log(` storyboard skeleton → ${used.skeletonPath}`);
247
+ if (used.briefSkeletonPath) console.log(` brief skeleton → ${used.briefSkeletonPath}`);
248
+ }
249
+ process.exit(0);
250
+ } catch (err) {
251
+ exitError(err.message, 1);
252
+ }
253
+ }
254
+
255
+ if (args.params !== undefined) {
256
+ if (type !== "lut" && type !== "grade") {
257
+ exitError(
258
+ type
259
+ ? `--params only supports --type lut or grade (got ${type})`
260
+ : "--params requires --type lut or grade",
261
+ 2,
262
+ );
263
+ }
264
+ try {
265
+ await runParams();
266
+ process.exit(0);
267
+ } catch (err) {
268
+ exitError(err.message, 1);
269
+ }
270
+ }
271
+
272
+ if (!args.type || !args.intent || !args.intent.trim()) {
273
+ console.error("error: --type and a non-empty --intent are required");
274
+ process.exit(2);
275
+ }
276
+
277
+ if (!listTypes().includes(args.type)) {
278
+ console.error(`error: unknown media type: ${args.type} (known: ${listTypes().join(", ")})`);
279
+ process.exit(2);
280
+ }
281
+
282
+ // Forced-provider validation: reject an unknown/unavailable provider name up
283
+ // front so a typo reads as a typo, not a catalog miss (`no provider could
284
+ // resolve`). Match rule mirrors runProviders (full name or dotted prefix).
285
+ if (args.provider && !providerMatches(args.type, args.provider)) {
286
+ console.error(
287
+ `error: unknown provider "${args.provider}" for type ${args.type} (available: ${providerNamesFor(args.type).join(", ")})`,
288
+ );
289
+ process.exit(2);
290
+ }
291
+
292
+ function recordAvailable(projectDir, record) {
293
+ if (!record) return false;
294
+ if (record.path) return existsSync(join(projectDir, record.path));
295
+ return record.type === "grade" && record.grading;
296
+ }
297
+
298
+ // Sparse `{ authMethod }` for a heygen-family provider name (e.g. "heygen.tts"),
299
+ // else `{}` — keeps auth_method telemetry absent for every non-heygen resolve
300
+ // instead of implying an auth method that doesn't apply.
301
+ function heygenAuthMethodFor(provider) {
302
+ if (!provider || !provider.startsWith("heygen.")) return {};
303
+ const authMethod = heygenAuthMethod();
304
+ return authMethod ? { authMethod } : {};
305
+ }
306
+
307
+ function localizeImportedRecord(record, localPath) {
308
+ if (record?.type === "grade" && record.grading?.lut) {
309
+ record.grading = {
310
+ ...record.grading,
311
+ lut: { ...record.grading.lut, src: localPath },
312
+ };
313
+ }
314
+ return record;
315
+ }
316
+
317
+ async function run() {
318
+ // A forced --provider means "(re)generate with THIS provider" — it bypasses
319
+ // every reuse rung (project/entity/assets/global cache) so it can't silently
320
+ // hand back an asset from a different provider. The floor only applies to the
321
+ // default (unforced) cascade.
322
+ const forced = !!args.provider;
323
+
324
+ // 1. project manifest — exact-prompt match
325
+ const projectHit = forced ? null : findByPrompt(projectDir, intent, type);
326
+ if (recordAvailable(projectDir, projectHit)) {
327
+ return result(projectHit, "cached");
328
+ }
329
+
330
+ // 1b. entity match in project. icon and image are interchangeable for
331
+ // entity hits — both live in images/, and figma-imported brand marks are
332
+ // always recorded as type image while agents ask for logos as type icon.
333
+ if (!forced && entity) {
334
+ const entityHit = findByEntity(projectDir, entity);
335
+ if (entityHit && typesMatch(entityHit.type, type) && recordAvailable(projectDir, entityHit)) {
336
+ return result(entityHit, "cached");
337
+ }
338
+ }
339
+
340
+ // 1c. scan existing assets/ directory for unregistered matches
341
+ const existingAsset =
342
+ forced || type === "grade" || type === "lut"
343
+ ? null
344
+ : findExistingAsset(projectDir, intent, type);
345
+ if (existingAsset) {
346
+ const id = nextId(projectDir, type);
347
+ const record = {
348
+ id,
349
+ type: existingAsset.type,
350
+ path: existingAsset.relativePath,
351
+ source: "existing",
352
+ description: existingAsset.name.replace(/[-_]/g, " "),
353
+ provenance: { provider: "local", adopted: true, prompt: intent },
354
+ };
355
+ appendRecord(projectDir, record);
356
+ regenerateIndex(projectDir);
357
+ return result(record, "existing");
358
+ }
359
+
360
+ // 2. global cache — exact-prompt or entity match
361
+ const cacheHit = forced ? null : cacheGet(intent, type);
362
+ if (cacheHit) {
363
+ const ext = extname(cacheHit.cached_path);
364
+ const imported = withReservedFileSync(projectDir, type, ext, ({ id, localPath }) =>
365
+ localizeImportedRecord(importFromCache(cacheHit, projectDir, id, localPath), localPath),
366
+ );
367
+ if (imported) {
368
+ appendRecord(projectDir, imported);
369
+ regenerateIndex(projectDir);
370
+ return result(imported, "reused");
371
+ }
372
+ }
373
+
374
+ if (!forced && entity) {
375
+ const entityCacheHit = cacheGetByEntity(entity);
376
+ if (entityCacheHit && typesMatch(entityCacheHit.type, type)) {
377
+ const ext = extname(entityCacheHit.cached_path);
378
+ const imported = withReservedFileSync(projectDir, type, ext, ({ id, localPath }) =>
379
+ localizeImportedRecord(
380
+ importFromCache(entityCacheHit, projectDir, id, localPath),
381
+ localPath,
382
+ ),
383
+ );
384
+ if (imported) {
385
+ appendRecord(projectDir, imported);
386
+ regenerateIndex(projectDir);
387
+ return result(imported, "reused");
388
+ }
389
+ }
390
+ }
391
+
392
+ // Offline guard: --local-only skips every remote provider (HeyGen catalog),
393
+ // leaving the project + global cache and any local provider.
394
+ const localOnly = args["local-only"];
395
+ const ctx = {
396
+ entity,
397
+ projectDir,
398
+ localOnly,
399
+ provider: args.provider,
400
+ avatarId: args["avatar-id"],
401
+ voiceId: args["voice-id"],
402
+ };
403
+
404
+ // Adherence nudge (offline, no auto-reuse): the exact-cache floor missed and
405
+ // we're about to fetch/generate. If lexically-similar assets already exist,
406
+ // point the agent at --candidates so it can reuse instead of fetching. Only a
407
+ // fuzzy match ever reaches the agent this way — never auto-applied. Goes to
408
+ // stderr so it reaches --json callers without corrupting stdout. Best-effort.
409
+ try {
410
+ const { similar } = listCandidates({ projectDir, type, intent, cap: CANDIDATE_CAP });
411
+ if (similar > 0) {
412
+ console.error(
413
+ `media-use: ${similar} similar cached asset${similar === 1 ? "" : "s"} already ${similar === 1 ? "exists" : "exist"} — run \`resolve --candidates --type ${type} --intent "${intent}"\` to review and reuse instead of fetching.`,
414
+ );
415
+ }
416
+ } catch {
417
+ // hint is best-effort; never block a resolve
418
+ }
419
+
420
+ if (type === "grade" || type === "lut") {
421
+ return resolveColor(type, intent, { projectDir });
422
+ }
423
+
424
+ // 3. provider search — registry tries providers in order (heygen-CLI first)
425
+ let searchResult = null;
426
+ let providerFailure = null;
427
+ try {
428
+ searchResult = await runCapability(type, "search", intent, ctx);
429
+ } catch (error) {
430
+ providerFailure = error;
431
+ // search failed, try generate
432
+ }
433
+
434
+ // 4. generate fallback — same ordered cascade for the generate capability
435
+ if (!searchResult) {
436
+ try {
437
+ searchResult = await runCapability(type, "generate", intent, ctx);
438
+ } catch (error) {
439
+ providerFailure ??= error;
440
+ // generate failed too
441
+ }
442
+ }
443
+
444
+ // A search/generate attempt against heygen may have fired a fire-and-forget
445
+ // media_use_provider_error track (reportHeygenFailure — heygen-search.mjs /
446
+ // voice-provider.mjs are sync call sites several layers below here and can't
447
+ // await it themselves). Join it now, before any process.exit() below can
448
+ // race it: both it and the miss/success telemetry below are separate,
449
+ // non-keepalive HTTP connections with no ordering guarantee otherwise.
450
+ await flushHeygenFailureTracking();
451
+
452
+ if (!searchResult) {
453
+ await track("media_use_resolve_miss", {
454
+ type,
455
+ local_only: !!localOnly,
456
+ provider_override: !!args.provider,
457
+ });
458
+ recordMiss({
459
+ type,
460
+ intent,
461
+ provider_override: !!args.provider,
462
+ local_only: !!args["local-only"],
463
+ });
464
+ // brand stays local: no frame.md/design.md -> upsell the HyperFrames design
465
+ // flow rather than reporting a generic miss (B5).
466
+ const msg =
467
+ providerFailure instanceof BundledSfxAssetsError
468
+ ? providerFailure.message
469
+ : type === "brand"
470
+ ? "no brand spec found — add a frame.md or design.md (colors/font/logo) to this project. Run the HyperFrames design flow to create one; brand tokens are read locally for deterministic rendering."
471
+ : args.provider
472
+ ? `provider "${args.provider}" could not resolve ${type}: "${intent}"${localOnly ? " (--local-only skips network providers; drop it or the --provider override)" : ""}`
473
+ : `no provider could resolve ${type}: "${intent}"`;
474
+ if (args.json) {
475
+ console.log(
476
+ JSON.stringify({
477
+ ok: false,
478
+ ...(providerFailure instanceof BundledSfxAssetsError
479
+ ? { code: providerFailure.code, fix: providerFailure.fix }
480
+ : {}),
481
+ error: msg,
482
+ }),
483
+ );
484
+ } else {
485
+ console.error(`error: ${msg}`);
486
+ }
487
+ process.exit(1);
488
+ }
489
+
490
+ // 5. freeze + register (atomic id+file reservation so concurrent resolves
491
+ // can't collide on an id during the download — MU-23)
492
+ const ext = searchResult.ext || extFromUrl(searchResult.url || "") || defaultExt(type);
493
+ const { id, localPath, fullPath } = await withReservedFile(
494
+ projectDir,
495
+ type,
496
+ ext,
497
+ async (reservation) => {
498
+ if (searchResult.localPath) {
499
+ freezeLocalFile(searchResult.localPath, reservation.fullPath);
500
+ } else if (searchResult.url) {
501
+ await freezeUrl(searchResult.url, reservation.fullPath);
502
+ } else {
503
+ throw new Error("provider returned no url or localPath");
504
+ }
505
+ return reservation;
506
+ },
507
+ );
508
+
509
+ const record = {
510
+ id,
511
+ type,
512
+ path: localPath,
513
+ source: searchResult.source || "search",
514
+ description: searchResult.metadata?.description || intent,
515
+ ...(searchResult.metadata?.duration != null && {
516
+ duration: Math.round(searchResult.metadata.duration * 10) / 10, // round to 0.1s like probe (voice bypassed it)
517
+ }),
518
+ ...(searchResult.metadata?.width != null && { width: searchResult.metadata.width }),
519
+ ...(searchResult.metadata?.height != null && { height: searchResult.metadata.height }),
520
+ ...(searchResult.metadata?.transparent != null && {
521
+ transparent: searchResult.metadata.transparent,
522
+ }),
523
+ ...(entity && { entity }),
524
+ provenance: {
525
+ provider: searchResult.metadata?.provider || "unknown",
526
+ prompt: intent,
527
+ // heygenAuthMethodFor spreads first so an explicit authMethod on a
528
+ // future provider's own metadata.provenance can still override it below
529
+ // -- safe today (no provider sets authMethod itself), but keep this
530
+ // ordering if that ever changes.
531
+ ...heygenAuthMethodFor(searchResult.metadata?.provider),
532
+ ...searchResult.metadata?.provenance,
533
+ },
534
+ };
535
+
536
+ const heygenRemediation = consumeHeygenRemediation();
537
+ if (
538
+ searchResult.metadata?.provider === "bundled.sfx" &&
539
+ !localOnly &&
540
+ !args.provider &&
541
+ heygenRemediation
542
+ ) {
543
+ record.advisory = heygenRemediation;
544
+ }
545
+
546
+ appendRecord(projectDir, record);
547
+ regenerateIndex(projectDir);
548
+ // Auto-promote: surface every fetched asset in the global cache so it's
549
+ // reusable across all hyperframes projects (B3). Non-fatal; dedup by sha.
550
+ // ponytail: promotes search/generate/ingest assets (the ones media-use
551
+ // fetched), not bulk --adopt imports — add those if cross-project reuse of
552
+ // pre-existing project assets is wanted.
553
+ try {
554
+ cachePut(fullPath, record);
555
+ } catch {
556
+ // promotion is best-effort; a resolve still succeeds locally
557
+ }
558
+ return result(record, searchResult.source || "search");
559
+ }
560
+
561
+ function mergeSmartAdjust(block) {
562
+ if (!args.for) return block;
563
+ const mediaPath = resolve(args.for);
564
+ // Clear upfront error beats an ffmpeg "No such file" stack on a typo'd path.
565
+ if (!existsSync(mediaPath)) throw new Error(`--for file not found: ${mediaPath}`);
566
+ const analysis = analyzeMediaGrade(mediaPath);
567
+ console.error(formatMeasuredNote(mediaPath, analysis.measured));
568
+ return {
569
+ ...block,
570
+ adjust: {
571
+ ...(block.adjust || {}),
572
+ ...analysis.adjust,
573
+ },
574
+ };
575
+ }
576
+
577
+ function freezeGeneratedLut(
578
+ params,
579
+ {
580
+ projectDir,
581
+ type,
582
+ description = "parametric color grade",
583
+ validationErrorPrefix = "generated LUT failed validation",
584
+ },
585
+ ) {
586
+ return withReservedFileSync(projectDir, type, ".cube", ({ id, localPath, fullPath }) => {
587
+ const tmpPath = `${fullPath}.tmp`;
588
+ try {
589
+ // Write + validate at .tmp, then atomic rename, so a crash between write and
590
+ // validate can't leave an invalid .cube at the final path.
591
+ writeFileSync(tmpPath, buildCube(params));
592
+ const check = validateCubeFile(tmpPath);
593
+ if (!check.ok) throw new Error(check.error);
594
+ renameSync(tmpPath, fullPath);
595
+ } catch (err) {
596
+ rmSync(tmpPath, { force: true });
597
+ throw new Error(`${validationErrorPrefix}: ${err.message}`);
598
+ }
599
+ return {
600
+ id,
601
+ localPath,
602
+ fullPath,
603
+ lut: { src: localPath, intensity: 1 },
604
+ source: "generated",
605
+ description,
606
+ metadata: {
607
+ provider: "cube_lut.builder",
608
+ provenance: { params },
609
+ },
610
+ };
611
+ });
612
+ }
613
+
614
+ function exitError(message, status = 1) {
615
+ if (args.json) {
616
+ console.log(JSON.stringify({ ok: false, error: message }));
617
+ } else {
618
+ console.error(`error: ${message}`);
619
+ }
620
+ process.exit(status);
621
+ }
622
+
623
+ function parseExplicitParams() {
624
+ try {
625
+ return JSON.parse(args.params);
626
+ } catch (err) {
627
+ throw new Error(`invalid --params JSON: ${err.message}`);
628
+ }
629
+ }
630
+
631
+ async function runParams() {
632
+ if (type === "lut" && args.for) {
633
+ throw new Error("--for is only supported with --type grade");
634
+ }
635
+ const params = parseExplicitParams();
636
+ const description =
637
+ typeof intent === "string" && intent.trim()
638
+ ? intent.trim()
639
+ : `custom parametric ${type === "lut" ? "lut" : "grade"}`;
640
+ const frozen = freezeGeneratedLut(params, {
641
+ projectDir,
642
+ type,
643
+ description,
644
+ validationErrorPrefix: "--params produced an invalid LUT",
645
+ });
646
+ const record = {
647
+ id: frozen.id,
648
+ type,
649
+ path: frozen.localPath,
650
+ source: frozen.source,
651
+ description: frozen.description,
652
+ ...(type === "grade" && { grading: mergeSmartAdjust({ intensity: 1, lut: frozen.lut }) }),
653
+ provenance: {
654
+ provider: frozen.metadata.provider,
655
+ ...frozen.metadata.provenance,
656
+ },
657
+ };
658
+ return finalizeColorRecord(record, frozen.source, frozen.fullPath);
659
+ }
660
+
661
+ async function finalizeColorRecord(record, source, fullPath = null) {
662
+ appendRecord(projectDir, record);
663
+ regenerateIndex(projectDir);
664
+ if (fullPath) {
665
+ try {
666
+ cachePut(fullPath, record);
667
+ } catch {
668
+ // promotion is best-effort
669
+ }
670
+ }
671
+ return result(record, source);
672
+ }
673
+
674
+ async function colorMiss(type, intent) {
675
+ await track("media_use_resolve_miss", {
676
+ type,
677
+ local_only: !!args["local-only"],
678
+ provider_override: !!args.provider,
679
+ });
680
+ recordMiss({
681
+ type,
682
+ intent,
683
+ provider_override: !!args.provider,
684
+ local_only: !!args["local-only"],
685
+ });
686
+ const msg = `no local color grade could resolve ${type}: "${intent}"`;
687
+ if (args.json) {
688
+ console.log(JSON.stringify({ ok: false, error: msg }));
689
+ } else {
690
+ console.error(`error: ${msg}`);
691
+ }
692
+ process.exit(1);
693
+ }
694
+
695
+ async function resolveGrade(intent, { projectDir }) {
696
+ const match = matchColorLook(intent);
697
+ if (match?.kind === "preset") {
698
+ const id = nextId(projectDir, "grade");
699
+ const grading = mergeSmartAdjust({ preset: match.preset, intensity: 1 });
700
+ const record = {
701
+ id,
702
+ type: "grade",
703
+ source: "preset",
704
+ description: intent,
705
+ grading,
706
+ provenance: {
707
+ provider: "color_grade.local",
708
+ prompt: intent,
709
+ preset: match.preset,
710
+ },
711
+ };
712
+ return finalizeColorRecord(record, "preset");
713
+ }
714
+
715
+ if (match?.kind === "library") {
716
+ let frozen;
717
+ try {
718
+ frozen = await freezeLibraryLut(match, {
719
+ projectDir,
720
+ type: "grade",
721
+ localOnly: args["local-only"],
722
+ });
723
+ } catch (err) {
724
+ if (isLibraryLutOfflineMiss(err)) return colorMiss("grade", intent);
725
+ throw err;
726
+ }
727
+ const grading = mergeSmartAdjust({ intensity: 1, lut: frozen.lut });
728
+ const record = {
729
+ id: frozen.id,
730
+ type: "grade",
731
+ path: frozen.localPath,
732
+ source: frozen.source,
733
+ description: frozen.description,
734
+ grading,
735
+ provenance: {
736
+ provider: frozen.metadata.provider,
737
+ prompt: intent,
738
+ ...frozen.metadata.provenance,
739
+ },
740
+ };
741
+ return finalizeColorRecord(record, frozen.source, frozen.fullPath);
742
+ }
743
+
744
+ const params = paramsFromIntent(intent);
745
+ if (!params) {
746
+ // No creative look matched. With --for, the measured adjust block is a
747
+ // valid grade on its own (footage auto-correction); only a true miss
748
+ // (no look AND no analysis) aborts.
749
+ if (args.for) {
750
+ const grading = mergeSmartAdjust({ intensity: 1 });
751
+ const record = {
752
+ id: nextId(projectDir, "grade"),
753
+ type: "grade",
754
+ source: "measured",
755
+ description: intent,
756
+ grading,
757
+ provenance: { provider: "color_grade.local", prompt: intent, measured: true },
758
+ };
759
+ return finalizeColorRecord(record, "measured");
760
+ }
761
+ return colorMiss("grade", intent);
762
+ }
763
+ const frozen = freezeGeneratedLut(params, { projectDir, type: "grade" });
764
+ const grading = mergeSmartAdjust({ intensity: 1, lut: frozen.lut });
765
+ const record = {
766
+ id: frozen.id,
767
+ type: "grade",
768
+ path: frozen.localPath,
769
+ source: frozen.source,
770
+ description: intent,
771
+ grading,
772
+ provenance: {
773
+ provider: frozen.metadata.provider,
774
+ prompt: intent,
775
+ ...frozen.metadata.provenance,
776
+ },
777
+ };
778
+ return finalizeColorRecord(record, frozen.source, frozen.fullPath);
779
+ }
780
+
781
+ async function resolveLut(intent, { projectDir }) {
782
+ if (args.for) {
783
+ throw new Error("--for is only supported with --type grade");
784
+ }
785
+ const match = matchColorLook(intent);
786
+ if (match?.kind === "library") {
787
+ let frozen;
788
+ try {
789
+ frozen = await freezeLibraryLut(match, {
790
+ projectDir,
791
+ type: "lut",
792
+ localOnly: args["local-only"],
793
+ });
794
+ } catch (err) {
795
+ if (isLibraryLutOfflineMiss(err)) return colorMiss("lut", intent);
796
+ throw err;
797
+ }
798
+ const record = {
799
+ id: frozen.id,
800
+ type: "lut",
801
+ path: frozen.localPath,
802
+ source: frozen.source,
803
+ description: frozen.description,
804
+ provenance: {
805
+ provider: frozen.metadata.provider,
806
+ prompt: intent,
807
+ ...frozen.metadata.provenance,
808
+ },
809
+ };
810
+ return finalizeColorRecord(record, frozen.source, frozen.fullPath);
811
+ }
812
+
813
+ const params = paramsFromIntent(intent);
814
+ if (!params) return colorMiss("lut", intent);
815
+ const frozen = freezeGeneratedLut(params, { projectDir, type: "lut" });
816
+ const record = {
817
+ id: frozen.id,
818
+ type: "lut",
819
+ path: frozen.localPath,
820
+ source: frozen.source,
821
+ description: intent,
822
+ provenance: {
823
+ provider: frozen.metadata.provider,
824
+ prompt: intent,
825
+ ...frozen.metadata.provenance,
826
+ },
827
+ };
828
+ return finalizeColorRecord(record, frozen.source, frozen.fullPath);
829
+ }
830
+
831
+ async function resolveColor(type, intent, options) {
832
+ if (type === "grade") return resolveGrade(intent, options);
833
+ return resolveLut(intent, options);
834
+ }
835
+
836
+ async function ingest(src) {
837
+ if (!type || !INGEST_TYPES.includes(type)) {
838
+ console.error(`error: --from requires --type (one of: ${INGEST_TYPES.join(", ")})`);
839
+ process.exit(2);
840
+ }
841
+ const isUrl = /^https?:\/\//i.test(src);
842
+ if (isUrl && !isDirectMediaUrl(src)) {
843
+ console.error(
844
+ `error: --from takes a direct public media URL or a local file; "${src}" is not a direct media link (no platform pages / yt-dlp)`,
845
+ );
846
+ process.exit(2);
847
+ }
848
+ if (!isUrl && !existsSync(resolve(src))) {
849
+ console.error(`error: file not found: ${src}`);
850
+ process.exit(2);
851
+ }
852
+ // Refuse 0-byte input: an empty asset would register clean but fail at render
853
+ // (freezeUrl already rejects empty responses; this covers local files).
854
+ if (!isUrl && statSync(resolve(src)).size === 0) {
855
+ console.error(`error: refusing to ingest a 0-byte file: ${src}`);
856
+ process.exit(2);
857
+ }
858
+ const ext = extname(isUrl ? new URL(src).pathname : src) || defaultExt(type);
859
+ const { id, localPath, fullPath } = await withReservedFile(
860
+ projectDir,
861
+ type,
862
+ ext,
863
+ async (reservation) => {
864
+ if (isUrl) await freezeUrl(src, reservation.fullPath);
865
+ else freezeLocalFile(resolve(src), reservation.fullPath);
866
+ return reservation;
867
+ },
868
+ );
869
+ if (type === "lut" || type === "grade") {
870
+ try {
871
+ const check = validateCubeFile(fullPath);
872
+ if (!check.ok) throw new Error(check.error);
873
+ } catch (err) {
874
+ rmSync(fullPath, { force: true });
875
+ exitError(`ingested LUT is invalid: ${err.message}`, 1);
876
+ }
877
+ }
878
+ const record = {
879
+ id,
880
+ type,
881
+ path: localPath,
882
+ source: "ingested",
883
+ description: basename(src.split("?")[0]),
884
+ provenance: { provider: "local", from: src },
885
+ };
886
+ appendRecord(projectDir, record);
887
+ regenerateIndex(projectDir);
888
+ try {
889
+ cachePut(fullPath, record); // surface ingested assets globally too (B3)
890
+ } catch {
891
+ // best-effort
892
+ }
893
+ await result(record, "ingested");
894
+ }
895
+
896
+ async function showCandidates() {
897
+ const projectDir = resolve(args.project);
898
+ const type = args.type;
899
+ if (!type || !listTypes().includes(type)) {
900
+ console.error(`error: --candidates requires --type (one of: ${listTypes().join(", ")})`);
901
+ process.exit(2);
902
+ }
903
+ const intent = args.intent || "";
904
+ const { candidates, truncated, total, similar } = listCandidates({
905
+ projectDir,
906
+ type,
907
+ intent,
908
+ cap: CANDIDATE_CAP,
909
+ });
910
+ await track("media_use_candidates", {
911
+ type,
912
+ project_n: total.project,
913
+ global_n: total.global,
914
+ local_only: !!args["local-only"],
915
+ });
916
+ if (args.json) {
917
+ console.log(JSON.stringify({ ok: true, candidates, truncated, total, similar }));
918
+ } else {
919
+ console.log(formatCandidates(candidates, { truncated, total }));
920
+ }
921
+ }
922
+
923
+ // Best-effort latest stable CLI tag from the CDN (the install script's source of
924
+ // truth). null on any failure (offline, no curl) — treated as "unknown", never fatal.
925
+ function latestHeygenStable() {
926
+ const probe = runCommand("curl", [
927
+ "-fsSL",
928
+ "--max-time",
929
+ "4",
930
+ "https://static.heygen.ai/cli/stable",
931
+ ]);
932
+ return probe.status === 0 ? firstSemver(commandText(probe)) : null;
933
+ }
934
+
935
+ function heygenAuthCheck() {
936
+ // `heygen auth status` already emits JSON by default (only `--human` opts out
937
+ // to a table) — there is no `--json`/`--output` flag; passing one errors with
938
+ // "unknown flag". emailFromAuthStatus parses that default JSON.
939
+ // NOTE: JSON-by-default is a v0.3.0 behavior — this probe assumes it, which
940
+ // HEYGEN_MIN_VERSION >= 0.3.0 (+ the version gate above) guarantees. If that
941
+ // floor is ever lowered, auth detection on an older CLI would silently break.
942
+ const authProbe = runCommand("heygen", ["auth", "status"]);
943
+ // spawnSync sets .error/.signal on a timeout or spawn failure (status then
944
+ // null). A stalled auth endpoint (transient network/DNS) must not be reported
945
+ // as an authoritative "not authenticated" with a re-login fix.
946
+ const timedOut = authProbe.error?.code === "ETIMEDOUT" || authProbe.signal != null;
947
+ const email = authProbe.status === 0 ? emailFromAuthStatus(commandText(authProbe)) : null;
948
+ return {
949
+ name: "heygen authenticated",
950
+ ok: !!email,
951
+ detail: email
952
+ ? `heygen authenticated as ${email}`
953
+ : timedOut
954
+ ? "heygen auth status timed out — possible network issue, not proof of sign-out"
955
+ : "heygen not authenticated",
956
+ fix: email ? "" : timedOut ? "check network, then re-run --doctor" : HEYGEN_AUTH_COMMAND,
957
+ };
958
+ }
959
+
960
+ function runDoctor() {
961
+ const checks = [];
962
+ const bundledSfx = inspectBundledSfxAssets();
963
+ checks.push({
964
+ name: "bundled SFX assets",
965
+ ok: bundledSfx.ok,
966
+ detail: bundledSfx.detail,
967
+ fix: bundledSfx.fix,
968
+ });
969
+ const heygenVersionProbe = runCommand("heygen", ["--version"]);
970
+ const heygenOnPath = heygenVersionProbe.status === 0;
971
+ const heygenVersionText = commandText(heygenVersionProbe);
972
+ const heygenVersion = firstSemver(heygenVersionText);
973
+
974
+ checks.push({
975
+ name: "heygen on PATH",
976
+ ok: heygenOnPath,
977
+ // Just "is the binary here" — the version row below owns the version string,
978
+ // so this row must not also render `heygen v0.3.0` (two byte-identical lines).
979
+ detail: heygenOnPath ? "heygen found on PATH" : "heygen not found",
980
+ fix: heygenOnPath ? "" : HEYGEN_INSTALL_COMMAND,
981
+ });
982
+
983
+ if (!heygenOnPath) {
984
+ checks.push({
985
+ name: "heygen version",
986
+ ok: false,
987
+ detail: "heygen version unavailable",
988
+ fix: HEYGEN_INSTALL_COMMAND,
989
+ });
990
+ checks.push({
991
+ name: "heygen authenticated",
992
+ ok: false,
993
+ detail: "heygen auth status unavailable",
994
+ fix: HEYGEN_INSTALL_COMMAND,
995
+ });
996
+ } else if (heygenVersion) {
997
+ const versionOk = !versionLessThan(heygenVersion, HEYGEN_MIN_VERSION);
998
+ // Keep it latest: even when the installed version clears the floor, nudge
999
+ // `heygen update` if a newer stable exists. Best-effort — silently skipped
1000
+ // when the CDN is unreachable, so it never blocks the check.
1001
+ const latest = versionOk ? latestHeygenStable() : null;
1002
+ const behind = latest && versionLessThan(heygenVersion, latest);
1003
+ checks.push({
1004
+ name: "heygen version",
1005
+ ok: versionOk,
1006
+ detail: versionOk
1007
+ ? `heygen v${heygenVersion}${behind ? ` (latest v${latest} available)` : ""}`
1008
+ : `heygen v${heygenVersion} (need >= v${HEYGEN_MIN_VERSION})`,
1009
+ fix: versionOk ? (behind ? HEYGEN_UPDATE_COMMAND : "") : HEYGEN_UPDATE_COMMAND,
1010
+ });
1011
+
1012
+ // Below the OAuth-capable floor the auth probe fails for the SAME root cause
1013
+ // (an old CLI can't OAuth and doesn't emit JSON auth status), which would
1014
+ // read as a confusing second "not authenticated" error. Skip it — one root
1015
+ // cause, one fix.
1016
+ checks.push(
1017
+ versionOk
1018
+ ? heygenAuthCheck()
1019
+ : {
1020
+ name: "heygen authenticated",
1021
+ ok: false,
1022
+ detail: "skipped — update heygen first",
1023
+ fix: HEYGEN_UPDATE_COMMAND,
1024
+ },
1025
+ );
1026
+ } else {
1027
+ // Fail-open: heygen ran but printed no semver (dev/stripped build). We can't
1028
+ // verify the version, so we don't block on it — but say so rather than a bare
1029
+ // green check that implies a real version comparison happened.
1030
+ checks.push({
1031
+ name: "heygen version",
1032
+ ok: true,
1033
+ detail: "heygen present; version unverifiable (no semver in --version output)",
1034
+ fix: "",
1035
+ });
1036
+
1037
+ checks.push(heygenAuthCheck());
1038
+ }
1039
+
1040
+ const ffmpegProbe = runCommand("ffmpeg", ["-version"]);
1041
+ checks.push({
1042
+ name: "ffmpeg on PATH",
1043
+ ok: ffmpegProbe.status === 0,
1044
+ detail: ffmpegProbe.status === 0 ? firstLine(ffmpegProbe.stdout) : "ffmpeg not found",
1045
+ fix: ffmpegProbe.status === 0 ? "" : "brew install ffmpeg",
1046
+ });
1047
+
1048
+ const ffprobeProbe = runCommand("ffprobe", ["-version"]);
1049
+ checks.push({
1050
+ name: "ffprobe on PATH",
1051
+ ok: ffprobeProbe.status === 0,
1052
+ detail: ffprobeProbe.status === 0 ? firstLine(ffprobeProbe.stdout) : "ffprobe not found",
1053
+ fix: ffprobeProbe.status === 0 ? "" : "brew install ffmpeg",
1054
+ });
1055
+
1056
+ const nodeOk = !versionLessThan(process.versions.node, MIN_NODE_VERSION);
1057
+ checks.push({
1058
+ name: "node version",
1059
+ ok: nodeOk,
1060
+ detail: `${process.version} (need >= v${MIN_NODE_VERSION})`,
1061
+ fix: nodeOk ? "" : `upgrade Node to >= v${MIN_NODE_VERSION}`,
1062
+ });
1063
+
1064
+ // ffmpeg AND ffprobe are both strictly required (see references/setup-providers.md); the exit code
1065
+ // must reflect that so a script gating on `--doctor` doesn't pass with ffprobe
1066
+ // missing and then break at the first probe call.
1067
+ const ffmpeg = checks.find((check) => check.name === "ffmpeg on PATH");
1068
+ const ffprobe = checks.find((check) => check.name === "ffprobe on PATH");
1069
+ return { ok: bundledSfx.ok && !!ffmpeg?.ok && !!ffprobe?.ok, checks };
1070
+ }
1071
+
1072
+ function printDoctor(checks) {
1073
+ const heygenChecks = new Set(["heygen on PATH", "heygen version", "heygen authenticated"]);
1074
+ for (const check of checks) {
1075
+ const prefix = check.ok ? "✓" : "✗";
1076
+ const freePath = heygenChecks.has(check.name)
1077
+ ? " — free-usage path: bgm/image/voice/avatar-video"
1078
+ : "";
1079
+ const fix = check.ok || !check.fix ? "" : ` — fix: ${check.fix}`;
1080
+ console.log(`${prefix} ${check.detail}${freePath}${fix}`);
1081
+ }
1082
+ }
1083
+
1084
+ function printStats(report) {
1085
+ console.log("media-use stats");
1086
+ console.log(`total resolves: ${report.total_resolves}`);
1087
+ console.log(`misses: ${report.misses}`);
1088
+ console.log(
1089
+ `hit rate: ${report.hit_rate == null ? "n/a" : `${Math.round(report.hit_rate * 100)}%`}`,
1090
+ );
1091
+ printMap("by type", report.by_type);
1092
+ printMap("by source", report.by_source);
1093
+ printMap("by provider", report.by_provider);
1094
+ printMap("by via", report.by_via);
1095
+ console.log(`global cache assets: ${report.global_cache_assets}`);
1096
+ console.log(`global cache disk: ${report.global_cache_disk_bytes} bytes`);
1097
+ console.log(`cross-project reuse: ${report.cross_project_reuse}`);
1098
+ console.log("top missed intents:");
1099
+ const entries = Object.entries(report.top_missed_intents);
1100
+ if (entries.length === 0) {
1101
+ console.log(" none");
1102
+ return;
1103
+ }
1104
+ for (const [type, misses] of entries) {
1105
+ console.log(` ${type}:`);
1106
+ for (const miss of misses) console.log(` ${miss.count} ${miss.intent}`);
1107
+ }
1108
+ }
1109
+
1110
+ function printMap(label, values) {
1111
+ const entries = Object.entries(values);
1112
+ console.log(`${label}:`);
1113
+ if (entries.length === 0) {
1114
+ console.log(" none");
1115
+ return;
1116
+ }
1117
+ for (const [key, value] of entries) console.log(` ${key}: ${value}`);
1118
+ }
1119
+
1120
+ function runCommand(bin, argv) {
1121
+ return spawnSync(bin, argv, {
1122
+ encoding: "utf8",
1123
+ timeout: 15000,
1124
+ });
1125
+ }
1126
+
1127
+ function commandText(result) {
1128
+ return [result.stdout, result.stderr].filter(Boolean).join("\n").trim();
1129
+ }
1130
+
1131
+ function firstLine(text) {
1132
+ return (
1133
+ String(text || "")
1134
+ .trim()
1135
+ .split(/\r?\n/)[0] || ""
1136
+ );
1137
+ }
1138
+
1139
+ function emailFromAuthStatus(text) {
1140
+ // JSON only (auth status emits JSON by default). No prose regex fallback: a
1141
+ // human-format body like "Session expired. Contact support@heygen.ai" would
1142
+ // otherwise report the user as authenticated as support@heygen.ai.
1143
+ const trimmed = String(text || "").trim();
1144
+ if (!trimmed.startsWith("{")) return null;
1145
+ try {
1146
+ const parsed = JSON.parse(trimmed);
1147
+ return parsed?.data?.email || parsed?.email || null;
1148
+ } catch {
1149
+ return null;
1150
+ }
1151
+ }
1152
+
1153
+ async function reuseGlobal(shaArg) {
1154
+ const projectDir = resolve(args.project);
1155
+ const type = args.type;
1156
+ if (!type || !listTypes().includes(type)) {
1157
+ console.error(`error: --reuse requires --type (one of: ${listTypes().join(", ")})`);
1158
+ process.exit(2);
1159
+ }
1160
+ if (!shaArg || !shaArg.trim()) {
1161
+ console.error("error: --reuse needs a content sha/prefix (from `resolve --candidates`)");
1162
+ process.exit(2);
1163
+ }
1164
+ const rec = findGlobalBySha(shaArg);
1165
+ if (rec && rec.ambiguous) {
1166
+ console.error(
1167
+ `error: sha prefix "${shaArg}" is ambiguous (${rec.count} matches) — use more characters`,
1168
+ );
1169
+ process.exit(2);
1170
+ }
1171
+ if (!rec) {
1172
+ console.error(`error: no reusable global asset matches sha "${shaArg}"`);
1173
+ process.exit(1);
1174
+ }
1175
+ // Type guard: don't import a bgm asset as an image (audio under images/).
1176
+ // icon<->image are interchangeable; everything else must match --type.
1177
+ if (!typesMatch(rec.type, type)) {
1178
+ console.error(`error: sha "${shaArg}" is a ${rec.type} asset, not ${type}`);
1179
+ process.exit(2);
1180
+ }
1181
+ const ext = extname(rec.cached_path || "") || defaultExt(type);
1182
+ const imported = withReservedFileSync(projectDir, type, ext, ({ id, localPath }) =>
1183
+ localizeImportedRecord(importFromCache(rec, projectDir, id, localPath), localPath),
1184
+ );
1185
+ if (!imported) {
1186
+ console.error(`error: cache entry for "${shaArg}" is incomplete or missing on disk`);
1187
+ process.exit(1);
1188
+ }
1189
+ // Distinguish an explicit agent reuse from an automatic normalize-exact hit.
1190
+ imported.source = "reused-explicit";
1191
+ imported.provenance = { ...imported.provenance, reused_by: "agent" };
1192
+ appendRecord(projectDir, imported);
1193
+ regenerateIndex(projectDir);
1194
+ await result(imported, "reused-explicit");
1195
+ }
1196
+
1197
+ async function result(record, source) {
1198
+ // Non-PII usage event: which media type, how it resolved, which provider won.
1199
+ // Never the intent text or paths. Awaited so a short-lived run flushes it.
1200
+ await track("media_use_resolve", {
1201
+ type: record.type,
1202
+ source,
1203
+ provider: record.provenance?.provider,
1204
+ // How a library LUT resolved: "url" (CDN), "params-fallback" (CDN failed →
1205
+ // parametric), or "params" (offline). Surfaces silent CDN→params downgrades
1206
+ // in prod, which --doctor can't (it only answers "reachable now?").
1207
+ via: record.provenance?.via,
1208
+ // Free (OAuth) vs. paid (API-key) heygen path — sparse: absent for every
1209
+ // non-heygen provider (see heygenAuthMethodFor at construction time). On a
1210
+ // cache/reuse hit this reports how the asset was ORIGINALLY fetched, not
1211
+ // this resolve's own credential state — intentional: it's a conversion
1212
+ // signal about the fetch that actually consumed a heygen credit, not
1213
+ // about the (free, no-credential) act of copying a cached file.
1214
+ auth_method: record.provenance?.authMethod,
1215
+ // "local" / "network_free" / "network_paid", straight from the registry's own
1216
+ // A/N/P declaration — so a dashboard can separate free lookups from calls that
1217
+ // spend credit without hardcoding provider names. Sparse: absent when the
1218
+ // record carries no provider (cache and reuse hits) or the name is unknown.
1219
+ provider_tier: providerTierFor(record.provenance?.provider),
1220
+ local_only: !!args["local-only"],
1221
+ provider_override: !!args.provider,
1222
+ });
1223
+ if (args.json) {
1224
+ const grading = record.type === "grade" && record.grading ? record.grading : null;
1225
+ console.log(
1226
+ JSON.stringify({
1227
+ ok: true,
1228
+ ...record,
1229
+ ...(grading || {}),
1230
+ ...(grading && { grading }),
1231
+ _source: source,
1232
+ }),
1233
+ );
1234
+ } else {
1235
+ const meta = formatMeta(record, source);
1236
+ console.log(`resolved ${record.id} → ${record.path || "inline"} (${meta})`);
1237
+ }
1238
+ }
1239
+
1240
+ function formatMeta(record, source) {
1241
+ const parts = [record.type];
1242
+ if (record.grading?.preset) parts.push(`preset ${record.grading.preset}`);
1243
+ if (record.grading?.lut) parts.push("lut");
1244
+ if (record.duration != null) parts.push(`${record.duration}s`);
1245
+ if (record.width && record.height) parts.push(`${record.width}×${record.height}`);
1246
+ if (record.transparent) parts.push("transparent");
1247
+ if (source === "reused" || source === "reused-explicit") parts.push("reused");
1248
+ if (source === "generated") parts.push("generated");
1249
+ return parts.join(", ");
1250
+ }
1251
+
1252
+ function extFromUrl(url) {
1253
+ try {
1254
+ return extname(new URL(url).pathname) || null;
1255
+ } catch {
1256
+ return null;
1257
+ }
1258
+ }
1259
+
1260
+ function defaultExt(type) {
1261
+ return DEFAULT_EXT[type] || ".bin";
1262
+ }
1263
+
1264
+ run().catch((err) => {
1265
+ if (args.json) {
1266
+ console.log(JSON.stringify({ ok: false, error: err.message }));
1267
+ } else {
1268
+ console.error(`error: ${err.message}`);
1269
+ }
1270
+ process.exit(1);
1271
+ });