dsh-hyperframes 0.3.1 → 0.4.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.
- package/README.en.md +6 -5
- package/README.md +7 -6
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -0
- package/package.json +63 -63
- package/skills/embedded-captions/SKILL.md +28 -3
- package/skills/embedded-captions/references/aesthetic-principles.md +2 -3
- package/skills/embedded-captions/references/rail.md +1 -1
- package/skills/embedded-captions/scripts/check-occlusion.cjs +4 -1
- package/skills/embedded-captions/scripts/check-overflow.cjs +1 -0
- package/skills/embedded-captions/scripts/check-rail-climax.cjs +5 -1
- package/skills/embedded-captions/scripts/fixtures/heroless/theme.json +11 -0
- package/skills/embedded-captions/scripts/hf-cli.cjs +33 -0
- package/skills/embedded-captions/scripts/make-theme.cjs +95 -57
- package/skills/embedded-captions/scripts/make-theme.test.mjs +131 -0
- package/skills/embedded-captions/scripts/matte.cjs +1 -13
- package/skills/embedded-captions/scripts/measure-layout.cjs +2 -1
- package/skills/embedded-captions/scripts/preview-frames.cjs +39 -11
- package/skills/embedded-captions/scripts/preview-frames.test.mjs +24 -0
- package/skills/embedded-captions/scripts/render-and-composite.sh +8 -52
- package/skills/embedded-captions/scripts/safe-zones.cjs +4 -1
- package/skills/embedded-captions/scripts/transcribe.cjs +5 -14
- package/skills/embedded-captions/scripts/transcribe.test.mjs +41 -0
- package/skills/faceless-explainer/SKILL.md +20 -16
- package/skills/faceless-explainer/references/story-design.md +1 -1
- package/skills/faceless-explainer/scripts/assemble-index.mjs +6 -4
- package/skills/faceless-explainer/scripts/assemble-index.test.mjs +57 -2
- package/skills/faceless-explainer/scripts/audio.mjs +2 -0
- package/skills/faceless-explainer/scripts/build-frame.mjs +6 -3
- package/skills/faceless-explainer/scripts/captions.mjs +7 -4
- package/skills/faceless-explainer/scripts/frame-packets.mjs +4 -4
- package/skills/faceless-explainer/scripts/lib/bgm-volume.mjs +4 -0
- package/skills/faceless-explainer/scripts/lib/captured-fonts.mjs +58 -0
- package/skills/{hyperframes-core → faceless-explainer}/scripts/lib/frame-packets-core.mjs +5 -23
- package/skills/faceless-explainer/scripts/lib/storyboard.mjs +1 -1
- package/skills/faceless-explainer/scripts/lib/transitions.json +3 -3
- package/skills/faceless-explainer/scripts/transitions.mjs +1 -0
- package/skills/faceless-explainer/scripts/transitions.test.mjs +2 -0
- package/skills/faceless-explainer/sub-agents/frame-worker.md +1 -1
- package/skills/figma/SKILL.md +2 -0
- package/skills/general-video/SKILL.md +13 -11
- package/skills/general-video/scripts/frame-packets.mjs +4 -4
- package/skills/general-video/scripts/lib/frame-packets-core.mjs +194 -0
- package/skills/general-video/sub-agents/frame-worker.md +1 -1
- package/skills/hyperframes/SKILL.md +40 -30
- package/skills/{hyperframes-core → hyperframes}/references/brief-contract.md +15 -15
- package/skills/{hyperframes-core → hyperframes}/references/brief-format.md +8 -8
- package/skills/hyperframes/references/capability-menu.md +2 -2
- package/skills/{hyperframes-core → hyperframes}/references/frame-worker-core.md +1 -1
- package/skills/hyperframes/references/intent-interview.md +16 -16
- package/skills/hyperframes/references/plugin-installation.md +43 -0
- package/skills/{hyperframes-core → hyperframes}/references/production-loop.md +11 -11
- package/skills/hyperframes/references/review-loop.md +37 -0
- package/skills/hyperframes/references/route-briefs.md +1 -1
- package/skills/hyperframes/references/routes/motion-graphics.md +1 -1
- package/skills/{hyperframes-core → hyperframes}/references/script-format.md +3 -3
- package/skills/hyperframes/references/skill-lifecycle.md +2 -0
- package/skills/{hyperframes-core → hyperframes}/references/storyboard-format.md +3 -34
- package/skills/hyperframes/scripts/lib/frame-packets-core.mjs +194 -0
- package/skills/hyperframes/scripts/plugin-cli.mjs +88 -0
- package/skills/hyperframes/scripts/plugin-cli.test.mjs +117 -0
- package/skills/hyperframes-animation/SKILL.md +5 -1
- package/skills/hyperframes-animation/adapters/gsap.md +1 -1
- package/skills/hyperframes-animation/adapters/lottie.md +15 -2
- package/skills/hyperframes-animation/adapters/three.md +14 -0
- package/skills/hyperframes-animation/blueprints/titlecard-reveal.md +1 -1
- package/skills/hyperframes-animation/references/motion-blur.md +133 -0
- package/skills/hyperframes-animation/rules/cursor-click-ripple.md +1 -1
- package/skills/hyperframes-animation/rules/dynamic-content-sequencing.md +1 -1
- package/skills/hyperframes-animation/rules/hacker-flip-3d.md +1 -1
- package/skills/hyperframes-animation/rules/kinetic-beat-slam.md +2 -2
- package/skills/hyperframes-animation/rules/motion-blur-streak.md +1 -1
- package/skills/hyperframes-animation/rules/vertical-spring-ticker.md +1 -1
- package/skills/hyperframes-animation/scripts/package-loader.mjs +47 -16
- package/skills/hyperframes-animation/scripts/package-loader.test.mjs +52 -0
- package/skills/hyperframes-animation/techniques.md +1 -1
- package/skills/hyperframes-animation/transitions/TRANSITION-REGISTRY.md +3 -3
- package/skills/hyperframes-animation/transitions/css-push.md +4 -4
- package/skills/hyperframes-audio/SKILL.md +30 -22
- package/skills/hyperframes-audio/scripts/carve.mjs +6 -3
- package/skills/hyperframes-audio/scripts/carve.test.mjs +16 -1
- package/skills/hyperframes-cli/SKILL.md +44 -35
- package/skills/hyperframes-cli/references/init-and-scaffold.md +8 -6
- package/skills/hyperframes-cli/references/lint-validate-inspect.md +3 -3
- package/skills/hyperframes-cli/references/preview-render.md +35 -32
- package/skills/hyperframes-cli/references/upgrade-info-misc.md +50 -1
- package/skills/hyperframes-core/SKILL.md +30 -24
- package/skills/hyperframes-core/references/composition-patterns.md +3 -42
- package/skills/hyperframes-core/references/creator-editing-recipes.md +131 -7
- package/skills/hyperframes-core/references/data-attributes.md +11 -11
- package/skills/hyperframes-core/references/determinism-rules.md +2 -19
- package/skills/hyperframes-core/references/full-screen-motion.md +0 -9
- package/skills/hyperframes-core/references/minimal-composition.md +2 -2
- package/skills/hyperframes-core/references/sub-compositions.md +3 -66
- package/skills/hyperframes-core/references/tailwind.md +1 -20
- package/skills/hyperframes-core/references/tracks-and-clips.md +2 -6
- package/skills/hyperframes-core/references/variables-and-media.md +3 -3
- package/skills/hyperframes-creative/SKILL.md +2 -0
- package/skills/hyperframes-creative/references/house-style.md +15 -15
- package/skills/hyperframes-creative/references/story-spine.md +3 -1
- package/skills/hyperframes-creative/references/storyboard-recipe.md +57 -0
- package/skills/hyperframes-creative/references/typography.md +1 -1
- package/skills/hyperframes-creative/scripts/package-loader.mjs +47 -16
- package/skills/hyperframes-creative/scripts/package-loader.test.mjs +52 -0
- package/skills/hyperframes-keyframes/SKILL.md +4 -2
- package/skills/hyperframes-registry/SKILL.md +3 -1
- package/skills/hyperframes-registry/references/contributing.md +8 -2
- package/skills/hyperframes-registry/references/discovery.md +20 -34
- package/skills/hyperframes-studio/SKILL.md +77 -0
- package/skills/media-use/SKILL.md +14 -12
- package/skills/media-use/audio/references/captions/authoring.md +4 -0
- package/skills/media-use/audio/references/remove-background.md +1 -1
- package/skills/media-use/audio/references/tts-to-captions.md +11 -2
- package/skills/media-use/audio/references/tts.md +84 -6
- package/skills/media-use/audio/scripts/audio.mjs +15 -6
- package/skills/media-use/audio/scripts/gemini-pipeline.test.mjs +113 -0
- package/skills/media-use/audio/scripts/lib/audio-meta.mjs +39 -0
- package/skills/media-use/audio/scripts/lib/audio-meta.test.mjs +136 -0
- package/skills/media-use/audio/scripts/lib/bgm-volume.mjs +4 -0
- package/skills/media-use/audio/scripts/lib/bgm.mjs +2 -6
- package/skills/media-use/audio/scripts/lib/gemini-auth.mjs +43 -0
- package/skills/media-use/audio/scripts/lib/gemini-auth.py +52 -0
- package/skills/media-use/audio/scripts/lib/gemini-auth.test.mjs +86 -0
- package/skills/media-use/audio/scripts/lib/gemini-auth_test.py +90 -0
- package/skills/media-use/audio/scripts/lib/gemini-tts.mjs +122 -0
- package/skills/media-use/audio/scripts/lib/gemini-tts.test.mjs +243 -0
- package/skills/media-use/audio/scripts/lib/heygen.mjs +2 -1
- package/skills/media-use/audio/scripts/lib/tts.mjs +15 -3
- package/skills/media-use/audio/scripts/wait-bgm.mjs +8 -4
- package/skills/media-use/audio/scripts/wait-bgm.test.mjs +65 -0
- package/skills/media-use/references/audio.md +3 -2
- package/skills/media-use/references/grading.md +7 -7
- package/skills/media-use/references/media-treatment-recipes.md +1 -1
- package/skills/media-use/references/memory.md +2 -2
- package/skills/media-use/references/meta.md +2 -2
- package/skills/media-use/references/operations.md +15 -13
- package/skills/media-use/references/resolve.md +22 -11
- package/skills/media-use/references/setup-providers.md +11 -11
- package/skills/media-use/scripts/audio-duck.mjs +19 -27
- package/skills/media-use/scripts/compatibility.test.mjs +96 -0
- package/skills/media-use/scripts/lib/config-lock.mjs +45 -0
- package/skills/media-use/scripts/lib/duck.mjs +16 -10
- package/skills/media-use/scripts/lib/media-fetch.mjs +85 -0
- package/skills/media-use/scripts/lib/media-home.mjs +20 -0
- package/skills/media-use/scripts/lib/npx-sync.mjs +28 -2
- package/skills/media-use/scripts/lib/prefs-store.mjs +2 -2
- package/skills/media-use/scripts/lib/recipe-store.mjs +2 -2
- package/skills/media-use/scripts/lib/telemetry.mjs +29 -41
- package/skills/media-use/scripts/lib/transcriptCutFade.mjs +21 -0
- package/skills/media-use/scripts/prefs.mjs +1 -1
- package/skills/media-use/scripts/recipe.mjs +1 -1
- package/skills/media-use/scripts/resolve-plugin.test.mjs +62 -0
- package/skills/media-use/scripts/resolve.mjs +27 -1267
- package/skills/media-use/scripts/transcribe.mjs +39 -25
- package/skills/media-use/scripts/transcribe.test.mjs +112 -0
- package/skills/media-use/scripts/transcript-cut.mjs +39 -8
- package/skills/media-use/scripts/transcript-cut.test.mjs +117 -0
- package/skills/motion-graphics/SKILL.md +3 -1
- package/skills/motion-graphics/agents/builder.md +1 -0
- package/skills/motion-graphics/agents/director.md +2 -1
- package/skills/motion-graphics/catalog-map.md +25 -13
- package/skills/motion-graphics/categories/charts/module.md +2 -1
- package/skills/motion-graphics/categories/lower-thirds/module.md +4 -0
- package/skills/motion-graphics/categories/news/module.md +1 -1
- package/skills/motion-graphics/references/motion-vocabulary.md +4 -0
- package/skills/music-to-video/SKILL.md +8 -6
- package/skills/music-to-video/references/montage.md +3 -6
- package/skills/music-to-video/references/motion-primitives/3d-card-flip/index.html +10 -111
- package/skills/music-to-video/references/motion-primitives/3d-card-flip/scene.html +119 -0
- package/skills/music-to-video/references/motion-primitives/bg-flow-field/index.html +11 -284
- package/skills/music-to-video/references/motion-primitives/bg-flow-field/scene.html +294 -0
- package/skills/music-to-video/references/motion-primitives/binary-decrypt/index.html +10 -76
- package/skills/music-to-video/references/motion-primitives/binary-decrypt/scene.html +85 -0
- package/skills/music-to-video/references/motion-primitives/blur-resolve/index.html +10 -52
- package/skills/music-to-video/references/motion-primitives/blur-resolve/scene.html +60 -0
- package/skills/music-to-video/references/motion-primitives/braam-punch/index.html +10 -92
- package/skills/music-to-video/references/motion-primitives/braam-punch/scene.html +100 -0
- package/skills/music-to-video/references/motion-primitives/chromatic-split/index.html +10 -103
- package/skills/music-to-video/references/motion-primitives/chromatic-split/scene.html +111 -0
- package/skills/music-to-video/references/motion-primitives/chrome-sweep/index.html +10 -60
- package/skills/music-to-video/references/motion-primitives/chrome-sweep/scene.html +68 -0
- package/skills/music-to-video/references/motion-primitives/counting-punch/index.html +10 -110
- package/skills/music-to-video/references/motion-primitives/counting-punch/scene.html +119 -0
- package/skills/music-to-video/references/motion-primitives/crash-zoom-in/index.html +10 -112
- package/skills/music-to-video/references/motion-primitives/crash-zoom-in/scene.html +120 -0
- package/skills/music-to-video/references/motion-primitives/datamosh-smear/index.html +10 -121
- package/skills/music-to-video/references/motion-primitives/datamosh-smear/scene.html +131 -0
- package/skills/music-to-video/references/motion-primitives/directional-fill/index.html +10 -90
- package/skills/music-to-video/references/motion-primitives/directional-fill/scene.html +103 -0
- package/skills/music-to-video/references/motion-primitives/dolly-zoom/index.html +10 -94
- package/skills/music-to-video/references/motion-primitives/dolly-zoom/scene.html +102 -0
- package/skills/music-to-video/references/motion-primitives/electric-arc/index.html +10 -100
- package/skills/music-to-video/references/motion-primitives/electric-arc/scene.html +105 -0
- package/skills/music-to-video/references/motion-primitives/flash-cut/index.html +10 -89
- package/skills/music-to-video/references/motion-primitives/flash-cut/scene.html +97 -0
- package/skills/music-to-video/references/motion-primitives/gooey-metaball/index.html +10 -197
- package/skills/music-to-video/references/motion-primitives/gooey-metaball/scene.html +206 -0
- package/skills/music-to-video/references/motion-primitives/hard-cut/index.html +10 -74
- package/skills/music-to-video/references/motion-primitives/hard-cut/scene.html +82 -0
- package/skills/music-to-video/references/motion-primitives/hypercut-whip/index.html +10 -36
- package/skills/music-to-video/references/motion-primitives/hypercut-whip/scene.html +44 -0
- package/skills/music-to-video/references/motion-primitives/iris-open/index.html +10 -61
- package/skills/music-to-video/references/motion-primitives/iris-open/scene.html +69 -0
- package/skills/music-to-video/references/motion-primitives/kinetic-letter-in/index.html +10 -55
- package/skills/music-to-video/references/motion-primitives/kinetic-letter-in/scene.html +64 -0
- package/skills/music-to-video/references/motion-primitives/liquid-morph/index.html +10 -88
- package/skills/music-to-video/references/motion-primitives/liquid-morph/scene.html +96 -0
- package/skills/music-to-video/references/motion-primitives/mask-reveal/index.html +10 -66
- package/skills/music-to-video/references/motion-primitives/mask-reveal/scene.html +74 -0
- package/skills/music-to-video/references/motion-primitives/mosaic-pack/index.html +10 -81
- package/skills/music-to-video/references/motion-primitives/mosaic-pack/scene.html +89 -0
- package/skills/music-to-video/references/motion-primitives/neon-flicker/index.html +10 -65
- package/skills/music-to-video/references/motion-primitives/neon-flicker/scene.html +73 -0
- package/skills/music-to-video/references/motion-primitives/outline-to-fill/index.html +10 -74
- package/skills/music-to-video/references/motion-primitives/outline-to-fill/scene.html +82 -0
- package/skills/music-to-video/references/motion-primitives/palette-flip/index.html +10 -89
- package/skills/music-to-video/references/motion-primitives/palette-flip/scene.html +97 -0
- package/skills/music-to-video/references/motion-primitives/particle-burst/index.html +10 -98
- package/skills/music-to-video/references/motion-primitives/particle-burst/scene.html +106 -0
- package/skills/music-to-video/references/motion-primitives/pixel-dissolve/index.html +10 -78
- package/skills/music-to-video/references/motion-primitives/pixel-dissolve/scene.html +86 -0
- package/skills/music-to-video/references/motion-primitives/radial-burst-lines/index.html +10 -117
- package/skills/music-to-video/references/motion-primitives/radial-burst-lines/scene.html +130 -0
- package/skills/music-to-video/references/motion-primitives/screen-shake/index.html +10 -70
- package/skills/music-to-video/references/motion-primitives/screen-shake/scene.html +78 -0
- package/skills/music-to-video/references/motion-primitives/slot-machine-reveal/index.html +10 -87
- package/skills/music-to-video/references/motion-primitives/slot-machine-reveal/scene.html +100 -0
- package/skills/music-to-video/references/motion-primitives/spotlight-sweep/index.html +10 -94
- package/skills/music-to-video/references/motion-primitives/spotlight-sweep/scene.html +102 -0
- package/skills/music-to-video/references/motion-primitives/staggered-exit/index.html +10 -74
- package/skills/music-to-video/references/motion-primitives/staggered-exit/scene.html +82 -0
- package/skills/music-to-video/references/motion-primitives/text-spectral-rays/index.html +11 -271
- package/skills/music-to-video/references/motion-primitives/text-spectral-rays/scene.html +280 -0
- package/skills/music-to-video/references/motion-primitives/text-wave-distort/index.html +10 -92
- package/skills/music-to-video/references/motion-primitives/text-wave-distort/scene.html +106 -0
- package/skills/music-to-video/references/motion-primitives/tile-mosaic/index.html +10 -101
- package/skills/music-to-video/references/motion-primitives/tile-mosaic/scene.html +109 -0
- package/skills/music-to-video/references/motion-primitives/typewriter-reveal/index.html +10 -79
- package/skills/music-to-video/references/motion-primitives/typewriter-reveal/scene.html +91 -0
- package/skills/music-to-video/references/motion-primitives/word-grid-burst/index.html +10 -83
- package/skills/music-to-video/references/motion-primitives/word-grid-burst/scene.html +96 -0
- package/skills/music-to-video/references/planning.md +2 -2
- package/skills/music-to-video/scripts/lib/storyboard.mjs +1 -1
- package/skills/music-to-video/sub-agents/frame-worker.md +2 -2
- package/skills/pr-to-video/SKILL.md +20 -16
- package/skills/pr-to-video/references/code-vocabulary.md +14 -12
- package/skills/pr-to-video/references/story-design.md +1 -1
- package/skills/pr-to-video/scripts/assemble-index.mjs +6 -4
- package/skills/pr-to-video/scripts/assemble-index.test.mjs +57 -2
- package/skills/pr-to-video/scripts/audio.mjs +2 -0
- package/skills/pr-to-video/scripts/build-frame.mjs +6 -3
- package/skills/pr-to-video/scripts/captions.mjs +7 -4
- package/skills/pr-to-video/scripts/captions.test.mjs +41 -0
- package/skills/pr-to-video/scripts/frame-packets.mjs +4 -4
- package/skills/pr-to-video/scripts/lib/bgm-volume.mjs +4 -0
- package/skills/pr-to-video/scripts/lib/captured-fonts.mjs +58 -0
- package/skills/pr-to-video/scripts/lib/frame-packets-core.mjs +194 -0
- package/skills/pr-to-video/scripts/lib/storyboard.mjs +1 -1
- package/skills/pr-to-video/scripts/lib/transitions.json +3 -3
- package/skills/pr-to-video/scripts/transitions.mjs +7 -5
- package/skills/pr-to-video/sub-agents/frame-worker.md +1 -1
- package/skills/product-launch-video/SKILL.md +20 -16
- package/skills/product-launch-video/references/story-design.md +1 -1
- package/skills/product-launch-video/scripts/assemble-index.mjs +6 -4
- package/skills/product-launch-video/scripts/assemble-index.test.mjs +57 -2
- package/skills/product-launch-video/scripts/audio.mjs +2 -0
- package/skills/product-launch-video/scripts/audio.test.mjs +16 -0
- package/skills/product-launch-video/scripts/build-frame-subsets.test.mjs +152 -0
- package/skills/product-launch-video/scripts/build-frame.mjs +6 -3
- package/skills/product-launch-video/scripts/captions.mjs +7 -4
- package/skills/product-launch-video/scripts/frame-packets.mjs +4 -4
- package/skills/product-launch-video/scripts/lib/bgm-volume.mjs +4 -0
- package/skills/product-launch-video/scripts/lib/captured-fonts.mjs +58 -0
- package/skills/product-launch-video/scripts/lib/frame-packets-core.mjs +194 -0
- package/skills/product-launch-video/scripts/lib/storyboard.mjs +1 -1
- package/skills/product-launch-video/scripts/lib/transitions.json +3 -3
- package/skills/product-launch-video/scripts/transitions.mjs +7 -5
- package/skills/product-launch-video/scripts/transitions.test.mjs +68 -0
- package/skills/product-launch-video/sub-agents/frame-worker.md +1 -1
- package/skills/remotion-to-hyperframes/SKILL.md +7 -4
- package/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/expected.json +5 -5
- package/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/hf-src/compositions/title.html +31 -0
- package/skills/remotion-to-hyperframes/assets/test-corpus/tier-1-title-card/hf-src/index.html +10 -25
- package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/README.md +8 -8
- package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/expected.json +9 -9
- package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/hf-src/compositions/scene-1.html +35 -0
- package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/hf-src/compositions/scene-2.html +35 -0
- package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/hf-src/compositions/scene-3.html +36 -0
- package/skills/remotion-to-hyperframes/assets/test-corpus/tier-2-multi-scene/hf-src/index.html +28 -71
- package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/expected.json +3 -3
- package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/hf-src/compositions/scene-1.html +52 -0
- package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/hf-src/compositions/scene-2.html +99 -0
- package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/hf-src/compositions/scene-3.html +55 -0
- package/skills/remotion-to-hyperframes/assets/test-corpus/tier-3-data-driven/hf-src/index.html +13 -212
- package/skills/remotion-to-hyperframes/references/api-map.md +16 -16
- package/skills/remotion-to-hyperframes/references/limitations.md +7 -7
- package/skills/remotion-to-hyperframes/references/lottie.md +5 -7
- package/skills/remotion-to-hyperframes/references/media.md +3 -3
- package/skills/remotion-to-hyperframes/references/parameters.md +5 -0
- package/skills/remotion-to-hyperframes/references/sequencing.md +71 -18
- package/skills/slideshow/SKILL.md +4 -1
- package/skills/slideshow/references/standalone-harness.md +0 -3
- package/skills/talking-head-recut/SKILL.md +10 -1
- package/skills/hyperframes-core/references/review-loop.md +0 -41
- package/skills/media-use/scripts/lib/adopt.mjs +0 -128
- package/skills/media-use/scripts/lib/adopt.test.mjs +0 -95
- package/skills/media-use/scripts/lib/bgm-provider.mjs +0 -20
- package/skills/media-use/scripts/lib/brand-provider.mjs +0 -59
- package/skills/media-use/scripts/lib/bundled-sfx-provider.mjs +0 -108
- package/skills/media-use/scripts/lib/bundled-sfx-provider.test.mjs +0 -85
- package/skills/media-use/scripts/lib/cache.mjs +0 -150
- package/skills/media-use/scripts/lib/candidates.mjs +0 -91
- package/skills/media-use/scripts/lib/candidates.test.mjs +0 -155
- package/skills/media-use/scripts/lib/codex-provider.mjs +0 -161
- package/skills/media-use/scripts/lib/codex-provider.test.mjs +0 -34
- package/skills/media-use/scripts/lib/coverage.test.mjs +0 -117
- package/skills/media-use/scripts/lib/cube-build.mjs +0 -181
- package/skills/media-use/scripts/lib/cube-build.test.mjs +0 -80
- package/skills/media-use/scripts/lib/cube-validate.mjs +0 -198
- package/skills/media-use/scripts/lib/cube-validate.test.mjs +0 -125
- package/skills/media-use/scripts/lib/cutlist.test.mjs +0 -148
- package/skills/media-use/scripts/lib/duck.test.mjs +0 -118
- package/skills/media-use/scripts/lib/error-diffusion.test.mjs +0 -102
- package/skills/media-use/scripts/lib/freeze.mjs +0 -70
- package/skills/media-use/scripts/lib/freeze.test.mjs +0 -46
- package/skills/media-use/scripts/lib/grade-analyzer.mjs +0 -264
- package/skills/media-use/scripts/lib/grade-analyzer.test.mjs +0 -285
- package/skills/media-use/scripts/lib/heygen-cli.mjs +0 -191
- package/skills/media-use/scripts/lib/heygen-cli.test.mjs +0 -301
- package/skills/media-use/scripts/lib/heygen-search.mjs +0 -45
- package/skills/media-use/scripts/lib/heygen-search.test.mjs +0 -49
- package/skills/media-use/scripts/lib/heygen-video-provider.mjs +0 -127
- package/skills/media-use/scripts/lib/heygen-video-provider.test.mjs +0 -344
- package/skills/media-use/scripts/lib/image-provider.mjs +0 -44
- package/skills/media-use/scripts/lib/local-models.mjs +0 -318
- package/skills/media-use/scripts/lib/local-models.test.mjs +0 -220
- package/skills/media-use/scripts/lib/local-run.mjs +0 -78
- package/skills/media-use/scripts/lib/local-run.test.mjs +0 -121
- package/skills/media-use/scripts/lib/logo-provider.mjs +0 -222
- package/skills/media-use/scripts/lib/logo-provider.test.mjs +0 -137
- package/skills/media-use/scripts/lib/ltx-video-provider.mjs +0 -94
- package/skills/media-use/scripts/lib/ltx-video-provider.test.mjs +0 -316
- package/skills/media-use/scripts/lib/lut-preset-provider.mjs +0 -266
- package/skills/media-use/scripts/lib/lut-preset-provider.test.mjs +0 -176
- package/skills/media-use/scripts/lib/manifest.test.mjs +0 -388
- package/skills/media-use/scripts/lib/match.mjs +0 -47
- package/skills/media-use/scripts/lib/mflux-provider.mjs +0 -128
- package/skills/media-use/scripts/lib/mflux-provider.test.mjs +0 -174
- package/skills/media-use/scripts/lib/misses.mjs +0 -49
- package/skills/media-use/scripts/lib/misses.test.mjs +0 -78
- package/skills/media-use/scripts/lib/npx-sync.test.mjs +0 -50
- package/skills/media-use/scripts/lib/parakeet-words.test.mjs +0 -44
- package/skills/media-use/scripts/lib/prefs-store.test.mjs +0 -189
- package/skills/media-use/scripts/lib/probe.mjs +0 -39
- package/skills/media-use/scripts/lib/probe.test.mjs +0 -31
- package/skills/media-use/scripts/lib/providers.mjs +0 -5
- package/skills/media-use/scripts/lib/recipe-store.test.mjs +0 -367
- package/skills/media-use/scripts/lib/registry.mjs +0 -218
- package/skills/media-use/scripts/lib/registry.test.mjs +0 -261
- package/skills/media-use/scripts/lib/search.mjs +0 -24
- package/skills/media-use/scripts/lib/search.test.mjs +0 -32
- package/skills/media-use/scripts/lib/sfx-provider.mjs +0 -23
- package/skills/media-use/scripts/lib/specs.mjs +0 -132
- package/skills/media-use/scripts/lib/specs.test.mjs +0 -157
- package/skills/media-use/scripts/lib/stats.mjs +0 -117
- package/skills/media-use/scripts/lib/stats.test.mjs +0 -165
- package/skills/media-use/scripts/lib/telemetry.test.mjs +0 -373
- package/skills/media-use/scripts/lib/tts-local-provider.mjs +0 -92
- package/skills/media-use/scripts/lib/tts-local-provider.test.mjs +0 -72
- package/skills/media-use/scripts/lib/usage.mjs +0 -57
- package/skills/media-use/scripts/lib/usage.test.mjs +0 -54
- package/skills/media-use/scripts/lib/voice-provider.mjs +0 -57
- package/skills/media-use/scripts/lib/voice-provider.test.mjs +0 -46
- package/skills/media-use/scripts/resolve.test.mjs +0 -1120
- /package/skills/{hyperframes-core → hyperframes}/references/subagent-dispatch.md +0 -0
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Motion blur — shutter smear on any animated element
|
|
2
|
+
|
|
3
|
+
## Read this part before you blur anything
|
|
4
|
+
|
|
5
|
+
Blur is not polish. It is the smear a real shutter leaves while the subject
|
|
6
|
+
crosses the frame, so it only reads as correct when the subject crosses enough
|
|
7
|
+
of the frame to have smeared. Applied to motion that was never fast enough, it
|
|
8
|
+
reads as a soft, cheap render: the eye sees mush where it expected an edge.
|
|
9
|
+
|
|
10
|
+
Do not blur:
|
|
11
|
+
|
|
12
|
+
| Case | Why | Do instead |
|
|
13
|
+
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | ----------------------------------- |
|
|
14
|
+
| Travel under about one element-width per frame | The copies pile up inside the element's own silhouette, so the result is a softer element, not a smear | Leave it sharp |
|
|
15
|
+
| A fade, a color change, a blur-in, a filter beat | Nothing reaches `transform`, so there is no trajectory to integrate and no smear to draw | Leave it sharp |
|
|
16
|
+
| Text meant to be read at that moment | A smeared word is an unreadable word, which is usually the opposite of the brief | Blur the approach, land sharp, hold |
|
|
17
|
+
| A slow drift, a parallax layer, a breathing loop | Below the half-pixel deadband it renders sharp anyway; above it, it looks like a mistake | Leave it sharp |
|
|
18
|
+
| The whole scene, or a container of many elements | Cost is the copies of an entire subtree, and a container that never moves smears nothing inside it | Point it at the element that moves |
|
|
19
|
+
|
|
20
|
+
Blur the beats that snap: a slam, a whip, a hard cut in position, a spin, a
|
|
21
|
+
scale punch. One to three of them in a composition, not every tween.
|
|
22
|
+
|
|
23
|
+
## Two routes, and they are not interchangeable
|
|
24
|
+
|
|
25
|
+
| Route | What it is | Use when |
|
|
26
|
+
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
|
27
|
+
| The `motion-blur` registry component | A DOM shutter synthesised in the page: N+1 additively blended copies of the element along its sampled trajectory | You want the smear visible in the preview, on selected elements, authored per element |
|
|
28
|
+
| The engine's `motionBlur` render option | The renderer integrates real sub-frame samples of the whole frame | You want every moving thing smeared, including canvas, video and transformed ancestors, and only in the final render |
|
|
29
|
+
|
|
30
|
+
The component smears what a `transform` can express, on the elements you mark.
|
|
31
|
+
The engine smears the frame. The component is the one an agent authors; the
|
|
32
|
+
engine option is a render-time decision and shows nothing in a preview.
|
|
33
|
+
|
|
34
|
+
## The contract: one attribute
|
|
35
|
+
|
|
36
|
+
Paste the component's snippet into the composition, then mark the element:
|
|
37
|
+
|
|
38
|
+
```html
|
|
39
|
+
<div id="root" data-composition-id="hero" data-duration="4" data-fps="30">
|
|
40
|
+
<div id="slam" data-hf-motion-blur></div>
|
|
41
|
+
<div id="title" data-hf-motion-blur='{"shutterAngle": 360}'></div>
|
|
42
|
+
</div>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Nothing to call and no ordering to get right. A marked element is attached as
|
|
46
|
+
soon as its composition's timeline is registered, and the registry is also
|
|
47
|
+
polled for about eight seconds after load, so a composition that mounts
|
|
48
|
+
asynchronously is picked up too. An element takes the timeline registered under
|
|
49
|
+
the `data-composition-id` of its nearest ancestor carrying that attribute, so a
|
|
50
|
+
sub-composition's targets follow that sub-composition.
|
|
51
|
+
|
|
52
|
+
Empty attribute means defaults. Any other value must parse as a JSON object, so
|
|
53
|
+
it needs double quotes on the keys. A value that parses to something else,
|
|
54
|
+
`null` or a bare number, warns and is skipped rather than quietly taken as
|
|
55
|
+
defaults.
|
|
56
|
+
|
|
57
|
+
`attachMotionBlur(target, timeline, options)` is for an element created later
|
|
58
|
+
than that window. It has an ordering contract, after every tween so the
|
|
59
|
+
timeline's final duration is known, and getting it wrong is silent. For markup
|
|
60
|
+
that is already in the document, use the attribute.
|
|
61
|
+
|
|
62
|
+
## Options
|
|
63
|
+
|
|
64
|
+
| Option | Default | Meaning |
|
|
65
|
+
| ----------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
66
|
+
| `shutterAngle` | 720 | Degrees of the frame interval the shutter is open. 720 is two frames, measured off a real After Effects export. 360 is one frame. 0 disables the smear |
|
|
67
|
+
| `shutterPhase` | -360 | Degrees the window start sits from the frame time. -360 centres the window on the frame |
|
|
68
|
+
| `samplesPerFrame` | 16 | Sub-intervals of the window, so this many plus one copies, each at 1 over this many opacity. Max 64 |
|
|
69
|
+
| `fps` | the `data-fps` of the target's own composition root, else 30 | Composition frame rate. Pass it explicitly when rendering with an fps override |
|
|
70
|
+
|
|
71
|
+
A key that is none of these four, and a value that is not a finite number, are
|
|
72
|
+
both refused by name rather than read as defaults. `{"shutterAngle": "720deg"}`
|
|
73
|
+
is a refusal, not a 720 degree shutter.
|
|
74
|
+
|
|
75
|
+
There is no axis, no strength and no radius. The smear is the trajectory,
|
|
76
|
+
integrated; its extent is speed times shutter time and is not a free parameter.
|
|
77
|
+
A template that passes `axis`, `blurMax` or `blurScale` carries an older fork of
|
|
78
|
+
this snippet and its options do nothing in the current one.
|
|
79
|
+
|
|
80
|
+
## The failure modes are all silent
|
|
81
|
+
|
|
82
|
+
Every one of these renders a plausible-looking sharp element and reports
|
|
83
|
+
nothing except where noted:
|
|
84
|
+
|
|
85
|
+
| Symptom | Cause | Fix |
|
|
86
|
+
| ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
|
|
87
|
+
| Console warns that no composition registered a timeline for an element | The element is outside every `data-composition-id`, or that composition never registers a timeline | Put it inside the composition's root, or register the timeline |
|
|
88
|
+
| Console warns the attribute is not JSON | Single quotes, unquoted keys, a trailing comma | Double-quoted JSON, or an empty attribute for defaults |
|
|
89
|
+
| Console warns the attribute is not a JSON object | `null`, a bare number, a quoted string, an array | An object, or an empty attribute for defaults |
|
|
90
|
+
| Console warns the attribute names no such option | A misspelled key, for example `samplesperframe` | Use one of the four names above, case-sensitive |
|
|
91
|
+
| Console warns the attribute needs a number for an option | A quoted or unit-suffixed value, for example `"720deg"` | A bare JSON number |
|
|
92
|
+
| Console warns it cannot blur a target inside another target | Both an element and one of its ancestors carry the attribute | Mark one of them, the one that moves |
|
|
93
|
+
| Console warns one call cannot blur compositions at different frame rates | One `attachMotionBlur` call named elements in two compositions whose `data-fps` differ | One call per composition |
|
|
94
|
+
| Console warns a second timeline registered for an element | The same `data-composition-id` key was registered twice with different timelines; the copies still follow the first | Register once per composition |
|
|
95
|
+
| No smear, no warning | The beat animates `left`, `top`, `width` or `height`; the snippet reads the resolved `transform` | Animate `x`, `y`, `scale`, `rotation` |
|
|
96
|
+
| No smear on a container's children | The marked element does not move; its children do | Mark the elements that move |
|
|
97
|
+
| A smear that lags the element | A transformed ancestor is doing the moving | Move the element itself, or use the engine route |
|
|
98
|
+
| Blur only on the first frame, or never in a preview | The host never seeks the timeline | HyperFrames seeks every frame; a paused timeline nobody seeks shows nothing |
|
|
99
|
+
| A smear left behind in the old parent | The target was reparented after attaching; the group stays where it was inserted and is never moved | Do not reparent a blurred element. Animate `x`/`y` instead, or attach after the move |
|
|
100
|
+
| A selector stops matching after attaching | A copy keeps the element's classes, because a class rule is the only thing that can style a copy's pseudo-elements | Address the element by id or by reference, never by a class a copy also carries |
|
|
101
|
+
|
|
102
|
+
## Cost
|
|
103
|
+
|
|
104
|
+
Each target costs N+1 copies of its whole subtree. Those are restyled on attach
|
|
105
|
+
and on resize, and re-transformed every frame, and the timeline is seeked N+1
|
|
106
|
+
times per frame to sample the trajectory. At the default 16 that is 17 copies
|
|
107
|
+
and 17 seeks per target per frame. Three marked elements is fine. Thirty is a
|
|
108
|
+
different render.
|
|
109
|
+
|
|
110
|
+
Drop `samplesPerFrame` before you drop the effect: 8 halves the cost and the
|
|
111
|
+
staircase is still smooth on a fast beat.
|
|
112
|
+
|
|
113
|
+
## The numbers, so you can argue with them
|
|
114
|
+
|
|
115
|
+
The defaults are measured against a 1920x1080 30 fps After Effects export of
|
|
116
|
+
translating text, not chosen. In that export the outermost trailing copy sits
|
|
117
|
+
exactly at the previous frame's position and the outermost leading copy exactly
|
|
118
|
+
at the next frame's, with 8 evenly spaced copies between on each side: a window
|
|
119
|
+
of two frames, phase minus one frame, 16 sub-intervals. The staircase across a
|
|
120
|
+
stroke steps by 0.063 plus or minus 0.002 of the sharp text intensity, a flat
|
|
121
|
+
1/16 per copy with no taper toward the window edges. Triangle weighting scores
|
|
122
|
+
1.6 dB worse against the same export.
|
|
123
|
+
|
|
124
|
+
Per-beat PSNR against that reference, sharp render versus this component:
|
|
125
|
+
translate +3.38 dB, scale +0.62, rotate X +0.43, rotate Y +0.84, rotate Z
|
|
126
|
+
+1.15. A beat that only scales or only rotates smears, which the earlier
|
|
127
|
+
SVG-filter stage could not do.
|
|
128
|
+
|
|
129
|
+
## See also
|
|
130
|
+
|
|
131
|
+
`../../registry/components/motion-blur/motion-blur.html` is the snippet and its
|
|
132
|
+
full header. `shutter-slam` is the same model as an installable component: the
|
|
133
|
+
After Effects reference case, six beats, elastic to the container.
|
|
@@ -89,7 +89,7 @@ tl.to(
|
|
|
89
89
|
| RIPPLE_EASE | discrete choice | `power2.out` standard ping · `power3.out` sharper attack · `expo.out` strong distant pulse |
|
|
90
90
|
| TARGET_X / TARGET_Y | layout-derived | must match the target's visual centroid — a 4 px miss reads as missing the button |
|
|
91
91
|
|
|
92
|
-
Reference values:
|
|
92
|
+
Reference values: `../examples/cta-orbit-collapse.html` — 0.5 s move on `back.out(1.3)`, click +0.2 s, press 0.08 s at 0.85/0.95, single ring to 5× over 0.7 s `power2.out`.
|
|
93
93
|
|
|
94
94
|
## Critical Constraints
|
|
95
95
|
|
|
@@ -134,7 +134,7 @@ Values: `HOLD_START` 0.8–1.2s; `DECAY` 0.75–0.88 (higher = longer runway bef
|
|
|
134
134
|
| TAIL_PAD | 0.0–1.0s | quiet beat after the last entry; prefer 0 when the next composition owns the breath |
|
|
135
135
|
| CONTENT N | 3–6 entries | <3 isn't a sequence; >6 drags (accelerating cadence relaxes this — see above) |
|
|
136
136
|
|
|
137
|
-
Reference:
|
|
137
|
+
Reference: `../examples/messaging-multi-phrase.html`.
|
|
138
138
|
|
|
139
139
|
## Critical Constraints
|
|
140
140
|
|
|
@@ -108,7 +108,7 @@ charEls.forEach((el, i) => {
|
|
|
108
108
|
| REVEAL_THRESHOLD | 0.5–0.7 | lower reveals too early (no tension); higher reads as a hard end-reveal |
|
|
109
109
|
| FLICKER_RATE | 3–6 frames per glyph swap | <3 looks like noise; >6 looks like discrete typing |
|
|
110
110
|
|
|
111
|
-
Reference:
|
|
111
|
+
Reference: `../examples/proof-logo-chain.html` (163px, 0.55s, 0.033s, 0.6).
|
|
112
112
|
|
|
113
113
|
## Critical Constraints
|
|
114
114
|
|
|
@@ -112,7 +112,7 @@ tl.to(
|
|
|
112
112
|
## Variations
|
|
113
113
|
|
|
114
114
|
- **Entrance easing by attack character** — `power4.out` hard slam ⭐ default hit · `expo.out` hardest snap (side-snaps, whip-ins) · `back.out(2)` overshoot pop (accents only, not body words) · `circ.out` heavy rise with momentum. Use **at least 3 distinct easings** across the piece.
|
|
115
|
-
- **Rhythm chrome alternatives** — a center beat bar or a `// label` monospace tag pulsing on-beat instead of the 5-tick metronome; mark any decorative that must survive a shader transition per
|
|
115
|
+
- **Rhythm chrome alternatives** — a center beat bar or a `// label` monospace tag pulsing on-beat instead of the 5-tick metronome; mark any decorative that must survive a shader transition per `../transitions/overview.md`.
|
|
116
116
|
- **Finale dressing** — stack + accent underline sweep ([css-marker-patterns](css-marker-patterns.md)); don't just leave the last phrase sitting.
|
|
117
117
|
|
|
118
118
|
## Values
|
|
@@ -129,7 +129,7 @@ tl.to(
|
|
|
129
129
|
- **One beat array, not scattered offsets** — every element times off `BEATS[]` / `PULSE`; this is the single biggest lever for "rhythmic".
|
|
130
130
|
- **Different entrance per phrase** — a reused `punchIn()` for all lines is the flat-but-competent tell. Vary the motion axis, reuse the ease _family_.
|
|
131
131
|
- **Finale repeat math**: `repeat: Math.max(0, Math.floor(dur / cycle) - 1)` — `Math.ceil` overshoots `data-duration` and trips the `gsap_repeat_ceil_overshoot` lint rule; a negative repeat is read by GSAP as `-1` (infinite).
|
|
132
|
-
- **No banned exit animations between scenes** — in a montage the _transition_ is the exit (
|
|
132
|
+
- **No banned exit animations between scenes** — in a montage the _transition_ is the exit (`../transitions/overview.md`); only a final scene may fade out.
|
|
133
133
|
- **Display font must be embedded** or it silently falls back at render — Anton / Bebas-as-literal are NOT embedded (`Bebas Neue` aliases to League Gothic; verify in `typography.md`).
|
|
134
134
|
|
|
135
135
|
## See also
|
|
@@ -12,7 +12,7 @@ Real motion blur isn't available to a seeked renderer (it integrates over shutte
|
|
|
12
12
|
- **(A) Directional SVG blur** — inline `<feGaussianBlur stdDeviation="X 0">` (X on the motion axis, 0 across it), tweened via a proxy. Cleanest; a true directional smear.
|
|
13
13
|
- **(B) Echo / ghost trail** — 2–4 duplicates at decreasing opacity, offset backward along the motion vector, collapsing into the lead as it settles. No filter cost; a stylized "speed-line" trail.
|
|
14
14
|
|
|
15
|
-
**Entrances and mid-shot moves only — never a mid-composition exit.** A blurred element fleeing off-frame mid-composition reads as a glitch; a hard exit between scenes is the transition's job (
|
|
15
|
+
**Entrances and mid-shot moves only — never a mid-composition exit.** A blurred element fleeing off-frame mid-composition reads as a glitch; a hard exit between scenes is the transition's job (`../transitions/overview.md`). One sanctioned scope extension: the envelope may ride the **camera wrapper** during a travel leg — see the Camera-Travel Carve-Out.
|
|
16
16
|
|
|
17
17
|
## How It Works
|
|
18
18
|
|
|
@@ -87,7 +87,7 @@ springs.forEach((spring, i) => {
|
|
|
87
87
|
| STEP_SPACING | 0.3–0.5s | **≤ STEP_DUR** so springs overlap (additive); wider gaps read as a lazy linear scroll |
|
|
88
88
|
| BOUNCE_FACTOR | 1.4–2.5 | 1.4 gentle click / 2.0 firm / 2.5+ casino spin-and-land for a climax step |
|
|
89
89
|
|
|
90
|
-
Reference:
|
|
90
|
+
Reference: `../examples/proof-logo-chain.html` (204px, 1 step, 0.45s).
|
|
91
91
|
|
|
92
92
|
## Critical Constraints
|
|
93
93
|
|
|
@@ -12,7 +12,7 @@ import { spawnSync } from "node:child_process";
|
|
|
12
12
|
import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
13
13
|
import { createRequire } from "node:module";
|
|
14
14
|
import { tmpdir } from "node:os";
|
|
15
|
-
import { basename, delimiter, dirname, join, parse, resolve } from "node:path";
|
|
15
|
+
import { basename, delimiter, dirname, join, parse, resolve, win32 as win32Path } from "node:path";
|
|
16
16
|
import { createInterface } from "node:readline/promises";
|
|
17
17
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
18
18
|
|
|
@@ -339,23 +339,54 @@ function ancestors(start) {
|
|
|
339
339
|
return dirs;
|
|
340
340
|
}
|
|
341
341
|
|
|
342
|
+
export function resolveNpmSpawnCommand(
|
|
343
|
+
args,
|
|
344
|
+
platform = process.platform,
|
|
345
|
+
env = process.env,
|
|
346
|
+
nodeExecPath = process.execPath,
|
|
347
|
+
pathExists = existsSync,
|
|
348
|
+
) {
|
|
349
|
+
if (platform !== "win32") {
|
|
350
|
+
return { cmd: "npm", args, opts: { stdio: "inherit" } };
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
const bundledNpmCli = win32Path.join(
|
|
354
|
+
win32Path.dirname(nodeExecPath),
|
|
355
|
+
"node_modules",
|
|
356
|
+
"npm",
|
|
357
|
+
"bin",
|
|
358
|
+
"npm-cli.js",
|
|
359
|
+
);
|
|
360
|
+
const npmCli = [env.npm_execpath, bundledNpmCli].find(
|
|
361
|
+
(candidate) => candidate && pathExists(candidate),
|
|
362
|
+
);
|
|
363
|
+
if (!npmCli) return null;
|
|
364
|
+
return {
|
|
365
|
+
cmd: env.npm_node_execpath || nodeExecPath,
|
|
366
|
+
args: [npmCli, ...args],
|
|
367
|
+
opts: { stdio: "inherit", windowsHide: true },
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
|
|
342
371
|
function bootstrapWithNpmInstall(packageNames) {
|
|
343
372
|
const installRoot = mkdtempSync(join(tmpdir(), "hyperframes-skill-deps-"));
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
{
|
|
358
|
-
|
|
373
|
+
const npmArgs = [
|
|
374
|
+
"install",
|
|
375
|
+
"--silent",
|
|
376
|
+
"--no-audit",
|
|
377
|
+
"--no-fund",
|
|
378
|
+
"--ignore-scripts",
|
|
379
|
+
"--no-save",
|
|
380
|
+
"--prefix",
|
|
381
|
+
installRoot,
|
|
382
|
+
...packageNames,
|
|
383
|
+
];
|
|
384
|
+
const npmCommand = resolveNpmSpawnCommand(npmArgs);
|
|
385
|
+
if (!npmCommand) {
|
|
386
|
+
rmSync(installRoot, { recursive: true, force: true });
|
|
387
|
+
throw new Error("Could not locate npm-cli.js for dependency bootstrap on Windows.");
|
|
388
|
+
}
|
|
389
|
+
const installResult = spawnSync(npmCommand.cmd, npmCommand.args, npmCommand.opts);
|
|
359
390
|
|
|
360
391
|
if (installResult.error) throw installResult.error;
|
|
361
392
|
if (installResult.status !== 0) {
|
|
@@ -5,10 +5,62 @@ import { copyFileSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
6
6
|
import { tmpdir } from "node:os";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
|
+
import { resolveNpmSpawnCommand } from "./package-loader.mjs";
|
|
8
9
|
|
|
9
10
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
10
11
|
const ENV = "HYPERFRAMES_SKILL_PKG_VERSION";
|
|
11
12
|
|
|
13
|
+
test("resolveNpmSpawnCommand routes Windows npm through node and npm-cli.js", () => {
|
|
14
|
+
const npmCli = "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js";
|
|
15
|
+
const node = "C:\\Program Files\\nodejs\\node.exe";
|
|
16
|
+
const resolved = resolveNpmSpawnCommand(
|
|
17
|
+
["install", "@hyperframes/producer@0.7.55", "value & calc"],
|
|
18
|
+
"win32",
|
|
19
|
+
{ npm_execpath: npmCli, npm_node_execpath: node },
|
|
20
|
+
node,
|
|
21
|
+
(path) => path === npmCli,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
assert.deepEqual(resolved, {
|
|
25
|
+
cmd: node,
|
|
26
|
+
args: [npmCli, "install", "@hyperframes/producer@0.7.55", "value & calc"],
|
|
27
|
+
opts: { stdio: "inherit", windowsHide: true },
|
|
28
|
+
});
|
|
29
|
+
assert.equal(resolved.opts.shell, undefined);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test("resolveNpmSpawnCommand finds npm-cli.js beside node for direct Windows runs", () => {
|
|
33
|
+
const node = "C:\\Program Files\\nodejs\\node.exe";
|
|
34
|
+
const npmCli = "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js";
|
|
35
|
+
const resolved = resolveNpmSpawnCommand(
|
|
36
|
+
["install", "@hyperframes/producer@0.7.55"],
|
|
37
|
+
"win32",
|
|
38
|
+
{},
|
|
39
|
+
node,
|
|
40
|
+
(path) => path === npmCli,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
assert.equal(resolved?.cmd, node);
|
|
44
|
+
assert.deepEqual(resolved?.args, [npmCli, "install", "@hyperframes/producer@0.7.55"]);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test(
|
|
48
|
+
"resolveNpmSpawnCommand launches the installed npm CLI on Windows",
|
|
49
|
+
{ skip: process.platform !== "win32" },
|
|
50
|
+
() => {
|
|
51
|
+
const resolved = resolveNpmSpawnCommand(["--version"]);
|
|
52
|
+
assert.ok(resolved);
|
|
53
|
+
|
|
54
|
+
const result = spawnSync(resolved.cmd, resolved.args, {
|
|
55
|
+
encoding: "utf8",
|
|
56
|
+
windowsHide: true,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
assert.equal(result.status, 0, result.stderr);
|
|
60
|
+
assert.match(result.stdout.trim(), /^\d+\./);
|
|
61
|
+
},
|
|
62
|
+
);
|
|
63
|
+
|
|
12
64
|
// (a) env override wins — no ancestor lookup, exact version echoed back.
|
|
13
65
|
test("hyperframesPackageSpec: env override wins", async () => {
|
|
14
66
|
const prev = process.env[ENV];
|
|
@@ -197,7 +197,7 @@ Vector animations that play inside a composition. Use for logos, character anima
|
|
|
197
197
|
</script>
|
|
198
198
|
```
|
|
199
199
|
|
|
200
|
-
`autoplay: false` + `
|
|
200
|
+
`autoplay: false` + `window.__hfLottie.push()` are mandatory — HyperFrames seeks each registered player to composition time, so a player left on `autoplay` runs in wall-clock and renders non-deterministically. `loop: true` is seek-safe: the adapter wraps composition time into the animation's own length, so a short cycle repeats for the whole scene. There is no playback-rate scaling: bake non-default speed into the Lottie asset. Characters (walk cycles, mascots, gestures) and the full `.lottie`/dotLottie contract: `adapters/lottie.md`.
|
|
201
201
|
|
|
202
202
|
---
|
|
203
203
|
|
|
@@ -97,11 +97,11 @@ whitelist is a _scene-worker_ prompt rule only — it does not bind index.html).
|
|
|
97
97
|
"note": "Directional. The injector picks __DX__/__DY__ from the direction and emits the horizontal OR vertical pair (not both).",
|
|
98
98
|
"gsap_template_horizontal": [
|
|
99
99
|
"tl.to(__OLD__, { x: __DX__, duration: __DUR__, ease: \"power3.inOut\" }, __T__);",
|
|
100
|
-
"tl.fromTo(__NEW__, { x: __DXIN__, opacity: 1 }, { x: 0, duration: __DUR__, ease: \"power3.inOut\" }, __T__);"
|
|
100
|
+
"tl.fromTo(__NEW__, { x: __DXIN__, opacity: 1 }, { x: 0, opacity: 1, duration: __DUR__, ease: \"power3.inOut\" }, __T__);"
|
|
101
101
|
],
|
|
102
102
|
"gsap_template_vertical": [
|
|
103
103
|
"tl.to(__OLD__, { y: __DY__, duration: __DUR__, ease: \"power3.inOut\" }, __T__);",
|
|
104
|
-
"tl.fromTo(__NEW__, { y: __DYIN__, opacity: 1 }, { y: 0, duration: __DUR__, ease: \"power3.inOut\" }, __T__);"
|
|
104
|
+
"tl.fromTo(__NEW__, { y: __DYIN__, opacity: 1 }, { y: 0, opacity: 1, duration: __DUR__, ease: \"power3.inOut\" }, __T__);"
|
|
105
105
|
]
|
|
106
106
|
},
|
|
107
107
|
{
|
|
@@ -128,7 +128,7 @@ whitelist is a _scene-worker_ prompt rule only — it does not bind index.html).
|
|
|
128
128
|
"note": "Old compresses to a vertical line on the left edge; new expands from the right edge. Incoming starts off (scaleX 0) so its higher-track stacking is harmless.",
|
|
129
129
|
"gsap_template": [
|
|
130
130
|
"tl.to(__OLD__, { scaleX: 0, transformOrigin: \"left center\", duration: __DUR__, ease: \"power3.inOut\" }, __T__);",
|
|
131
|
-
"tl.fromTo(__NEW__, { scaleX: 0, transformOrigin: \"right center\", opacity: 1 }, { scaleX: 1, transformOrigin: \"right center\", duration: __DUR__, ease: \"power3.inOut\" }, __T__);"
|
|
131
|
+
"tl.fromTo(__NEW__, { scaleX: 0, transformOrigin: \"right center\", opacity: 1 }, { scaleX: 1, transformOrigin: \"right center\", opacity: 1, duration: __DUR__, ease: \"power3.inOut\" }, __T__);"
|
|
132
132
|
]
|
|
133
133
|
}
|
|
134
134
|
],
|
|
@@ -6,7 +6,7 @@ Both scenes move together — new pushes old out.
|
|
|
6
6
|
|
|
7
7
|
```js
|
|
8
8
|
tl.to(old, { x: -1920, duration: 0.5, ease: "power3.inOut" }, T);
|
|
9
|
-
tl.fromTo(new, { x: 1920, opacity: 1 }, { x: 0, duration: 0.5, ease: "power3.inOut" }, T);
|
|
9
|
+
tl.fromTo(new, { x: 1920, opacity: 1 }, { x: 0, opacity: 1, duration: 0.5, ease: "power3.inOut" }, T);
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
### Vertical Push
|
|
@@ -15,7 +15,7 @@ Same as push slide but vertical.
|
|
|
15
15
|
|
|
16
16
|
```js
|
|
17
17
|
tl.to(old, { y: -1080, duration: 0.5, ease: "power3.inOut" }, T);
|
|
18
|
-
tl.fromTo(new, { y: 1080, opacity: 1 }, { y: 0, duration: 0.5, ease: "power3.inOut" }, T);
|
|
18
|
+
tl.fromTo(new, { y: 1080, opacity: 1 }, { y: 0, opacity: 1, duration: 0.5, ease: "power3.inOut" }, T);
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
### Elastic Push
|
|
@@ -24,7 +24,7 @@ Push with overshoot bounce on the incoming scene.
|
|
|
24
24
|
|
|
25
25
|
```js
|
|
26
26
|
tl.to(old, { x: -1920, duration: 0.5, ease: "power3.in" }, T);
|
|
27
|
-
tl.fromTo(new, { x: 1920, opacity: 1 }, { x: 30, duration: 0.4, ease: "power4.out" }, T + 0.1);
|
|
27
|
+
tl.fromTo(new, { x: 1920, opacity: 1 }, { x: 30, opacity: 1, duration: 0.4, ease: "power4.out" }, T + 0.1);
|
|
28
28
|
tl.to(new, { x: -15, duration: 0.15, ease: "sine.inOut" }, T + 0.5);
|
|
29
29
|
tl.to(new, { x: 0, duration: 0.1, ease: "sine.out" }, T + 0.65);
|
|
30
30
|
```
|
|
@@ -36,6 +36,6 @@ Old compresses, new expands from opposite side.
|
|
|
36
36
|
```js
|
|
37
37
|
tl.to(old, { scaleX: 0, transformOrigin: "left center", duration: 0.4, ease: "power3.inOut" }, T);
|
|
38
38
|
tl.fromTo(new, { scaleX: 0, transformOrigin: "right center", opacity: 1 },
|
|
39
|
-
{ scaleX: 1, duration: 0.4, ease: "power3.inOut" }, T + 0.1);
|
|
39
|
+
{ scaleX: 1, opacity: 1, duration: 0.4, ease: "power3.inOut" }, T + 0.1);
|
|
40
40
|
tl.set(old, { opacity: 0 }, T + 0.5);
|
|
41
41
|
```
|
|
@@ -13,6 +13,8 @@ description: >
|
|
|
13
13
|
`/hyperframes-core`.
|
|
14
14
|
---
|
|
15
15
|
|
|
16
|
+
**Plugin installs:** Before setup or freshness commands, follow [plugin execution rules](../hyperframes/references/plugin-installation.md) when this skill is inside a HyperFrames plugin. Standalone installs keep the update instructions below.
|
|
17
|
+
|
|
16
18
|
# HyperFrames Audio
|
|
17
19
|
|
|
18
20
|
A mix is a set of relationships, not a stack of processors. Two tracks that each
|
|
@@ -32,10 +34,11 @@ crossfade envelopes, track gain/track volume, volume and effect automation,
|
|
|
32
34
|
ducking/voiceover carve, and the effect chain. `/media-use` owns sourcing,
|
|
33
35
|
generation, and preprocessing.
|
|
34
36
|
|
|
35
|
-
Constant `data-playback-rate` (`0.1..
|
|
37
|
+
Constant `data-playback-rate` (`0.1..10`) is render-safe for picture and
|
|
36
38
|
pitch-preserved sound when matching audio/video elements use the same timing,
|
|
37
|
-
source offset, and rate.
|
|
38
|
-
|
|
39
|
+
source offset, and rate. A speed ramp is a `rate` lane in `data-automation`
|
|
40
|
+
(see `docs/reference/speed-ramps`); it wins over the constant and keeps pitch
|
|
41
|
+
in preview and render. HyperFrames does not
|
|
39
42
|
provide automatic waveform sync or drift correction.
|
|
40
43
|
For copyable cut/crossfade/retime recipes, use `/hyperframes-core` → `references/creator-editing-recipes.md`.
|
|
41
44
|
|
|
@@ -252,11 +255,7 @@ analysis time, so a clip added to the group later is covered without touching
|
|
|
252
255
|
<audio id="vo-middle" data-audio-group="voiceover" …></audio>
|
|
253
256
|
<audio id="vo-outro" data-audio-group="voiceover" …></audio>
|
|
254
257
|
|
|
255
|
-
<audio
|
|
256
|
-
id="music"
|
|
257
|
-
data-fx-carve='{"enabled":true,"sources":["voiceover"],"strength":0.25}'
|
|
258
|
-
…
|
|
259
|
-
></audio>
|
|
258
|
+
<audio id="music" data-fx-carve='{"enabled":true,"sources":["voiceover"],"strength":0.8}' …></audio>
|
|
260
259
|
```
|
|
261
260
|
|
|
262
261
|
A `sources` list naming two or more plain clip ids instead of a group is caught
|
|
@@ -355,17 +354,26 @@ many bands, how wide, how far to favour intelligibility over raw voice energy,
|
|
|
355
354
|
how far the level may drop, how far under the voice to aim. Those six move
|
|
356
355
|
together in any real mix — a gentle carve is a shallow cut in few bands with
|
|
357
356
|
little ducking, a hard one is deeper in more bands with more — so they are one
|
|
358
|
-
relationship written once, in `carveProfile`.
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
357
|
+
relationship written once, in `carveProfile`. `carve.mjs` defaults to `0.8` —
|
|
358
|
+
six bands from 250 Hz to 2.5 kHz cut about 7 dB each and 15 dB at 1.6 kHz, with
|
|
359
|
+
19 dB of level room — because a bed under narration has to get out of the way
|
|
360
|
+
first and be music second; `0.25` (a 6 dB dip in three bands, 6 dB of room) kept
|
|
361
|
+
the bed present but still let it fight the voice, and was judged too weak in
|
|
362
|
+
practice. At `0.5` the dip reaches 10 dB, which is where a carve starts being
|
|
363
|
+
heard as an effect rather than as room for the voice. Drop the strength when the
|
|
364
|
+
bed is the point and the voice is sparse. `0` is spectral only — one band, no
|
|
365
|
+
level match at all.
|
|
366
|
+
|
|
367
|
+
**Carve by default — required whenever music plays under a voice.** A bed
|
|
368
|
+
under any voice track (narration, avatar speech, interview, voiceover) gets a
|
|
369
|
+
carve as part of finishing the mix, not as a polish step to get to if there is
|
|
370
|
+
time. Place both tracks, run the command below (default strength `0.8`; add
|
|
371
|
+
`--bed` / `--voice` when detection picks wrong), confirm the written
|
|
372
|
+
`data-fx-carve`, `data-fx-chain` and `data-automation` with `npx hyperframes check`,
|
|
373
|
+
and only then render. A volume duck on its own is not a finished mix: it leaves
|
|
374
|
+
the voice and the bed fighting in the 1–3 kHz band and costs the bed all of its
|
|
375
|
+
presence for the whole voiceover. Skip the carve only when there is no voice for
|
|
376
|
+
the music to sit under — a music video, a title card, a montage cut to the track.
|
|
369
377
|
|
|
370
378
|
**It always follows the voice.** There is no static mode: a fixed depth thins the
|
|
371
379
|
bed through every pause, and once you have heard both there is no reason to want it.
|
|
@@ -399,9 +407,9 @@ dynamically at the default strength, and prints what it decided:
|
|
|
399
407
|
```
|
|
400
408
|
bed music-bed (name looks like music)
|
|
401
409
|
voice narration (only track left)
|
|
402
|
-
carve strength 0.
|
|
403
|
-
bands 400Hz -
|
|
404
|
-
level
|
|
410
|
+
carve strength 0.8 dynamic
|
|
411
|
+
bands 250Hz -7.4dB q2.06, 400Hz -7.4dB q2.06, 630Hz -7.4dB q2.06, 1000Hz -7.4dB q2.06, 1600Hz -14.8dB q2.06, 2500Hz -7.4dB q2.06
|
|
412
|
+
level 273-point envelope, floor -19.2 dB
|
|
405
413
|
```
|
|
406
414
|
|
|
407
415
|
Name the tracks with `--bed` / `--voice` (repeatable) when the automatic choice is
|
|
@@ -34,17 +34,20 @@ import { pathToFileURL } from "node:url";
|
|
|
34
34
|
* bands and envelopes come out the same either way. */
|
|
35
35
|
const SAMPLE_RATE = 48000;
|
|
36
36
|
|
|
37
|
+
/** Default carve strength. 0.25 kept the bed present but still fighting the voice. */
|
|
38
|
+
export const DEFAULT_STRENGTH = 0.8;
|
|
39
|
+
|
|
37
40
|
const usage = `carve.mjs --comp <file.html> [--bed <elementId>] [--voice <elementId> ...]
|
|
38
41
|
[--strength 0..1] [--dry-run] [--core <dir>]
|
|
39
42
|
|
|
40
43
|
--bed id of the music track that gets carved (detected if omitted)
|
|
41
44
|
--voice id of a voice to make room for; repeatable (detected if omitted)
|
|
42
|
-
--strength how hard to carve, 0..1 (default
|
|
45
|
+
--strength how hard to carve, 0..1 (default ${DEFAULT_STRENGTH})
|
|
43
46
|
--dry-run report what it would write, touch nothing
|
|
44
47
|
--core directory to resolve @hyperframes/core from (default: the comp's)`;
|
|
45
48
|
|
|
46
|
-
function parseArgs(argv) {
|
|
47
|
-
const args = { strength:
|
|
49
|
+
export function parseArgs(argv) {
|
|
50
|
+
const args = { strength: DEFAULT_STRENGTH, dryRun: false, voices: [] };
|
|
48
51
|
for (let i = 0; i < argv.length; i += 1) {
|
|
49
52
|
const flag = argv[i];
|
|
50
53
|
const next = () => {
|
|
@@ -5,7 +5,13 @@ import { mkdirSync, mkdtempSync, rmSync, symlinkSync, writeFileSync } from "node
|
|
|
5
5
|
import { tmpdir } from "node:os";
|
|
6
6
|
import { dirname, join } from "node:path";
|
|
7
7
|
import { fileURLToPath } from "node:url";
|
|
8
|
-
import {
|
|
8
|
+
import {
|
|
9
|
+
DEFAULT_STRENGTH,
|
|
10
|
+
carveSources,
|
|
11
|
+
groupSourceRefusal,
|
|
12
|
+
loadCore,
|
|
13
|
+
parseArgs,
|
|
14
|
+
} from "./carve.mjs";
|
|
9
15
|
|
|
10
16
|
const SCRIPTS_DIR = dirname(fileURLToPath(import.meta.url));
|
|
11
17
|
|
|
@@ -237,3 +243,12 @@ test("members is required, so dropping it cannot silently restore the group form
|
|
|
237
243
|
assert.throws(() => carveSources(voices, bed("bgm", "music")), TypeError);
|
|
238
244
|
assert.throws(() => groupSourceRefusal(voices, bed("bgm", "music")), TypeError);
|
|
239
245
|
});
|
|
246
|
+
|
|
247
|
+
test("the default strength is 0.8, and --strength still overrides it", () => {
|
|
248
|
+
// 0.25 left the bed audibly fighting the voice on narrated builds; a carve at
|
|
249
|
+
// the default has to already be a finished mix. Pinned so it cannot drift back
|
|
250
|
+
// unnoticed — core pins its own DEFAULT_CARVE the same way.
|
|
251
|
+
assert.equal(DEFAULT_STRENGTH, 0.8);
|
|
252
|
+
assert.equal(parseArgs(["--comp", "x.html"]).strength, 0.8);
|
|
253
|
+
assert.equal(parseArgs(["--comp", "x.html", "--strength", "0.25"]).strength, 0.25);
|
|
254
|
+
});
|