hyper-animator-codex 0.7.0 → 0.8.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 (321) hide show
  1. package/README.md +67 -7
  2. package/bin/hyper-animator-codex.mjs +31 -9
  3. package/bin/postinstall.mjs +19 -0
  4. package/lib/install-options.mjs +3 -0
  5. package/lib/install-skill.mjs +84 -2
  6. package/lib/minimax-config.mjs +3 -3
  7. package/package.json +3 -2
  8. package/skills/hyper-animator-codex/SKILL.md +58 -20
  9. package/skills/hyper-animator-codex/agents/openai.yaml +2 -2
  10. package/skills/hyper-animator-codex/contracts/shot-plan.schema.json +214 -0
  11. package/skills/hyper-animator-codex/contracts/workflow-policy.json +85 -0
  12. package/skills/hyper-animator-codex/references/HyperFrames-AI-Generation-Patterns-codex.md +788 -0
  13. package/skills/hyper-animator-codex/references/beat-sync-workflow.md +7 -0
  14. package/skills/hyper-animator-codex/references/examples/shot-plan-dual-catalog.json +69 -0
  15. package/skills/hyper-animator-codex/references/hyperframes-agent-pseudocode.ts +1 -1
  16. package/skills/hyper-animator-codex/references/hyperframes-catalog-map.json +97 -230
  17. package/skills/hyper-animator-codex/references/hyperframes-intent-workflow.md +23 -7
  18. package/skills/hyper-animator-codex/references/minimax-music-workflow.md +24 -4
  19. package/skills/hyper-animator-codex/references/narration-audio-workflow.md +31 -1
  20. package/skills/hyper-animator-codex/references/shotcraft/LICENSE +202 -0
  21. package/skills/hyper-animator-codex/references/shotcraft/cards/ai-stream-response/README.md +46 -0
  22. package/skills/hyper-animator-codex/references/shotcraft/cards/autolayout-gap-dial/README.md +53 -0
  23. package/skills/hyper-animator-codex/references/shotcraft/cards/beat-cut-moves/README.md +54 -0
  24. package/skills/hyper-animator-codex/references/shotcraft/cards/beat-step-list-theme-cycle/README.md +59 -0
  25. package/skills/hyper-animator-codex/references/shotcraft/cards/before-after-slider-scrub/README.md +47 -0
  26. package/skills/hyper-animator-codex/references/shotcraft/cards/bottom-push-stack-wipe/README.md +58 -0
  27. package/skills/hyper-animator-codex/references/shotcraft/cards/brand-frame-snap/README.md +51 -0
  28. package/skills/hyper-animator-codex/references/shotcraft/cards/brand-ink-open/README.md +35 -0
  29. package/skills/hyper-animator-codex/references/shotcraft/cards/bubble-swarm-takeover/README.md +62 -0
  30. package/skills/hyper-animator-codex/references/shotcraft/cards/canvas-materialize-moves/README.md +55 -0
  31. package/skills/hyper-animator-codex/references/shotcraft/cards/card-flip-reveal/README.md +50 -0
  32. package/skills/hyper-animator-codex/references/shotcraft/cards/card-flock-tumble/README.md +54 -0
  33. package/skills/hyper-animator-codex/references/shotcraft/cards/cel-flash-stomp/README.md +54 -0
  34. package/skills/hyper-animator-codex/references/shotcraft/cards/chart-live-moves/README.md +51 -0
  35. package/skills/hyper-animator-codex/references/shotcraft/cards/circle-match-iris/README.md +53 -0
  36. package/skills/hyper-animator-codex/references/shotcraft/cards/cloner-depth-echo/README.md +38 -0
  37. package/skills/hyper-animator-codex/references/shotcraft/cards/collab-cursor-moves/README.md +48 -0
  38. package/skills/hyper-animator-codex/references/shotcraft/cards/color-block-step-wipe/README.md +54 -0
  39. package/skills/hyper-animator-codex/references/shotcraft/cards/command-palette-summon/README.md +45 -0
  40. package/skills/hyper-animator-codex/references/shotcraft/cards/crane-rise-reveal/README.md +47 -0
  41. package/skills/hyper-animator-codex/references/shotcraft/cards/crash-zoom-punch/README.md +38 -0
  42. package/skills/hyper-animator-codex/references/shotcraft/cards/dataviz-landscape-open/README.md +54 -0
  43. package/skills/hyper-animator-codex/references/shotcraft/cards/deck-deal-flyin/README.md +45 -0
  44. package/skills/hyper-animator-codex/references/shotcraft/cards/depth-layer-moves/README.md +40 -0
  45. package/skills/hyper-animator-codex/references/shotcraft/cards/document-typewriter-reveal/README.md +40 -0
  46. package/skills/hyper-animator-codex/references/shotcraft/cards/draw-svg-trace/README.md +50 -0
  47. package/skills/hyper-animator-codex/references/shotcraft/cards/edit-hook-moves/README.md +38 -0
  48. package/skills/hyper-animator-codex/references/shotcraft/cards/element-body-moves/README.md +49 -0
  49. package/skills/hyper-animator-codex/references/shotcraft/cards/fui-hud-moves/README.md +44 -0
  50. package/skills/hyper-animator-codex/references/shotcraft/cards/gauge-readout-moves/README.md +45 -0
  51. package/skills/hyper-animator-codex/references/shotcraft/cards/glow-flyline-moves/README.md +51 -0
  52. package/skills/hyper-animator-codex/references/shotcraft/cards/gradient-word-sweep/README.md +49 -0
  53. package/skills/hyper-animator-codex/references/shotcraft/cards/graze-face-tour/README.md +56 -0
  54. package/skills/hyper-animator-codex/references/shotcraft/cards/hashtag-to-pill-materialize/README.md +57 -0
  55. package/skills/hyper-animator-codex/references/shotcraft/cards/hires-rasterize-3d-text/README.md +34 -0
  56. package/skills/hyper-animator-codex/references/shotcraft/cards/icon-field-colorize/README.md +53 -0
  57. package/skills/hyper-animator-codex/references/shotcraft/cards/icon-performance-moves/README.md +46 -0
  58. package/skills/hyper-animator-codex/references/shotcraft/cards/impact-feedback/README.md +50 -0
  59. package/skills/hyper-animator-codex/references/shotcraft/cards/input-trigger-moves/README.md +49 -0
  60. package/skills/hyper-animator-codex/references/shotcraft/cards/integration-hub-map/README.md +54 -0
  61. package/skills/hyper-animator-codex/references/shotcraft/cards/letterspace-materialize/README.md +52 -0
  62. package/skills/hyper-animator-codex/references/shotcraft/cards/light-play-moves/README.md +49 -0
  63. package/skills/hyper-animator-codex/references/shotcraft/cards/line-boil/README.md +52 -0
  64. package/skills/hyper-animator-codex/references/shotcraft/cards/line-carry-transition/README.md +52 -0
  65. package/skills/hyper-animator-codex/references/shotcraft/cards/list-stack-press/README.md +43 -0
  66. package/skills/hyper-animator-codex/references/shotcraft/cards/magician-card-flourish/README.md +63 -0
  67. package/skills/hyper-animator-codex/references/shotcraft/cards/marker-underline-title/README.md +48 -0
  68. package/skills/hyper-animator-codex/references/shotcraft/cards/montage-rhythm-moves/README.md +55 -0
  69. package/skills/hyper-animator-codex/references/shotcraft/cards/morph-from-primitive/README.md +51 -0
  70. package/skills/hyper-animator-codex/references/shotcraft/cards/neon-frame-forerun/README.md +50 -0
  71. package/skills/hyper-animator-codex/references/shotcraft/cards/neon-frame-orbit-drop/README.md +50 -0
  72. package/skills/hyper-animator-codex/references/shotcraft/cards/neon-triple-marquee/README.md +55 -0
  73. package/skills/hyper-animator-codex/references/shotcraft/cards/odometer-digit-roll/README.md +54 -0
  74. package/skills/hyper-animator-codex/references/shotcraft/cards/outro-group-photo-launch/README.md +39 -0
  75. package/skills/hyper-animator-codex/references/shotcraft/cards/overhead-camera-moves/README.md +50 -0
  76. package/skills/hyper-animator-codex/references/shotcraft/cards/page-turn-transitions/README.md +48 -0
  77. package/skills/hyper-animator-codex/references/shotcraft/cards/page-waterfall-wall/README.md +52 -0
  78. package/skills/hyper-animator-codex/references/shotcraft/cards/panel-grid-moves/README.md +52 -0
  79. package/skills/hyper-animator-codex/references/shotcraft/cards/paper-craft-moves/README.md +46 -0
  80. package/skills/hyper-animator-codex/references/shotcraft/cards/paper-plane-messenger/README.md +62 -0
  81. package/skills/hyper-animator-codex/references/shotcraft/cards/paper-title-card/README.md +36 -0
  82. package/skills/hyper-animator-codex/references/shotcraft/cards/particle-celebrate-hits/README.md +42 -0
  83. package/skills/hyper-animator-codex/references/shotcraft/cards/particle-sand-fill/README.md +39 -0
  84. package/skills/hyper-animator-codex/references/shotcraft/cards/pill-slot-cycle/README.md +57 -0
  85. package/skills/hyper-animator-codex/references/shotcraft/cards/print-texture-transitions/README.md +40 -0
  86. package/skills/hyper-animator-codex/references/shotcraft/cards/rhythm-interrupt-moves/README.md +44 -0
  87. package/skills/hyper-animator-codex/references/shotcraft/cards/riso-print-hits/README.md +54 -0
  88. package/skills/hyper-animator-codex/references/shotcraft/cards/row-embed/README.md +36 -0
  89. package/skills/hyper-animator-codex/references/shotcraft/cards/runway-ground-skim/README.md +52 -0
  90. package/skills/hyper-animator-codex/references/shotcraft/cards/sakuga-timing-shift/README.md +50 -0
  91. package/skills/hyper-animator-codex/references/shotcraft/cards/scene-locked-title/README.md +43 -0
  92. package/skills/hyper-animator-codex/references/shotcraft/cards/scroll-brake-moves/README.md +45 -0
  93. package/skills/hyper-animator-codex/references/shotcraft/cards/segmented-thumb-hero/README.md +57 -0
  94. package/skills/hyper-animator-codex/references/shotcraft/cards/shot-transitions/README.md +60 -0
  95. package/skills/hyper-animator-codex/references/shotcraft/cards/skeleton-reveal/README.md +54 -0
  96. package/skills/hyper-animator-codex/references/shotcraft/cards/slam-entrance-moves/README.md +53 -0
  97. package/skills/hyper-animator-codex/references/shotcraft/cards/smear-multiples/README.md +49 -0
  98. package/skills/hyper-animator-codex/references/shotcraft/cards/space-camera-moves/README.md +53 -0
  99. package/skills/hyper-animator-codex/references/shotcraft/cards/spectrum-morph-ui/README.md +50 -0
  100. package/skills/hyper-animator-codex/references/shotcraft/cards/speed-ramp-freeze/README.md +42 -0
  101. package/skills/hyper-animator-codex/references/shotcraft/cards/split-flap-title/README.md +52 -0
  102. package/skills/hyper-animator-codex/references/shotcraft/cards/spotlight-hero-card/README.md +39 -0
  103. package/skills/hyper-animator-codex/references/shotcraft/cards/spotlight-sweep-moves/README.md +51 -0
  104. package/skills/hyper-animator-codex/references/shotcraft/cards/steep-tilt-glide/README.md +53 -0
  105. package/skills/hyper-animator-codex/references/shotcraft/cards/stroke-segment-build/README.md +43 -0
  106. package/skills/hyper-animator-codex/references/shotcraft/cards/tear-streak-transitions/README.md +43 -0
  107. package/skills/hyper-animator-codex/references/shotcraft/cards/tension-camera-moves/README.md +55 -0
  108. package/skills/hyper-animator-codex/references/shotcraft/cards/text-as-mask/README.md +50 -0
  109. package/skills/hyper-animator-codex/references/shotcraft/cards/text-column-converge/README.md +55 -0
  110. package/skills/hyper-animator-codex/references/shotcraft/cards/theme-switch-moves/README.md +44 -0
  111. package/skills/hyper-animator-codex/references/shotcraft/cards/timeline-travel/README.md +43 -0
  112. package/skills/hyper-animator-codex/references/shotcraft/cards/title-demote-to-label/README.md +58 -0
  113. package/skills/hyper-animator-codex/references/shotcraft/cards/trailer-grammar-moves/README.md +51 -0
  114. package/skills/hyper-animator-codex/references/shotcraft/cards/transition-hidden-cut/README.md +52 -0
  115. package/skills/hyper-animator-codex/references/shotcraft/cards/transition-travel/README.md +48 -0
  116. package/skills/hyper-animator-codex/references/shotcraft/cards/type-and-filter/README.md +37 -0
  117. package/skills/hyper-animator-codex/references/shotcraft/cards/type-assembly-moves/README.md +50 -0
  118. package/skills/hyper-animator-codex/references/shotcraft/cards/type-entrance-moves/README.md +46 -0
  119. package/skills/hyper-animator-codex/references/shotcraft/cards/type-rhythm-sync/README.md +47 -0
  120. package/skills/hyper-animator-codex/references/shotcraft/cards/typewriter-moves/README.md +50 -0
  121. package/skills/hyper-animator-codex/references/shotcraft/cards/ui-strip-away-outro/README.md +63 -0
  122. package/skills/hyper-animator-codex/references/shotcraft/cards/ui-to-brand-morph/README.md +52 -0
  123. package/skills/hyper-animator-codex/references/shotcraft/cards/voice-waveform-live/README.md +52 -0
  124. package/skills/hyper-animator-codex/references/shotcraft/cards/wall-reveal-moves/README.md +53 -0
  125. package/skills/hyper-animator-codex/references/shotcraft/cards/wipe-transitions/README.md +47 -0
  126. package/skills/hyper-animator-codex/references/shotcraft/cards/word-relay-filmstrip/README.md +50 -0
  127. package/skills/hyper-animator-codex/references/shotcraft/catalog.json +3946 -0
  128. package/skills/hyper-animator-codex/references/shotcraft/references/aesthetic-rules.md +157 -0
  129. package/skills/hyper-animator-codex/references/shotcraft/references/final-review.md +107 -0
  130. package/skills/hyper-animator-codex/references/shotcraft/references/guided-free-creation.md +197 -0
  131. package/skills/hyper-animator-codex/references/shotcraft/references/music-beat-sync.md +125 -0
  132. package/skills/hyper-animator-codex/references/shotcraft/references/pipeline.md +357 -0
  133. package/skills/hyper-animator-codex/references/shotcraft/references/sound-design.md +126 -0
  134. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/Caption.tsx +50 -0
  135. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/DigitRoll.tsx +45 -0
  136. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/FlashCut.tsx +20 -0
  137. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/FlatPanel.tsx +65 -0
  138. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/PageCam.tsx +151 -0
  139. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/VerticalTicker.tsx +129 -0
  140. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/helpers/camera.tsx +75 -0
  141. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/helpers/motion.ts +40 -0
  142. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/helpers/rand.ts +11 -0
  143. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/helpers/shake.ts +10 -0
  144. package/skills/hyper-animator-codex/references/shotcraft/source/demos/_fixtures/Fixtures.tsx +83 -0
  145. package/skills/hyper-animator-codex/references/shotcraft/source/demos/ai-stream-response/StreamResponse.tsx +146 -0
  146. package/skills/hyper-animator-codex/references/shotcraft/source/demos/autolayout-gap-dial/AutolayoutGapDial.tsx +174 -0
  147. package/skills/hyper-animator-codex/references/shotcraft/source/demos/beat-cut-moves/BeatCutAccelerando.tsx +77 -0
  148. package/skills/hyper-animator-codex/references/shotcraft/source/demos/beat-cut-moves/PaparazziFlash.tsx +115 -0
  149. package/skills/hyper-animator-codex/references/shotcraft/source/demos/beat-step-list-theme-cycle/BeatStepListThemeCycle.tsx +98 -0
  150. package/skills/hyper-animator-codex/references/shotcraft/source/demos/before-after-slider-scrub/BeforeAfterSliderScrub.tsx +99 -0
  151. package/skills/hyper-animator-codex/references/shotcraft/source/demos/bottom-push-stack-wipe/BottomPushStackWipe.tsx +79 -0
  152. package/skills/hyper-animator-codex/references/shotcraft/source/demos/brand-frame-snap/BrandFrameSnap.tsx +110 -0
  153. package/skills/hyper-animator-codex/references/shotcraft/source/demos/bubble-swarm-takeover/BubbleSwarmTakeover.tsx +189 -0
  154. package/skills/hyper-animator-codex/references/shotcraft/source/demos/canvas-materialize-moves/DiagramCascadeBuild.tsx +172 -0
  155. package/skills/hyper-animator-codex/references/shotcraft/source/demos/canvas-materialize-moves/PanelToCanvasMaterialize.tsx +254 -0
  156. package/skills/hyper-animator-codex/references/shotcraft/source/demos/card-flip-reveal/CardFlipReveal.tsx +139 -0
  157. package/skills/hyper-animator-codex/references/shotcraft/source/demos/card-flock-tumble/CardFlockTumble.tsx +382 -0
  158. package/skills/hyper-animator-codex/references/shotcraft/source/demos/cel-flash-stomp/CelFlashStomp.tsx +111 -0
  159. package/skills/hyper-animator-codex/references/shotcraft/source/demos/chart-live-moves/AxisRescaleShockV2.tsx +282 -0
  160. package/skills/hyper-animator-codex/references/shotcraft/source/demos/chart-live-moves/OscilloscopeStreamV2.tsx +227 -0
  161. package/skills/hyper-animator-codex/references/shotcraft/source/demos/chart-live-moves/UnitDotSwarmRegroupV2.tsx +248 -0
  162. package/skills/hyper-animator-codex/references/shotcraft/source/demos/circle-match-iris/CircleMatchIris.tsx +124 -0
  163. package/skills/hyper-animator-codex/references/shotcraft/source/demos/cloner-depth-echo/ClonerDepthEcho.tsx +90 -0
  164. package/skills/hyper-animator-codex/references/shotcraft/source/demos/collab-cursor-moves/CursorCastEnsemble.tsx +136 -0
  165. package/skills/hyper-animator-codex/references/shotcraft/source/demos/collab-cursor-moves/CursorDialogueDuet.tsx +145 -0
  166. package/skills/hyper-animator-codex/references/shotcraft/source/demos/color-block-step-wipe/ColorBlockStepWipe.tsx +157 -0
  167. package/skills/hyper-animator-codex/references/shotcraft/source/demos/command-palette-summon/CommandPaletteSummon.tsx +173 -0
  168. package/skills/hyper-animator-codex/references/shotcraft/source/demos/crane-rise-reveal/CraneRiseReveal.tsx +91 -0
  169. package/skills/hyper-animator-codex/references/shotcraft/source/demos/crash-zoom-punch/CrashImpactReal.tsx +63 -0
  170. package/skills/hyper-animator-codex/references/shotcraft/source/demos/crash-zoom-punch/CrashZoomReal.tsx +60 -0
  171. package/skills/hyper-animator-codex/references/shotcraft/source/demos/dataviz-landscape-open/DatavizLandscapeOpen.tsx +401 -0
  172. package/skills/hyper-animator-codex/references/shotcraft/source/demos/depth-layer-moves/DollyZoomReal.tsx +55 -0
  173. package/skills/hyper-animator-codex/references/shotcraft/source/demos/depth-layer-moves/MultiplaneReal.tsx +45 -0
  174. package/skills/hyper-animator-codex/references/shotcraft/source/demos/draw-svg-trace/DrawSvgTrace.tsx +199 -0
  175. package/skills/hyper-animator-codex/references/shotcraft/source/demos/edit-hook-moves/LogoStingButton.tsx +106 -0
  176. package/skills/hyper-animator-codex/references/shotcraft/source/demos/element-body-moves/AxialStretch.tsx +112 -0
  177. package/skills/hyper-animator-codex/references/shotcraft/source/demos/element-body-moves/ContactShadowLift.tsx +117 -0
  178. package/skills/hyper-animator-codex/references/shotcraft/source/demos/fui-hud-moves/LineUnfoldPanel.tsx +125 -0
  179. package/skills/hyper-animator-codex/references/shotcraft/source/demos/fui-hud-moves/ReticleLockOn.tsx +139 -0
  180. package/skills/hyper-animator-codex/references/shotcraft/source/demos/gauge-readout-moves/NeedleSweepSelftest.tsx +146 -0
  181. package/skills/hyper-animator-codex/references/shotcraft/source/demos/gauge-readout-moves/TapeScrollFixedPointer.tsx +120 -0
  182. package/skills/hyper-animator-codex/references/shotcraft/source/demos/glow-flyline-moves/FlylineArc.tsx +158 -0
  183. package/skills/hyper-animator-codex/references/shotcraft/source/demos/glow-flyline-moves/GlowOrbAmbient.tsx +131 -0
  184. package/skills/hyper-animator-codex/references/shotcraft/source/demos/glow-flyline-moves/OrbFlylineRelay.tsx +268 -0
  185. package/skills/hyper-animator-codex/references/shotcraft/source/demos/gradient-word-sweep/GradientWordSweep.tsx +307 -0
  186. package/skills/hyper-animator-codex/references/shotcraft/source/demos/graze-face-tour/GrazeFaceTour.tsx +469 -0
  187. package/skills/hyper-animator-codex/references/shotcraft/source/demos/hashtag-to-pill-materialize/HashtagToPillMaterialize.tsx +166 -0
  188. package/skills/hyper-animator-codex/references/shotcraft/source/demos/icon-field-colorize/IconFieldColorize.tsx +93 -0
  189. package/skills/hyper-animator-codex/references/shotcraft/source/demos/icon-performance-moves/AttentionBounce.tsx +193 -0
  190. package/skills/hyper-animator-codex/references/shotcraft/source/demos/icon-performance-moves/PopBurstConfirm.tsx +162 -0
  191. package/skills/hyper-animator-codex/references/shotcraft/source/demos/impact-feedback/AnimeImpact.tsx +149 -0
  192. package/skills/hyper-animator-codex/references/shotcraft/source/demos/impact-feedback/HitCounter.tsx +147 -0
  193. package/skills/hyper-animator-codex/references/shotcraft/source/demos/input-trigger-moves/CursorPerformancePunchIn.tsx +154 -0
  194. package/skills/hyper-animator-codex/references/shotcraft/source/demos/input-trigger-moves/KeycapSmashCut.tsx +217 -0
  195. package/skills/hyper-animator-codex/references/shotcraft/source/demos/integration-hub-map/IntegrationHubMap.tsx +554 -0
  196. package/skills/hyper-animator-codex/references/shotcraft/source/demos/letterspace-materialize/LetterspaceMaterialize.tsx +85 -0
  197. package/skills/hyper-animator-codex/references/shotcraft/source/demos/light-play-moves/HalationBloom.tsx +139 -0
  198. package/skills/hyper-animator-codex/references/shotcraft/source/demos/light-play-moves/SheenSweepRetry.tsx +85 -0
  199. package/skills/hyper-animator-codex/references/shotcraft/source/demos/light-play-moves/SpotlightSweepReveal.tsx +102 -0
  200. package/skills/hyper-animator-codex/references/shotcraft/source/demos/line-boil/LineBoil.tsx +140 -0
  201. package/skills/hyper-animator-codex/references/shotcraft/source/demos/line-carry-transition/LineCarryTransition.tsx +151 -0
  202. package/skills/hyper-animator-codex/references/shotcraft/source/demos/magician-card-flourish/MagicianCardFlourish.tsx +294 -0
  203. package/skills/hyper-animator-codex/references/shotcraft/source/demos/marker-underline-title/MarkerUnderlineTitle.tsx +87 -0
  204. package/skills/hyper-animator-codex/references/shotcraft/source/demos/montage-rhythm-moves/DominoCascade.tsx +125 -0
  205. package/skills/hyper-animator-codex/references/shotcraft/source/demos/montage-rhythm-moves/DropBlackoutSlam.tsx +135 -0
  206. package/skills/hyper-animator-codex/references/shotcraft/source/demos/montage-rhythm-moves/WrightTripleCut.tsx +175 -0
  207. package/skills/hyper-animator-codex/references/shotcraft/source/demos/morph-from-primitive/MorphFromPrimitive.tsx +190 -0
  208. package/skills/hyper-animator-codex/references/shotcraft/source/demos/neon-frame-forerun/NeonFrameForerun.tsx +279 -0
  209. package/skills/hyper-animator-codex/references/shotcraft/source/demos/neon-frame-orbit-drop/NeonFrameForerunOrbit.tsx +273 -0
  210. package/skills/hyper-animator-codex/references/shotcraft/source/demos/neon-triple-marquee/NeonTripleMarquee.tsx +111 -0
  211. package/skills/hyper-animator-codex/references/shotcraft/source/demos/odometer-digit-roll/OdometerDigitRoll.tsx +178 -0
  212. package/skills/hyper-animator-codex/references/shotcraft/source/demos/overhead-camera-moves/OverheadTabletopDrop.tsx +129 -0
  213. package/skills/hyper-animator-codex/references/shotcraft/source/demos/overhead-camera-moves/TiltReveal.tsx +55 -0
  214. package/skills/hyper-animator-codex/references/shotcraft/source/demos/page-turn-transitions/BarnDoorSplit.tsx +138 -0
  215. package/skills/hyper-animator-codex/references/shotcraft/source/demos/page-turn-transitions/CubeRotate.tsx +114 -0
  216. package/skills/hyper-animator-codex/references/shotcraft/source/demos/page-waterfall-wall/PageWaterfallWall.tsx +76 -0
  217. package/skills/hyper-animator-codex/references/shotcraft/source/demos/page-waterfall-wall/VerticalTicker.tsx +129 -0
  218. package/skills/hyper-animator-codex/references/shotcraft/source/demos/panel-grid-moves/ComicPanelSplit.tsx +171 -0
  219. package/skills/hyper-animator-codex/references/shotcraft/source/demos/panel-grid-moves/FlipGridReflow.tsx +121 -0
  220. package/skills/hyper-animator-codex/references/shotcraft/source/demos/panel-grid-moves/GridFlashMosaic.tsx +182 -0
  221. package/skills/hyper-animator-codex/references/shotcraft/source/demos/paper-craft-moves/MaskingTapeSlap.tsx +163 -0
  222. package/skills/hyper-animator-codex/references/shotcraft/source/demos/paper-craft-moves/PopupBookRise.tsx +134 -0
  223. package/skills/hyper-animator-codex/references/shotcraft/source/demos/paper-plane-messenger/PaperPlaneMessenger.tsx +183 -0
  224. package/skills/hyper-animator-codex/references/shotcraft/source/demos/particle-celebrate-hits/ConfettiCrossfire.tsx +115 -0
  225. package/skills/hyper-animator-codex/references/shotcraft/source/demos/particle-celebrate-hits/CounterTickSparks.tsx +103 -0
  226. package/skills/hyper-animator-codex/references/shotcraft/source/demos/particle-sand-fill/ParticleSandFill.tsx +119 -0
  227. package/skills/hyper-animator-codex/references/shotcraft/source/demos/pill-slot-cycle/PillSlotCycle.tsx +220 -0
  228. package/skills/hyper-animator-codex/references/shotcraft/source/demos/print-texture-transitions/InkBleedReveal.tsx +81 -0
  229. package/skills/hyper-animator-codex/references/shotcraft/source/demos/rhythm-interrupt-moves/JumpCutPunchIn.tsx +72 -0
  230. package/skills/hyper-animator-codex/references/shotcraft/source/demos/rhythm-interrupt-moves/StrobeBlackFrames.tsx +99 -0
  231. package/skills/hyper-animator-codex/references/shotcraft/source/demos/riso-print-hits/RisoBeatPump.tsx +155 -0
  232. package/skills/hyper-animator-codex/references/shotcraft/source/demos/riso-print-hits/RisoMisregistrationHit.tsx +120 -0
  233. package/skills/hyper-animator-codex/references/shotcraft/source/demos/runway-ground-skim/RunwayGroundSkim.tsx +258 -0
  234. package/skills/hyper-animator-codex/references/shotcraft/source/demos/sakuga-timing-shift/SakugaTimingShift.tsx +178 -0
  235. package/skills/hyper-animator-codex/references/shotcraft/source/demos/scene-locked-title/SceneLockedTitle.tsx +98 -0
  236. package/skills/hyper-animator-codex/references/shotcraft/source/demos/scroll-brake-moves/BrakeReticleLock.tsx +171 -0
  237. package/skills/hyper-animator-codex/references/shotcraft/source/demos/scroll-brake-moves/ChangelogScrollBrake.tsx +117 -0
  238. package/skills/hyper-animator-codex/references/shotcraft/source/demos/segmented-thumb-hero/SegmentedThumbHero.tsx +213 -0
  239. package/skills/hyper-animator-codex/references/shotcraft/source/demos/shot-transitions/MaskWipeReal.tsx +67 -0
  240. package/skills/hyper-animator-codex/references/shotcraft/source/demos/shot-transitions/PortalWipeV2.tsx +128 -0
  241. package/skills/hyper-animator-codex/references/shotcraft/source/demos/shot-transitions/WhipBrakeReal.tsx +60 -0
  242. package/skills/hyper-animator-codex/references/shotcraft/source/demos/shot-transitions/WhipPanReal.tsx +45 -0
  243. package/skills/hyper-animator-codex/references/shotcraft/source/demos/skeleton-reveal/SkeletonReveal.tsx +283 -0
  244. package/skills/hyper-animator-codex/references/shotcraft/source/demos/slam-entrance-moves/ImpactBurstKit.tsx +185 -0
  245. package/skills/hyper-animator-codex/references/shotcraft/source/demos/slam-entrance-moves/KanadaPerspectiveSnap.tsx +91 -0
  246. package/skills/hyper-animator-codex/references/shotcraft/source/demos/slam-entrance-moves/ScoreSlam.tsx +225 -0
  247. package/skills/hyper-animator-codex/references/shotcraft/source/demos/smear-multiples/SmearMultiples.tsx +88 -0
  248. package/skills/hyper-animator-codex/references/shotcraft/source/demos/space-camera-moves/DroneDiveLanding.tsx +91 -0
  249. package/skills/hyper-animator-codex/references/shotcraft/source/demos/space-camera-moves/ExplodedView.tsx +178 -0
  250. package/skills/hyper-animator-codex/references/shotcraft/source/demos/space-camera-moves/SnorricamLock.tsx +130 -0
  251. package/skills/hyper-animator-codex/references/shotcraft/source/demos/spectrum-morph-ui/SpectrumMorphUi.tsx +129 -0
  252. package/skills/hyper-animator-codex/references/shotcraft/source/demos/speed-ramp-freeze/FreezeAnnotateReal.tsx +70 -0
  253. package/skills/hyper-animator-codex/references/shotcraft/source/demos/speed-ramp-freeze/SpeedRampReal.tsx +58 -0
  254. package/skills/hyper-animator-codex/references/shotcraft/source/demos/split-flap-title/SplitFlapFlip.tsx +189 -0
  255. package/skills/hyper-animator-codex/references/shotcraft/source/demos/spotlight-sweep-moves/CornerSpotlightReveal.tsx +121 -0
  256. package/skills/hyper-animator-codex/references/shotcraft/source/demos/spotlight-sweep-moves/GlowWakeSleepPanel.tsx +183 -0
  257. package/skills/hyper-animator-codex/references/shotcraft/source/demos/spotlight-sweep-moves/SlideSpotlightPan.tsx +171 -0
  258. package/skills/hyper-animator-codex/references/shotcraft/source/demos/steep-tilt-glide/SteepTiltGlide.tsx +315 -0
  259. package/skills/hyper-animator-codex/references/shotcraft/source/demos/stroke-segment-build/StrokeSegmentBuild.tsx +126 -0
  260. package/skills/hyper-animator-codex/references/shotcraft/source/demos/tear-streak-transitions/GlitchDisplace.tsx +107 -0
  261. package/skills/hyper-animator-codex/references/shotcraft/source/demos/tension-camera-moves/BulletTimeFreezeOrbit.tsx +219 -0
  262. package/skills/hyper-animator-codex/references/shotcraft/source/demos/tension-camera-moves/DutchRollToLevel.tsx +110 -0
  263. package/skills/hyper-animator-codex/references/shotcraft/source/demos/tension-camera-moves/PullBackIsolation.tsx +120 -0
  264. package/skills/hyper-animator-codex/references/shotcraft/source/demos/tension-camera-moves/SlowPushIn.tsx +96 -0
  265. package/skills/hyper-animator-codex/references/shotcraft/source/demos/text-as-mask/TextAsMask.tsx +94 -0
  266. package/skills/hyper-animator-codex/references/shotcraft/source/demos/text-column-converge/TextColumnConverge.tsx +122 -0
  267. package/skills/hyper-animator-codex/references/shotcraft/source/demos/theme-switch-moves/PaletteThemeRipple.tsx +207 -0
  268. package/skills/hyper-animator-codex/references/shotcraft/source/demos/theme-switch-moves/ThemeSweepToggle.tsx +123 -0
  269. package/skills/hyper-animator-codex/references/shotcraft/source/demos/timeline-travel/TimelineTravel.tsx +123 -0
  270. package/skills/hyper-animator-codex/references/shotcraft/source/demos/title-demote-to-label/TitleDemoteToLabel.tsx +174 -0
  271. package/skills/hyper-animator-codex/references/shotcraft/source/demos/trailer-grammar-moves/CardFootageCadence.tsx +118 -0
  272. package/skills/hyper-animator-codex/references/shotcraft/source/demos/trailer-grammar-moves/SmashCut.tsx +105 -0
  273. package/skills/hyper-animator-codex/references/shotcraft/source/demos/trailer-grammar-moves/TrailerBumper.tsx +103 -0
  274. package/skills/hyper-animator-codex/references/shotcraft/source/demos/transition-hidden-cut/InvisibleCut.tsx +93 -0
  275. package/skills/hyper-animator-codex/references/shotcraft/source/demos/transition-hidden-cut/LightLeakBurn.tsx +122 -0
  276. package/skills/hyper-animator-codex/references/shotcraft/source/demos/transition-hidden-cut/VersusSlam.tsx +104 -0
  277. package/skills/hyper-animator-codex/references/shotcraft/source/demos/transition-travel/LetterformZoom.tsx +141 -0
  278. package/skills/hyper-animator-codex/references/shotcraft/source/demos/transition-travel/SharedElementMorph.tsx +101 -0
  279. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-assembly-moves/LetterformDriftAssembly.tsx +107 -0
  280. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-assembly-moves/SplitTextStagger.tsx +101 -0
  281. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-assembly-moves/TextOnPath.tsx +92 -0
  282. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-assembly-moves/TrackingExpandReveal.tsx +109 -0
  283. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-entrance-moves/LetterDropPhysics.tsx +100 -0
  284. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-entrance-moves/ScrambleDecode.tsx +90 -0
  285. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-rhythm-sync/FontWeightPump.tsx +124 -0
  286. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-rhythm-sync/KaraokeFillSync.tsx +93 -0
  287. package/skills/hyper-animator-codex/references/shotcraft/source/demos/typewriter-moves/TerminalTypewriter.tsx +122 -0
  288. package/skills/hyper-animator-codex/references/shotcraft/source/demos/typewriter-moves/TypewriterErrorRetype.tsx +109 -0
  289. package/skills/hyper-animator-codex/references/shotcraft/source/demos/ui-strip-away-outro/UiStripAwayOutro.tsx +218 -0
  290. package/skills/hyper-animator-codex/references/shotcraft/source/demos/ui-to-brand-morph/IconFlipBloomLogo.tsx +199 -0
  291. package/skills/hyper-animator-codex/references/shotcraft/source/demos/ui-to-brand-morph/InputMorphsIntoLogo.tsx +215 -0
  292. package/skills/hyper-animator-codex/references/shotcraft/source/demos/voice-waveform-live/VoiceWaveformLive.tsx +171 -0
  293. package/skills/hyper-animator-codex/references/shotcraft/source/demos/wall-reveal-moves/BentoLightUp.tsx +135 -0
  294. package/skills/hyper-animator-codex/references/shotcraft/source/demos/wipe-transitions/BlindsSlice.tsx +107 -0
  295. package/skills/hyper-animator-codex/references/shotcraft/source/demos/wipe-transitions/ClockWipe.tsx +83 -0
  296. package/skills/hyper-animator-codex/references/shotcraft/source/demos/word-relay-filmstrip/WordRelayFilmstrip.tsx +300 -0
  297. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/Root.tsx +15 -0
  298. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/Caption.tsx +49 -0
  299. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/DigitRoll.tsx +44 -0
  300. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/FlashCut.tsx +19 -0
  301. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/Main.tsx +163 -0
  302. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/PaperTitleCard.tsx +89 -0
  303. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/live/PageCam.tsx +145 -0
  304. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/live/SceneDetail.tsx +146 -0
  305. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/live/SceneFlyIn.tsx +447 -0
  306. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/live/SceneOpen.tsx +532 -0
  307. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/live/SceneOutroLive.tsx +394 -0
  308. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/live/ScenePapers.tsx +185 -0
  309. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/live/SceneWbr.tsx +299 -0
  310. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/index.ts +4 -0
  311. package/skills/hyper-animator-codex/references/shotcraft/source-notes.md +10 -0
  312. package/skills/hyper-animator-codex/scripts/generate_minimax_music.mjs +27 -10
  313. package/skills/hyper-animator-codex/scripts/generate_minimax_tts.mjs +142 -13
  314. package/skills/hyper-animator-codex/scripts/generate_subtitles.mjs +42 -3
  315. package/skills/hyper-animator-codex/scripts/minimax_runtime_config.mjs +3 -3
  316. package/skills/hyper-animator-codex/scripts/query_shotcraft.mjs +140 -0
  317. package/skills/hyper-animator-codex/scripts/validate_hyperframes_html.py +22 -0
  318. package/skills/hyper-animator-codex/scripts/validate_provider_policy.mjs +108 -0
  319. package/skills/hyper-animator-codex/scripts/validate_shot_plan.mjs +193 -0
  320. package/skills/hyper-animator-codex/vendor/music-beat-detector/beat_detector/analyzer.py +3 -1
  321. package/skills/hyper-animator-codex/vendor/music-beat-detector/beat_detector/beat.py +37 -1
