dsh-hyperframes 0.3.2 → 0.4.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.
- package/README.en.md +5 -4
- package/README.md +6 -5
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -0
- package/package.json +2 -2
- 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
|
@@ -20,7 +20,7 @@ assemble those from a generic LUT plus handmade CSS vignette/grain/opacity.
|
|
|
20
20
|
**Never `cat`/read a `.cube` file into context.** A 3D LUT is ~size^3 lines of raw numbers (33^3 ≈ 36k lines at the default size). It bloats context and carries zero human/agent-legible signal. To understand or choose a LUT, use `hyperframes grade-compare` to see it rendered, or `cube-validate.mjs` for a one-line `{ok,size}` check. Read `.media/index.md` or `luts/index.json` for the description. Never read the LUT body itself.
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
|
|
23
|
+
npx hyperframes media-use resolve --type grade --intent "warm daylight" --project . --json
|
|
24
24
|
```
|
|
25
25
|
|
|
26
26
|
Preset-first output uses the core runtime vocabulary and does not freeze a file:
|
|
@@ -93,7 +93,7 @@ For a reusable color transform beyond the preset vocabulary, freeze a validated
|
|
|
93
93
|
`.cube` under `.media/luts/` and return a block that references it:
|
|
94
94
|
|
|
95
95
|
```bash
|
|
96
|
-
|
|
96
|
+
npx hyperframes media-use resolve --type grade --intent "teal orange blockbuster" --project . --json
|
|
97
97
|
```
|
|
98
98
|
|
|
99
99
|
```json
|
|
@@ -106,20 +106,20 @@ node <SKILL_DIR>/scripts/resolve.mjs --type grade --intent "teal orange blockbus
|
|
|
106
106
|
Use `lut` when you only need the reusable `.cube` file:
|
|
107
107
|
|
|
108
108
|
```bash
|
|
109
|
-
|
|
109
|
+
npx hyperframes media-use resolve --type lut --intent "teal orange blockbuster" --project .
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
For a describable technical look, author an explicit parametric LUT with `--params`:
|
|
113
113
|
|
|
114
114
|
```bash
|
|
115
|
-
|
|
116
|
-
|
|
115
|
+
npx hyperframes media-use resolve --type lut --params '{"contrast":0.2,"temperature":-0.3}' --project .
|
|
116
|
+
npx hyperframes media-use resolve --type grade --params '{"exposure":0.2}' --project . --json
|
|
117
117
|
```
|
|
118
118
|
|
|
119
119
|
For a LUT generated by your own script, ingest it with `--from`; media-use validates it before registration and rejects invalid or oversized cubes:
|
|
120
120
|
|
|
121
121
|
```bash
|
|
122
|
-
|
|
122
|
+
npx hyperframes media-use resolve --type lut --from custom.cube --project .
|
|
123
123
|
```
|
|
124
124
|
|
|
125
125
|
Parametric math (`buildCube`) cannot reproduce real film stocks or emulsion
|
|
@@ -155,6 +155,6 @@ validates generated or downloaded cubes as it freezes them under
|
|
|
155
155
|
`.media/luts/`.
|
|
156
156
|
|
|
157
157
|
```bash
|
|
158
|
-
|
|
158
|
+
npx hyperframes media-use resolve --type lut --intent "teal orange blockbuster" --project . --json
|
|
159
159
|
node skills/media-use/scripts/lib/cube-validate.mjs .media/luts/lut_001.cube
|
|
160
160
|
```
|
|
@@ -784,7 +784,7 @@ node <SKILL_DIR>/scripts/dither.mjs \
|
|
|
784
784
|
--palette '#17121a,#824c50,#e09873,#f7ddb1' \
|
|
785
785
|
--point-size 3
|
|
786
786
|
|
|
787
|
-
|
|
787
|
+
npx hyperframes media-use resolve \
|
|
788
788
|
--from .media/generated/video_001.atkinson.mp4 --type video --project .
|
|
789
789
|
```
|
|
790
790
|
|
|
@@ -10,7 +10,7 @@ node <SKILL_DIR>/scripts/prefs.mjs record --hyperframes . --key destination --va
|
|
|
10
10
|
node <SKILL_DIR>/scripts/prefs.mjs record --hyperframes . --key style_preset --value pin-and-paper --workflow faceless-explainer
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
Only what the user actually confirmed gets recorded — never an inferred or defaulted value. How workflows consume these (a remembered value becomes the recommended default with a receipt, and never skips a question) is the brief contract's rule: `hyperframes
|
|
13
|
+
Only what the user actually confirmed gets recorded — never an inferred or defaulted value. How workflows consume these (a remembered value becomes the recommended default with a receipt, and never skips a question) is the brief contract's rule: `hyperframes/references/brief-contract.md` § 2, Remembered defaults.
|
|
14
14
|
|
|
15
15
|
## Recipes — frozen video bundles
|
|
16
16
|
|
|
@@ -22,7 +22,7 @@ node <SKILL_DIR>/scripts/recipe.mjs list --hyperframes . --workflow product-laun
|
|
|
22
22
|
node <SKILL_DIR>/scripts/recipe.mjs use --hyperframes . --name weekly-promo # also: resolve.mjs --type recipe --entity weekly-promo
|
|
23
23
|
```
|
|
24
24
|
|
|
25
|
-
The freeze is offered once after the final approval (`hyperframes
|
|
25
|
+
The freeze is offered once after the final approval (`hyperframes/references/review-loop.md` § 4), and the intent layer (`/hyperframes` → `references/intent-interview.md`, step 1) checks for a match before its first question. Adopting a recipe fills the brief, the design spec, and the storyboard skeleton — and unlike preferences it may skip the questions it answers: the bundle was approved as a whole, and adoption itself is the question.
|
|
26
26
|
|
|
27
27
|
## Files
|
|
28
28
|
|
|
@@ -9,7 +9,7 @@ HyperFrames owns media _playback_; media-use owns everything else. Each row is e
|
|
|
9
9
|
| HyperFrames gap | media-use owns it via |
|
|
10
10
|
| ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
11
11
|
| Audio-only, no image/icon | `resolve --type image\|icon` (heygen asset search) |
|
|
12
|
-
| No third-party brand logos | `resolve --type logo` (
|
|
12
|
+
| No third-party brand logos | `resolve --type logo` (theSVG → GitHub org avatar → domain favicon) |
|
|
13
13
|
| No voice / audio generation | `resolve --type voice` (HeyGen TTS free-usage path; optional local Kokoro) + the audio engine (`audio/scripts/audio.mjs`) |
|
|
14
14
|
| Scattered/duplicated audio engine | one consolidated engine under `audio/` (hyperframes-media retired) |
|
|
15
15
|
| No agent media-ops (cut/reframe/transform) | `references/operations.md` + `resolve --from` to register outputs |
|
|
@@ -26,7 +26,7 @@ HyperFrames owns media _playback_; media-use owns everything else. Each row is e
|
|
|
26
26
|
Use `resolve --stats` for a local, shareable report over the current project's `.media/` manifest, the global `~/.media/` cache, and local resolve misses. Human output is compact; add `--json` for a single machine-readable object, and `--days N` to window timestamped records.
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
|
|
29
|
+
npx hyperframes media-use resolve --stats --project . --days 7
|
|
30
30
|
# media-use stats
|
|
31
31
|
# total resolves: 12
|
|
32
32
|
# misses: 2
|
|
@@ -79,7 +79,7 @@ node <SKILL_DIR>/scripts/dither.mjs \
|
|
|
79
79
|
--palette '#0f380f,#306230,#8bac0f,#9bbc0f' \
|
|
80
80
|
--point-size 3
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
npx hyperframes media-use resolve \
|
|
83
83
|
--from source.atkinson.mp4 --type video --project .
|
|
84
84
|
```
|
|
85
85
|
|
|
@@ -112,14 +112,16 @@ engine directly.
|
|
|
112
112
|
# install once: uv venv ~/.venvs/parakeet && VIRTUAL_ENV=~/.venvs/parakeet uv pip install parakeet-mlx
|
|
113
113
|
node <SKILL_DIR>/scripts/transcribe.mjs --input talk.mp4 --out talk.transcribe.json
|
|
114
114
|
|
|
115
|
-
#
|
|
115
|
+
# the hyperframes CLI runs Parakeet on macOS, Linux and Windows once it is installed:
|
|
116
|
+
npx hyperframes models install parakeet # once, ~640 MB, ask the user first
|
|
116
117
|
npx hyperframes transcribe talk.mp4 --engine parakeet # or --engine auto (default)
|
|
117
118
|
```
|
|
118
119
|
|
|
119
|
-
VERIFIED on 24GB: accurate, ~3s (cached) for 8s audio. Parakeet covers
|
|
120
|
-
|
|
121
|
-
installed, transcribe.mjs
|
|
122
|
-
`
|
|
120
|
+
VERIFIED on 24GB: accurate, ~3s (cached) for 8s audio. Parakeet covers 25
|
|
121
|
+
European languages, English included. For other languages, or when parakeet-mlx is not
|
|
122
|
+
installed, transcribe.mjs falls back to `hyperframes transcribe`, which uses the
|
|
123
|
+
CLI's Parakeet when `models install parakeet` has run and whisper.cpp (99
|
|
124
|
+
languages) otherwise. `--engine parakeet|whisper` forces one. (Cohere
|
|
123
125
|
Transcribe tops the leaderboard on paper but its mlx-audio quants produced
|
|
124
126
|
garbage and ran 40-70x slower on a Mac in testing, so it is not wired in.)
|
|
125
127
|
|
|
@@ -145,9 +147,10 @@ Use `--plan` first when you want to inspect the kept segment JSON before encodin
|
|
|
145
147
|
|
|
146
148
|
## Ducking (declare in-composition / bake for export)
|
|
147
149
|
|
|
148
|
-
B1, declare ducking in the composition. `audio-duck.mjs` emits
|
|
149
|
-
|
|
150
|
-
untouched.
|
|
150
|
+
B1, declare ducking in the composition. `audio-duck.mjs` emits a volume lane
|
|
151
|
+
as a `data-automation` attribute. Add it to the background `<audio>` element;
|
|
152
|
+
the source file stays untouched. Lane times are clip-local, so pass
|
|
153
|
+
`--composition` to let the script subtract the element's `data-start`.
|
|
151
154
|
|
|
152
155
|
```bash
|
|
153
156
|
node <SKILL_DIR>/scripts/audio-duck.mjs \
|
|
@@ -156,10 +159,9 @@ node <SKILL_DIR>/scripts/audio-duck.mjs \
|
|
|
156
159
|
--composition index.html
|
|
157
160
|
```
|
|
158
161
|
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
tl.to("#bgm", { volume: 0.6, duration: 0.4 }, 9.87);
|
|
162
|
+
```html
|
|
163
|
+
<!-- auto-duck: #bgm under narration; add to its <audio> element -->
|
|
164
|
+
data-automation='{"version":1,"lanes":[{"target":"volume","points":[{"t":0,"v":0.6},{"t":3.42,"v":0.6},{"t":3.57,"v":0.15},{"t":9.87,"v":0.15},{"t":10.27,"v":0.6}]}]}'
|
|
163
165
|
```
|
|
164
166
|
|
|
165
167
|
B2, bake ducking only for exported or standalone files.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Resolve — command, flags, reuse, adopt, inventory
|
|
2
2
|
|
|
3
3
|
```bash
|
|
4
|
-
|
|
4
|
+
npx hyperframes media-use resolve --type <type> --intent "<description>" --project <dir>
|
|
5
5
|
```
|
|
6
6
|
|
|
7
7
|
Returns one line: `resolved <id> → <path> (<type>, <metadata>)`
|
|
@@ -14,7 +14,7 @@ Returns one line: `resolved <id> → <path> (<type>, <metadata>)`
|
|
|
14
14
|
| `sfx` | Sound effects | Bundled 19-file library + HeyGen catalog |
|
|
15
15
|
| `image` | Photos, backgrounds | HeyGen asset search (75k+ vectors) |
|
|
16
16
|
| `icon` | Icons, symbols | HeyGen asset search (type=icon) |
|
|
17
|
-
| `logo` | Official brand marks |
|
|
17
|
+
| `logo` | Official brand marks | theSVG → GitHub org avatar → domain favicon |
|
|
18
18
|
| `voice` | TTS voiceover | HeyGen TTS free-usage path; optional local Kokoro |
|
|
19
19
|
| `grade` | HyperFrames color-grading blocks | Core preset → look index params/CDN LUT → deterministic cube |
|
|
20
20
|
| `lut` | Reusable `.cube` LUT files | Look index params/CDN LUT → deterministic cube |
|
|
@@ -23,31 +23,31 @@ Returns one line: `resolved <id> → <path> (<type>, <metadata>)`
|
|
|
23
23
|
|
|
24
24
|
```bash
|
|
25
25
|
# Background music
|
|
26
|
-
|
|
26
|
+
npx hyperframes media-use resolve --type bgm --intent "upbeat tech launch" --project .
|
|
27
27
|
# → resolved bgm_001 → .media/audio/bgm/bgm_001.mp3 (bgm, 25s)
|
|
28
28
|
|
|
29
29
|
# Sound effect
|
|
30
|
-
|
|
30
|
+
npx hyperframes media-use resolve --type sfx --intent "whoosh" --project .
|
|
31
31
|
# → resolved sfx_001 → .media/audio/sfx/sfx_001.mp3 (sfx, 0.57s)
|
|
32
32
|
|
|
33
33
|
# Image
|
|
34
|
-
|
|
34
|
+
npx hyperframes media-use resolve --type image --intent "gradient tech background" --project .
|
|
35
35
|
# → resolved image_001 → .media/images/image_001.jpg (image)
|
|
36
36
|
|
|
37
37
|
# Icon
|
|
38
|
-
|
|
38
|
+
npx hyperframes media-use resolve --type icon --intent "rocket" --project .
|
|
39
39
|
# → resolved icon_001 → .media/images/icon_001.png (icon, transparent)
|
|
40
40
|
|
|
41
41
|
# Brand logo (official mark — never redrawn by hand)
|
|
42
|
-
|
|
42
|
+
npx hyperframes media-use resolve --type logo --entity linkedin --intent "LinkedIn logo" --project .
|
|
43
43
|
# → resolved logo_001 → .media/images/logo_001.svg (logo, official mark)
|
|
44
44
|
|
|
45
45
|
# Color grade block
|
|
46
|
-
|
|
46
|
+
npx hyperframes media-use resolve --type grade --intent "warm daylight" --project . --json
|
|
47
47
|
# → {"ok":true,"preset":"warm-daylight","grading":{"preset":"warm-daylight","intensity":1},...}
|
|
48
48
|
|
|
49
49
|
# LUT file
|
|
50
|
-
|
|
50
|
+
npx hyperframes media-use resolve --type lut --intent "teal orange blockbuster" --project .
|
|
51
51
|
# → resolved lut_001 → .media/luts/lut_001.cube (lut)
|
|
52
52
|
```
|
|
53
53
|
|
|
@@ -76,7 +76,7 @@ node <SKILL_DIR>/scripts/resolve.mjs --type lut --intent "teal orange blockbuste
|
|
|
76
76
|
Before resolving bgm/sfx/image/icon/logo/grade/lut, **check what already exists and reuse it when it fits.** media-use does not semantically match for you — you are the judge. It surfaces candidates; you decide.
|
|
77
77
|
|
|
78
78
|
```bash
|
|
79
|
-
|
|
79
|
+
npx hyperframes media-use resolve --type bgm --intent "upbeat tech launch" --candidates --project .
|
|
80
80
|
# [project] upbeat tech launch (25s, heygen.audio.sounds)
|
|
81
81
|
# .media/audio/bgm/bgm_001.wav
|
|
82
82
|
# [global] energetic tech intro (22s, heygen.audio.sounds)
|
|
@@ -105,12 +105,23 @@ The deterministic floor still runs automatically: an identical (case/whitespace-
|
|
|
105
105
|
|
|
106
106
|
Steps 1 and 3 are the **deterministic floor**: they only auto-reuse an exact-normalized match, never a fuzzy one. Semantic reuse ("close enough") is the agent's explicit call via [Reuse before you resolve](#reuse-before-you-resolve) — it never happens automatically. The agent gets back **one line**; candidates, scores, provenance stay on disk.
|
|
107
107
|
|
|
108
|
+
## Stamping provenance when mounting a resolved video
|
|
109
|
+
|
|
110
|
+
`resolve` never writes composition HTML itself — mounting a `<video>` element
|
|
111
|
+
into a composition is always the agent's own edit. When the mounted video's
|
|
112
|
+
manifest record has `provenance.provider === "heygen.video"` (check
|
|
113
|
+
`.media/manifest.jsonl` or the one-line resolve output for the provider name),
|
|
114
|
+
add `data-media-source="heygen"` to that `<video>` tag. Leave the attribute off
|
|
115
|
+
entirely for every other provider (`ltx.local`, an adopted/local file, etc.) —
|
|
116
|
+
this is not a general provider taxonomy, just the one signal render telemetry
|
|
117
|
+
tracks today.
|
|
118
|
+
|
|
108
119
|
## Adopt existing projects
|
|
109
120
|
|
|
110
121
|
Most HyperFrames projects already have assets in `assets/`. media-use adopts them:
|
|
111
122
|
|
|
112
123
|
```bash
|
|
113
|
-
|
|
124
|
+
npx hyperframes media-use resolve --adopt --project .
|
|
114
125
|
# → adopted 9 assets from assets/
|
|
115
126
|
# bgm_001 → assets/bgm/mango-fizz.mp3 (bgm, 146.6s)
|
|
116
127
|
# image_001 → assets/images/avatar.jpg (image, 400×400)
|
|
@@ -12,7 +12,7 @@ heygen auth login --oauth # OAuth = free subscription credits; --api-key bills A
|
|
|
12
12
|
This unlocks the FREE path for bgm/sfx/image/icon catalog search, TTS (voice), and avatar videos. Sign in with `--oauth` — the free allowance rides on the OAuth session (an API key bills API credits instead). **media-use requires heygen >= v0.3.0 uniformly** (the OAuth free-usage path needs it), so `--doctor` nudges older CLIs to update even for API-key-only use. Before resolving anything, verify setup with:
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
|
|
15
|
+
npx hyperframes media-use resolve --doctor
|
|
16
16
|
```
|
|
17
17
|
|
|
18
18
|
## Providers
|
|
@@ -31,7 +31,7 @@ see the ladder and override.
|
|
|
31
31
|
| image | heygen search free-usage path; optional local mflux; codex `image_gen` upsell |
|
|
32
32
|
| voice | heygen tts free-usage path; optional local **Kokoro** (free, on-device) |
|
|
33
33
|
| icon | heygen asset search free-usage path |
|
|
34
|
-
| logo |
|
|
34
|
+
| logo | theSVG (thesvg.org), then GitHub org avatar, then domain favicon (all free) |
|
|
35
35
|
| grade/lut | local core-preset map, params/CDN look index, deterministic `buildCube` fallback |
|
|
36
36
|
| video | heygen avatar video free-usage path (sign-in nudge on auth failure); optional local LTX (`videogen` ladder). Image-to-video / photo-avatar / dub stay manual `heygen` recipes |
|
|
37
37
|
|
|
@@ -59,15 +59,15 @@ tools are OPT-IN alternatives where they exist; install one to unlock its free,
|
|
|
59
59
|
private, on-device path instead of or ahead of HeyGen for that type. Only
|
|
60
60
|
`ffmpeg`/`ffprobe` are strictly required for the tool to run at all.
|
|
61
61
|
|
|
62
|
-
| Tool | Serves | Install
|
|
63
|
-
| ------------------ | ------------------------------------------------------------------------------- |
|
|
64
|
-
| `ffmpeg`/`ffprobe` | adopt probing, smart-grade signalstats, cut, duck bake, loudnorm | system package (`brew install ffmpeg`)
|
|
65
|
-
| `heygen` | catalog (bgm/sfx/image/icon) + TTS (voice) + avatar video — the free-usage path | install through [verified HeyGen release instructions](https://developers.heygen.com/cli), then `heygen auth login --oauth` (needs >= v0.3.0)
|
|
66
|
-
| `mflux-generate` | local image gen (FLUX), best-for-RAM | `uv venv ~/.venvs/mflux && VIRTUAL_ENV=~/.venvs/mflux uv pip install mflux==0.9.6`
|
|
67
|
-
| `codex` | image gen upsell (ChatGPT sub) | Codex CLI, logged in via ChatGPT (owns its own auth)
|
|
68
|
-
| `parakeet-mlx` | local transcription (default ASR, best)
|
|
69
|
-
| `ltx-2-mlx` | local video gen | `git clone https://github.com/dgrauet/ltx-2-mlx && cd ltx-2-mlx && uv sync --all-extras`
|
|
70
|
-
| `npx hyperframes` | Kokoro TTS (voice), whisper.cpp (transcribe
|
|
62
|
+
| Tool | Serves | Install |
|
|
63
|
+
| ------------------ | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
64
|
+
| `ffmpeg`/`ffprobe` | adopt probing, smart-grade signalstats, cut, duck bake, loudnorm | system package (`brew install ffmpeg`) |
|
|
65
|
+
| `heygen` | catalog (bgm/sfx/image/icon) + TTS (voice) + avatar video — the free-usage path | install through [verified HeyGen release instructions](https://developers.heygen.com/cli), then `heygen auth login --oauth` (needs >= v0.3.0) |
|
|
66
|
+
| `mflux-generate` | local image gen (FLUX), best-for-RAM | `uv venv ~/.venvs/mflux && VIRTUAL_ENV=~/.venvs/mflux uv pip install mflux==0.9.6` |
|
|
67
|
+
| `codex` | image gen upsell (ChatGPT sub) | Codex CLI, logged in via ChatGPT (owns its own auth) |
|
|
68
|
+
| `parakeet-mlx` | local transcription (default ASR, best) on Apple Silicon | `uv venv ~/.venvs/parakeet && VIRTUAL_ENV=~/.venvs/parakeet uv pip install parakeet-mlx` |
|
|
69
|
+
| `ltx-2-mlx` | local video gen | `git clone https://github.com/dgrauet/ltx-2-mlx && cd ltx-2-mlx && uv sync --all-extras` |
|
|
70
|
+
| `npx hyperframes` | Kokoro TTS (voice), Parakeet or whisper.cpp (transcribe), remove-background | via the hyperframes CLI; Parakeet on macOS, Windows and glibc 2.32+ Linux: `npx hyperframes models install parakeet`; whisper.cpp is built on first use (Homebrew on macOS, else git+cmake) |
|
|
71
71
|
|
|
72
72
|
The RAM-graded local-model shortlist + exact per-tier install/invoke lives in
|
|
73
73
|
`scripts/lib/local-models.mjs` (the agent can read `describeModelLadder(cap, specs)`
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
5
|
import { parseArgs } from "node:util";
|
|
6
|
-
import { duckKeyframes, speechSpans } from "./lib/duck.mjs";
|
|
6
|
+
import { duckKeyframes, duckLane, speechSpans } from "./lib/duck.mjs";
|
|
7
7
|
import { track } from "./lib/telemetry.mjs";
|
|
8
8
|
|
|
9
9
|
const { values: args } = parseArgs({
|
|
@@ -25,7 +25,7 @@ const { values: args } = parseArgs({
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
if (args.help) {
|
|
28
|
-
console.log(`media-use audio-duck — generate
|
|
28
|
+
console.log(`media-use audio-duck — generate a volume ducking lane (data-automation)
|
|
29
29
|
|
|
30
30
|
Usage:
|
|
31
31
|
node audio-duck.mjs --meta audio_meta.json --target "#bgm"
|
|
@@ -40,8 +40,8 @@ Options:
|
|
|
40
40
|
--sequential Place multi-line meta back to back at composition time
|
|
41
41
|
--gap Extra seconds between sequential lines (default: 0)
|
|
42
42
|
--offsets Explicit placement, "l1=0,l2=3.4" (voice id = start seconds)
|
|
43
|
-
--composition Read target data-volume from this HTML file
|
|
44
|
-
--json Output { spans, keyframes }
|
|
43
|
+
--composition Read target data-volume and data-start from this HTML file
|
|
44
|
+
--json Output { spans, keyframes, lane }
|
|
45
45
|
--help, -h Show this help`);
|
|
46
46
|
process.exit(0);
|
|
47
47
|
}
|
|
@@ -59,7 +59,7 @@ function run() {
|
|
|
59
59
|
if (!args.meta || !args.target) throw new Error("--meta and --target are required");
|
|
60
60
|
const meta = JSON.parse(readFileSync(resolve(args.meta), "utf8"));
|
|
61
61
|
const target = args.target;
|
|
62
|
-
const baseVolume =
|
|
62
|
+
const { baseVolume, clipStart } = readTargetAttrs(args.composition, target);
|
|
63
63
|
const offsets = args.offsets
|
|
64
64
|
? Object.fromEntries(
|
|
65
65
|
args.offsets.split(",").map((pair) => {
|
|
@@ -81,41 +81,33 @@ function run() {
|
|
|
81
81
|
baseVolume,
|
|
82
82
|
});
|
|
83
83
|
|
|
84
|
+
const lane = duckLane(keyframes, { clipStart, baseVolume });
|
|
85
|
+
|
|
84
86
|
if (args.json) {
|
|
85
|
-
console.log(JSON.stringify({ spans, keyframes }));
|
|
87
|
+
console.log(JSON.stringify({ spans, keyframes, lane }));
|
|
86
88
|
return;
|
|
87
89
|
}
|
|
88
90
|
|
|
89
|
-
console.log(
|
|
90
|
-
|
|
91
|
-
);
|
|
92
|
-
for (const keyframe of keyframes) {
|
|
93
|
-
console.log(
|
|
94
|
-
`tl.to(${JSON.stringify(target)}, { volume: ${fmt(keyframe.volume)}, duration: ${fmt(
|
|
95
|
-
keyframe.duration,
|
|
96
|
-
)} }, ${fmt(keyframe.time)});`,
|
|
97
|
-
);
|
|
98
|
-
}
|
|
91
|
+
console.log(`<!-- auto-duck: ${target} under narration; add to its <audio> element -->`);
|
|
92
|
+
console.log(`data-automation='${JSON.stringify(lane)}'`);
|
|
99
93
|
}
|
|
100
94
|
|
|
101
|
-
function
|
|
102
|
-
if (!composition || !target.startsWith("#")) return 1;
|
|
95
|
+
function readTargetAttrs(composition, target) {
|
|
96
|
+
if (!composition || !target.startsWith("#")) return { baseVolume: 1, clipStart: 0 };
|
|
103
97
|
const id = target.slice(1);
|
|
104
98
|
const html = readFileSync(resolve(composition), "utf8");
|
|
105
99
|
// ponytail: regex is enough here because this only reads one attribute from
|
|
106
100
|
// one user-authored composition element, not arbitrary HTML.
|
|
107
101
|
const tag = html.match(new RegExp(`<[^>]*\\bid=["']${escapeRegExp(id)}["'][^>]*>`, "i"))?.[0];
|
|
108
|
-
const
|
|
109
|
-
const volume =
|
|
110
|
-
|
|
102
|
+
const attr = (name) => Number(tag?.match(new RegExp(`\\b${name}=["']([^"']+)["']`, "i"))?.[1]);
|
|
103
|
+
const volume = attr("data-volume");
|
|
104
|
+
const start = attr("data-start");
|
|
105
|
+
return {
|
|
106
|
+
baseVolume: Number.isFinite(volume) ? volume : 1,
|
|
107
|
+
clipStart: Number.isFinite(start) ? start : 0,
|
|
108
|
+
};
|
|
111
109
|
}
|
|
112
110
|
|
|
113
111
|
function escapeRegExp(value) {
|
|
114
112
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
115
113
|
}
|
|
116
|
-
|
|
117
|
-
function fmt(n) {
|
|
118
|
-
return Number(n)
|
|
119
|
-
.toFixed(3)
|
|
120
|
-
.replace(/\.?0+$/, "");
|
|
121
|
-
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { cpSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { execFileSync } from "node:child_process";
|
|
6
|
+
import test from "node:test";
|
|
7
|
+
import { pathToFileURL } from "node:url";
|
|
8
|
+
|
|
9
|
+
process.env.HYPERFRAMES_MEDIA_HOME = mkdtempSync(join(tmpdir(), "media-use-compat-home-"));
|
|
10
|
+
|
|
11
|
+
function run(scriptsDir, script, args) {
|
|
12
|
+
return execFileSync(process.execPath, [join(scriptsDir, script), ...args], {
|
|
13
|
+
encoding: "utf8",
|
|
14
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
test("published memory scripts run without reaching outside the skill", () => {
|
|
19
|
+
const scratchDir = mkdtempSync(join(tmpdir(), "media-use-compat-"));
|
|
20
|
+
const skillDir = join(scratchDir, "media-use");
|
|
21
|
+
cpSync(new URL("..", import.meta.url), skillDir, { recursive: true });
|
|
22
|
+
const scriptsDir = join(skillDir, "scripts");
|
|
23
|
+
const projectDir = join(scratchDir, "project");
|
|
24
|
+
try {
|
|
25
|
+
run(scriptsDir, "prefs.mjs", ["get", "--hyperframes", projectDir, "--json"]);
|
|
26
|
+
run(scriptsDir, "recipe.mjs", ["list", "--hyperframes", projectDir, "--json"]);
|
|
27
|
+
run(scriptsDir, "transcribe.mjs", ["--help"]);
|
|
28
|
+
} finally {
|
|
29
|
+
rmSync(scratchDir, { recursive: true, force: true });
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test("published audio helpers import without the CLI package tree", () => {
|
|
34
|
+
const root = mkdtempSync(join(tmpdir(), "media-use-audio-"));
|
|
35
|
+
const skill = join(root, "media-use");
|
|
36
|
+
try {
|
|
37
|
+
cpSync(new URL("..", import.meta.url), skill, { recursive: true });
|
|
38
|
+
for (const helper of ["heygen.mjs", "tts.mjs"])
|
|
39
|
+
run(join(skill, "audio/scripts/lib"), helper, []);
|
|
40
|
+
} finally {
|
|
41
|
+
rmSync(root, { recursive: true, force: true });
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
for (const name of ["faceless-explainer", "pr-to-video", "product-launch-video"]) {
|
|
46
|
+
test(name + " assembles from its installed directory alone", () => {
|
|
47
|
+
const root = mkdtempSync(join(tmpdir(), "installed-workflow-"));
|
|
48
|
+
try {
|
|
49
|
+
const skill = join(root, name);
|
|
50
|
+
cpSync(new URL("../../" + name, import.meta.url), skill, { recursive: true });
|
|
51
|
+
const project = join(root, "project");
|
|
52
|
+
mkdirSync(join(project, "compositions/frames"), { recursive: true });
|
|
53
|
+
writeFileSync(
|
|
54
|
+
join(project, "STORYBOARD.md"),
|
|
55
|
+
"---\nformat: 1920x1080\nmessage: Test\n---\n\n## Frame 1\n- duration: 3s\n- src: compositions/frames/01-a.html\n",
|
|
56
|
+
);
|
|
57
|
+
writeFileSync(
|
|
58
|
+
join(project, "compositions/frames/01-a.html"),
|
|
59
|
+
'<template><div data-composition-id="01-a" data-duration="3" data-width="1920" data-height="1080"><section class="clip" data-start="0" data-duration="3"></section></div></template>',
|
|
60
|
+
);
|
|
61
|
+
run(join(skill, "scripts"), "assemble-index.mjs", [
|
|
62
|
+
"--hyperframes",
|
|
63
|
+
project,
|
|
64
|
+
"--storyboard",
|
|
65
|
+
join(project, "STORYBOARD.md"),
|
|
66
|
+
]);
|
|
67
|
+
assert.match(readFileSync(join(project, "index.html"), "utf8"), /01-a/);
|
|
68
|
+
importPacketBuilder(join(skill, "scripts/frame-packets.mjs"));
|
|
69
|
+
} finally {
|
|
70
|
+
rmSync(root, { recursive: true, force: true });
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
test("general-video packet builder starts from its installed directory alone", () => {
|
|
76
|
+
const root = mkdtempSync(join(tmpdir(), "installed-packets-"));
|
|
77
|
+
try {
|
|
78
|
+
cpSync(new URL("../../general-video", import.meta.url), root, { recursive: true });
|
|
79
|
+
importPacketBuilder(join(root, "scripts/frame-packets.mjs"));
|
|
80
|
+
} finally {
|
|
81
|
+
rmSync(root, { recursive: true, force: true });
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
function importPacketBuilder(path) {
|
|
86
|
+
execFileSync(
|
|
87
|
+
process.execPath,
|
|
88
|
+
[
|
|
89
|
+
"--input-type=module",
|
|
90
|
+
"-e",
|
|
91
|
+
'const m = await import(process.argv[1]); if (typeof m.buildFramePackets !== "function") throw new Error("missing builder");',
|
|
92
|
+
pathToFileURL(path).href,
|
|
93
|
+
],
|
|
94
|
+
{ stdio: "pipe" },
|
|
95
|
+
);
|
|
96
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
// The one lock on ~/.hyperframes/config.json, for the CLI, its auto-update step and media-use. The auto-update step
|
|
2
|
+
// embeds this function's source, so it must use only its arguments and globals.
|
|
3
|
+
export function withFileLock(lockPath, fs, task) {
|
|
4
|
+
const token = `${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
5
|
+
const started = Date.now();
|
|
6
|
+
for (;;) {
|
|
7
|
+
let fd;
|
|
8
|
+
try {
|
|
9
|
+
fd = fs.openSync(lockPath, "wx");
|
|
10
|
+
} catch (error) {
|
|
11
|
+
if (error.code !== "EEXIST") throw error;
|
|
12
|
+
// Never taken over: a lock older than any hold was left by a process that stopped, and a person removes it.
|
|
13
|
+
let leftover = false;
|
|
14
|
+
try {
|
|
15
|
+
leftover = Date.now() - fs.statSync(lockPath).mtimeMs > 5000;
|
|
16
|
+
} catch {}
|
|
17
|
+
if (leftover || Date.now() - started > 10000)
|
|
18
|
+
throw Object.assign(
|
|
19
|
+
new Error(
|
|
20
|
+
`Settings are locked by another hyperframes process. If none is running, delete ${lockPath}`,
|
|
21
|
+
),
|
|
22
|
+
{ code: "HF_SETTINGS_LOCKED" },
|
|
23
|
+
);
|
|
24
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, 25);
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
fs.writeSync(fd, token);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
fs.rmSync(lockPath, { force: true });
|
|
31
|
+
throw error;
|
|
32
|
+
} finally {
|
|
33
|
+
fs.closeSync(fd);
|
|
34
|
+
}
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
return task();
|
|
39
|
+
} finally {
|
|
40
|
+
// No code removes another's lock, so release needs no check (only a person deleting a live one defeats it).
|
|
41
|
+
try {
|
|
42
|
+
fs.rmSync(lockPath);
|
|
43
|
+
} catch {}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -1,15 +1,6 @@
|
|
|
1
1
|
import { wordListsFromMediaMeta } from "./words.mjs";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
* Speech spans from word timestamps.
|
|
5
|
-
*
|
|
6
|
-
* audio_meta.json word times are relative to EACH LINE'S OWN FILE, not to the
|
|
7
|
-
* composition. Without placement info, multiple lines would overlap at t=0 and
|
|
8
|
-
* merge into one bogus span. Placement options:
|
|
9
|
-
* offsets: { [voiceId]: startSeconds } explicit composition placement
|
|
10
|
-
* sequential: stack lines back to back (plus `gap` seconds between lines)
|
|
11
|
-
* A single word list (bare transcript) needs neither.
|
|
12
|
-
*/
|
|
3
|
+
// audio_meta.json word times are relative to each line's own file.
|
|
13
4
|
export function speechSpans(meta, { mergeGap = 0.6, offsets, sequential = false, gap = 0 } = {}) {
|
|
14
5
|
const merge = Number(mergeGap);
|
|
15
6
|
const lists = wordListsFromMediaMeta(meta);
|
|
@@ -63,6 +54,21 @@ export function duckKeyframes(
|
|
|
63
54
|
return keyframes.sort((a, b) => a.time - b.time);
|
|
64
55
|
}
|
|
65
56
|
|
|
57
|
+
/** Volume lane for `data-automation`: composition-time keyframes as clip-local ramps. */
|
|
58
|
+
export function duckLane(keyframes, { clipStart = 0, baseVolume = 1 } = {}) {
|
|
59
|
+
const start = finiteOr(clipStart, 0);
|
|
60
|
+
const points = [{ t: 0, v: round3(finiteOr(baseVolume, 1)) }];
|
|
61
|
+
const push = (t, v) => {
|
|
62
|
+
if (t > points.at(-1).t) points.push({ t: round3(t), v });
|
|
63
|
+
};
|
|
64
|
+
for (const kf of keyframes) {
|
|
65
|
+
const t = Math.max(0, kf.time - start);
|
|
66
|
+
push(t, points.at(-1).v);
|
|
67
|
+
push(t + kf.duration, kf.volume);
|
|
68
|
+
}
|
|
69
|
+
return { version: 1, lanes: [{ target: "volume", points }] };
|
|
70
|
+
}
|
|
71
|
+
|
|
66
72
|
function mergeIntervals(intervals, mergeGap) {
|
|
67
73
|
const sorted = intervals
|
|
68
74
|
.map((range) => ({ start: round3(range.start), end: round3(range.end) }))
|