hyper-animator-codex 0.7.1 → 0.8.1

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 -4
  2. package/bin/hyper-animator-codex.mjs +1 -1
  3. package/lib/minimax-config.mjs +3 -3
  4. package/package.json +4 -1
  5. package/skills/hyper-animator-codex/SKILL.md +66 -22
  6. package/skills/hyper-animator-codex/agents/openai.yaml +2 -2
  7. package/skills/hyper-animator-codex/contracts/shot-plan.schema.json +280 -0
  8. package/skills/hyper-animator-codex/contracts/workflow-policy.json +97 -0
  9. package/skills/hyper-animator-codex/references/HyperFrames-AI-Generation-Patterns-codex.md +788 -0
  10. package/skills/hyper-animator-codex/references/beat-sync-workflow.md +7 -0
  11. package/skills/hyper-animator-codex/references/examples/shot-plan-dual-catalog.json +99 -0
  12. package/skills/hyper-animator-codex/references/hyperframes-agent-pseudocode.ts +1 -1
  13. package/skills/hyper-animator-codex/references/hyperframes-catalog-map.json +97 -230
  14. package/skills/hyper-animator-codex/references/hyperframes-intent-workflow.md +32 -8
  15. package/skills/hyper-animator-codex/references/minimax-music-workflow.md +24 -4
  16. package/skills/hyper-animator-codex/references/narration-audio-workflow.md +47 -10
  17. package/skills/hyper-animator-codex/references/shotcraft/LICENSE +202 -0
  18. package/skills/hyper-animator-codex/references/shotcraft/cards/ai-stream-response/README.md +46 -0
  19. package/skills/hyper-animator-codex/references/shotcraft/cards/autolayout-gap-dial/README.md +53 -0
  20. package/skills/hyper-animator-codex/references/shotcraft/cards/beat-cut-moves/README.md +54 -0
  21. package/skills/hyper-animator-codex/references/shotcraft/cards/beat-step-list-theme-cycle/README.md +59 -0
  22. package/skills/hyper-animator-codex/references/shotcraft/cards/before-after-slider-scrub/README.md +47 -0
  23. package/skills/hyper-animator-codex/references/shotcraft/cards/bottom-push-stack-wipe/README.md +58 -0
  24. package/skills/hyper-animator-codex/references/shotcraft/cards/brand-frame-snap/README.md +51 -0
  25. package/skills/hyper-animator-codex/references/shotcraft/cards/brand-ink-open/README.md +35 -0
  26. package/skills/hyper-animator-codex/references/shotcraft/cards/bubble-swarm-takeover/README.md +62 -0
  27. package/skills/hyper-animator-codex/references/shotcraft/cards/canvas-materialize-moves/README.md +55 -0
  28. package/skills/hyper-animator-codex/references/shotcraft/cards/card-flip-reveal/README.md +50 -0
  29. package/skills/hyper-animator-codex/references/shotcraft/cards/card-flock-tumble/README.md +54 -0
  30. package/skills/hyper-animator-codex/references/shotcraft/cards/cel-flash-stomp/README.md +54 -0
  31. package/skills/hyper-animator-codex/references/shotcraft/cards/chart-live-moves/README.md +51 -0
  32. package/skills/hyper-animator-codex/references/shotcraft/cards/circle-match-iris/README.md +53 -0
  33. package/skills/hyper-animator-codex/references/shotcraft/cards/cloner-depth-echo/README.md +38 -0
  34. package/skills/hyper-animator-codex/references/shotcraft/cards/collab-cursor-moves/README.md +48 -0
  35. package/skills/hyper-animator-codex/references/shotcraft/cards/color-block-step-wipe/README.md +54 -0
  36. package/skills/hyper-animator-codex/references/shotcraft/cards/command-palette-summon/README.md +45 -0
  37. package/skills/hyper-animator-codex/references/shotcraft/cards/crane-rise-reveal/README.md +47 -0
  38. package/skills/hyper-animator-codex/references/shotcraft/cards/crash-zoom-punch/README.md +38 -0
  39. package/skills/hyper-animator-codex/references/shotcraft/cards/dataviz-landscape-open/README.md +54 -0
  40. package/skills/hyper-animator-codex/references/shotcraft/cards/deck-deal-flyin/README.md +45 -0
  41. package/skills/hyper-animator-codex/references/shotcraft/cards/depth-layer-moves/README.md +40 -0
  42. package/skills/hyper-animator-codex/references/shotcraft/cards/document-typewriter-reveal/README.md +40 -0
  43. package/skills/hyper-animator-codex/references/shotcraft/cards/draw-svg-trace/README.md +50 -0
  44. package/skills/hyper-animator-codex/references/shotcraft/cards/edit-hook-moves/README.md +38 -0
  45. package/skills/hyper-animator-codex/references/shotcraft/cards/element-body-moves/README.md +49 -0
  46. package/skills/hyper-animator-codex/references/shotcraft/cards/fui-hud-moves/README.md +44 -0
  47. package/skills/hyper-animator-codex/references/shotcraft/cards/gauge-readout-moves/README.md +45 -0
  48. package/skills/hyper-animator-codex/references/shotcraft/cards/glow-flyline-moves/README.md +51 -0
  49. package/skills/hyper-animator-codex/references/shotcraft/cards/gradient-word-sweep/README.md +49 -0
  50. package/skills/hyper-animator-codex/references/shotcraft/cards/graze-face-tour/README.md +56 -0
  51. package/skills/hyper-animator-codex/references/shotcraft/cards/hashtag-to-pill-materialize/README.md +57 -0
  52. package/skills/hyper-animator-codex/references/shotcraft/cards/hires-rasterize-3d-text/README.md +34 -0
  53. package/skills/hyper-animator-codex/references/shotcraft/cards/icon-field-colorize/README.md +53 -0
  54. package/skills/hyper-animator-codex/references/shotcraft/cards/icon-performance-moves/README.md +46 -0
  55. package/skills/hyper-animator-codex/references/shotcraft/cards/impact-feedback/README.md +50 -0
  56. package/skills/hyper-animator-codex/references/shotcraft/cards/input-trigger-moves/README.md +49 -0
  57. package/skills/hyper-animator-codex/references/shotcraft/cards/integration-hub-map/README.md +54 -0
  58. package/skills/hyper-animator-codex/references/shotcraft/cards/letterspace-materialize/README.md +52 -0
  59. package/skills/hyper-animator-codex/references/shotcraft/cards/light-play-moves/README.md +49 -0
  60. package/skills/hyper-animator-codex/references/shotcraft/cards/line-boil/README.md +52 -0
  61. package/skills/hyper-animator-codex/references/shotcraft/cards/line-carry-transition/README.md +52 -0
  62. package/skills/hyper-animator-codex/references/shotcraft/cards/list-stack-press/README.md +43 -0
  63. package/skills/hyper-animator-codex/references/shotcraft/cards/magician-card-flourish/README.md +63 -0
  64. package/skills/hyper-animator-codex/references/shotcraft/cards/marker-underline-title/README.md +48 -0
  65. package/skills/hyper-animator-codex/references/shotcraft/cards/montage-rhythm-moves/README.md +55 -0
  66. package/skills/hyper-animator-codex/references/shotcraft/cards/morph-from-primitive/README.md +51 -0
  67. package/skills/hyper-animator-codex/references/shotcraft/cards/neon-frame-forerun/README.md +50 -0
  68. package/skills/hyper-animator-codex/references/shotcraft/cards/neon-frame-orbit-drop/README.md +50 -0
  69. package/skills/hyper-animator-codex/references/shotcraft/cards/neon-triple-marquee/README.md +55 -0
  70. package/skills/hyper-animator-codex/references/shotcraft/cards/odometer-digit-roll/README.md +54 -0
  71. package/skills/hyper-animator-codex/references/shotcraft/cards/outro-group-photo-launch/README.md +39 -0
  72. package/skills/hyper-animator-codex/references/shotcraft/cards/overhead-camera-moves/README.md +50 -0
  73. package/skills/hyper-animator-codex/references/shotcraft/cards/page-turn-transitions/README.md +48 -0
  74. package/skills/hyper-animator-codex/references/shotcraft/cards/page-waterfall-wall/README.md +52 -0
  75. package/skills/hyper-animator-codex/references/shotcraft/cards/panel-grid-moves/README.md +52 -0
  76. package/skills/hyper-animator-codex/references/shotcraft/cards/paper-craft-moves/README.md +46 -0
  77. package/skills/hyper-animator-codex/references/shotcraft/cards/paper-plane-messenger/README.md +62 -0
  78. package/skills/hyper-animator-codex/references/shotcraft/cards/paper-title-card/README.md +36 -0
  79. package/skills/hyper-animator-codex/references/shotcraft/cards/particle-celebrate-hits/README.md +42 -0
  80. package/skills/hyper-animator-codex/references/shotcraft/cards/particle-sand-fill/README.md +39 -0
  81. package/skills/hyper-animator-codex/references/shotcraft/cards/pill-slot-cycle/README.md +57 -0
  82. package/skills/hyper-animator-codex/references/shotcraft/cards/print-texture-transitions/README.md +40 -0
  83. package/skills/hyper-animator-codex/references/shotcraft/cards/rhythm-interrupt-moves/README.md +44 -0
  84. package/skills/hyper-animator-codex/references/shotcraft/cards/riso-print-hits/README.md +54 -0
  85. package/skills/hyper-animator-codex/references/shotcraft/cards/row-embed/README.md +36 -0
  86. package/skills/hyper-animator-codex/references/shotcraft/cards/runway-ground-skim/README.md +52 -0
  87. package/skills/hyper-animator-codex/references/shotcraft/cards/sakuga-timing-shift/README.md +50 -0
  88. package/skills/hyper-animator-codex/references/shotcraft/cards/scene-locked-title/README.md +43 -0
  89. package/skills/hyper-animator-codex/references/shotcraft/cards/scroll-brake-moves/README.md +45 -0
  90. package/skills/hyper-animator-codex/references/shotcraft/cards/segmented-thumb-hero/README.md +57 -0
  91. package/skills/hyper-animator-codex/references/shotcraft/cards/shot-transitions/README.md +60 -0
  92. package/skills/hyper-animator-codex/references/shotcraft/cards/skeleton-reveal/README.md +54 -0
  93. package/skills/hyper-animator-codex/references/shotcraft/cards/slam-entrance-moves/README.md +53 -0
  94. package/skills/hyper-animator-codex/references/shotcraft/cards/smear-multiples/README.md +49 -0
  95. package/skills/hyper-animator-codex/references/shotcraft/cards/space-camera-moves/README.md +53 -0
  96. package/skills/hyper-animator-codex/references/shotcraft/cards/spectrum-morph-ui/README.md +50 -0
  97. package/skills/hyper-animator-codex/references/shotcraft/cards/speed-ramp-freeze/README.md +42 -0
  98. package/skills/hyper-animator-codex/references/shotcraft/cards/split-flap-title/README.md +52 -0
  99. package/skills/hyper-animator-codex/references/shotcraft/cards/spotlight-hero-card/README.md +39 -0
  100. package/skills/hyper-animator-codex/references/shotcraft/cards/spotlight-sweep-moves/README.md +51 -0
  101. package/skills/hyper-animator-codex/references/shotcraft/cards/steep-tilt-glide/README.md +53 -0
  102. package/skills/hyper-animator-codex/references/shotcraft/cards/stroke-segment-build/README.md +43 -0
  103. package/skills/hyper-animator-codex/references/shotcraft/cards/tear-streak-transitions/README.md +43 -0
  104. package/skills/hyper-animator-codex/references/shotcraft/cards/tension-camera-moves/README.md +55 -0
  105. package/skills/hyper-animator-codex/references/shotcraft/cards/text-as-mask/README.md +50 -0
  106. package/skills/hyper-animator-codex/references/shotcraft/cards/text-column-converge/README.md +55 -0
  107. package/skills/hyper-animator-codex/references/shotcraft/cards/theme-switch-moves/README.md +44 -0
  108. package/skills/hyper-animator-codex/references/shotcraft/cards/timeline-travel/README.md +43 -0
  109. package/skills/hyper-animator-codex/references/shotcraft/cards/title-demote-to-label/README.md +58 -0
  110. package/skills/hyper-animator-codex/references/shotcraft/cards/trailer-grammar-moves/README.md +51 -0
  111. package/skills/hyper-animator-codex/references/shotcraft/cards/transition-hidden-cut/README.md +52 -0
  112. package/skills/hyper-animator-codex/references/shotcraft/cards/transition-travel/README.md +48 -0
  113. package/skills/hyper-animator-codex/references/shotcraft/cards/type-and-filter/README.md +37 -0
  114. package/skills/hyper-animator-codex/references/shotcraft/cards/type-assembly-moves/README.md +50 -0
  115. package/skills/hyper-animator-codex/references/shotcraft/cards/type-entrance-moves/README.md +46 -0
  116. package/skills/hyper-animator-codex/references/shotcraft/cards/type-rhythm-sync/README.md +47 -0
  117. package/skills/hyper-animator-codex/references/shotcraft/cards/typewriter-moves/README.md +50 -0
  118. package/skills/hyper-animator-codex/references/shotcraft/cards/ui-strip-away-outro/README.md +63 -0
  119. package/skills/hyper-animator-codex/references/shotcraft/cards/ui-to-brand-morph/README.md +52 -0
  120. package/skills/hyper-animator-codex/references/shotcraft/cards/voice-waveform-live/README.md +52 -0
  121. package/skills/hyper-animator-codex/references/shotcraft/cards/wall-reveal-moves/README.md +53 -0
  122. package/skills/hyper-animator-codex/references/shotcraft/cards/wipe-transitions/README.md +47 -0
  123. package/skills/hyper-animator-codex/references/shotcraft/cards/word-relay-filmstrip/README.md +50 -0
  124. package/skills/hyper-animator-codex/references/shotcraft/catalog.json +3946 -0
  125. package/skills/hyper-animator-codex/references/shotcraft/motion-pack/README.md +32 -0
  126. package/skills/hyper-animator-codex/references/shotcraft/motion-pack/shotcraft-motion-pack.js +178 -0
  127. package/skills/hyper-animator-codex/references/shotcraft/references/aesthetic-rules.md +157 -0
  128. package/skills/hyper-animator-codex/references/shotcraft/references/final-review.md +107 -0
  129. package/skills/hyper-animator-codex/references/shotcraft/references/guided-free-creation.md +197 -0
  130. package/skills/hyper-animator-codex/references/shotcraft/references/music-beat-sync.md +125 -0
  131. package/skills/hyper-animator-codex/references/shotcraft/references/pipeline.md +357 -0
  132. package/skills/hyper-animator-codex/references/shotcraft/references/sound-design.md +126 -0
  133. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/Caption.tsx +50 -0
  134. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/DigitRoll.tsx +45 -0
  135. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/FlashCut.tsx +20 -0
  136. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/FlatPanel.tsx +65 -0
  137. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/PageCam.tsx +151 -0
  138. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/VerticalTicker.tsx +129 -0
  139. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/helpers/camera.tsx +75 -0
  140. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/helpers/motion.ts +40 -0
  141. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/helpers/rand.ts +11 -0
  142. package/skills/hyper-animator-codex/references/shotcraft/source/assets/lib/helpers/shake.ts +10 -0
  143. package/skills/hyper-animator-codex/references/shotcraft/source/demos/_fixtures/Fixtures.tsx +83 -0
  144. package/skills/hyper-animator-codex/references/shotcraft/source/demos/ai-stream-response/StreamResponse.tsx +146 -0
  145. package/skills/hyper-animator-codex/references/shotcraft/source/demos/autolayout-gap-dial/AutolayoutGapDial.tsx +174 -0
  146. package/skills/hyper-animator-codex/references/shotcraft/source/demos/beat-cut-moves/BeatCutAccelerando.tsx +77 -0
  147. package/skills/hyper-animator-codex/references/shotcraft/source/demos/beat-cut-moves/PaparazziFlash.tsx +115 -0
  148. package/skills/hyper-animator-codex/references/shotcraft/source/demos/beat-step-list-theme-cycle/BeatStepListThemeCycle.tsx +98 -0
  149. package/skills/hyper-animator-codex/references/shotcraft/source/demos/before-after-slider-scrub/BeforeAfterSliderScrub.tsx +99 -0
  150. package/skills/hyper-animator-codex/references/shotcraft/source/demos/bottom-push-stack-wipe/BottomPushStackWipe.tsx +79 -0
  151. package/skills/hyper-animator-codex/references/shotcraft/source/demos/brand-frame-snap/BrandFrameSnap.tsx +110 -0
  152. package/skills/hyper-animator-codex/references/shotcraft/source/demos/bubble-swarm-takeover/BubbleSwarmTakeover.tsx +189 -0
  153. package/skills/hyper-animator-codex/references/shotcraft/source/demos/canvas-materialize-moves/DiagramCascadeBuild.tsx +172 -0
  154. package/skills/hyper-animator-codex/references/shotcraft/source/demos/canvas-materialize-moves/PanelToCanvasMaterialize.tsx +254 -0
  155. package/skills/hyper-animator-codex/references/shotcraft/source/demos/card-flip-reveal/CardFlipReveal.tsx +139 -0
  156. package/skills/hyper-animator-codex/references/shotcraft/source/demos/card-flock-tumble/CardFlockTumble.tsx +382 -0
  157. package/skills/hyper-animator-codex/references/shotcraft/source/demos/cel-flash-stomp/CelFlashStomp.tsx +111 -0
  158. package/skills/hyper-animator-codex/references/shotcraft/source/demos/chart-live-moves/AxisRescaleShockV2.tsx +282 -0
  159. package/skills/hyper-animator-codex/references/shotcraft/source/demos/chart-live-moves/OscilloscopeStreamV2.tsx +227 -0
  160. package/skills/hyper-animator-codex/references/shotcraft/source/demos/chart-live-moves/UnitDotSwarmRegroupV2.tsx +248 -0
  161. package/skills/hyper-animator-codex/references/shotcraft/source/demos/circle-match-iris/CircleMatchIris.tsx +124 -0
  162. package/skills/hyper-animator-codex/references/shotcraft/source/demos/cloner-depth-echo/ClonerDepthEcho.tsx +90 -0
  163. package/skills/hyper-animator-codex/references/shotcraft/source/demos/collab-cursor-moves/CursorCastEnsemble.tsx +136 -0
  164. package/skills/hyper-animator-codex/references/shotcraft/source/demos/collab-cursor-moves/CursorDialogueDuet.tsx +145 -0
  165. package/skills/hyper-animator-codex/references/shotcraft/source/demos/color-block-step-wipe/ColorBlockStepWipe.tsx +157 -0
  166. package/skills/hyper-animator-codex/references/shotcraft/source/demos/command-palette-summon/CommandPaletteSummon.tsx +173 -0
  167. package/skills/hyper-animator-codex/references/shotcraft/source/demos/crane-rise-reveal/CraneRiseReveal.tsx +91 -0
  168. package/skills/hyper-animator-codex/references/shotcraft/source/demos/crash-zoom-punch/CrashImpactReal.tsx +63 -0
  169. package/skills/hyper-animator-codex/references/shotcraft/source/demos/crash-zoom-punch/CrashZoomReal.tsx +60 -0
  170. package/skills/hyper-animator-codex/references/shotcraft/source/demos/dataviz-landscape-open/DatavizLandscapeOpen.tsx +401 -0
  171. package/skills/hyper-animator-codex/references/shotcraft/source/demos/depth-layer-moves/DollyZoomReal.tsx +55 -0
  172. package/skills/hyper-animator-codex/references/shotcraft/source/demos/depth-layer-moves/MultiplaneReal.tsx +45 -0
  173. package/skills/hyper-animator-codex/references/shotcraft/source/demos/draw-svg-trace/DrawSvgTrace.tsx +199 -0
  174. package/skills/hyper-animator-codex/references/shotcraft/source/demos/edit-hook-moves/LogoStingButton.tsx +106 -0
  175. package/skills/hyper-animator-codex/references/shotcraft/source/demos/element-body-moves/AxialStretch.tsx +112 -0
  176. package/skills/hyper-animator-codex/references/shotcraft/source/demos/element-body-moves/ContactShadowLift.tsx +117 -0
  177. package/skills/hyper-animator-codex/references/shotcraft/source/demos/fui-hud-moves/LineUnfoldPanel.tsx +125 -0
  178. package/skills/hyper-animator-codex/references/shotcraft/source/demos/fui-hud-moves/ReticleLockOn.tsx +139 -0
  179. package/skills/hyper-animator-codex/references/shotcraft/source/demos/gauge-readout-moves/NeedleSweepSelftest.tsx +146 -0
  180. package/skills/hyper-animator-codex/references/shotcraft/source/demos/gauge-readout-moves/TapeScrollFixedPointer.tsx +120 -0
  181. package/skills/hyper-animator-codex/references/shotcraft/source/demos/glow-flyline-moves/FlylineArc.tsx +158 -0
  182. package/skills/hyper-animator-codex/references/shotcraft/source/demos/glow-flyline-moves/GlowOrbAmbient.tsx +131 -0
  183. package/skills/hyper-animator-codex/references/shotcraft/source/demos/glow-flyline-moves/OrbFlylineRelay.tsx +268 -0
  184. package/skills/hyper-animator-codex/references/shotcraft/source/demos/gradient-word-sweep/GradientWordSweep.tsx +307 -0
  185. package/skills/hyper-animator-codex/references/shotcraft/source/demos/graze-face-tour/GrazeFaceTour.tsx +469 -0
  186. package/skills/hyper-animator-codex/references/shotcraft/source/demos/hashtag-to-pill-materialize/HashtagToPillMaterialize.tsx +166 -0
  187. package/skills/hyper-animator-codex/references/shotcraft/source/demos/icon-field-colorize/IconFieldColorize.tsx +93 -0
  188. package/skills/hyper-animator-codex/references/shotcraft/source/demos/icon-performance-moves/AttentionBounce.tsx +193 -0
  189. package/skills/hyper-animator-codex/references/shotcraft/source/demos/icon-performance-moves/PopBurstConfirm.tsx +162 -0
  190. package/skills/hyper-animator-codex/references/shotcraft/source/demos/impact-feedback/AnimeImpact.tsx +149 -0
  191. package/skills/hyper-animator-codex/references/shotcraft/source/demos/impact-feedback/HitCounter.tsx +147 -0
  192. package/skills/hyper-animator-codex/references/shotcraft/source/demos/input-trigger-moves/CursorPerformancePunchIn.tsx +154 -0
  193. package/skills/hyper-animator-codex/references/shotcraft/source/demos/input-trigger-moves/KeycapSmashCut.tsx +217 -0
  194. package/skills/hyper-animator-codex/references/shotcraft/source/demos/integration-hub-map/IntegrationHubMap.tsx +554 -0
  195. package/skills/hyper-animator-codex/references/shotcraft/source/demos/letterspace-materialize/LetterspaceMaterialize.tsx +85 -0
  196. package/skills/hyper-animator-codex/references/shotcraft/source/demos/light-play-moves/HalationBloom.tsx +139 -0
  197. package/skills/hyper-animator-codex/references/shotcraft/source/demos/light-play-moves/SheenSweepRetry.tsx +85 -0
  198. package/skills/hyper-animator-codex/references/shotcraft/source/demos/light-play-moves/SpotlightSweepReveal.tsx +102 -0
  199. package/skills/hyper-animator-codex/references/shotcraft/source/demos/line-boil/LineBoil.tsx +140 -0
  200. package/skills/hyper-animator-codex/references/shotcraft/source/demos/line-carry-transition/LineCarryTransition.tsx +151 -0
  201. package/skills/hyper-animator-codex/references/shotcraft/source/demos/magician-card-flourish/MagicianCardFlourish.tsx +294 -0
  202. package/skills/hyper-animator-codex/references/shotcraft/source/demos/marker-underline-title/MarkerUnderlineTitle.tsx +87 -0
  203. package/skills/hyper-animator-codex/references/shotcraft/source/demos/montage-rhythm-moves/DominoCascade.tsx +125 -0
  204. package/skills/hyper-animator-codex/references/shotcraft/source/demos/montage-rhythm-moves/DropBlackoutSlam.tsx +135 -0
  205. package/skills/hyper-animator-codex/references/shotcraft/source/demos/montage-rhythm-moves/WrightTripleCut.tsx +175 -0
  206. package/skills/hyper-animator-codex/references/shotcraft/source/demos/morph-from-primitive/MorphFromPrimitive.tsx +190 -0
  207. package/skills/hyper-animator-codex/references/shotcraft/source/demos/neon-frame-forerun/NeonFrameForerun.tsx +279 -0
  208. package/skills/hyper-animator-codex/references/shotcraft/source/demos/neon-frame-orbit-drop/NeonFrameForerunOrbit.tsx +273 -0
  209. package/skills/hyper-animator-codex/references/shotcraft/source/demos/neon-triple-marquee/NeonTripleMarquee.tsx +111 -0
  210. package/skills/hyper-animator-codex/references/shotcraft/source/demos/odometer-digit-roll/OdometerDigitRoll.tsx +178 -0
  211. package/skills/hyper-animator-codex/references/shotcraft/source/demos/overhead-camera-moves/OverheadTabletopDrop.tsx +129 -0
  212. package/skills/hyper-animator-codex/references/shotcraft/source/demos/overhead-camera-moves/TiltReveal.tsx +55 -0
  213. package/skills/hyper-animator-codex/references/shotcraft/source/demos/page-turn-transitions/BarnDoorSplit.tsx +138 -0
  214. package/skills/hyper-animator-codex/references/shotcraft/source/demos/page-turn-transitions/CubeRotate.tsx +114 -0
  215. package/skills/hyper-animator-codex/references/shotcraft/source/demos/page-waterfall-wall/PageWaterfallWall.tsx +76 -0
  216. package/skills/hyper-animator-codex/references/shotcraft/source/demos/page-waterfall-wall/VerticalTicker.tsx +129 -0
  217. package/skills/hyper-animator-codex/references/shotcraft/source/demos/panel-grid-moves/ComicPanelSplit.tsx +171 -0
  218. package/skills/hyper-animator-codex/references/shotcraft/source/demos/panel-grid-moves/FlipGridReflow.tsx +121 -0
  219. package/skills/hyper-animator-codex/references/shotcraft/source/demos/panel-grid-moves/GridFlashMosaic.tsx +182 -0
  220. package/skills/hyper-animator-codex/references/shotcraft/source/demos/paper-craft-moves/MaskingTapeSlap.tsx +163 -0
  221. package/skills/hyper-animator-codex/references/shotcraft/source/demos/paper-craft-moves/PopupBookRise.tsx +134 -0
  222. package/skills/hyper-animator-codex/references/shotcraft/source/demos/paper-plane-messenger/PaperPlaneMessenger.tsx +183 -0
  223. package/skills/hyper-animator-codex/references/shotcraft/source/demos/particle-celebrate-hits/ConfettiCrossfire.tsx +115 -0
  224. package/skills/hyper-animator-codex/references/shotcraft/source/demos/particle-celebrate-hits/CounterTickSparks.tsx +103 -0
  225. package/skills/hyper-animator-codex/references/shotcraft/source/demos/particle-sand-fill/ParticleSandFill.tsx +119 -0
  226. package/skills/hyper-animator-codex/references/shotcraft/source/demos/pill-slot-cycle/PillSlotCycle.tsx +220 -0
  227. package/skills/hyper-animator-codex/references/shotcraft/source/demos/print-texture-transitions/InkBleedReveal.tsx +81 -0
  228. package/skills/hyper-animator-codex/references/shotcraft/source/demos/rhythm-interrupt-moves/JumpCutPunchIn.tsx +72 -0
  229. package/skills/hyper-animator-codex/references/shotcraft/source/demos/rhythm-interrupt-moves/StrobeBlackFrames.tsx +99 -0
  230. package/skills/hyper-animator-codex/references/shotcraft/source/demos/riso-print-hits/RisoBeatPump.tsx +155 -0
  231. package/skills/hyper-animator-codex/references/shotcraft/source/demos/riso-print-hits/RisoMisregistrationHit.tsx +120 -0
  232. package/skills/hyper-animator-codex/references/shotcraft/source/demos/runway-ground-skim/RunwayGroundSkim.tsx +258 -0
  233. package/skills/hyper-animator-codex/references/shotcraft/source/demos/sakuga-timing-shift/SakugaTimingShift.tsx +178 -0
  234. package/skills/hyper-animator-codex/references/shotcraft/source/demos/scene-locked-title/SceneLockedTitle.tsx +98 -0
  235. package/skills/hyper-animator-codex/references/shotcraft/source/demos/scroll-brake-moves/BrakeReticleLock.tsx +171 -0
  236. package/skills/hyper-animator-codex/references/shotcraft/source/demos/scroll-brake-moves/ChangelogScrollBrake.tsx +117 -0
  237. package/skills/hyper-animator-codex/references/shotcraft/source/demos/segmented-thumb-hero/SegmentedThumbHero.tsx +213 -0
  238. package/skills/hyper-animator-codex/references/shotcraft/source/demos/shot-transitions/MaskWipeReal.tsx +67 -0
  239. package/skills/hyper-animator-codex/references/shotcraft/source/demos/shot-transitions/PortalWipeV2.tsx +128 -0
  240. package/skills/hyper-animator-codex/references/shotcraft/source/demos/shot-transitions/WhipBrakeReal.tsx +60 -0
  241. package/skills/hyper-animator-codex/references/shotcraft/source/demos/shot-transitions/WhipPanReal.tsx +45 -0
  242. package/skills/hyper-animator-codex/references/shotcraft/source/demos/skeleton-reveal/SkeletonReveal.tsx +283 -0
  243. package/skills/hyper-animator-codex/references/shotcraft/source/demos/slam-entrance-moves/ImpactBurstKit.tsx +185 -0
  244. package/skills/hyper-animator-codex/references/shotcraft/source/demos/slam-entrance-moves/KanadaPerspectiveSnap.tsx +91 -0
  245. package/skills/hyper-animator-codex/references/shotcraft/source/demos/slam-entrance-moves/ScoreSlam.tsx +225 -0
  246. package/skills/hyper-animator-codex/references/shotcraft/source/demos/smear-multiples/SmearMultiples.tsx +88 -0
  247. package/skills/hyper-animator-codex/references/shotcraft/source/demos/space-camera-moves/DroneDiveLanding.tsx +91 -0
  248. package/skills/hyper-animator-codex/references/shotcraft/source/demos/space-camera-moves/ExplodedView.tsx +178 -0
  249. package/skills/hyper-animator-codex/references/shotcraft/source/demos/space-camera-moves/SnorricamLock.tsx +130 -0
  250. package/skills/hyper-animator-codex/references/shotcraft/source/demos/spectrum-morph-ui/SpectrumMorphUi.tsx +129 -0
  251. package/skills/hyper-animator-codex/references/shotcraft/source/demos/speed-ramp-freeze/FreezeAnnotateReal.tsx +70 -0
  252. package/skills/hyper-animator-codex/references/shotcraft/source/demos/speed-ramp-freeze/SpeedRampReal.tsx +58 -0
  253. package/skills/hyper-animator-codex/references/shotcraft/source/demos/split-flap-title/SplitFlapFlip.tsx +189 -0
  254. package/skills/hyper-animator-codex/references/shotcraft/source/demos/spotlight-sweep-moves/CornerSpotlightReveal.tsx +121 -0
  255. package/skills/hyper-animator-codex/references/shotcraft/source/demos/spotlight-sweep-moves/GlowWakeSleepPanel.tsx +183 -0
  256. package/skills/hyper-animator-codex/references/shotcraft/source/demos/spotlight-sweep-moves/SlideSpotlightPan.tsx +171 -0
  257. package/skills/hyper-animator-codex/references/shotcraft/source/demos/steep-tilt-glide/SteepTiltGlide.tsx +315 -0
  258. package/skills/hyper-animator-codex/references/shotcraft/source/demos/stroke-segment-build/StrokeSegmentBuild.tsx +126 -0
  259. package/skills/hyper-animator-codex/references/shotcraft/source/demos/tear-streak-transitions/GlitchDisplace.tsx +107 -0
  260. package/skills/hyper-animator-codex/references/shotcraft/source/demos/tension-camera-moves/BulletTimeFreezeOrbit.tsx +219 -0
  261. package/skills/hyper-animator-codex/references/shotcraft/source/demos/tension-camera-moves/DutchRollToLevel.tsx +110 -0
  262. package/skills/hyper-animator-codex/references/shotcraft/source/demos/tension-camera-moves/PullBackIsolation.tsx +120 -0
  263. package/skills/hyper-animator-codex/references/shotcraft/source/demos/tension-camera-moves/SlowPushIn.tsx +96 -0
  264. package/skills/hyper-animator-codex/references/shotcraft/source/demos/text-as-mask/TextAsMask.tsx +94 -0
  265. package/skills/hyper-animator-codex/references/shotcraft/source/demos/text-column-converge/TextColumnConverge.tsx +122 -0
  266. package/skills/hyper-animator-codex/references/shotcraft/source/demos/theme-switch-moves/PaletteThemeRipple.tsx +207 -0
  267. package/skills/hyper-animator-codex/references/shotcraft/source/demos/theme-switch-moves/ThemeSweepToggle.tsx +123 -0
  268. package/skills/hyper-animator-codex/references/shotcraft/source/demos/timeline-travel/TimelineTravel.tsx +123 -0
  269. package/skills/hyper-animator-codex/references/shotcraft/source/demos/title-demote-to-label/TitleDemoteToLabel.tsx +174 -0
  270. package/skills/hyper-animator-codex/references/shotcraft/source/demos/trailer-grammar-moves/CardFootageCadence.tsx +118 -0
  271. package/skills/hyper-animator-codex/references/shotcraft/source/demos/trailer-grammar-moves/SmashCut.tsx +105 -0
  272. package/skills/hyper-animator-codex/references/shotcraft/source/demos/trailer-grammar-moves/TrailerBumper.tsx +103 -0
  273. package/skills/hyper-animator-codex/references/shotcraft/source/demos/transition-hidden-cut/InvisibleCut.tsx +93 -0
  274. package/skills/hyper-animator-codex/references/shotcraft/source/demos/transition-hidden-cut/LightLeakBurn.tsx +122 -0
  275. package/skills/hyper-animator-codex/references/shotcraft/source/demos/transition-hidden-cut/VersusSlam.tsx +104 -0
  276. package/skills/hyper-animator-codex/references/shotcraft/source/demos/transition-travel/LetterformZoom.tsx +141 -0
  277. package/skills/hyper-animator-codex/references/shotcraft/source/demos/transition-travel/SharedElementMorph.tsx +101 -0
  278. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-assembly-moves/LetterformDriftAssembly.tsx +107 -0
  279. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-assembly-moves/SplitTextStagger.tsx +101 -0
  280. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-assembly-moves/TextOnPath.tsx +92 -0
  281. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-assembly-moves/TrackingExpandReveal.tsx +109 -0
  282. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-entrance-moves/LetterDropPhysics.tsx +100 -0
  283. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-entrance-moves/ScrambleDecode.tsx +90 -0
  284. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-rhythm-sync/FontWeightPump.tsx +124 -0
  285. package/skills/hyper-animator-codex/references/shotcraft/source/demos/type-rhythm-sync/KaraokeFillSync.tsx +93 -0
  286. package/skills/hyper-animator-codex/references/shotcraft/source/demos/typewriter-moves/TerminalTypewriter.tsx +122 -0
  287. package/skills/hyper-animator-codex/references/shotcraft/source/demos/typewriter-moves/TypewriterErrorRetype.tsx +109 -0
  288. package/skills/hyper-animator-codex/references/shotcraft/source/demos/ui-strip-away-outro/UiStripAwayOutro.tsx +218 -0
  289. package/skills/hyper-animator-codex/references/shotcraft/source/demos/ui-to-brand-morph/IconFlipBloomLogo.tsx +199 -0
  290. package/skills/hyper-animator-codex/references/shotcraft/source/demos/ui-to-brand-morph/InputMorphsIntoLogo.tsx +215 -0
  291. package/skills/hyper-animator-codex/references/shotcraft/source/demos/voice-waveform-live/VoiceWaveformLive.tsx +171 -0
  292. package/skills/hyper-animator-codex/references/shotcraft/source/demos/wall-reveal-moves/BentoLightUp.tsx +135 -0
  293. package/skills/hyper-animator-codex/references/shotcraft/source/demos/wipe-transitions/BlindsSlice.tsx +107 -0
  294. package/skills/hyper-animator-codex/references/shotcraft/source/demos/wipe-transitions/ClockWipe.tsx +83 -0
  295. package/skills/hyper-animator-codex/references/shotcraft/source/demos/word-relay-filmstrip/WordRelayFilmstrip.tsx +300 -0
  296. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/Root.tsx +15 -0
  297. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/Caption.tsx +49 -0
  298. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/DigitRoll.tsx +44 -0
  299. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/FlashCut.tsx +19 -0
  300. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/Main.tsx +163 -0
  301. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/PaperTitleCard.tsx +89 -0
  302. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/live/PageCam.tsx +145 -0
  303. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/live/SceneDetail.tsx +146 -0
  304. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/live/SceneFlyIn.tsx +447 -0
  305. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/live/SceneOpen.tsx +532 -0
  306. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/live/SceneOutroLive.tsx +394 -0
  307. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/live/ScenePapers.tsx +185 -0
  308. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/aifl/live/SceneWbr.tsx +299 -0
  309. package/skills/hyper-animator-codex/references/shotcraft/source/template/src/index.ts +4 -0
  310. package/skills/hyper-animator-codex/references/shotcraft/source-notes.md +10 -0
  311. package/skills/hyper-animator-codex/scripts/generate_minimax_music.mjs +27 -10
  312. package/skills/hyper-animator-codex/scripts/generate_minimax_tts.mjs +142 -13
  313. package/skills/hyper-animator-codex/scripts/generate_subtitles.mjs +42 -3
  314. package/skills/hyper-animator-codex/scripts/git_checkpoint.mjs +2 -2
  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 +266 -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
  `);
@@ -193,7 +193,7 @@ function parsePorcelainLine(line) {
193
193
  }
194
194
 
195
195
  function porcelainLines(pathspecs = []) {
196
- const args = ["status", "--porcelain=v1", "--untracked-files=all"];
196
+ const args = ["-c", "core.quotePath=false", "status", "--porcelain=v1", "--untracked-files=all"];
197
197
 
198
198
  if (pathspecs.length > 0) {
199
199
  args.push("--", ...pathspecs);
@@ -230,7 +230,7 @@ function trackedOrUntrackedMatching(pathspecs) {
230
230
  }
231
231
 
232
232
  function stagedFiles() {
233
- return git(["diff", "--cached", "--name-only", "--diff-filter=ACDMR"], { check: true }).stdout
233
+ return git(["-c", "core.quotePath=false", "diff", "--cached", "--name-only", "--diff-filter=ACDMR"], { check: true }).stdout
234
234
  .split("\n")
235
235
  .map((line) => line.trim())
236
236
  .filter(Boolean)
@@ -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,266 @@
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
+ const WORKFLOW_STAGES = new Set(["visual_draft", "audio_integrated", "render_ready"]);
9
+ const AUDIO_MODES = new Set(["generated", "user_local_file", "none", "deferred"]);
10
+ const ENERGY_LEVELS = new Set(["quiet", "balanced", "high", "cinematic"]);
11
+ const MOTION_PRESETS = new Set([
12
+ "none",
13
+ "slam-entrance",
14
+ "whip-transition",
15
+ "crash-zoom",
16
+ "push-stack-wipe",
17
+ "dataviz-landscape-open",
18
+ "panel-grid-reflow",
19
+ "brand-resolve",
20
+ ]);
21
+ const SHOTCRAFT_MOTION_PRESETS = new Map([
22
+ ["slam-entrance-moves", "slam-entrance"],
23
+ ["shot-transitions", "whip-transition"],
24
+ ["crash-zoom-punch", "crash-zoom"],
25
+ ["bottom-push-stack-wipe", "push-stack-wipe"],
26
+ ["dataviz-landscape-open", "dataviz-landscape-open"],
27
+ ["panel-grid-moves", "panel-grid-reflow"],
28
+ ["ui-to-brand-morph", "brand-resolve"],
29
+ ]);
30
+
31
+ function isObject(value) {
32
+ return value !== null && typeof value === "object" && !Array.isArray(value);
33
+ }
34
+
35
+ function validateAudioTrack(track, label, errors) {
36
+ if (!isObject(track)) {
37
+ errors.push(`audio.${label} must be an object`);
38
+ return;
39
+ }
40
+
41
+ if (!AUDIO_MODES.has(track.mode)) {
42
+ errors.push(`audio.${label}.mode must be generated, user_local_file, none, or deferred`);
43
+ }
44
+ if (track.mode === "generated" && track.provider !== "minimax_cn") {
45
+ errors.push(`audio.${label}.provider must be minimax_cn when mode is generated`);
46
+ }
47
+ if (track.mode === "user_local_file" && (typeof track.path !== "string" || !track.path.trim())) {
48
+ errors.push(`audio.${label}.path is required when mode is user_local_file`);
49
+ }
50
+ if ((track.mode === "none" || track.mode === "deferred") && track.provider !== undefined) {
51
+ errors.push(`audio.${label}.provider must be omitted when mode is ${track.mode}`);
52
+ }
53
+ if ((track.mode === "none" || track.mode === "deferred") && track.path !== undefined) {
54
+ errors.push(`audio.${label}.path must be omitted when mode is ${track.mode}`);
55
+ }
56
+ }
57
+
58
+ function validateMotionContract(contract, label, shotcraftRefs, errors) {
59
+ if (!isObject(contract)) {
60
+ errors.push(`${label}.motion_contract is required`);
61
+ return;
62
+ }
63
+
64
+ if (!MOTION_PRESETS.has(contract.motion_preset)) {
65
+ errors.push(`${label}.motion_contract.motion_preset must be one of ${[...MOTION_PRESETS].join(", ")}`);
66
+ }
67
+ const expectedPresets = shotcraftRefs
68
+ .map((reference) => SHOTCRAFT_MOTION_PRESETS.get(reference))
69
+ .filter(Boolean);
70
+ if (expectedPresets.length > 0 && !expectedPresets.includes(contract.motion_preset)) {
71
+ errors.push(`${label}.motion_contract.motion_preset must use ${expectedPresets.join(" or ")} for selected ShotCraft refs`);
72
+ }
73
+ if (!ENERGY_LEVELS.has(contract.energy)) {
74
+ errors.push(`${label}.motion_contract.energy must be quiet, balanced, high, or cinematic`);
75
+ }
76
+ for (const field of ["camera", "transition"]) {
77
+ if (typeof contract[field] !== "string" || !contract[field].trim()) {
78
+ errors.push(`${label}.motion_contract.${field} is required`);
79
+ }
80
+ }
81
+ if (!Array.isArray(contract.shotcraft_commitments) || contract.shotcraft_commitments.length === 0) {
82
+ errors.push(`${label}.motion_contract.shotcraft_commitments must contain at least one item`);
83
+ } else {
84
+ contract.shotcraft_commitments.forEach((commitment, index) => {
85
+ if (typeof commitment !== "string" || !commitment.trim()) {
86
+ errors.push(`${label}.motion_contract.shotcraft_commitments[${index}] must be a non-empty string`);
87
+ }
88
+ });
89
+ }
90
+ if (!Number.isFinite(contract.readable_rest_seconds) || contract.readable_rest_seconds < 0) {
91
+ errors.push(`${label}.motion_contract.readable_rest_seconds must be zero or greater`);
92
+ }
93
+ }
94
+
95
+ function validateShotPlan(plan, catalogs) {
96
+ const errors = [];
97
+
98
+ if (!isObject(plan)) return ["plan must be a JSON object"];
99
+ if (plan.schema_version !== "1.0.0") errors.push("schema_version must be 1.0.0");
100
+ if (!WORKFLOW_STAGES.has(plan.workflow_stage)) {
101
+ errors.push("workflow_stage must be visual_draft, audio_integrated, or render_ready");
102
+ }
103
+ if (!["assemble_existing_catalog_items", "generate_new_hyperframes_html"].includes(plan.generation_mode)) {
104
+ errors.push("generation_mode is invalid");
105
+ }
106
+ if (plan.catalog_strategy !== "dual_catalog") errors.push("catalog_strategy must be dual_catalog");
107
+
108
+ if (!isObject(plan.dimensions)
109
+ || !Number.isInteger(plan.dimensions.width)
110
+ || !Number.isInteger(plan.dimensions.height)
111
+ || plan.dimensions.width <= 0
112
+ || plan.dimensions.height <= 0) {
113
+ errors.push("dimensions.width and dimensions.height must be positive integers");
114
+ }
115
+ if (!Number.isFinite(plan.duration_seconds) || plan.duration_seconds <= 0) {
116
+ errors.push("duration_seconds must be a positive number");
117
+ }
118
+
119
+ if (!isObject(plan.audio)) {
120
+ errors.push("audio must be an object");
121
+ } else {
122
+ validateAudioTrack(plan.audio.narration, "narration", errors);
123
+ validateAudioTrack(plan.audio.bgm, "bgm", errors);
124
+ if (plan.workflow_stage === "visual_draft" && plan.audio.narration?.mode === "generated") {
125
+ errors.push("audio.narration must not be generated before visual confirmation");
126
+ }
127
+ if (plan.workflow_stage !== "visual_draft" && plan.audio.narration?.mode === "deferred") {
128
+ errors.push("audio.narration.mode cannot stay deferred after visual confirmation");
129
+ }
130
+ }
131
+
132
+ if (!isObject(plan.model_routing)) {
133
+ errors.push("model_routing must be an object");
134
+ } else {
135
+ if (plan.model_routing.page_animation_authoring !== "gpt-5.6-sol") {
136
+ errors.push("model_routing.page_animation_authoring must be gpt-5.6-sol");
137
+ }
138
+ if (!plan.model_routing.planning_and_validation) {
139
+ errors.push("model_routing.planning_and_validation is required");
140
+ } else if (plan.model_routing.planning_and_validation === "gpt-5.6-sol") {
141
+ errors.push("model_routing.planning_and_validation must not use gpt-5.6-sol");
142
+ }
143
+ }
144
+
145
+ if (!Array.isArray(plan.shots) || plan.shots.length === 0) {
146
+ errors.push("shots must contain at least one shot");
147
+ return errors;
148
+ }
149
+
150
+ const ids = new Set();
151
+ plan.shots.forEach((shot, index) => {
152
+ const label = `shots[${index}]`;
153
+ if (!isObject(shot)) {
154
+ errors.push(`${label} must be an object`);
155
+ return;
156
+ }
157
+ if (typeof shot.id !== "string" || !/^[a-z][a-z0-9-]*$/.test(shot.id)) {
158
+ errors.push(`${label}.id must be a kebab-case identifier`);
159
+ } else if (ids.has(shot.id)) {
160
+ errors.push(`${label}.id must be unique`);
161
+ } else {
162
+ ids.add(shot.id);
163
+ }
164
+ if (!Number.isFinite(shot.start_seconds) || shot.start_seconds < 0) {
165
+ errors.push(`${label}.start_seconds must be zero or greater`);
166
+ }
167
+ if (!Number.isFinite(shot.end_seconds) || shot.end_seconds <= shot.start_seconds) {
168
+ errors.push(`${label}.end_seconds must be greater than start_seconds`);
169
+ }
170
+ if (typeof shot.purpose !== "string" || !shot.purpose.trim()) {
171
+ errors.push(`${label}.purpose is required`);
172
+ }
173
+ if (!Array.isArray(shot.hyperframes_refs)) {
174
+ errors.push(`${label}.hyperframes_refs must be an array`);
175
+ } else {
176
+ if (shot.hyperframes_refs.length === 0) {
177
+ errors.push(`${label}.hyperframes_refs must contain at least one HyperFrames reference`);
178
+ }
179
+ for (const reference of shot.hyperframes_refs) {
180
+ if (!catalogs.hyperframes.has(reference)) {
181
+ errors.push(`${label} has unknown HyperFrames reference: ${reference}`);
182
+ }
183
+ }
184
+ }
185
+ if (!Array.isArray(shot.shotcraft_refs)) {
186
+ errors.push(`${label}.shotcraft_refs must be an array`);
187
+ } else {
188
+ if (shot.shotcraft_refs.length === 0) {
189
+ errors.push(`${label}.shotcraft_refs must contain at least one ShotCraft reference`);
190
+ }
191
+ for (const reference of shot.shotcraft_refs) {
192
+ if (!catalogs.shotcraft.has(reference)) {
193
+ errors.push(`${label} has unknown ShotCraft reference: ${reference}`);
194
+ }
195
+ }
196
+ }
197
+ validateMotionContract(shot.motion_contract, label, Array.isArray(shot.shotcraft_refs) ? shot.shotcraft_refs : [], errors);
198
+
199
+ if (index === 0 && shot.start_seconds !== 0) {
200
+ errors.push("shots must start at 0 seconds");
201
+ }
202
+ if (index > 0 && Number.isFinite(shot.start_seconds)) {
203
+ const previous = plan.shots[index - 1];
204
+ if (Number.isFinite(previous?.end_seconds) && Math.abs(shot.start_seconds - previous.end_seconds) > 0.001) {
205
+ errors.push(`shots must be contiguous: ${label}.start_seconds must equal shots[${index - 1}].end_seconds`);
206
+ }
207
+ }
208
+ });
209
+
210
+ const lastEnd = plan.shots.at(-1)?.end_seconds;
211
+ if (Number.isFinite(lastEnd)
212
+ && Number.isFinite(plan.duration_seconds)
213
+ && Math.abs(lastEnd - plan.duration_seconds) > 0.001) {
214
+ errors.push("last shot end_seconds must equal duration_seconds");
215
+ }
216
+
217
+ return errors;
218
+ }
219
+
220
+ function output(payload, code = 0) {
221
+ console.log(JSON.stringify(payload, null, 2));
222
+ process.exitCode = code;
223
+ }
224
+
225
+ async function main() {
226
+ try {
227
+ const path = process.argv[2];
228
+ if (!path || path === "--help" || path === "-h") {
229
+ console.log("Usage: validate_shot_plan.mjs <shot-plan.json>");
230
+ process.exitCode = path ? 0 : 1;
231
+ return;
232
+ }
233
+ const plan = JSON.parse(await readFile(path, "utf8"));
234
+ const hyperframesCatalog = JSON.parse(await readFile(
235
+ join(skillRoot, "references", "hyperframes-catalog-map.json"),
236
+ "utf8",
237
+ ));
238
+ const shotcraftCatalog = JSON.parse(await readFile(
239
+ join(skillRoot, "references", "shotcraft", "catalog.json"),
240
+ "utf8",
241
+ ));
242
+ const catalogs = {
243
+ hyperframes: new Set(hyperframesCatalog.items.map((item) => item.id)),
244
+ shotcraft: new Set(shotcraftCatalog.cards.flatMap((card) => [
245
+ card.name,
246
+ ...card.styles.map((style) => style.key),
247
+ ])),
248
+ };
249
+ const errors = validateShotPlan(plan, catalogs);
250
+ if (errors.length > 0) {
251
+ output({ ok: false, path, errors }, 1);
252
+ return;
253
+ }
254
+ output({
255
+ ok: true,
256
+ path,
257
+ shot_count: plan.shots.length,
258
+ duration_seconds: plan.duration_seconds,
259
+ catalog_strategy: plan.catalog_strategy,
260
+ });
261
+ } catch (error) {
262
+ output({ ok: false, errors: [error.message] }, 1);
263
+ }
264
+ }
265
+
266
+ main();