@@ -15,6 +15,7 @@ function requireValue(args, index, flag) {
15
15
  function parseArgs(args) {
16
16
  const parsed = {
17
17
  narration: undefined,
18
+ timing_manifest: undefined,
18
19
  output_dir: join(process.cwd(), "hyper-animator-output", "subtitles"),
19
20
  style: "default",
20
21
  };
@@ -30,6 +31,9 @@ function parseArgs(args) {
30
31
  } else if (arg === "--style") {
31
32
  parsed.style = requireValue(args, index, arg);
32
33
  index += 1;
34
+ } else if (arg === "--timing-manifest") {
35
+ parsed.timing_manifest = requireValue(args, index, arg);
36
+ index += 1;
33
37
  } else if (arg === "--help" || arg === "-h") {
34
38
  parsed.help = true;
35
39
  } else {
@@ -71,14 +75,43 @@ function roundTime(value) {
71
75
  return Number(value.toFixed(3));
72
76
  }
73
77
 
74
- function buildCues(narration) {
78
+ function validateTimingManifest(manifest, narration) {
79
+ if (!manifest || typeof manifest !== "object" || !Array.isArray(manifest.scenes)) {
80
+ throw new Error("timing manifest must include scenes[]");
81
+ }
82
+ if (manifest.provider !== "minimax_cn") {
83
+ throw new Error("timing manifest provider must be minimax_cn");
84
+ }
85
+ if (manifest.scenes.length !== narration.scenes.length) {
86
+ throw new Error("timing manifest scene count must match narration scenes");
87
+ }
88
+
89
+ let expectedStart = 0;
90
+ manifest.scenes.forEach((scene, index) => {
91
+ if (!Number.isFinite(scene.start_seconds) || !Number.isFinite(scene.end_seconds)
92
+ || scene.start_seconds < 0 || scene.end_seconds <= scene.start_seconds) {
93
+ throw new Error(`timing manifest scenes[${index}] must have valid start_seconds/end_seconds`);
94
+ }
95
+ if (Math.abs(scene.start_seconds - expectedStart) > 0.001) {
96
+ throw new Error(`timing manifest scenes[${index}] must be contiguous`);
97
+ }
98
+ expectedStart = scene.end_seconds;
99
+ });
100
+ }
101
+
102
+ function buildCues(narration, timingManifest) {
75
103
  const cues = [];
76
104
  let cursor = 0;
77
105
 
78
106
  narration.scenes.forEach((scene, sceneIndex) => {
79
107
  const parts = splitNarration(scene.narration);
80
- const duration = Number(scene.duration_estimate) || Math.max(parts.length * 2, 2);
108
+ const timing = timingManifest?.scenes?.[sceneIndex];
109
+ const sceneStart = timing?.start_seconds ?? cursor;
110
+ const duration = timing
111
+ ? timing.end_seconds - timing.start_seconds
112
+ : Number(scene.duration_estimate) || Math.max(parts.length * 2, 2);
81
113
  const cueDuration = duration / Math.max(parts.length, 1);
114
+ cursor = sceneStart;
82
115
 
83
116
  parts.forEach((text) => {
84
117
  const start = cursor;
@@ -124,8 +157,12 @@ async function generateSubtitles(options) {
124
157
 
125
158
  const narration = JSON.parse(await readFile(options.narration, "utf8"));
126
159
  validateNarration(narration);
160
+ const timingManifest = options.timing_manifest
161
+ ? JSON.parse(await readFile(options.timing_manifest, "utf8"))
162
+ : null;
163
+ if (timingManifest) validateTimingManifest(timingManifest, narration);
127
164
 
128
- const cues = buildCues(narration);
165
+ const cues = buildCues(narration, timingManifest);
129
166
  await mkdir(options.output_dir, { recursive: true });
130
167
 
131
168
  const jsonPath = join(options.output_dir, "subtitles.json");
@@ -134,6 +171,7 @@ async function generateSubtitles(options) {
134
171
  ok: true,
135
172
  style: options.style,
136
173
  source: options.narration,
174
+ timing_source: options.timing_manifest ?? null,
137
175
  cues,
138
176
  };
139
177
 
@@ -153,6 +191,7 @@ function printHelp() {
153
191
 
154
192
  Options:
155
193
  --narration <file> Narration JSON file
194
+ --timing-manifest <file> MiniMax narration-manifest.json with exact scene timing
156
195
  --output-dir <dir> Output directory, default hyper-animator-output/subtitles
157
196
  --style <name> Subtitle style label for downstream HTML/render steps
158
197
  `);
@@ -1,8 +1,8 @@
1
1
  import { readFile, stat } from "node:fs/promises";
2
2
  import { join } from "node:path";
3
3
 
4
- export const DEFAULT_MINIMAX_MODEL = "music-2.6-free";
5
- export const TEXT_MUSIC_MODELS = new Set(["music-2.6", "music-2.6-free"]);
4
+ export const DEFAULT_MINIMAX_MODEL = "music-2.6";
5
+ export const TEXT_MUSIC_MODELS = new Set(["music-3.0", "music-2.6", "music-2.6-free"]);
6
6
 
7
7
  async function pathExists(path) {
8
8
  try {
@@ -61,7 +61,7 @@ export function validateMinimaxConfig(config = {}) {
61
61
  const model = normalized.model || DEFAULT_MINIMAX_MODEL;
62
62
 
63
63
  if (!TEXT_MUSIC_MODELS.has(model)) {
64
- throw new Error(`Unsupported MiniMax text music model: ${model}. Use music-2.6 or music-2.6-free.`);
64
+ throw new Error(`Unsupported MiniMax text music model: ${model}. Use music-3.0, music-2.6, or music-2.6-free.`);
65
65
  }
66
66
 
67
67
  return {
@@ -0,0 +1,140 @@
1
+ #!/usr/bin/env node
2
+ import { readFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ const scriptDir = dirname(fileURLToPath(import.meta.url));
7
+ const catalogPath = join(dirname(scriptDir), "references", "shotcraft", "catalog.json");
8
+
9
+ function requireValue(args, index, flag) {
10
+ const value = args[index + 1];
11
+ if (!value || value.startsWith("--")) throw new Error(`${flag} requires a value`);
12
+ return value;
13
+ }
14
+
15
+ function parseArgs(args) {
16
+ const parsed = { limit: 8, json: false, include_reference_only: false };
17
+ for (let index = 0; index < args.length; index += 1) {
18
+ const arg = args[index];
19
+ if (arg === "--query" || arg === "-q") {
20
+ parsed.query = requireValue(args, index, arg);
21
+ index += 1;
22
+ } else if (arg === "--limit") {
23
+ parsed.limit = Number.parseInt(requireValue(args, index, arg), 10);
24
+ index += 1;
25
+ } else if (arg === "--json") {
26
+ parsed.json = true;
27
+ } else if (arg === "--include-reference-only") {
28
+ parsed.include_reference_only = true;
29
+ } else if (arg === "--help" || arg === "-h") {
30
+ parsed.help = true;
31
+ } else {
32
+ throw new Error(`Unknown option: ${arg}`);
33
+ }
34
+ }
35
+ return parsed;
36
+ }
37
+
38
+ function tokens(value) {
39
+ return String(value)
40
+ .toLowerCase()
41
+ .split(/[\s,,。::;;/|()[\]{}"'`_-]+/)
42
+ .map((token) => token.trim())
43
+ .filter(Boolean);
44
+ }
45
+
46
+ function scoreText(queryTokens, fields) {
47
+ const haystack = fields.filter(Boolean).join("\n").toLowerCase();
48
+ return queryTokens.reduce((score, token) => {
49
+ if (!haystack.includes(token)) return score;
50
+ const exactWord = new RegExp(`(^|[^a-z0-9])${token.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}([^a-z0-9]|$)`, "i");
51
+ return score + (exactWord.test(haystack) ? 4 : 2);
52
+ }, 0);
53
+ }
54
+
55
+ function rankCard(card, queryTokens, includeReferenceOnly) {
56
+ const eligibleStyles = card.styles.filter((style) => (
57
+ includeReferenceOnly || style.implementation_status === "implemented"
58
+ ));
59
+ if (eligibleStyles.length === 0) return null;
60
+
61
+ const styleScores = eligibleStyles.map((style) => ({
62
+ style,
63
+ score: scoreText(queryTokens, [
64
+ style.key,
65
+ style.label,
66
+ style.description,
67
+ style.use,
68
+ ]),
69
+ })).sort((left, right) => right.score - left.score || left.style.key.localeCompare(right.style.key));
70
+
71
+ const cardScore = scoreText(queryTokens, [
72
+ card.name,
73
+ card.summary,
74
+ card.use,
75
+ card.energy,
76
+ card.intention,
77
+ ]);
78
+ const bestStyle = styleScores[0];
79
+ const slugBonus = queryTokens.some((token) => card.name.includes(token)) ? 3 : 0;
80
+ return {
81
+ score: cardScore + bestStyle.score + slugBonus,
82
+ card: card.name,
83
+ summary: card.summary,
84
+ use: card.use,
85
+ duration: card.duration,
86
+ energy: card.energy,
87
+ code_status: card.code_status,
88
+ style: bestStyle.style.key,
89
+ implementation_status: bestStyle.style.implementation_status,
90
+ usage_document: bestStyle.style.usage_document || card.usage_document,
91
+ source_files: bestStyle.style.source_files,
92
+ };
93
+ }
94
+
95
+ function printHuman(results) {
96
+ for (const [index, result] of results.entries()) {
97
+ console.log(`${index + 1}. ${result.card} / ${result.style} (score ${result.score})`);
98
+ console.log(` ${result.summary}`);
99
+ console.log(` use: ${result.use}`);
100
+ console.log(` source: ${result.source_files.join(", ")}`);
101
+ }
102
+ }
103
+
104
+ async function main() {
105
+ try {
106
+ const args = parseArgs(process.argv.slice(2));
107
+ if (args.help) {
108
+ console.log("Usage: query_shotcraft.mjs --query <text> [--limit 8] [--json] [--include-reference-only]");
109
+ return;
110
+ }
111
+ if (!args.query?.trim()) throw new Error("--query is required");
112
+ if (!Number.isInteger(args.limit) || args.limit < 1 || args.limit > 50) {
113
+ throw new Error("--limit must be an integer from 1 to 50");
114
+ }
115
+
116
+ const catalog = JSON.parse(await readFile(catalogPath, "utf8"));
117
+ const queryTokens = tokens(args.query);
118
+ const results = catalog.cards
119
+ .map((card) => rankCard(card, queryTokens, args.include_reference_only))
120
+ .filter((result) => result && result.score > 0)
121
+ .sort((left, right) => right.score - left.score || left.card.localeCompare(right.card))
122
+ .slice(0, args.limit);
123
+
124
+ if (args.json) {
125
+ console.log(JSON.stringify({
126
+ ok: true,
127
+ query: args.query,
128
+ source_revision: catalog.source_revision,
129
+ results,
130
+ }, null, 2));
131
+ } else {
132
+ printHuman(results);
133
+ }
134
+ } catch (error) {
135
+ console.log(JSON.stringify({ ok: false, error: error.message }, null, 2));
136
+ process.exitCode = 1;
137
+ }
138
+ }
139
+
140
+ main();
@@ -13,6 +13,20 @@ def has_attr(html: str, name: str) -> bool:
13
13
  return re.search(rf"\b{name}\s*=\s*['\"]?[^'\"\s>]+", html, re.IGNORECASE) is not None
14
14
 
15
15
 
16
+ def numeric_attr(html: str, name: str) -> float | None:
17
+ match = re.search(
18
+ rf"\b{name}\s*=\s*(?:['\"]([^'\"]+)['\"]|([^\s>]+))",
19
+ html,
20
+ re.IGNORECASE,
21
+ )
22
+ if not match:
23
+ return None
24
+ try:
25
+ return float(match.group(1) or match.group(2))
26
+ except ValueError:
27
+ return None
28
+
29
+
16
30
  def check_html(
17
31
  html: str,
18
32
  *,
@@ -26,6 +40,11 @@ def check_html(
26
40
  for attr in ("data-width", "data-height", "data-duration", "data-composition-id"):
27
41
  if not has_attr(html, attr):
28
42
  failures.append(f"missing {attr}")
43
+ for attr in ("data-width", "data-height", "data-duration"):
44
+ if has_attr(html, attr):
45
+ value = numeric_attr(html, attr)
46
+ if value is None or value <= 0:
47
+ failures.append(f"{attr} must be a positive number")
29
48
 
30
49
  if "<!-- paste from " in html:
31
50
  failures.append("unresolved component paste placeholder")
@@ -47,6 +66,9 @@ def check_html(
47
66
  if re.search(r"\bsetInterval\s*\(", html):
48
67
  failures.append("uses setInterval(); primary render progress must be timeline-driven")
49
68
 
69
+ if re.search(r"\bMath\s*\.\s*random\s*\(", html):
70
+ failures.append("uses Math.random(); visual generation must use a fixed-seed deterministic PRNG")
71
+
50
72
  if re.search(r"\brequestAnimationFrame\s*\(", html) and "fallback" not in html.lower():
51
73
  warnings.append("requestAnimationFrame found; ensure it is not the primary render clock and has render fallback")
52
74
 
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env node
2
+ import { readFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ const scriptDir = dirname(fileURLToPath(import.meta.url));
7
+ const policyPath = join(dirname(scriptDir), "contracts", "workflow-policy.json");
8
+
9
+ function requireValue(args, index, flag) {
10
+ const value = args[index + 1];
11
+ if (!value || value.startsWith("--")) throw new Error(`${flag} requires a value`);
12
+ return value;
13
+ }
14
+
15
+ function parseArgs(args) {
16
+ const parsed = {};
17
+ for (let index = 0; index < args.length; index += 1) {
18
+ const arg = args[index];
19
+ if (["--kind", "--provider", "--endpoint"].includes(arg)) {
20
+ parsed[arg.slice(2)] = requireValue(args, index, arg);
21
+ index += 1;
22
+ } else if (arg === "--help" || arg === "-h") {
23
+ parsed.help = true;
24
+ } else {
25
+ throw new Error(`Unknown option: ${arg}`);
26
+ }
27
+ }
28
+ return parsed;
29
+ }
30
+
31
+ function output(payload, exitCode = 0) {
32
+ console.log(JSON.stringify(payload, null, 2));
33
+ process.exitCode = exitCode;
34
+ }
35
+
36
+ function reject(code, message, details = {}) {
37
+ output({ ok: false, error: { code, message, ...details } }, 1);
38
+ }
39
+
40
+ async function main() {
41
+ try {
42
+ const args = parseArgs(process.argv.slice(2));
43
+ if (args.help) {
44
+ console.log("Usage: validate_provider_policy.mjs --kind <narration|bgm> --provider <name> --endpoint <url>");
45
+ return;
46
+ }
47
+
48
+ if (!["narration", "bgm"].includes(args.kind)) {
49
+ reject("invalid_kind", "--kind must be narration or bgm");
50
+ return;
51
+ }
52
+ if (!args.provider) {
53
+ reject("missing_provider", "--provider is required");
54
+ return;
55
+ }
56
+ if (!args.endpoint || !URL.canParse(args.endpoint)) {
57
+ reject("invalid_endpoint", "--endpoint must be a valid URL");
58
+ return;
59
+ }
60
+
61
+ const policy = JSON.parse(await readFile(policyPath, "utf8"));
62
+ const normalizedProvider = args.provider.trim().toLowerCase();
63
+ if (policy.audio.forbidden_providers.includes(normalizedProvider)) {
64
+ reject("forbidden_provider", `${args.provider} is forbidden by the generated-audio policy`, {
65
+ provider: normalizedProvider,
66
+ });
67
+ return;
68
+ }
69
+
70
+ const route = args.kind === "narration"
71
+ ? policy.audio.generated_narration
72
+ : policy.audio.generated_bgm;
73
+ if (normalizedProvider !== route.provider) {
74
+ reject("provider_mismatch", `${args.kind} generation requires provider ${route.provider}`, {
75
+ expected: route.provider,
76
+ actual: normalizedProvider,
77
+ });
78
+ return;
79
+ }
80
+
81
+ const actual = new URL(args.endpoint);
82
+ const expected = new URL(route.endpoint);
83
+ const allowedEndpoints = [route.endpoint, ...(route.backup_endpoints || [])]
84
+ .map((endpoint) => new URL(endpoint));
85
+ if (!allowedEndpoints.some((allowed) => (
86
+ actual.origin === allowed.origin && actual.pathname === allowed.pathname
87
+ ))) {
88
+ reject("endpoint_mismatch", `${args.kind} generation requires the MiniMax mainland endpoint`, {
89
+ expected: route.endpoint,
90
+ actual: args.endpoint,
91
+ });
92
+ return;
93
+ }
94
+
95
+ output({
96
+ ok: true,
97
+ kind: args.kind,
98
+ provider: route.provider,
99
+ endpoint: args.endpoint,
100
+ primary_endpoint: route.endpoint,
101
+ region: "cn",
102
+ });
103
+ } catch (error) {
104
+ reject("validation", error.message);
105
+ }
106
+ }
107
+
108
+ main();
@@ -0,0 +1,193 @@
1
+ #!/usr/bin/env node
2
+ import { readFile } from "node:fs/promises";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+
6
+ const scriptDir = dirname(fileURLToPath(import.meta.url));
7
+ const skillRoot = dirname(scriptDir);
8
+
9
+ function isObject(value) {
10
+ return value !== null && typeof value === "object" && !Array.isArray(value);
11
+ }
12
+
13
+ function validateAudioTrack(track, label, errors) {
14
+ if (!isObject(track)) {
15
+ errors.push(`audio.${label} must be an object`);
16
+ return;
17
+ }
18
+
19
+ if (!["generated", "user_local_file", "none"].includes(track.mode)) {
20
+ errors.push(`audio.${label}.mode must be generated, user_local_file, or none`);
21
+ }
22
+ if (track.mode === "generated" && track.provider !== "minimax_cn") {
23
+ errors.push(`audio.${label}.provider must be minimax_cn when mode is generated`);
24
+ }
25
+ if (track.mode === "user_local_file" && (typeof track.path !== "string" || !track.path.trim())) {
26
+ errors.push(`audio.${label}.path is required when mode is user_local_file`);
27
+ }
28
+ if (track.mode === "none" && track.provider !== undefined) {
29
+ errors.push(`audio.${label}.provider must be omitted when mode is none`);
30
+ }
31
+ }
32
+
33
+ function validateShotPlan(plan, catalogs) {
34
+ const errors = [];
35
+
36
+ if (!isObject(plan)) return ["plan must be a JSON object"];
37
+ if (plan.schema_version !== "1.0.0") errors.push("schema_version must be 1.0.0");
38
+ if (!["assemble_existing_catalog_items", "generate_new_hyperframes_html"].includes(plan.generation_mode)) {
39
+ errors.push("generation_mode is invalid");
40
+ }
41
+ if (plan.catalog_strategy !== "dual_catalog") errors.push("catalog_strategy must be dual_catalog");
42
+
43
+ if (!isObject(plan.dimensions)
44
+ || !Number.isInteger(plan.dimensions.width)
45
+ || !Number.isInteger(plan.dimensions.height)
46
+ || plan.dimensions.width <= 0
47
+ || plan.dimensions.height <= 0) {
48
+ errors.push("dimensions.width and dimensions.height must be positive integers");
49
+ }
50
+ if (!Number.isFinite(plan.duration_seconds) || plan.duration_seconds <= 0) {
51
+ errors.push("duration_seconds must be a positive number");
52
+ }
53
+
54
+ if (!isObject(plan.audio)) {
55
+ errors.push("audio must be an object");
56
+ } else {
57
+ validateAudioTrack(plan.audio.narration, "narration", errors);
58
+ validateAudioTrack(plan.audio.bgm, "bgm", errors);
59
+ }
60
+
61
+ if (!isObject(plan.model_routing)) {
62
+ errors.push("model_routing must be an object");
63
+ } else {
64
+ if (plan.model_routing.page_animation_authoring !== "gpt-5.6-sol") {
65
+ errors.push("model_routing.page_animation_authoring must be gpt-5.6-sol");
66
+ }
67
+ if (!plan.model_routing.planning_and_validation) {
68
+ errors.push("model_routing.planning_and_validation is required");
69
+ } else if (plan.model_routing.planning_and_validation === "gpt-5.6-sol") {
70
+ errors.push("model_routing.planning_and_validation must not use gpt-5.6-sol");
71
+ }
72
+ }
73
+
74
+ if (!Array.isArray(plan.shots) || plan.shots.length === 0) {
75
+ errors.push("shots must contain at least one shot");
76
+ return errors;
77
+ }
78
+
79
+ const ids = new Set();
80
+ plan.shots.forEach((shot, index) => {
81
+ const label = `shots[${index}]`;
82
+ if (!isObject(shot)) {
83
+ errors.push(`${label} must be an object`);
84
+ return;
85
+ }
86
+ if (typeof shot.id !== "string" || !/^[a-z][a-z0-9-]*$/.test(shot.id)) {
87
+ errors.push(`${label}.id must be a kebab-case identifier`);
88
+ } else if (ids.has(shot.id)) {
89
+ errors.push(`${label}.id must be unique`);
90
+ } else {
91
+ ids.add(shot.id);
92
+ }
93
+ if (!Number.isFinite(shot.start_seconds) || shot.start_seconds < 0) {
94
+ errors.push(`${label}.start_seconds must be zero or greater`);
95
+ }
96
+ if (!Number.isFinite(shot.end_seconds) || shot.end_seconds <= shot.start_seconds) {
97
+ errors.push(`${label}.end_seconds must be greater than start_seconds`);
98
+ }
99
+ if (typeof shot.purpose !== "string" || !shot.purpose.trim()) {
100
+ errors.push(`${label}.purpose is required`);
101
+ }
102
+ if (!Array.isArray(shot.hyperframes_refs)) {
103
+ errors.push(`${label}.hyperframes_refs must be an array`);
104
+ } else {
105
+ for (const reference of shot.hyperframes_refs) {
106
+ if (!catalogs.hyperframes.has(reference)) {
107
+ errors.push(`${label} has unknown HyperFrames reference: ${reference}`);
108
+ }
109
+ }
110
+ }
111
+ if (!Array.isArray(shot.shotcraft_refs)) {
112
+ errors.push(`${label}.shotcraft_refs must be an array`);
113
+ } else {
114
+ for (const reference of shot.shotcraft_refs) {
115
+ if (!catalogs.shotcraft.has(reference)) {
116
+ errors.push(`${label} has unknown ShotCraft reference: ${reference}`);
117
+ }
118
+ }
119
+ }
120
+ if (Array.isArray(shot.hyperframes_refs)
121
+ && Array.isArray(shot.shotcraft_refs)
122
+ && shot.hyperframes_refs.length + shot.shotcraft_refs.length === 0) {
123
+ errors.push(`${label} must reference at least one catalog`);
124
+ }
125
+
126
+ if (index === 0 && shot.start_seconds !== 0) {
127
+ errors.push("shots must start at 0 seconds");
128
+ }
129
+ if (index > 0 && Number.isFinite(shot.start_seconds)) {
130
+ const previous = plan.shots[index - 1];
131
+ if (Number.isFinite(previous?.end_seconds) && Math.abs(shot.start_seconds - previous.end_seconds) > 0.001) {
132
+ errors.push(`shots must be contiguous: ${label}.start_seconds must equal shots[${index - 1}].end_seconds`);
133
+ }
134
+ }
135
+ });
136
+
137
+ const lastEnd = plan.shots.at(-1)?.end_seconds;
138
+ if (Number.isFinite(lastEnd)
139
+ && Number.isFinite(plan.duration_seconds)
140
+ && Math.abs(lastEnd - plan.duration_seconds) > 0.001) {
141
+ errors.push("last shot end_seconds must equal duration_seconds");
142
+ }
143
+
144
+ return errors;
145
+ }
146
+
147
+ function output(payload, code = 0) {
148
+ console.log(JSON.stringify(payload, null, 2));
149
+ process.exitCode = code;
150
+ }
151
+
152
+ async function main() {
153
+ try {
154
+ const path = process.argv[2];
155
+ if (!path || path === "--help" || path === "-h") {
156
+ console.log("Usage: validate_shot_plan.mjs <shot-plan.json>");
157
+ process.exitCode = path ? 0 : 1;
158
+ return;
159
+ }
160
+ const plan = JSON.parse(await readFile(path, "utf8"));
161
+ const hyperframesCatalog = JSON.parse(await readFile(
162
+ join(skillRoot, "references", "hyperframes-catalog-map.json"),
163
+ "utf8",
164
+ ));
165
+ const shotcraftCatalog = JSON.parse(await readFile(
166
+ join(skillRoot, "references", "shotcraft", "catalog.json"),
167
+ "utf8",
168
+ ));
169
+ const catalogs = {
170
+ hyperframes: new Set(hyperframesCatalog.items.map((item) => item.id)),
171
+ shotcraft: new Set(shotcraftCatalog.cards.flatMap((card) => [
172
+ card.name,
173
+ ...card.styles.map((style) => style.key),
174
+ ])),
175
+ };
176
+ const errors = validateShotPlan(plan, catalogs);
177
+ if (errors.length > 0) {
178
+ output({ ok: false, path, errors }, 1);
179
+ return;
180
+ }
181
+ output({
182
+ ok: true,
183
+ path,
184
+ shot_count: plan.shots.length,
185
+ duration_seconds: plan.duration_seconds,
186
+ catalog_strategy: plan.catalog_strategy,
187
+ });
188
+ } catch (error) {
189
+ output({ ok: false, errors: [error.message] }, 1);
190
+ }
191
+ }
192
+
193
+ main();
@@ -23,6 +23,7 @@ class MetaInfo:
23
23
  sample_rate: int
24
24
  bpm: float
25
25
  time_signature: str = "4/4"
26
+ beat_grid: dict = field(default_factory=dict)
26
27
 
27
28
 
28
29
  @dataclass
@@ -116,7 +117,8 @@ def analyze(
116
117
  duration_ms=duration_ms,
117
118
  sample_rate=sr,
118
119
  bpm=beat_result.bpm,
119
- time_signature=beat_result.time_signature
120
+ time_signature=beat_result.time_signature,
121
+ beat_grid=beat_result.beat_grid
120
122
  )
121
123
 
122
124
  result = AnalysisResult(
@@ -30,6 +30,41 @@ class BeatResult:
30
30
  bpm: float
31
31
  beats: List[Beat]
32
32
  time_signature: str = "4/4"
33
+ beat_grid: dict = None
34
+
35
+
36
+ def _fit_beat_grid(beat_times: np.ndarray, fallback_bpm: float) -> tuple[float, dict]:
37
+ """Fit t_i = phase + i * period and report grid reliability."""
38
+ if len(beat_times) < 2:
39
+ period = 60.0 / fallback_bpm if fallback_bpm > 0 else 0.0
40
+ phase = float(beat_times[0]) if len(beat_times) == 1 else 0.0
41
+ return fallback_bpm, {
42
+ "method": "insufficient_beats",
43
+ "phase_ms": round(phase * 1000, 3),
44
+ "period_ms": round(period * 1000, 3),
45
+ "max_residual_ms": None,
46
+ "rms_residual_ms": None,
47
+ "reliable": False,
48
+ "threshold_ms": 15.0,
49
+ }
50
+
51
+ indexes = np.arange(len(beat_times), dtype=float)
52
+ design = np.vstack([indexes, np.ones_like(indexes)]).T
53
+ (period, phase), *_ = np.linalg.lstsq(design, beat_times, rcond=None)
54
+ residuals = beat_times - (phase + indexes * period)
55
+ max_residual_ms = float(np.max(np.abs(residuals)) * 1000)
56
+ rms_residual_ms = float(np.sqrt(np.mean(residuals ** 2)) * 1000)
57
+ fitted_bpm = 60.0 / period if period > 0 else fallback_bpm
58
+
59
+ return fitted_bpm, {
60
+ "method": "least_squares",
61
+ "phase_ms": round(float(phase) * 1000, 3),
62
+ "period_ms": round(float(period) * 1000, 3),
63
+ "max_residual_ms": round(max_residual_ms, 3),
64
+ "rms_residual_ms": round(rms_residual_ms, 3),
65
+ "reliable": max_residual_ms <= 15.0,
66
+ "threshold_ms": 15.0,
67
+ }
33
68
 
34
69
 
35
70
  def detect_beats(
@@ -52,6 +87,7 @@ def detect_beats(
52
87
 
53
88
  # 转换为时间(毫秒)
54
89
  beat_times = librosa.frames_to_time(beat_frames, sr=sr)
90
+ bpm, beat_grid = _fit_beat_grid(beat_times, bpm)
55
91
  beat_times_ms = [int(t * 1000) for t in beat_times]
56
92
 
57
93
  # 计算每个beat的能量
@@ -82,7 +118,7 @@ def detect_beats(
82
118
  if on_progress:
83
119
  on_progress(100.0)
84
120
 
85
- return BeatResult(bpm=bpm, beats=beats)
121
+ return BeatResult(bpm=bpm, beats=beats, beat_grid=beat_grid)
86
122
 
87
123
 
88
124
  def _compute_beat_energies(