dsh-hyperframes 0.3.2 → 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 +4 -3
- package/README.md +5 -4
- 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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { stageCapturedFonts } from "./lib/captured-fonts.mjs";
|
|
2
3
|
// captions.mjs — build the captions sub-composition from STORYBOARD + audio_meta.
|
|
3
4
|
//
|
|
4
5
|
// One mode: `build`. Reads STORYBOARD.md (frame order + durations → cumulative
|
|
@@ -263,7 +264,7 @@ function buildFromSkin(skin, groups, total, W, H, tokens, die, faces = "", fonts
|
|
|
263
264
|
out = fillOnce(
|
|
264
265
|
out,
|
|
265
266
|
/var GROUPS = \[\];/,
|
|
266
|
-
`var GROUPS = ${JSON.stringify(groups)};`,
|
|
267
|
+
`var GROUPS = ${JSON.stringify(groups).replace(/</g, "\\u003c")};`,
|
|
267
268
|
"`var GROUPS = [];` hole",
|
|
268
269
|
);
|
|
269
270
|
out = fillOnce(out, /var DURATION = 0;/, `var DURATION = ${total};`, "`var DURATION = 0;` hole");
|
|
@@ -344,7 +345,8 @@ function brandFontFaces(framePath, hyperframesDir) {
|
|
|
344
345
|
// underscore/hyphen-named brand font (e.g. TT Norms Pro), which is exactly the
|
|
345
346
|
// font_family_without_font_face bug.
|
|
346
347
|
const norm = (s) => s.toLowerCase().replace(/[^a-z0-9]/g, "");
|
|
347
|
-
const
|
|
348
|
+
const captured = stageCapturedFonts(hyperframesDir, families);
|
|
349
|
+
const faces = [...captured.faces];
|
|
348
350
|
const seen = new Set();
|
|
349
351
|
const claimed = new Set(); // each file is claimed by the MOST SPECIFIC family only
|
|
350
352
|
// Match the longest family key first so "TT Norms Pro" can't swallow the files that
|
|
@@ -363,12 +365,13 @@ function brandFontFaces(framePath, hyperframesDir) {
|
|
|
363
365
|
if (!/\.(woff2|woff|ttf|otf)$/i.test(f)) continue;
|
|
364
366
|
if (claimed.has(f)) continue; // a more specific family already took this file
|
|
365
367
|
if (!norm(f.replace(/\.(woff2|woff|ttf|otf)$/i, "")).startsWith(key)) continue;
|
|
368
|
+
claimed.add(f);
|
|
369
|
+
if (captured.families.has(fam.toLowerCase())) continue;
|
|
366
370
|
const w = weightOf(f);
|
|
367
371
|
const style = styleOf(f);
|
|
368
372
|
const dedup = `${fam}-${w}-${style}`;
|
|
369
373
|
if (seen.has(dedup)) continue; // one src per face; assets/fonts wins over capture
|
|
370
374
|
seen.add(dedup);
|
|
371
|
-
claimed.add(f);
|
|
372
375
|
faces.push(
|
|
373
376
|
` @font-face { font-family: '${fam}'; src: url('${d.rel}/${f}') format('${fmtOf(f)}'); font-weight: ${w}; font-style: ${style}; font-display: block; }`,
|
|
374
377
|
);
|
|
@@ -480,7 +483,7 @@ function buildCaptionsHtml(groups, total, W, H) {
|
|
|
480
483
|
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js" integrity="sha384-sG0Hv1tP1lZCk9KQmrIbY/XNwi+OY84GQqhMscbnsoBFqAz8KNCil1kvfL3Hbbk2" crossorigin="anonymous"></script>
|
|
481
484
|
<script>
|
|
482
485
|
(function () {
|
|
483
|
-
var GROUPS = ${JSON.stringify(groups)};
|
|
486
|
+
var GROUPS = ${JSON.stringify(groups).replace(/</g, "\\u003c")};
|
|
484
487
|
var cap = document.getElementById("cap");
|
|
485
488
|
var tl = gsap.timeline({ paused: true });
|
|
486
489
|
GROUPS.forEach(function (g) {
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// Thin wrapper over the shared packet builder in hyperframes
|
|
3
|
+
// Thin wrapper over the shared packet builder in hyperframes — this file only
|
|
4
4
|
// pins the paths that are specific to this workflow skill. The logic (frame
|
|
5
5
|
// splitting, rule citation, packet bounds, `_role.md` assembly) has one owner:
|
|
6
|
-
// ../../hyperframes
|
|
6
|
+
// ../../hyperframes/scripts/lib/frame-packets-core.mjs
|
|
7
7
|
|
|
8
8
|
import { dirname, resolve } from "node:path";
|
|
9
9
|
import { fileURLToPath } from "node:url";
|
|
10
|
-
import * as core from "
|
|
10
|
+
import * as core from "./lib/frame-packets-core.mjs";
|
|
11
11
|
|
|
12
12
|
const SKILL_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
13
13
|
const CONFIG = {
|
|
14
14
|
animationDir: resolve(SKILL_DIR, "../hyperframes-animation"),
|
|
15
|
-
corePath: resolve(SKILL_DIR, "../hyperframes
|
|
15
|
+
corePath: resolve(SKILL_DIR, "../hyperframes/references/frame-worker-core.md"),
|
|
16
16
|
deltaPath: resolve(SKILL_DIR, "sub-agents/frame-worker.md"),
|
|
17
17
|
};
|
|
18
18
|
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
|
|
4
|
+
// Capture preserves subset and variable-axis descriptors in extracted/page.html.
|
|
5
|
+
// Filenames alone cannot identify a face's character coverage.
|
|
6
|
+
export function stageCapturedFonts(projectDir, families) {
|
|
7
|
+
const page = join(projectDir, "capture/extracted/page.html");
|
|
8
|
+
const result = { faces: [], families: new Set(), files: new Set() };
|
|
9
|
+
if (!existsSync(page)) return result;
|
|
10
|
+
const wanted = new Set(families.map((family) => family.toLowerCase()));
|
|
11
|
+
const html = readFileSync(page, "utf8");
|
|
12
|
+
const copied = new Set();
|
|
13
|
+
for (const style of html.matchAll(/<style\b[^>]*>([\s\S]*?)<\/style\s*>/gi)) {
|
|
14
|
+
const css = style[1].replace(/\/\*[\s\S]*?\*\//g, "");
|
|
15
|
+
for (const match of css.matchAll(/@font-face\s*\{([^}]+)\}/gi)) {
|
|
16
|
+
const body = match[1];
|
|
17
|
+
const familyValue = /(?:^|;)\s*font-family\s*:\s*([^;]+)/i.exec(body)?.[1]?.trim();
|
|
18
|
+
if (!familyValue) continue;
|
|
19
|
+
const family = familyValue.replace(/^(['"])(.*)\1$/, "$2");
|
|
20
|
+
if (!wanted.has(family.toLowerCase())) continue;
|
|
21
|
+
result.families.add(family.toLowerCase());
|
|
22
|
+
const source = /(?:^|;)\s*src\s*:\s*([^;]+)/i.exec(body);
|
|
23
|
+
if (!source) continue;
|
|
24
|
+
const sources = localFontSources(source[1], projectDir);
|
|
25
|
+
if (!sources.length) {
|
|
26
|
+
console.warn("Captured font has no downloaded source: " + family);
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
for (const file of sources) {
|
|
30
|
+
if (copied.has(file.name)) continue;
|
|
31
|
+
if (!copied.size) mkdirSync(join(projectDir, "assets/fonts"), { recursive: true });
|
|
32
|
+
copyFileSync(file.source, join(projectDir, file.target));
|
|
33
|
+
copied.add(file.name);
|
|
34
|
+
result.files.add(file.target);
|
|
35
|
+
}
|
|
36
|
+
const src = sources.map((file) => file.css).join(", ");
|
|
37
|
+
const rule = "@font-face{" + body.replace(source[1], src) + "}";
|
|
38
|
+
if (!result.faces.includes(rule)) result.faces.push(rule);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function localFontSources(source, projectDir) {
|
|
45
|
+
const files = [];
|
|
46
|
+
for (const match of source.matchAll(
|
|
47
|
+
/url\(\s*(?:"([^"]+)"|'([^']+)'|([^\s)]+))\s*\)(\s*format\([^)]*\))?/gi,
|
|
48
|
+
)) {
|
|
49
|
+
const url = match[1] ?? match[2] ?? match[3];
|
|
50
|
+
const name = /^assets\/fonts\/([a-z0-9_.-]+\.(?:woff2?|ttf|otf))$/i.exec(url)?.[1];
|
|
51
|
+
if (!name) continue;
|
|
52
|
+
const path = join(projectDir, "capture/assets/fonts", name);
|
|
53
|
+
if (!existsSync(path)) continue;
|
|
54
|
+
const target = "assets/fonts/captured-" + name;
|
|
55
|
+
files.push({ name, source: path, target, css: 'url("' + target + '")' + (match[4] ?? "") });
|
|
56
|
+
}
|
|
57
|
+
return files;
|
|
58
|
+
}
|
|
@@ -1,20 +1,6 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
// its own paths (animation skill, role delta, design-truth resolution, extra packet
|
|
5
|
-
// sections) and delegates everything else here, exactly as the markdown half already
|
|
6
|
-
// does with `references/frame-worker-core.md` + each workflow's delta. One owner for
|
|
7
|
-
// the packet-building logic; the wrappers own only what genuinely differs per workflow.
|
|
8
|
-
//
|
|
9
|
-
// Packet (<frame_id>.md) = project inputs + the frame's exact `## Frame N` block
|
|
10
|
-
// + the blueprint body + every cited rule recipe, inlined — so a worker never opens
|
|
11
|
-
// the shared STORYBOARD.md or any skill document. Cited motions are found
|
|
12
|
-
// mechanically: the explicit `- rules:` field when present, plus every valid rule id
|
|
13
|
-
// (a filename under the animation skill's rules/) mentioned in the block.
|
|
14
|
-
//
|
|
15
|
-
// _role.md = frame-worker-core.md + the workflow's sub-agents/frame-worker.md,
|
|
16
|
-
// concatenated verbatim — the complete worker role, assembled from the two source
|
|
17
|
-
// documents so nothing is hand-maintained twice.
|
|
1
|
+
// Frame packets inline the storyboard frame, blueprint and cited recipes.
|
|
2
|
+
// Workflow wrappers supply resource paths and workflow-specific sections.
|
|
3
|
+
// The role combines the shared worker contract with the workflow delta.
|
|
18
4
|
|
|
19
5
|
import {
|
|
20
6
|
existsSync,
|
|
@@ -100,12 +86,8 @@ export function resourceSections(block, { animationDir, ruleIds, frameId }) {
|
|
|
100
86
|
if (blueprint) {
|
|
101
87
|
const blueprintsDir = join(animationDir, "blueprints");
|
|
102
88
|
const path = join(blueprintsDir, `${blueprint}.md`);
|
|
103
|
-
//
|
|
104
|
-
//
|
|
105
|
-
// the run still reported success. Name it instead — but only when the library
|
|
106
|
-
// is actually there to be named against. The animation skill installs on
|
|
107
|
-
// demand, so an absent blueprints/ is a missing install, not a bad id, and it
|
|
108
|
-
// degrades with a warning exactly like an absent rules/ (see knownRuleIds).
|
|
89
|
+
// An installed library must contain the named blueprint.
|
|
90
|
+
// An absent on-demand library warns, like missing motion rules.
|
|
109
91
|
if (!existsSync(blueprintsDir)) {
|
|
110
92
|
console.warn(
|
|
111
93
|
`frame-packets: no blueprints dir at ${blueprintsDir} — packets will inline no blueprint`,
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// ship standalone: installed via `npx skills add`, a skill's scripts can't reach
|
|
6
6
|
// the monorepo's core package, and the core export points at .ts source that
|
|
7
7
|
// `node` (which runs these scripts) can't load. CANONICAL contract = the core
|
|
8
|
-
// parser + skills/hyperframes
|
|
8
|
+
// parser + skills/hyperframes/references/storyboard-format.md; keep this in
|
|
9
9
|
// lockstep. Behavior: never throws, accepts freeform narrative, recognizes
|
|
10
10
|
// Frame/Beat/Scene headings at H2/H3, preserves unknown keys verbatim under
|
|
11
11
|
// `extra` (keys lowercased). Pure node — no deps.
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"note": "Directional. The injector picks __DX__/__DY__ from the direction and emits the horizontal OR vertical pair (not both).",
|
|
35
35
|
"gsap_template_horizontal": [
|
|
36
36
|
"tl.to(__OLD__, { x: __DX__, duration: __DUR__, ease: \"power3.inOut\" }, __T__);",
|
|
37
|
-
"tl.fromTo(__NEW__, { x: __DXIN__, opacity: 1 }, { x: 0, duration: __DUR__, ease: \"power3.inOut\" }, __T__);"
|
|
37
|
+
"tl.fromTo(__NEW__, { x: __DXIN__, opacity: 1 }, { x: 0, opacity: 1, duration: __DUR__, ease: \"power3.inOut\" }, __T__);"
|
|
38
38
|
],
|
|
39
39
|
"gsap_template_vertical": [
|
|
40
40
|
"tl.to(__OLD__, { y: __DY__, duration: __DUR__, ease: \"power3.inOut\" }, __T__);",
|
|
41
|
-
"tl.fromTo(__NEW__, { y: __DYIN__, opacity: 1 }, { y: 0, duration: __DUR__, ease: \"power3.inOut\" }, __T__);"
|
|
41
|
+
"tl.fromTo(__NEW__, { y: __DYIN__, opacity: 1 }, { y: 0, opacity: 1, duration: __DUR__, ease: \"power3.inOut\" }, __T__);"
|
|
42
42
|
]
|
|
43
43
|
},
|
|
44
44
|
{
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"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.",
|
|
62
62
|
"gsap_template": [
|
|
63
63
|
"tl.to(__OLD__, { scaleX: 0, transformOrigin: \"left center\", duration: __DUR__, ease: \"power3.inOut\" }, __T__);",
|
|
64
|
-
"tl.fromTo(__NEW__, { scaleX: 0, transformOrigin: \"right center\", opacity: 1 }, { scaleX: 1, transformOrigin: \"right center\", duration: __DUR__, ease: \"power3.inOut\" }, __T__);"
|
|
64
|
+
"tl.fromTo(__NEW__, { scaleX: 0, transformOrigin: \"right center\", opacity: 1 }, { scaleX: 1, transformOrigin: \"right center\", opacity: 1, duration: __DUR__, ease: \"power3.inOut\" }, __T__);"
|
|
65
65
|
]
|
|
66
66
|
}
|
|
67
67
|
],
|
|
@@ -248,6 +248,7 @@ function runInject(argv) {
|
|
|
248
248
|
gsapLines.push(
|
|
249
249
|
...buildGsap(rec, outgoing.id, incoming.id, dur, T, spec.direction, CW, CH, die),
|
|
250
250
|
);
|
|
251
|
+
gsapLines.push(`tl.addLabel("hf:transition:${outgoing.id}:${incoming.id}:${rec.name}", ${T});`);
|
|
251
252
|
applied.push({ from: outgoing.id, to: incoming.id, type: rec.name, dur, T });
|
|
252
253
|
}
|
|
253
254
|
|
|
@@ -65,4 +65,6 @@ format: 1920x1080
|
|
|
65
65
|
const outgoing = readFileSync(join(project, "compositions/frames/01-a.html"), "utf8");
|
|
66
66
|
assert.match(outgoing, /data-composition-id="01-a" data-duration="2.5"/);
|
|
67
67
|
assert.match(outgoing, /class="clip"[^>]*data-duration="2.5"/);
|
|
68
|
+
const index = readFileSync(join(project, "index.html"), "utf8");
|
|
69
|
+
assert.match(index, /tl\.addLabel\("hf:transition:01-a:02-b:crossfade", 2\)/);
|
|
68
70
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Frame worker — faceless-explainer delta
|
|
2
2
|
|
|
3
|
-
> The shared law is the core contract above (the packet builder prepends `../hyperframes
|
|
3
|
+
> The shared law is the core contract above (the packet builder prepends `../hyperframes/references/frame-worker-core.md` to this file as `_role.md`) — read the two as one role. This file carries only what's specific to a faceless-explainer frame; you run N-up, **one frame each** — your dispatch carries exactly one packet. Tempted to add a generic GSAP / timeline rule here? Wrong home — it belongs in the core contract or `hyperframes-core`.
|
|
4
4
|
|
|
5
5
|
## Your `focal:` / `roles:` — invented elements
|
|
6
6
|
|
package/skills/figma/SKILL.md
CHANGED
|
@@ -3,6 +3,8 @@ name: figma
|
|
|
3
3
|
description: Import Figma content into a HyperFrames composition — rendered assets, brand tokens, components, storyboard sections → reconstructed motion (frames read as states, not slides) (REST/CLI), connector-assisted motion when available, and shaders from a connector or native export. Use when the user pastes a figma.com link or asks to bring a Figma design, frame, logo, brand, or animation into a video/composition.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
+
**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.
|
|
7
|
+
|
|
6
8
|
> **First, keep this skill fresh — confirm with the user before running:** `npx hyperframes skills update figma`. A fast no-op when everything is current; otherwise it refreshes this skill plus the core domain skills it depends on before you rely on them.
|
|
7
9
|
|
|
8
10
|
# Figma → HyperFrames
|
|
@@ -8,6 +8,8 @@ description: >
|
|
|
8
8
|
Route fresh creation through hyperframes before using this skill.
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
+
**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.
|
|
12
|
+
|
|
11
13
|
# General video
|
|
12
14
|
|
|
13
15
|
Before relying on this workflow, run:
|
|
@@ -20,7 +22,7 @@ A successful no-op means the skill is current. Surface an update failure instead
|
|
|
20
22
|
|
|
21
23
|
## 1. Apply cross-cutting source adapters
|
|
22
24
|
|
|
23
|
-
- **Media:** For any audio, image, icon, logo, voice, grade, LUT, treatment/effect, caption, or media-operation need, load `/media-use` and follow `../media-use/references/resolve.md` (resolve, adopt, reuse) and `../media-use/references/setup-providers.md` (providers, auth). Vague footage feedback and named styles use `../media-use/references/media-treatments.md` before editing; do not improvise supported media effects with CSS/SVG/opacity. Before the first authenticated provider action, run `npx hyperframes auth status` and relay its output verbatim. If signed out, apply the gate in `../hyperframes
|
|
25
|
+
- **Media:** For any audio, image, icon, logo, voice, grade, LUT, treatment/effect, caption, or media-operation need, load `/media-use` and follow `../media-use/references/resolve.md` (resolve, adopt, reuse) and `../media-use/references/setup-providers.md` (providers, auth). Vague footage feedback and named styles use `../media-use/references/media-treatments.md` before editing; do not improvise supported media effects with CSS/SVG/opacity. Before the first authenticated provider action, run `npx hyperframes auth status` and relay its output verbatim. If signed out, apply the gate in `../hyperframes/references/brief-contract.md`: collaborative waits for sign-in or an explicit offline choice; autonomous states the status and continues through an available offline provider. Surface a blocker when no offline provider can satisfy a required capability. Local adoption alone does not require an auth gate.
|
|
24
26
|
- **Figma:** If any input is a `figma.com` URL, run `/figma` first. Build from its exported assets, tokens, components, or storyboard frames. Do not use raw Figma connector calls because they skip SVG sanitization, media provenance, and brand-token binding.
|
|
25
27
|
|
|
26
28
|
These adapters do not change the workflow selected by `/hyperframes`.
|
|
@@ -42,16 +44,16 @@ For a new project, choose a kebab-case directory name from the brief and scaffol
|
|
|
42
44
|
npx hyperframes init "videos/<project>" --non-interactive --example=blank --skill=general-video
|
|
43
45
|
```
|
|
44
46
|
|
|
45
|
-
Then write `BRIEF.md` at the project root using `../hyperframes
|
|
47
|
+
Then write `BRIEF.md` at the project root using `../hyperframes/references/brief-format.md`. In an existing project, the root is the directory containing `hyperframes.json`. Record only the confirmed preference-backed fields named by the brief format, using `node <MEDIA_DIR>/scripts/prefs.mjs record --hyperframes <PROJECT_ROOT>`; never record inferred defaults. Here `<MEDIA_DIR>` is the installed `/media-use` skill directory and `<PROJECT_ROOT>` is the directory containing `hyperframes.json`. If the intent layer adopted a recipe, apply it now with `node <MEDIA_DIR>/scripts/recipe.mjs use --hyperframes <PROJECT_ROOT> --name <name>` and do not ask again.
|
|
46
48
|
|
|
47
49
|
## 3. Interpret the run shape
|
|
48
50
|
|
|
49
|
-
Use only the canonical terms from `../hyperframes
|
|
51
|
+
Use only the canonical terms from `../hyperframes/references/brief-contract.md`:
|
|
50
52
|
|
|
51
53
|
| Field | Meaning | Effect |
|
|
52
54
|
| -------------- | ------------------------------------- | ----------------------------------------------------------------------------------- |
|
|
53
55
|
| `flow` | Who drives | `automation`: choose and execute the route. `companion`: co-create in conversation. |
|
|
54
|
-
| `storyboard` |
|
|
56
|
+
| `storyboard` | Plan, sketch, and review before build | `yes`: run plan and sketch review (`storyboard.html`). `no`: build without it. |
|
|
55
57
|
| derived `mode` | How checkpoint gates behave | Follow the brief contract. Never ask the user to name a mode. |
|
|
56
58
|
|
|
57
59
|
Do not invent synonyms for these states. An ongoing “just build it” signal is handled by the intent layer and arrives as `flow: automation`, `storyboard: no`.
|
|
@@ -88,9 +90,9 @@ These reads are mandatory when their condition matches:
|
|
|
88
90
|
| Any composition HTML or scene layout | `/hyperframes-core`; use `references/determinism-rules.md` for its layout contract |
|
|
89
91
|
| Any non-trivial creation or visual treatment | `/hyperframes-creative` → `references/house-style.md` and `references/video-composition.md` |
|
|
90
92
|
| Any motion, animation, or scene transition | `/hyperframes-animation`; follow its routing to the matching rules, adapters, blueprints, or transition references |
|
|
91
|
-
| `storyboard: yes` | `../hyperframes
|
|
93
|
+
| `storyboard: yes` | `../hyperframes/references/storyboard-format.md` and `../hyperframes/references/review-loop.md` |
|
|
92
94
|
| Any media asset or operation, including narration, BGM, SFX, captions, grading, or transforms | `/media-use`; for framework playback and placement also read `/hyperframes-core` → `references/variables-and-media.md` |
|
|
93
|
-
| Multi-scene assembly | `../hyperframes
|
|
95
|
+
| Multi-scene assembly | `../hyperframes/references/production-loop.md` |
|
|
94
96
|
| `flow: companion`, before the first plan | `/hyperframes-creative` → `references/story-spine.md` and `references/house-style.md`; the nearest genre lens and the full `../hyperframes/references/capability-menu.md` — the ceiling treatment is designed from these, not recalled |
|
|
95
97
|
| A companion capability offer, capture, beat grid, generative video, map, publishing, or cross-workflow capability | `../hyperframes/references/capability-menu.md` |
|
|
96
98
|
| A design spec exists, before final approval | `/hyperframes-creative` → `references/design-adherence.md` |
|
|
@@ -101,8 +103,8 @@ Do not replace these reads with recollection. Progressive disclosure saves conte
|
|
|
101
103
|
|
|
102
104
|
Use this dependency order. Skip a stage only when its input is absent.
|
|
103
105
|
|
|
104
|
-
1. **Plan.** State the viewer arc, structure, rhythm, and duration driver. Use one file for a short single scene; use sub-compositions for three or more hard scene cuts or any reused scene. Read `/hyperframes-creative` → `references/story-spine.md` for narrated arcs, `references/beat-direction.md` for rhythm, and `/hyperframes-core` → `references/composition-patterns.md` for structure. For an open-ended multi-scene brief, expand the prompt through `/hyperframes-creative` → `references/prompt-expansion.md`. A multi-scene plan cites each scene's shape: a blueprint id from `/hyperframes-animation` → `blueprints-index.md` when one fits, or the named rules it composes from `rules-index.md` when none does — motion names come from those indexes, never invented. Story truth decides which scenes exist; the citation dresses them. A multi-scene plan is also recorded as the dispatch artifact: one `## Frame N` block per scene in `STORYBOARD.md` — `status: outline`, a declared `src:`, the blueprint/rules citation, and the beat text — **even when `storyboard: no`**. The block is the dispatch unit; the
|
|
105
|
-
2. **Review the plan when requested.** For `storyboard: yes`, run the shared review loop over those blocks. For `storyboard: no`, continue without
|
|
106
|
+
1. **Plan.** State the viewer arc, structure, rhythm, and duration driver. Use one file for a short single scene; use sub-compositions for three or more hard scene cuts or any reused scene. Read `/hyperframes-creative` → `references/story-spine.md` for narrated arcs, `references/beat-direction.md` for rhythm, and `/hyperframes-core` → `references/composition-patterns.md` for structure. For an open-ended multi-scene brief, expand the prompt through `/hyperframes-creative` → `references/prompt-expansion.md`. A multi-scene plan cites each scene's shape: a blueprint id from `/hyperframes-animation` → `blueprints-index.md` when one fits, or the named rules it composes from `rules-index.md` when none does — motion names come from those indexes, never invented. Story truth decides which scenes exist; the citation dresses them. **Search the live catalog before you plan to build any named look yourself**: for every look, effect, treatment or transition the brief names — "CRT scanlines", "glitch", "film grain", "shimmer sweep", "confetti burst" — run `npx hyperframes catalog --query "<the look, in plain English>" --json` and read the top results before the plan names how that look gets built. The search needs **nothing installed**: no project, no prior `add`, no account. It ranks the whole hosted registry (~400 blocks and components) from any directory, so it also applies to a look the user asks for mid-build. Blocks the plan names are installed at stage 3; hand-author a look only after a search for it came back with nothing that fits. A multi-scene plan is also recorded as the dispatch artifact: one `## Frame N` block per scene in `STORYBOARD.md` — `status: outline`, a declared `src:`, the blueprint/rules citation, and the beat text — **even when `storyboard: no`**. The block is the dispatch unit; the storyboard sheet is only the review surface.
|
|
107
|
+
2. **Review the plan when requested.** For `storyboard: yes`, run the shared review loop over those blocks. For `storyboard: no`, continue without a plan pause or sketch sheet. When a plan pause happens anyway, fold the sub-agent delegation grant (needed by codex for step 4's dispatch) into that pause rather than stopping again later.
|
|
106
108
|
3. **Resolve dependencies.** Install registry blocks before parallel work. Stage user assets, adopt existing media, and resolve only what the brief requires. Start audio early when its timings drive duration.
|
|
107
109
|
4. **Build scenes.** For a short single-scene piece, implement the scene at its most visible moment before adding motion (the confirmed wireframe, when present, is that end state and must not be redrawn), then animate from its cited blueprint or rules — read the full recipe body (`/hyperframes-animation` → `blueprints/<id>.md`, `rules/<id>.md`) before writing motion.
|
|
108
110
|
|
|
@@ -110,10 +112,10 @@ Use this dependency order. Skip a stage only when its input is absent.
|
|
|
110
112
|
|
|
111
113
|
`node <SKILL_DIR>/scripts/frame-packets.mjs --project "$PROJECT_DIR" --storyboard "$PROJECT_DIR/STORYBOARD.md"`
|
|
112
114
|
|
|
113
|
-
The builder writes one bounded packet per scene under `.hyperframes/frame-packets/` (the scene's exact storyboard block + the blueprint body + every cited rule recipe, inlined) and `_role.md` (`../hyperframes
|
|
115
|
+
The builder writes one bounded packet per scene under `.hyperframes/frame-packets/` (the scene's exact storyboard block + the blueprint body + every cited rule recipe, inlined) and `_role.md` (`../hyperframes/references/frame-worker-core.md` + this skill's `sub-agents/frame-worker.md`, concatenated verbatim — the complete worker role). Dispatch the workers — 2–3 scene packets each, all in one wave (`../hyperframes/references/subagent-dispatch.md`); each worker's prompt carries `_role.md` and its packets — paste them in full, or hand the file paths for the worker to read first (equivalent either way) — plus a dispatch context with `PROJECT_DIR`, its `frame_id`s, and canvas size. WAIT on every scene's `compositions/<frame_id>.html` + `compositions/<frame_id>.motion.json`. Workers read only their packets and the design truth file; they never open `STORYBOARD.md` or the skill documents. With no delegation channel, fall back serially: process one packet at a time in this context, still working from the packet alone.
|
|
114
116
|
|
|
115
117
|
5. **Merge motion sidecars.** Collect the workers' `compositions/<frame_id>.motion.json` files and carry their durations and exit/entry vectors into assembly; where the doctrine chain (`/motion-doctrine`) is installed, translate them into the project ledger before stamping seams.
|
|
116
|
-
6. **Assemble.** Mount scenes, media, transitions, captions, and audio using the production loop. Real voice duration overrides estimates.
|
|
118
|
+
6. **Assemble.** Mount scenes, media, transitions, captions, and audio using the production loop. Real voice duration overrides estimates. When a music bed plays under any voice track, carve the bed before verifying: `/hyperframes-audio` → `scripts/carve.mjs --comp index.html`. A volume duck alone does not finish the mix.
|
|
117
119
|
7. **Verify.** Use `npx hyperframes lint` for fast feedback after the first HTML pass and structural changes. For the final gate, run `npx hyperframes check`; it reruns lint internally, so do not run a redundant standalone lint immediately before it. For sub-compositions, inspect midpoint snapshots. For multi-scene work, review the animation map.
|
|
118
120
|
8. **Final approval.** Open the final Studio preview only after checks pass. Ask whether to render or revise. Render only after approval.
|
|
119
121
|
|
|
@@ -162,4 +164,4 @@ A run is complete only when:
|
|
|
162
164
|
- the user approves the final Studio preview before render;
|
|
163
165
|
- the rendered file is verified when a render was requested.
|
|
164
166
|
|
|
165
|
-
After final approval, offer once to freeze the run as a recipe, following `../hyperframes
|
|
167
|
+
After final approval, offer once to freeze the run as a recipe, following `../hyperframes/references/review-loop.md` § 4.
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// Thin wrapper over the shared packet builder in hyperframes
|
|
3
|
+
// Thin wrapper over the shared packet builder in hyperframes — this file pins
|
|
4
4
|
// this workflow's paths plus its one behavioral difference: design truth resolves
|
|
5
5
|
// frame.md → design.md → DESIGN.md (general-video § 6 order). Everything else has
|
|
6
|
-
// one owner: ../../hyperframes
|
|
6
|
+
// one owner: ../../hyperframes/scripts/lib/frame-packets-core.mjs
|
|
7
7
|
|
|
8
8
|
import { existsSync } from "node:fs";
|
|
9
9
|
import { dirname, join, resolve } from "node:path";
|
|
10
10
|
import { fileURLToPath } from "node:url";
|
|
11
|
-
import * as core from "
|
|
11
|
+
import * as core from "./lib/frame-packets-core.mjs";
|
|
12
12
|
|
|
13
13
|
const SKILL_DIR = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
14
14
|
|
|
@@ -22,7 +22,7 @@ function designTruthLine(projectDir) {
|
|
|
22
22
|
|
|
23
23
|
const CONFIG = {
|
|
24
24
|
animationDir: resolve(SKILL_DIR, "../hyperframes-animation"),
|
|
25
|
-
corePath: resolve(SKILL_DIR, "../hyperframes
|
|
25
|
+
corePath: resolve(SKILL_DIR, "../hyperframes/references/frame-worker-core.md"),
|
|
26
26
|
deltaPath: resolve(SKILL_DIR, "sub-agents/frame-worker.md"),
|
|
27
27
|
designTruthLine,
|
|
28
28
|
};
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
// Frame packets inline the storyboard frame, blueprint and cited recipes.
|
|
2
|
+
// Workflow wrappers supply resource paths and workflow-specific sections.
|
|
3
|
+
// The role combines the shared worker contract with the workflow delta.
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
existsSync,
|
|
7
|
+
mkdirSync,
|
|
8
|
+
readFileSync,
|
|
9
|
+
readdirSync,
|
|
10
|
+
realpathSync,
|
|
11
|
+
writeFileSync,
|
|
12
|
+
} from "node:fs";
|
|
13
|
+
import { basename, join, resolve } from "node:path";
|
|
14
|
+
import { pathToFileURL } from "node:url";
|
|
15
|
+
|
|
16
|
+
export function field(block, name) {
|
|
17
|
+
const match = block.match(new RegExp(`^-\\s+${name}:\\s*(.+)$`, "im"));
|
|
18
|
+
return match?.[1]?.trim() ?? null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function splitFrames(storyboard) {
|
|
22
|
+
const matches = [...storyboard.matchAll(/^## Frame\s+([^\n]+)$/gm)];
|
|
23
|
+
return matches.map((match, index) => {
|
|
24
|
+
const start = match.index;
|
|
25
|
+
const end = matches[index + 1]?.index ?? storyboard.length;
|
|
26
|
+
return {
|
|
27
|
+
heading: match[1].trim(),
|
|
28
|
+
block: storyboard.slice(start, end).trim(),
|
|
29
|
+
};
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function frameId(frame) {
|
|
34
|
+
const src = field(frame.block, "src");
|
|
35
|
+
if (!src) throw new Error(`${frame.heading}: missing src`);
|
|
36
|
+
return basename(src).replace(/\.html?$/i, "");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function selectedFile(path, heading) {
|
|
40
|
+
if (!path || !existsSync(path)) return "";
|
|
41
|
+
return `\n## ${heading}\n\n${readFileSync(path, "utf8").trim()}\n`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function escapeRegExp(id) {
|
|
45
|
+
return id.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function knownRuleIds(animationDir) {
|
|
49
|
+
const rulesDir = join(animationDir, "rules");
|
|
50
|
+
if (!existsSync(rulesDir)) {
|
|
51
|
+
console.warn(
|
|
52
|
+
`frame-packets: no rules dir at ${rulesDir} — packets will inline no motion recipes`,
|
|
53
|
+
);
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
return readdirSync(rulesDir)
|
|
57
|
+
.filter((name) => name.endsWith(".md"))
|
|
58
|
+
.map((name) => name.replace(/\.md$/, ""));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function citedRules(block, ruleIds) {
|
|
62
|
+
const explicit = (field(block, "rules") ?? "")
|
|
63
|
+
.split(/[,\s]+/)
|
|
64
|
+
.map((rule) => rule.trim())
|
|
65
|
+
.filter(Boolean);
|
|
66
|
+
const mentioned = ruleIds.filter((id) =>
|
|
67
|
+
new RegExp(`(?<![\\w-])${escapeRegExp(id)}(?![\\w-])`, "i").test(block),
|
|
68
|
+
);
|
|
69
|
+
return [...new Set([...explicit, ...mentioned])].filter((id) => ruleIds.includes(id));
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// visual-design.md tells the author to write the blueprint as `<id> (Reproduce)`
|
|
73
|
+
// or `<id> (Adapt)` — the qualifier is direction for the frame worker, not part of
|
|
74
|
+
// the filename. Parse the field into the id it names (or null for `compose`), so
|
|
75
|
+
// no caller ever resolves a raw field value against the blueprints directory.
|
|
76
|
+
export function blueprintId(block) {
|
|
77
|
+
const raw = field(block, "blueprint");
|
|
78
|
+
if (!raw) return null;
|
|
79
|
+
const id = raw.replace(/\s*\([^)]*\)\s*$/, "").trim();
|
|
80
|
+
return id && id.toLowerCase() !== "compose" ? id : null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function resourceSections(block, { animationDir, ruleIds, frameId }) {
|
|
84
|
+
let sections = "";
|
|
85
|
+
const blueprint = blueprintId(block);
|
|
86
|
+
if (blueprint) {
|
|
87
|
+
const blueprintsDir = join(animationDir, "blueprints");
|
|
88
|
+
const path = join(blueprintsDir, `${blueprint}.md`);
|
|
89
|
+
// An installed library must contain the named blueprint.
|
|
90
|
+
// An absent on-demand library warns, like missing motion rules.
|
|
91
|
+
if (!existsSync(blueprintsDir)) {
|
|
92
|
+
console.warn(
|
|
93
|
+
`frame-packets: no blueprints dir at ${blueprintsDir} — packets will inline no blueprint`,
|
|
94
|
+
);
|
|
95
|
+
} else if (!existsSync(path)) {
|
|
96
|
+
throw new Error(`${frameId ?? "frame"}: blueprint "${blueprint}" has no file at ${path}`);
|
|
97
|
+
} else {
|
|
98
|
+
sections += selectedFile(path, `Selected blueprint: ${blueprint}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
for (const rule of citedRules(block, ruleIds)) {
|
|
102
|
+
sections += selectedFile(
|
|
103
|
+
join(animationDir, "rules", `${rule}.md`),
|
|
104
|
+
`Selected motion rule: ${rule}`,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
return sections;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function buildRolePayload({ corePath, deltaPath, outDir }) {
|
|
111
|
+
const core = readFileSync(corePath, "utf8").trim();
|
|
112
|
+
const delta = readFileSync(deltaPath, "utf8").trim();
|
|
113
|
+
const role = `${core}\n\n---\n\n${delta}\n`;
|
|
114
|
+
mkdirSync(outDir, { recursive: true });
|
|
115
|
+
const path = join(outDir, "_role.md");
|
|
116
|
+
writeFileSync(path, role);
|
|
117
|
+
return { path, bytes: Buffer.byteLength(role) };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function buildFramePackets({
|
|
121
|
+
projectDir,
|
|
122
|
+
storyboardPath = join(projectDir, "STORYBOARD.md"),
|
|
123
|
+
outDir = join(projectDir, ".hyperframes", "frame-packets"),
|
|
124
|
+
maxPacketBytes = 48_000,
|
|
125
|
+
animationDir,
|
|
126
|
+
corePath,
|
|
127
|
+
deltaPath,
|
|
128
|
+
// Per-workflow hooks (all optional):
|
|
129
|
+
// designTruthLine(projectDir) -> the packet's design-truth input line
|
|
130
|
+
// validateFrame(frame, id) -> throw to reject a frame before packing
|
|
131
|
+
// extraSections(block) -> extra packet sections appended after the rule recipes
|
|
132
|
+
designTruthLine = (dir) => `- Design tokens: ${join(resolve(dir), "frame.md")}`,
|
|
133
|
+
validateFrame,
|
|
134
|
+
extraSections,
|
|
135
|
+
}) {
|
|
136
|
+
const storyboard = readFileSync(storyboardPath, "utf8");
|
|
137
|
+
const frames = splitFrames(storyboard);
|
|
138
|
+
if (frames.length === 0) throw new Error("STORYBOARD.md has no frame blocks");
|
|
139
|
+
const ruleIds = knownRuleIds(animationDir);
|
|
140
|
+
|
|
141
|
+
const packets = frames.map((frame) => {
|
|
142
|
+
const id = frameId(frame);
|
|
143
|
+
if (validateFrame) validateFrame(frame, id);
|
|
144
|
+
const packet = `# Frame packet: ${id}\n\n## Project inputs\n\n- Project: ${resolve(projectDir)}\n${designTruthLine(projectDir)}\n- RULES_DIR: ${join(animationDir, "rules")}\n\n## Assigned storyboard block\n\n${frame.block}\n${resourceSections(frame.block, { animationDir, ruleIds, frameId: id })}${extraSections ? extraSections(frame.block) : ""}`;
|
|
145
|
+
const bytes = Buffer.byteLength(packet);
|
|
146
|
+
if (bytes > maxPacketBytes) {
|
|
147
|
+
throw new Error(`${id}: frame packet is ${bytes} bytes (limit ${maxPacketBytes})`);
|
|
148
|
+
}
|
|
149
|
+
return { frameId: id, path: join(outDir, `${id}.md`), bytes, packet };
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
mkdirSync(outDir, { recursive: true });
|
|
153
|
+
for (const { path, packet } of packets) writeFileSync(path, packet);
|
|
154
|
+
buildRolePayload({ corePath, deltaPath, outDir });
|
|
155
|
+
return packets.map(({ packet: _packet, ...result }) => result);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function flag(argv, name, fallback) {
|
|
159
|
+
const index = argv.indexOf(`--${name}`);
|
|
160
|
+
return index >= 0 && argv[index + 1] ? argv[index + 1] : fallback;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// realpath both sides: on macOS /tmp → /private/tmp, and node resolves the main
|
|
164
|
+
// module's symlinks in import.meta.url while argv[1] keeps the invoked spelling —
|
|
165
|
+
// a raw compare silently skips main() when invoked through any symlinked path.
|
|
166
|
+
export function isMainModule(importMetaUrl) {
|
|
167
|
+
if (!process.argv[1]) return false;
|
|
168
|
+
try {
|
|
169
|
+
return pathToFileURL(realpathSync(process.argv[1])).href === importMetaUrl;
|
|
170
|
+
} catch {
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
export function runCli({ buildFramePackets: build, buildRolePayload: buildRole }) {
|
|
176
|
+
const argv = process.argv.slice(2);
|
|
177
|
+
const projectDir = resolve(flag(argv, "project", "."));
|
|
178
|
+
const outDir = resolve(flag(argv, "out-dir", join(projectDir, ".hyperframes", "frame-packets")));
|
|
179
|
+
try {
|
|
180
|
+
const packets = build({
|
|
181
|
+
projectDir,
|
|
182
|
+
storyboardPath: resolve(flag(argv, "storyboard", join(projectDir, "STORYBOARD.md"))),
|
|
183
|
+
outDir,
|
|
184
|
+
});
|
|
185
|
+
const role = buildRole({ outDir });
|
|
186
|
+
console.log(`✓ frame packets: ${packets.length} bounded packet(s)`);
|
|
187
|
+
for (const packet of packets)
|
|
188
|
+
console.log(` ${packet.frameId}: ${packet.bytes} bytes → ${packet.path}`);
|
|
189
|
+
console.log(` worker role: ${role.bytes} bytes → ${role.path}`);
|
|
190
|
+
} catch (error) {
|
|
191
|
+
console.error(`✗ frame packets: ${error.message}`);
|
|
192
|
+
process.exit(1);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Frame worker — general-video delta
|
|
2
2
|
|
|
3
|
-
> The shared law is the core contract above (the packet builder prepends
|
|
3
|
+
> The shared law is the core contract above (the packet builder prepends `../../hyperframes/references/frame-worker-core.md` to this file as `_role.md`) — read the two as one role. This file carries only what's specific to a general-video scene; you run N-up, **one scene each** — your dispatch carries exactly one packet. Tempted to add a generic GSAP / timeline rule here? Wrong home — it belongs in the core contract or `hyperframes-core`.
|
|
4
4
|
|
|
5
5
|
## Your scene is invented, not captured
|
|
6
6
|
|