@ignix-social/editor 0.1.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/LICENSE +190 -0
- package/NOTICE +54 -0
- package/README.md +23 -0
- package/bin/ignix-editor.mjs +8 -0
- package/package.json +53 -0
- package/patches/index.mjs +53 -0
- package/scripts/build-ffmpeg-macos.sh +35 -0
- package/scripts/build-whisper-macos.sh +21 -0
- package/scripts/vendor.mjs +41 -0
- package/skills/ignix-editor/SKILL.md +132 -0
- package/src/audio.mjs +31 -0
- package/src/binaries.json +46 -0
- package/src/binaries.mjs +83 -0
- package/src/cli.mjs +254 -0
- package/src/prepare.mjs +74 -0
- package/src/runtime/ignix-frame.js +92 -0
- package/src/transcribe.mjs +71 -0
- package/src/validate.mjs +71 -0
- package/templates/blank/index.html +41 -0
- package/vendor/hyperframes/README.md +181 -0
- package/vendor/hyperframes/UPSTREAM.json +12 -0
- package/vendor/hyperframes/bin/hyperframes-localize-fonts.mjs +12 -0
- package/vendor/hyperframes/bin/hyperframes.mjs +11 -0
- package/vendor/hyperframes/dist/add-LR3ZR2A5.js +79 -0
- package/vendor/hyperframes/dist/agentPromptGenerator-VIIPZCJ3.js +143 -0
- package/vendor/hyperframes/dist/animatedGifPrep-P2T6YM7Z.js +34 -0
- package/vendor/hyperframes/dist/asset-BE2DOV72.js +26 -0
- package/vendor/hyperframes/dist/assetCataloger-VBLPHX24.js +340 -0
- package/vendor/hyperframes/dist/auth-RCQB2ZT7.js +60 -0
- package/vendor/hyperframes/dist/autoUpdate-RJAX3DAZ.js +268 -0
- package/vendor/hyperframes/dist/backgroundChecks-H2LCUIMJ.js +61 -0
- package/vendor/hyperframes/dist/backgroundChecksWorker.js +26 -0
- package/vendor/hyperframes/dist/batchRender-FT7AP7XH.js +355 -0
- package/vendor/hyperframes/dist/beat-analyzer.global.js +338 -0
- package/vendor/hyperframes/dist/beats-Y2EOP72P.js +309 -0
- package/vendor/hyperframes/dist/benchmark-MZ7GY3JW.js +231 -0
- package/vendor/hyperframes/dist/browser-HUTAMRQE.js +237 -0
- package/vendor/hyperframes/dist/bundleWithLocalizedFonts-5QOPOB5D.js +52 -0
- package/vendor/hyperframes/dist/capture-RLZA6EMR.js +4079 -0
- package/vendor/hyperframes/dist/capture-SZZ4IYJK.js +290 -0
- package/vendor/hyperframes/dist/captureFile-LYOJOUIE.js +15 -0
- package/vendor/hyperframes/dist/captureTimeout-PA4FYWT5.js +27 -0
- package/vendor/hyperframes/dist/catalog-KYU55EWR.js +1001 -0
- package/vendor/hyperframes/dist/check-TCG4PXLR.js +1697 -0
- package/vendor/hyperframes/dist/checkBrowser-RPMO4OW5.js +1032 -0
- package/vendor/hyperframes/dist/chunk-2EAXUCCE.js +88 -0
- package/vendor/hyperframes/dist/chunk-2EGFTPWD.js +1077 -0
- package/vendor/hyperframes/dist/chunk-2PSPARWP.js +6058 -0
- package/vendor/hyperframes/dist/chunk-2YN64IN5.js +5747 -0
- package/vendor/hyperframes/dist/chunk-3GXQPCJC.js +682 -0
- package/vendor/hyperframes/dist/chunk-3ZP5DXE7.js +15 -0
- package/vendor/hyperframes/dist/chunk-4NWOGZZS.js +1990 -0
- package/vendor/hyperframes/dist/chunk-4PFZPP2N.js +587 -0
- package/vendor/hyperframes/dist/chunk-4THIAPBL.js +128 -0
- package/vendor/hyperframes/dist/chunk-4YYJOFKS.js +28 -0
- package/vendor/hyperframes/dist/chunk-54HJ63Q2.js +29 -0
- package/vendor/hyperframes/dist/chunk-5ETJX6WM.js +89 -0
- package/vendor/hyperframes/dist/chunk-5IAKAQA7.js +389 -0
- package/vendor/hyperframes/dist/chunk-5Z63TBTX.js +37 -0
- package/vendor/hyperframes/dist/chunk-6BEFEWFB.js +25 -0
- package/vendor/hyperframes/dist/chunk-6CSYCFQV.js +68 -0
- package/vendor/hyperframes/dist/chunk-6CTIGJY7.js +154 -0
- package/vendor/hyperframes/dist/chunk-7HG4BFIN.js +93 -0
- package/vendor/hyperframes/dist/chunk-7JZ4FXP2.js +118 -0
- package/vendor/hyperframes/dist/chunk-A2Z4Z4VL.js +2961 -0
- package/vendor/hyperframes/dist/chunk-AMKC3AXA.js +25 -0
- package/vendor/hyperframes/dist/chunk-AVUUN2XD.js +4847 -0
- package/vendor/hyperframes/dist/chunk-AWDFDFI3.js +46 -0
- package/vendor/hyperframes/dist/chunk-AWNBM3MZ.js +94 -0
- package/vendor/hyperframes/dist/chunk-BXCMXMJQ.js +73 -0
- package/vendor/hyperframes/dist/chunk-BZ56MTDX.js +6 -0
- package/vendor/hyperframes/dist/chunk-CFKU7HTK.js +171 -0
- package/vendor/hyperframes/dist/chunk-CWPVM2QV.js +308 -0
- package/vendor/hyperframes/dist/chunk-DPVXBVLL.js +31292 -0
- package/vendor/hyperframes/dist/chunk-DQBY7FRR.js +397 -0
- package/vendor/hyperframes/dist/chunk-E6RPWJVC.js +213 -0
- package/vendor/hyperframes/dist/chunk-EISRN4E6.js +294 -0
- package/vendor/hyperframes/dist/chunk-EOVYQ3IG.js +143 -0
- package/vendor/hyperframes/dist/chunk-F3WZGU7C.js +479 -0
- package/vendor/hyperframes/dist/chunk-FCSIGXXP.js +366 -0
- package/vendor/hyperframes/dist/chunk-FI4I7CME.js +56 -0
- package/vendor/hyperframes/dist/chunk-FLWXXDNS.js +15 -0
- package/vendor/hyperframes/dist/chunk-GK4AIFIH.js +11171 -0
- package/vendor/hyperframes/dist/chunk-GMECXFAN.js +57 -0
- package/vendor/hyperframes/dist/chunk-GULOKZLI.js +155 -0
- package/vendor/hyperframes/dist/chunk-H4YZZ2VQ.js +68 -0
- package/vendor/hyperframes/dist/chunk-H6QMKUYA.js +477 -0
- package/vendor/hyperframes/dist/chunk-HBBJFK6I.js +273 -0
- package/vendor/hyperframes/dist/chunk-HRUGC23L.js +212 -0
- package/vendor/hyperframes/dist/chunk-HVW7ABXD.js +19 -0
- package/vendor/hyperframes/dist/chunk-HW6OYASV.js +344 -0
- package/vendor/hyperframes/dist/chunk-HWKCIWQT.js +3578 -0
- package/vendor/hyperframes/dist/chunk-I465DBM6.js +1214 -0
- package/vendor/hyperframes/dist/chunk-IGLEPPTN.js +24 -0
- package/vendor/hyperframes/dist/chunk-IGNAAHS3.js +433 -0
- package/vendor/hyperframes/dist/chunk-IHFUKJOR.js +85 -0
- package/vendor/hyperframes/dist/chunk-IQ3OUQ5Z.js +213 -0
- package/vendor/hyperframes/dist/chunk-ISN5GRYI.js +20 -0
- package/vendor/hyperframes/dist/chunk-IUZFXWSV.js +446 -0
- package/vendor/hyperframes/dist/chunk-JH556Q42.js +647 -0
- package/vendor/hyperframes/dist/chunk-JTHMTOMQ.js +601 -0
- package/vendor/hyperframes/dist/chunk-K2EQN4VU.js +405 -0
- package/vendor/hyperframes/dist/chunk-K2FTXJYH.js +16044 -0
- package/vendor/hyperframes/dist/chunk-K4WIOZFP.js +32 -0
- package/vendor/hyperframes/dist/chunk-K4WKGXRC.js +18 -0
- package/vendor/hyperframes/dist/chunk-KBJUXVOJ.js +172 -0
- package/vendor/hyperframes/dist/chunk-KC5XXX3X.js +590 -0
- package/vendor/hyperframes/dist/chunk-KNU5COPB.js +29 -0
- package/vendor/hyperframes/dist/chunk-KZI44OPA.js +185 -0
- package/vendor/hyperframes/dist/chunk-L3YOGIPG.js +48 -0
- package/vendor/hyperframes/dist/chunk-LAOCA3MQ.js +189 -0
- package/vendor/hyperframes/dist/chunk-LCSMOLGX.js +312 -0
- package/vendor/hyperframes/dist/chunk-LFGJWOVA.js +61 -0
- package/vendor/hyperframes/dist/chunk-LHSR3M4M.js +498 -0
- package/vendor/hyperframes/dist/chunk-LYNI3FOL.js +123 -0
- package/vendor/hyperframes/dist/chunk-M2WBOQ2Q.js +54 -0
- package/vendor/hyperframes/dist/chunk-MRF4AMKD.js +104 -0
- package/vendor/hyperframes/dist/chunk-MWB3ZIFM.js +852 -0
- package/vendor/hyperframes/dist/chunk-NGKM64BP.js +39 -0
- package/vendor/hyperframes/dist/chunk-NXMYHJAL.js +43 -0
- package/vendor/hyperframes/dist/chunk-OAF4XJOW.js +192 -0
- package/vendor/hyperframes/dist/chunk-OFQWTKPW.js +117 -0
- package/vendor/hyperframes/dist/chunk-P6LJ4Y32.js +4662 -0
- package/vendor/hyperframes/dist/chunk-PBN6GBJE.js +108 -0
- package/vendor/hyperframes/dist/chunk-PDAMK4Q5.js +28 -0
- package/vendor/hyperframes/dist/chunk-PFCFR3KZ.js +20 -0
- package/vendor/hyperframes/dist/chunk-PJ3HDUCY.js +108 -0
- package/vendor/hyperframes/dist/chunk-PMRBLBUP.js +152 -0
- package/vendor/hyperframes/dist/chunk-PPQUYWTW.js +240 -0
- package/vendor/hyperframes/dist/chunk-Q5X2B5WT.js +29 -0
- package/vendor/hyperframes/dist/chunk-Q7IU7MOR.js +351 -0
- package/vendor/hyperframes/dist/chunk-QC4FJVLM.js +371 -0
- package/vendor/hyperframes/dist/chunk-QNYYOUU3.js +1318 -0
- package/vendor/hyperframes/dist/chunk-RDNNAKEP.js +161 -0
- package/vendor/hyperframes/dist/chunk-RMHUQGRK.js +657 -0
- package/vendor/hyperframes/dist/chunk-RQVDTPGD.js +6 -0
- package/vendor/hyperframes/dist/chunk-RVCWIIZ7.js +68 -0
- package/vendor/hyperframes/dist/chunk-S3D6GE5W.js +72 -0
- package/vendor/hyperframes/dist/chunk-S3S4TGEH.js +424 -0
- package/vendor/hyperframes/dist/chunk-S7NPLFWV.js +11395 -0
- package/vendor/hyperframes/dist/chunk-SHB5VDMH.js +51 -0
- package/vendor/hyperframes/dist/chunk-TCLGPL65.js +860 -0
- package/vendor/hyperframes/dist/chunk-THXFSPLV.js +40 -0
- package/vendor/hyperframes/dist/chunk-TJSTGSAW.js +354 -0
- package/vendor/hyperframes/dist/chunk-TQFG7HTI.js +1024 -0
- package/vendor/hyperframes/dist/chunk-TVCRUG2S.js +265 -0
- package/vendor/hyperframes/dist/chunk-TWWSYAKJ.js +24 -0
- package/vendor/hyperframes/dist/chunk-U7CZBDMV.js +27 -0
- package/vendor/hyperframes/dist/chunk-UEZXMWG3.js +139 -0
- package/vendor/hyperframes/dist/chunk-UYEZTK4U.js +61 -0
- package/vendor/hyperframes/dist/chunk-VC76R6W2.js +27 -0
- package/vendor/hyperframes/dist/chunk-VFCKXTBB.js +159 -0
- package/vendor/hyperframes/dist/chunk-VWG7OQKU.js +22 -0
- package/vendor/hyperframes/dist/chunk-VXVRPIJA.js +105 -0
- package/vendor/hyperframes/dist/chunk-WBLXWOYK.js +15 -0
- package/vendor/hyperframes/dist/chunk-WERLJGIC.js +20 -0
- package/vendor/hyperframes/dist/chunk-WMQNIQDJ.js +2057 -0
- package/vendor/hyperframes/dist/chunk-WPHMNO44.js +4528 -0
- package/vendor/hyperframes/dist/chunk-X5HWXQPU.js +113 -0
- package/vendor/hyperframes/dist/chunk-X7MTZ4T2.js +6 -0
- package/vendor/hyperframes/dist/chunk-XH4DSOS5.js +59 -0
- package/vendor/hyperframes/dist/chunk-XS4EJSKU.js +23 -0
- package/vendor/hyperframes/dist/chunk-XT5P4QMO.js +181 -0
- package/vendor/hyperframes/dist/chunk-XT7X6QCP.js +6 -0
- package/vendor/hyperframes/dist/chunk-XUHOIDKG.js +6 -0
- package/vendor/hyperframes/dist/chunk-XUXGIA7H.js +485 -0
- package/vendor/hyperframes/dist/chunk-XZABUQTX.js +113 -0
- package/vendor/hyperframes/dist/chunk-Y6W4DVPS.js +356 -0
- package/vendor/hyperframes/dist/chunk-YEIFI443.js +44 -0
- package/vendor/hyperframes/dist/chunk-YQZNILVH.js +375 -0
- package/vendor/hyperframes/dist/chunk-Z27A7NUB.js +65 -0
- package/vendor/hyperframes/dist/chunk-Z6B37SNM.js +3081 -0
- package/vendor/hyperframes/dist/chunk-ZJUKFZ2P.js +10954 -0
- package/vendor/hyperframes/dist/chunk-ZKDMAOFU.js +32 -0
- package/vendor/hyperframes/dist/chunk-ZMXUQLI2.js +17219 -0
- package/vendor/hyperframes/dist/chunk-ZTZ7NCJT.js +58 -0
- package/vendor/hyperframes/dist/chunk-ZTZA4UWZ.js +108 -0
- package/vendor/hyperframes/dist/clean-W57E5YQ3.js +293 -0
- package/vendor/hyperframes/dist/cli.js +495 -0
- package/vendor/hyperframes/dist/cloud-FFTJGZ24.js +70 -0
- package/vendor/hyperframes/dist/cloudrun-AJUTHUEA.js +763 -0
- package/vendor/hyperframes/dist/colors-HKWSZCGK.js +15 -0
- package/vendor/hyperframes/dist/commands/contrast-audit.browser.js +459 -0
- package/vendor/hyperframes/dist/commands/layout-audit.browser.js +2102 -0
- package/vendor/hyperframes/dist/commands/motion-sample.browser.js +74 -0
- package/vendor/hyperframes/dist/commands/motion-signature.browser.js +374 -0
- package/vendor/hyperframes/dist/compare-AYCTT55F.js +421 -0
- package/vendor/hyperframes/dist/compiler-QO36EXLS.js +121 -0
- package/vendor/hyperframes/dist/component-VFFR2O7T.js +176 -0
- package/vendor/hyperframes/dist/compositions-QTVN3U2A.js +228 -0
- package/vendor/hyperframes/dist/contactSheet-27SRU7A4.js +22 -0
- package/vendor/hyperframes/dist/delete-ZAKYCB7I.js +114 -0
- package/vendor/hyperframes/dist/deploy-MX76RZ36.js +101 -0
- package/vendor/hyperframes/dist/destroy-H2TZBYHH.js +42 -0
- package/vendor/hyperframes/dist/deterministicFonts-HAEMV4TM.js +50 -0
- package/vendor/hyperframes/dist/dist-EWXJGN63.js +129 -0
- package/vendor/hyperframes/dist/dist-FNNGCKFS.js +29 -0
- package/vendor/hyperframes/dist/dist-S3PJNPXQ.js +392 -0
- package/vendor/hyperframes/dist/docker/Dockerfile.render +65 -0
- package/vendor/hyperframes/dist/docs/compositions.md +67 -0
- package/vendor/hyperframes/dist/docs/data-attributes.md +27 -0
- package/vendor/hyperframes/dist/docs/examples.md +19 -0
- package/vendor/hyperframes/dist/docs/gsap.md +26 -0
- package/vendor/hyperframes/dist/docs/rendering.md +35 -0
- package/vendor/hyperframes/dist/docs/troubleshooting.md +29 -0
- package/vendor/hyperframes/dist/docs-QAPJEGLS.js +131 -0
- package/vendor/hyperframes/dist/doctor-AI7C3FON.js +67 -0
- package/vendor/hyperframes/dist/dom-IROKGVJI.js +14 -0
- package/vendor/hyperframes/dist/dotEnv-AECLXQSO.js +14 -0
- package/vendor/hyperframes/dist/events-7LALYNKZ.js +92 -0
- package/vendor/hyperframes/dist/events-FQY3HGKZ.js +88 -0
- package/vendor/hyperframes/dist/feedback-WCMDMSTK.js +472 -0
- package/vendor/hyperframes/dist/ffmpeg-QIUFEFTY.js +35 -0
- package/vendor/hyperframes/dist/figma-64WY462P.js +63 -0
- package/vendor/hyperframes/dist/fontData.generated-NXAOI4GH.js +13 -0
- package/vendor/hyperframes/dist/fontLocalizeCli.js +132 -0
- package/vendor/hyperframes/dist/get-FPOMJMZB.js +103 -0
- package/vendor/hyperframes/dist/gpuPolicy-2ZUZE5D6.js +38 -0
- package/vendor/hyperframes/dist/grade-compare-E2CKPST4.js +647 -0
- package/vendor/hyperframes/dist/gsapParser-DIYYX6JT.js +2846 -0
- package/vendor/hyperframes/dist/gsapParserAcorn-E3GEIRZB.js +28 -0
- package/vendor/hyperframes/dist/help-YRQIDDML.js +197 -0
- package/vendor/hyperframes/dist/history-PP5NDRV3.js +571 -0
- package/vendor/hyperframes/dist/hyperframe-runtime.js +1081 -0
- package/vendor/hyperframes/dist/hyperframe.manifest.json +22 -0
- package/vendor/hyperframes/dist/hyperframe.runtime.iife.js +1081 -0
- package/vendor/hyperframes/dist/hyperframes-player.global.js +474 -0
- package/vendor/hyperframes/dist/hyperframes-slideshow.global.js +149 -0
- package/vendor/hyperframes/dist/info-SEX3B7JL.js +153 -0
- package/vendor/hyperframes/dist/init-U3AKHO5B.js +1147 -0
- package/vendor/hyperframes/dist/inspect-Q3K6EDEK.js +97 -0
- package/vendor/hyperframes/dist/installer-K6O5WF44.js +37 -0
- package/vendor/hyperframes/dist/keyframes-DC64JCI3.js +2602 -0
- package/vendor/hyperframes/dist/lambda-D7UMN4DJ.js +451 -0
- package/vendor/hyperframes/dist/layout-XSPPDHOO.js +86 -0
- package/vendor/hyperframes/dist/lib-TPG2ZMAX.js +128 -0
- package/vendor/hyperframes/dist/lint-7DQZE7L3.js +164 -0
- package/vendor/hyperframes/dist/lintProject-OHBBM3DJ.js +27 -0
- package/vendor/hyperframes/dist/list-4K5MVDQX.js +162 -0
- package/vendor/hyperframes/dist/login-NTX4OWXL.js +377 -0
- package/vendor/hyperframes/dist/logout-Q654A3SI.js +100 -0
- package/vendor/hyperframes/dist/manager-67P2XFXQ.js +34 -0
- package/vendor/hyperframes/dist/manager-CT3D67CG.js +38 -0
- package/vendor/hyperframes/dist/manager-GFN75DM4.js +30 -0
- package/vendor/hyperframes/dist/media-treatment-5FYAOPNL.js +972 -0
- package/vendor/hyperframes/dist/media-use-4XXGABIL.js +113 -0
- package/vendor/hyperframes/dist/models-C4E4IWJD.js +137 -0
- package/vendor/hyperframes/dist/motionShot-S4MIGMT5.js +614 -0
- package/vendor/hyperframes/dist/normalize-O76AC4HE.js +333 -0
- package/vendor/hyperframes/dist/normalize-audio-CSFTXLXD.js +276 -0
- package/vendor/hyperframes/dist/open-2ZD6BHZG.js +115 -0
- package/vendor/hyperframes/dist/pipeline-TNGWUZQC.js +54 -0
- package/vendor/hyperframes/dist/play-CTMUXX6E.js +349 -0
- package/vendor/hyperframes/dist/policies-FSDZVS2E.js +292 -0
- package/vendor/hyperframes/dist/preflight-SMNV6RW2.js +45 -0
- package/vendor/hyperframes/dist/present-WQVHV5CR.js +350 -0
- package/vendor/hyperframes/dist/preview-JOJXTH75.js +1820 -0
- package/vendor/hyperframes/dist/producer-ECLEN5RP.js +13 -0
- package/vendor/hyperframes/dist/progress-FBIEEB7Y.js +73 -0
- package/vendor/hyperframes/dist/projectConfig-HYJMJ5BY.js +56 -0
- package/vendor/hyperframes/dist/publication-HQ5Y3KBM.js +29 -0
- package/vendor/hyperframes/dist/publish-VHDYQASC.js +430 -0
- package/vendor/hyperframes/dist/refresh-K24ETHMA.js +53 -0
- package/vendor/hyperframes/dist/remove-background-W2YX2NVH.js +253 -0
- package/vendor/hyperframes/dist/render-AO5VX3YI.js +177 -0
- package/vendor/hyperframes/dist/render-LNO62LEL.js +2367 -0
- package/vendor/hyperframes/dist/render-TTQI7TGN.js +796 -0
- package/vendor/hyperframes/dist/render-batch-YH7CTWNY.js +284 -0
- package/vendor/hyperframes/dist/renderCancellation-JPIHE47X.js +35 -0
- package/vendor/hyperframes/dist/renderSetupWorker.js +79 -0
- package/vendor/hyperframes/dist/resolver-IZ647GBZ.js +38 -0
- package/vendor/hyperframes/dist/runtimeVersion.js +18 -0
- package/vendor/hyperframes/dist/screenshotCapture-ECBTLCU6.js +179 -0
- package/vendor/hyperframes/dist/shaderTransitionWorker.js +44 -0
- package/vendor/hyperframes/dist/sherpa-KKLNW6U2.js +314 -0
- package/vendor/hyperframes/dist/sherpaWorker.js +77 -0
- package/vendor/hyperframes/dist/sites-TNVKZS73.js +52 -0
- package/vendor/hyperframes/dist/skill-ZHVLH7KX.js +15 -0
- package/vendor/hyperframes/dist/skills/hyperframes/SKILL.md +152 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/brief-contract.md +108 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/brief-format.md +72 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/capability-menu.md +47 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/frame-worker-core.md +80 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/intent-interview.md +73 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/pitch-round.md +40 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/plugin-installation.md +43 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/production-loop.md +26 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/review-loop.md +37 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/route-briefs.md +11 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/embedded-captions.md +11 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/faceless-explainer.md +12 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/general-video.md +12 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/motion-graphics.md +11 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/music-to-video.md +12 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/pr-to-video.md +28 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/product-launch-video.md +13 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/remotion-to-hyperframes.md +9 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/slideshow.md +11 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/routes/talking-head-recut.md +11 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/script-format.md +52 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/skill-lifecycle.md +35 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/storyboard-format.md +99 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/subagent-dispatch.md +35 -0
- package/vendor/hyperframes/dist/skills/hyperframes/references/workflow-catalog.md +10 -0
- package/vendor/hyperframes/dist/skills/hyperframes/scripts/lib/frame-packets-core.mjs +194 -0
- package/vendor/hyperframes/dist/skills/hyperframes/scripts/plugin-cli.mjs +88 -0
- package/vendor/hyperframes/dist/skills/hyperframes/scripts/plugin-cli.test.mjs +117 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/SKILL.md +189 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/beats.md +19 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/cloud.md +163 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/cloudrun.md +62 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/compare-and-batch.md +105 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/doctor-browser.md +57 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/init-and-scaffold.md +74 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/lambda.md +185 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/lint-validate-inspect.md +132 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/preview-render.md +193 -0
- package/vendor/hyperframes/dist/skills/hyperframes-cli/references/upgrade-info-misc.md +134 -0
- package/vendor/hyperframes/dist/skills/media-use/SKILL.md +100 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/CREDITS.md +35 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/chime.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/click-soft.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/click.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/error.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/glitch-1.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/glitch-2.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/glitch-3.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/impact-bass-1.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/impact-bass-2.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/key-press.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/manifest.json +97 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/notification.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/ping.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/pop.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/riser.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/sparkle.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/typing.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/whoosh-cinematic.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/whoosh-short.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/assets/sfx/whoosh.mp3 +0 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/bgm.md +76 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/captions/authoring.md +163 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/captions/motion.md +87 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/captions/transcript-handling.md +97 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/remove-background.md +143 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/requirements.md +29 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/sfx.md +42 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/transcribe.md +52 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/tts-to-captions.md +35 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/references/tts.md +260 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/audio.mjs +311 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/audio.test.mjs +159 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/gemini-pipeline.test.mjs +131 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-tts.mjs +122 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-tts.test.mjs +38 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-voice.mjs +98 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/heygen-voice.test.mjs +233 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/audio-meta.mjs +39 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/audio-meta.test.mjs +136 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/bgm-volume.mjs +4 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/bgm.mjs +257 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/bgm.test.mjs +74 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/concurrency.mjs +14 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/concurrency.test.mjs +41 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth.mjs +43 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth.py +52 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth.test.mjs +86 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-auth_test.py +90 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-tts.mjs +122 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/gemini-tts.test.mjs +243 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/heygen.mjs +197 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/heygen.test.mjs +185 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/media-record.mjs +114 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/media-record.test.mjs +205 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/python.mjs +77 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/python.test.mjs +136 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/sfx.mjs +165 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/sfx.test.mjs +121 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/tts.mjs +389 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/tts.spawn.test.mjs +158 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lib/tts.test.mjs +230 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/lyria-recipe.py +136 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/wait-bgm.mjs +175 -0
- package/vendor/hyperframes/dist/skills/media-use/audio/scripts/wait-bgm.test.mjs +108 -0
- package/vendor/hyperframes/dist/skills/media-use/luts/README.md +28 -0
- package/vendor/hyperframes/dist/skills/media-use/luts/index.json +57 -0
- package/vendor/hyperframes/dist/skills/media-use/references/audio.md +20 -0
- package/vendor/hyperframes/dist/skills/media-use/references/grading.md +160 -0
- package/vendor/hyperframes/dist/skills/media-use/references/media-treatment-recipes.md +929 -0
- package/vendor/hyperframes/dist/skills/media-use/references/media-treatments.md +202 -0
- package/vendor/hyperframes/dist/skills/media-use/references/memory.md +37 -0
- package/vendor/hyperframes/dist/skills/media-use/references/meta.md +61 -0
- package/vendor/hyperframes/dist/skills/media-use/references/operations.md +327 -0
- package/vendor/hyperframes/dist/skills/media-use/references/resolve.md +150 -0
- package/vendor/hyperframes/dist/skills/media-use/references/setup-providers.md +80 -0
- package/vendor/hyperframes/dist/skills/media-use/references/telemetry-dashboard.md +49 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/audio-duck.mjs +113 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/compatibility.test.mjs +96 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/dither.mjs +328 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/dither.test.mjs +176 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/eval.mjs +369 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/adopt.mjs +128 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/adopt.test.mjs +95 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/bgm-provider.mjs +20 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/brand-provider.mjs +59 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/bundled-sfx-provider.mjs +119 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/bundled-sfx-provider.test.mjs +139 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cache.mjs +148 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/candidates.mjs +91 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/candidates.test.mjs +155 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/codex-provider.mjs +161 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/codex-provider.test.mjs +34 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/config-lock.d.mts +3 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/config-lock.mjs +45 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/config-lock.test.mjs +79 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/coverage.test.mjs +136 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-build.mjs +181 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-build.test.mjs +80 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-validate.mjs +198 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cube-validate.test.mjs +125 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cutlist.mjs +184 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/cutlist.test.mjs +162 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/duck.mjs +95 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/duck.test.mjs +153 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/error-diffusion.mjs +230 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/error-diffusion.test.mjs +102 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/ff-binaries.mjs +37 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/freeze.mjs +72 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/freeze.test.mjs +138 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/grade-analyzer.mjs +265 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/grade-analyzer.test.mjs +285 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-cli.mjs +191 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-cli.test.mjs +301 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-search.mjs +45 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-search.test.mjs +49 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-video-provider.mjs +138 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/heygen-video-provider.test.mjs +435 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/image-provider.mjs +44 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/index-gen.mjs +63 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-media-search.mjs +32 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-models.mjs +318 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-models.test.mjs +220 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-run.mjs +78 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/local-run.test.mjs +121 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/logo-provider.mjs +244 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/logo-provider.test.mjs +298 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/ltx-video-provider.mjs +94 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/ltx-video-provider.test.mjs +316 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/lut-preset-provider.mjs +271 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/lut-preset-provider.test.mjs +199 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/manifest.d.mts +19 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/manifest.mjs +279 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/manifest.test.mjs +397 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/match.mjs +47 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-fetch.mjs +85 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-fetch.test.mjs +197 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-home.mjs +20 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-home.test.mjs +61 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-search.d.mts +9 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/media-search.mjs +107 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/mflux-provider.mjs +128 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/mflux-provider.test.mjs +174 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/misses.mjs +49 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/misses.test.mjs +89 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/npx-sync.mjs +31 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/npx-sync.test.mjs +50 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/parakeet-words.mjs +27 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/parakeet-words.test.mjs +44 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/prefs-store.mjs +180 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/prefs-store.test.mjs +189 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/probe.mjs +41 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/probe.test.mjs +148 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/providers.mjs +5 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/recipe-store.mjs +367 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/recipe-store.test.mjs +367 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/registry.mjs +212 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/registry.test.mjs +262 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/search.mjs +24 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/search.test.mjs +32 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/sfx-provider.mjs +23 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/specs.mjs +132 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/specs.test.mjs +157 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/stats.mjs +117 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/stats.test.mjs +165 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/svg-sanitize.mjs +21 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/telemetry.mjs +210 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/telemetry.test.mjs +437 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/test-home.test.mjs +10 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/transcriptCutFade.mjs +21 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/transcriptCutFade.test.mjs +33 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/tts-local-provider.mjs +94 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/tts-local-provider.test.mjs +72 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/usage.mjs +57 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/usage.test.mjs +54 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/voice-provider.mjs +57 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/voice-provider.test.mjs +46 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/lib/words.mjs +18 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/prefs.mjs +70 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/recipe.mjs +103 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/resolve-plugin.test.mjs +62 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/resolve.mjs +1369 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/transcribe.mjs +194 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/transcribe.test.mjs +112 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/transcript-cut.mjs +270 -0
- package/vendor/hyperframes/dist/skills/media-use/scripts/transcript-cut.test.mjs +117 -0
- package/vendor/hyperframes/dist/skills-MJ2J4GEM.js +808 -0
- package/vendor/hyperframes/dist/skillsUpdateCheck-TKTYQN5R.js +26 -0
- package/vendor/hyperframes/dist/slideshow-EJ4IMY6P.js +24 -0
- package/vendor/hyperframes/dist/snapshot-KIVDUUMN.js +875 -0
- package/vendor/hyperframes/dist/src-6YQBJGWR.js +202 -0
- package/vendor/hyperframes/dist/src-PVYUYV3M.js +471 -0
- package/vendor/hyperframes/dist/state-KAXGHF77.js +26 -0
- package/vendor/hyperframes/dist/staticProjectServer-7EU666GS.js +49 -0
- package/vendor/hyperframes/dist/status-YM52BQ6S.js +311 -0
- package/vendor/hyperframes/dist/studio/assets/hyperframes-player-Cp8e_Zst.js +473 -0
- package/vendor/hyperframes/dist/studio/assets/index-BX3KHhGX.js +71 -0
- package/vendor/hyperframes/dist/studio/assets/index-CASEBNy2.js +1 -0
- package/vendor/hyperframes/dist/studio/assets/index-D11atkBt.css +1 -0
- package/vendor/hyperframes/dist/studio/assets/index-DMTt9nTf.js +531 -0
- package/vendor/hyperframes/dist/studio/assets/index-oE1pOdAy.js +399 -0
- package/vendor/hyperframes/dist/studio/chunk-5VSXRGIX.js +948 -0
- package/vendor/hyperframes/dist/studio/chunk-5VSXRGIX.js.map +1 -0
- package/vendor/hyperframes/dist/studio/chunk-7UQWVN52.js +938 -0
- package/vendor/hyperframes/dist/studio/chunk-7UQWVN52.js.map +1 -0
- package/vendor/hyperframes/dist/studio/chunk-EEXSYY5F.js +190 -0
- package/vendor/hyperframes/dist/studio/chunk-EEXSYY5F.js.map +1 -0
- package/vendor/hyperframes/dist/studio/chunk-FOEID72M.js +1441 -0
- package/vendor/hyperframes/dist/studio/chunk-FOEID72M.js.map +1 -0
- package/vendor/hyperframes/dist/studio/chunk-PZ5AY32C.js +10 -0
- package/vendor/hyperframes/dist/studio/chunk-PZ5AY32C.js.map +1 -0
- package/vendor/hyperframes/dist/studio/chunk-TDWGXBUT.js +1103 -0
- package/vendor/hyperframes/dist/studio/chunk-TDWGXBUT.js.map +1 -0
- package/vendor/hyperframes/dist/studio/domEditingLayers-IEVLO54Z.js +47 -0
- package/vendor/hyperframes/dist/studio/domEditingLayers-IEVLO54Z.js.map +1 -0
- package/vendor/hyperframes/dist/studio/favicon.svg +14 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/audio.svg +7 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/captions.svg +5 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/composition.svg +12 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/image.svg +18 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/music.svg +10 -0
- package/vendor/hyperframes/dist/studio/icons/timeline/text.svg +3 -0
- package/vendor/hyperframes/dist/studio/index.css +165 -0
- package/vendor/hyperframes/dist/studio/index.css.map +1 -0
- package/vendor/hyperframes/dist/studio/index.d.ts +4296 -0
- package/vendor/hyperframes/dist/studio/index.html +23 -0
- package/vendor/hyperframes/dist/studio/index.js +99693 -0
- package/vendor/hyperframes/dist/studio/index.js.map +1 -0
- package/vendor/hyperframes/dist/studio/player.d.ts +30 -0
- package/vendor/hyperframes/dist/studio/player.js +10 -0
- package/vendor/hyperframes/dist/studio/player.js.map +1 -0
- package/vendor/hyperframes/dist/studio/styles/tailwind-preset.d.ts +39 -0
- package/vendor/hyperframes/dist/studio/styles/tailwind-preset.js +50 -0
- package/vendor/hyperframes/dist/studio/styles/tailwind-preset.js.map +1 -0
- package/vendor/hyperframes/dist/studio/styles.css +1 -0
- package/vendor/hyperframes/dist/studio/ui.d.ts +296 -0
- package/vendor/hyperframes/dist/studio/ui.js +66 -0
- package/vendor/hyperframes/dist/studio/ui.js.map +1 -0
- package/vendor/hyperframes/dist/studio-api-PNQZRPX5.js +136 -0
- package/vendor/hyperframes/dist/studioSelectionClient-IUUPKUHZ.js +25 -0
- package/vendor/hyperframes/dist/studioServer-UWRBPIOJ.js +1457 -0
- package/vendor/hyperframes/dist/synthesize-K62TIZWI.js +182 -0
- package/vendor/hyperframes/dist/system-EZYZNUFD.js +44 -0
- package/vendor/hyperframes/dist/telemetry-2YC4SGQU.js +144 -0
- package/vendor/hyperframes/dist/telemetry-QMYM4WME.js +95 -0
- package/vendor/hyperframes/dist/templates/_shared/AGENTS.md +107 -0
- package/vendor/hyperframes/dist/templates/_shared/CLAUDE.md +107 -0
- package/vendor/hyperframes/dist/templates/blank/index.html +55 -0
- package/vendor/hyperframes/dist/templates/from-file/index.html +75 -0
- package/vendor/hyperframes/dist/templates/warm-grain/compositions/captions.html +154 -0
- package/vendor/hyperframes/dist/templates/warm-grain/compositions/graphics.html +162 -0
- package/vendor/hyperframes/dist/templates/warm-grain/compositions/intro.html +87 -0
- package/vendor/hyperframes/dist/templates/warm-grain/index.html +264 -0
- package/vendor/hyperframes/dist/templates/warm-grain/registry-item.json +34 -0
- package/vendor/hyperframes/dist/timeline-77Z3BBQM.js +1377 -0
- package/vendor/hyperframes/dist/tokens-OBGTYE4Z.js +92 -0
- package/vendor/hyperframes/dist/transcribe-7NVFHCGA.js +387 -0
- package/vendor/hyperframes/dist/transcribe-BNSJRR4M.js +62 -0
- package/vendor/hyperframes/dist/tts-P3LIPIL5.js +234 -0
- package/vendor/hyperframes/dist/updateCheck-UDWIJ4ZQ.js +39 -0
- package/vendor/hyperframes/dist/upgrade-CT3CPO3E.js +231 -0
- package/vendor/hyperframes/dist/urlDownloader-H6WRI2UE.js +39 -0
- package/vendor/hyperframes/dist/usage-EC3KFUIJ.js +2139 -0
- package/vendor/hyperframes/dist/validate-65QDZJWZ.js +70 -0
- package/vendor/hyperframes/dist/video-FGSGKRSV.js +261 -0
- package/vendor/hyperframes/dist/workspaceBuildCheck-TOLGAI4T.js +133 -0
- package/vendor/hyperframes/package.json +80 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
4
|
+
import {
|
|
5
|
+
existsSync,
|
|
6
|
+
readFileSync,
|
|
7
|
+
writeFileSync,
|
|
8
|
+
copyFileSync,
|
|
9
|
+
renameSync,
|
|
10
|
+
mkdtempSync,
|
|
11
|
+
rmSync,
|
|
12
|
+
} from "node:fs";
|
|
13
|
+
import { homedir, tmpdir } from "node:os";
|
|
14
|
+
import { basename, extname, join, resolve } from "node:path";
|
|
15
|
+
import { parseArgs, stripVTControlCharacters } from "node:util";
|
|
16
|
+
import { mergeTokensToWords } from "./lib/parakeet-words.mjs";
|
|
17
|
+
import { track } from "./lib/telemetry.mjs";
|
|
18
|
+
import { resolveNpxInvocation } from "./lib/npx-sync.mjs";
|
|
19
|
+
|
|
20
|
+
// The DEFAULT local transcription path. Prefers NVIDIA Parakeet-TDT via
|
|
21
|
+
// parakeet-mlx, which beats whisper.cpp on the Open ASR Leaderboard (~6.05% vs
|
|
22
|
+
// 7.44% avg WER, and 4.73% vs 5.96% on noisy test-other) and is 5-10x faster
|
|
23
|
+
// with native punctuation. Emits { text, words:[{text,start,end}] } (word
|
|
24
|
+
// timestamps merged from Parakeet's sub-word tokens) for transcript-cut /
|
|
25
|
+
// captions / the audio engine.
|
|
26
|
+
//
|
|
27
|
+
// Parakeet v3 covers English + 25 European languages. For other languages, or
|
|
28
|
+
// when parakeet-mlx is not installed, it falls back to whisper.cpp via
|
|
29
|
+
// `hyperframes transcribe` (99 languages; the CLI resolves/builds whisper.cpp
|
|
30
|
+
// on first use — it is not bundled). `--engine` forces one.
|
|
31
|
+
|
|
32
|
+
const { values: args } = parseArgs({
|
|
33
|
+
options: {
|
|
34
|
+
input: { type: "string", short: "i" },
|
|
35
|
+
out: { type: "string", short: "o" },
|
|
36
|
+
engine: { type: "string", default: "auto" }, // auto | parakeet | whisper
|
|
37
|
+
model: { type: "string", default: "mlx-community/parakeet-tdt-0.6b-v3" },
|
|
38
|
+
json: { type: "boolean", default: false },
|
|
39
|
+
help: { type: "boolean", short: "h", default: false },
|
|
40
|
+
},
|
|
41
|
+
strict: true,
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
if (args.help) {
|
|
45
|
+
console.log(`media-use transcribe: better-than-whisper local ASR (Parakeet), whisper.cpp fallback
|
|
46
|
+
|
|
47
|
+
Usage:
|
|
48
|
+
node transcribe.mjs --input audio.wav [--out audio.transcribe.json] [--engine auto|parakeet|whisper]
|
|
49
|
+
|
|
50
|
+
Parakeet (default) beats whisper.cpp on accuracy + speed for English/European
|
|
51
|
+
languages; whisper.cpp (99 languages) is the fallback. Install Parakeet once:
|
|
52
|
+
npx hyperframes models install parakeet (macOS, Windows, Linux with glibc 2.32+)
|
|
53
|
+
uv venv ~/.venvs/parakeet && VIRTUAL_ENV=~/.venvs/parakeet uv pip install parakeet-mlx (Apple Silicon)`);
|
|
54
|
+
process.exit(0);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (!args.input) {
|
|
58
|
+
console.error("error: --input is required");
|
|
59
|
+
process.exit(2);
|
|
60
|
+
}
|
|
61
|
+
const inputPath = resolve(args.input);
|
|
62
|
+
if (!existsSync(inputPath)) {
|
|
63
|
+
console.error(`error: input not found: ${inputPath}`);
|
|
64
|
+
process.exit(2);
|
|
65
|
+
}
|
|
66
|
+
const outPath = resolve(
|
|
67
|
+
args.out || `${inputPath.slice(0, -extname(inputPath).length)}.transcribe.json`,
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
// Locate the parakeet-mlx runner the same way the CLI does: env override, then
|
|
71
|
+
// the documented ~/.venvs/parakeet install, then PATH. Checking the venv (not
|
|
72
|
+
// just PATH) is what keeps a user who followed the install docs verbatim from
|
|
73
|
+
// silently falling through to whisper. Returns the runner path, or null.
|
|
74
|
+
function resolveParakeet() {
|
|
75
|
+
for (const p of [
|
|
76
|
+
process.env.HYPERFRAMES_PARAKEET,
|
|
77
|
+
join(homedir(), ".venvs", "parakeet", "bin", "parakeet-mlx"),
|
|
78
|
+
]) {
|
|
79
|
+
if (p && existsSync(p)) return p;
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
execFileSync("parakeet-mlx", ["--help"], {
|
|
83
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
84
|
+
timeout: 20000,
|
|
85
|
+
});
|
|
86
|
+
return "parakeet-mlx";
|
|
87
|
+
} catch {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Write via a sibling temp + atomic rename so a SIGKILL mid-write can't leave a
|
|
93
|
+
// truncated transcript at outPath (downstream reads it as valid JSON).
|
|
94
|
+
function atomicWrite(target, data) {
|
|
95
|
+
const tmp = `${target}.tmp-${process.pid}`;
|
|
96
|
+
writeFileSync(tmp, data);
|
|
97
|
+
renameSync(tmp, target);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function report(engine, wordCount) {
|
|
101
|
+
if (args.json) console.log(JSON.stringify({ ok: true, out: outPath, engine, words: wordCount }));
|
|
102
|
+
else
|
|
103
|
+
console.log(
|
|
104
|
+
`transcribed ${basename(inputPath)} -> ${outPath}${wordCount != null ? ` (${wordCount} words,` : " ("}${engine})`,
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function runParakeet(runner) {
|
|
109
|
+
const workDir = mkdtempSync(join(tmpdir(), "media-use-asr-"));
|
|
110
|
+
try {
|
|
111
|
+
execFileSync(
|
|
112
|
+
runner,
|
|
113
|
+
[inputPath, "--model", args.model, "--output-format", "json", "--output-dir", workDir],
|
|
114
|
+
{ stdio: ["ignore", "pipe", "pipe"], timeout: 1_800_000 },
|
|
115
|
+
);
|
|
116
|
+
const jsonPath = join(workDir, `${basename(inputPath, extname(inputPath))}.json`);
|
|
117
|
+
if (!existsSync(jsonPath)) throw new Error("parakeet produced no JSON");
|
|
118
|
+
const merged = mergeTokensToWords(JSON.parse(readFileSync(jsonPath, "utf8")));
|
|
119
|
+
atomicWrite(outPath, JSON.stringify(merged, null, 2));
|
|
120
|
+
report("parakeet", merged.words.length);
|
|
121
|
+
} finally {
|
|
122
|
+
rmSync(workDir, { recursive: true, force: true });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// The hyperframes CLI (its Parakeet, else whisper.cpp built on first use — see
|
|
127
|
+
// SKILL.md): writes transcript.json into --dir; relocate to --out.
|
|
128
|
+
function runCli(cliEngine) {
|
|
129
|
+
const workDir = mkdtempSync(join(tmpdir(), "media-use-whisper-"));
|
|
130
|
+
try {
|
|
131
|
+
// On Windows a bare "npx" is npx.cmd, which execFileSync cannot exec
|
|
132
|
+
// (spawnSync npx ENOENT) — resolveNpxInvocation reroutes it through
|
|
133
|
+
// node + npx-cli.js (and throws actionably when it can't), same
|
|
134
|
+
// mechanism as the audio engine's TTS spawns.
|
|
135
|
+
// Under auto or parakeet the CLI may run its own Parakeet; --json says which engine ran.
|
|
136
|
+
const resolved = resolveNpxInvocation(
|
|
137
|
+
["hyperframes", "transcribe", inputPath, "--dir", workDir, "--engine", cliEngine, "--json"],
|
|
138
|
+
{ stdio: ["ignore", "pipe", "pipe"], timeout: 1_800_000 },
|
|
139
|
+
);
|
|
140
|
+
let stdout;
|
|
141
|
+
try {
|
|
142
|
+
stdout = String(execFileSync(resolved.cmd, resolved.args, resolved.opts));
|
|
143
|
+
} catch (e) {
|
|
144
|
+
// stderr holds spinner redraws and --json prints the reason on stdout, so keep the last lines.
|
|
145
|
+
const tail = stripVTControlCharacters(`${e.stderr ?? ""}\n${e.stdout ?? ""}`)
|
|
146
|
+
.split(/[\r\n]+/)
|
|
147
|
+
.map((l) => l.trim())
|
|
148
|
+
.filter((l) => l && l !== "│")
|
|
149
|
+
.slice(-3)
|
|
150
|
+
.join("\n");
|
|
151
|
+
throw new Error(
|
|
152
|
+
`hyperframes transcribe failed (exit ${e.status ?? e.code})${tail ? `:\n${tail}` : ""}`,
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
const produced = join(workDir, "transcript.json");
|
|
156
|
+
if (!existsSync(produced))
|
|
157
|
+
throw new Error("hyperframes transcribe produced no transcript.json");
|
|
158
|
+
const tmp = `${outPath}.tmp-${process.pid}`;
|
|
159
|
+
copyFileSync(produced, tmp);
|
|
160
|
+
renameSync(tmp, outPath); // atomic publish
|
|
161
|
+
let words;
|
|
162
|
+
try {
|
|
163
|
+
const t = JSON.parse(readFileSync(outPath, "utf8"));
|
|
164
|
+
// The CLI writes a flat word array, not { words }.
|
|
165
|
+
words = Array.isArray(t) ? t.length : undefined;
|
|
166
|
+
} catch {
|
|
167
|
+
/* leave undefined */
|
|
168
|
+
}
|
|
169
|
+
let ran = "whisper";
|
|
170
|
+
try {
|
|
171
|
+
ran = JSON.parse(stdout.trim().split("\n").at(-1)).engine === "parakeet" ? "parakeet" : ran;
|
|
172
|
+
} catch {
|
|
173
|
+
/* no JSON line: keep whisper */
|
|
174
|
+
}
|
|
175
|
+
report(ran, words);
|
|
176
|
+
return ran;
|
|
177
|
+
} finally {
|
|
178
|
+
rmSync(workDir, { recursive: true, force: true });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
try {
|
|
183
|
+
const parakeetBin = resolveParakeet();
|
|
184
|
+
const asked = args.engine === "parakeet" || args.engine === "whisper" ? args.engine : "auto";
|
|
185
|
+
// Without parakeet-mlx, the CLI's own Parakeet (any OS, `hyperframes models install parakeet`).
|
|
186
|
+
let engine = "parakeet";
|
|
187
|
+
if (asked !== "whisper" && parakeetBin) runParakeet(parakeetBin);
|
|
188
|
+
else engine = runCli(asked);
|
|
189
|
+
await track("media_use_transcribe", { engine });
|
|
190
|
+
} catch (err) {
|
|
191
|
+
if (args.json) console.log(JSON.stringify({ ok: false, error: err.message }));
|
|
192
|
+
else console.error(`error: transcription failed: ${err.message}`);
|
|
193
|
+
process.exit(1);
|
|
194
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
3
|
+
import { chmodSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import test from "node:test";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
|
|
9
|
+
// The stub stands in for `npx hyperframes transcribe <in> --dir <dir> ...`: it records its args,
|
|
10
|
+
// writes the CLI's flat array and prints the CLI's --json line naming `cliEngine`.
|
|
11
|
+
function runScript(engine, cliEngine) {
|
|
12
|
+
const root = mkdtempSync(join(tmpdir(), "media-use-transcribe-"));
|
|
13
|
+
try {
|
|
14
|
+
const bin = join(root, "bin");
|
|
15
|
+
mkdirSync(bin);
|
|
16
|
+
writeFileSync(
|
|
17
|
+
join(bin, "npx"),
|
|
18
|
+
`#!/bin/sh\necho "$@" > "${root}/args"\nwhile [ "$1" != "--dir" ]; do shift; done\n` +
|
|
19
|
+
`echo '[{"text":"a","start":0,"end":1},{"text":"b","start":1,"end":2}]' > "$2/transcript.json"\n` +
|
|
20
|
+
`echo '{"ok":true,"engine":"${cliEngine}"}'\n`,
|
|
21
|
+
);
|
|
22
|
+
chmodSync(join(bin, "npx"), 0o755);
|
|
23
|
+
const input = join(root, "in.wav");
|
|
24
|
+
writeFileSync(input, "");
|
|
25
|
+
const script = fileURLToPath(new URL("./transcribe.mjs", import.meta.url));
|
|
26
|
+
const env = { ...process.env, PATH: `${bin}:${process.env.PATH}`, HOME: root };
|
|
27
|
+
delete env.HYPERFRAMES_PARAKEET;
|
|
28
|
+
const out = execFileSync(
|
|
29
|
+
process.execPath,
|
|
30
|
+
[script, "--input", input, "--engine", engine, "--json"],
|
|
31
|
+
{
|
|
32
|
+
encoding: "utf8",
|
|
33
|
+
env: { ...env, HYPERFRAMES_MEDIA_HOME: join(root, "home"), HYPERFRAMES_NO_TELEMETRY: "1" },
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
return { result: JSON.parse(out.trim()), args: readFileSync(join(root, "args"), "utf8") };
|
|
37
|
+
} finally {
|
|
38
|
+
rmSync(root, { recursive: true, force: true });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
test(
|
|
43
|
+
"--engine whisper makes the CLI run whisper and reports the flat transcript's word count",
|
|
44
|
+
{ skip: process.platform === "win32" },
|
|
45
|
+
() => {
|
|
46
|
+
const { result, args } = runScript("whisper", "whisper");
|
|
47
|
+
assert.match(args, /--engine whisper --json/);
|
|
48
|
+
assert.equal(result.words, 2);
|
|
49
|
+
assert.equal(result.engine, "whisper");
|
|
50
|
+
},
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
test(
|
|
54
|
+
"auto reports the engine the CLI says it ran, Parakeet included",
|
|
55
|
+
{ skip: process.platform === "win32" },
|
|
56
|
+
() => {
|
|
57
|
+
const { result, args } = runScript("auto", "parakeet");
|
|
58
|
+
assert.match(args, /--engine auto --json/);
|
|
59
|
+
assert.equal(result.engine, "parakeet");
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
test(
|
|
64
|
+
"--engine parakeet without parakeet-mlx asks the CLI for its Parakeet",
|
|
65
|
+
{ skip: process.platform === "win32" },
|
|
66
|
+
() => {
|
|
67
|
+
const { result, args } = runScript("parakeet", "parakeet");
|
|
68
|
+
assert.match(args, /--engine parakeet --json/);
|
|
69
|
+
assert.equal(result.engine, "parakeet");
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
test(
|
|
74
|
+
"a failed --engine parakeet run reports the reason the CLI printed on stdout",
|
|
75
|
+
{ skip: process.platform === "win32" },
|
|
76
|
+
() => {
|
|
77
|
+
const root = mkdtempSync(join(tmpdir(), "media-use-transcribe-"));
|
|
78
|
+
try {
|
|
79
|
+
const bin = join(root, "bin");
|
|
80
|
+
mkdirSync(bin);
|
|
81
|
+
const reason =
|
|
82
|
+
"Parakeet is not installed. Install it with: hyperframes models install parakeet";
|
|
83
|
+
writeFileSync(
|
|
84
|
+
join(bin, "npx"),
|
|
85
|
+
`#!/bin/sh\necho '{"ok":false,"error":"${reason}"}'\nexit 1\n`,
|
|
86
|
+
);
|
|
87
|
+
chmodSync(join(bin, "npx"), 0o755);
|
|
88
|
+
const input = join(root, "in.wav");
|
|
89
|
+
writeFileSync(input, "");
|
|
90
|
+
const script = fileURLToPath(new URL("./transcribe.mjs", import.meta.url));
|
|
91
|
+
const res = spawnSync(
|
|
92
|
+
process.execPath,
|
|
93
|
+
[script, "--input", input, "--engine", "parakeet", "--json"],
|
|
94
|
+
{
|
|
95
|
+
encoding: "utf8",
|
|
96
|
+
env: {
|
|
97
|
+
...process.env,
|
|
98
|
+
HYPERFRAMES_PARAKEET: "",
|
|
99
|
+
PATH: `${bin}:${process.env.PATH}`,
|
|
100
|
+
HOME: root,
|
|
101
|
+
HYPERFRAMES_MEDIA_HOME: join(root, "home"),
|
|
102
|
+
HYPERFRAMES_NO_TELEMETRY: "1",
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
);
|
|
106
|
+
assert.equal(res.status, 1);
|
|
107
|
+
assert.match(JSON.parse(res.stdout.trim()).error, /hyperframes models install parakeet/);
|
|
108
|
+
} finally {
|
|
109
|
+
rmSync(root, { recursive: true, force: true });
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
);
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
4
|
+
import { mkdtempSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
5
|
+
import { tmpdir } from "node:os";
|
|
6
|
+
import { dirname, extname, join, resolve } from "node:path";
|
|
7
|
+
import { parseArgs } from "node:util";
|
|
8
|
+
import { compileCutList } from "./lib/cutlist.mjs";
|
|
9
|
+
import { fadeFilterFor } from "./lib/transcriptCutFade.mjs";
|
|
10
|
+
import { track } from "./lib/telemetry.mjs";
|
|
11
|
+
|
|
12
|
+
const { values: args } = parseArgs({
|
|
13
|
+
options: {
|
|
14
|
+
input: { type: "string" },
|
|
15
|
+
transcript: { type: "string" },
|
|
16
|
+
remove: { type: "string" },
|
|
17
|
+
"remove-words": { type: "string" },
|
|
18
|
+
"remove-fillers": { type: "string" },
|
|
19
|
+
"cut-silence": { type: "string" },
|
|
20
|
+
keep: { type: "string" },
|
|
21
|
+
copy: { type: "boolean", default: false },
|
|
22
|
+
plan: { type: "boolean", default: false },
|
|
23
|
+
out: { type: "string" },
|
|
24
|
+
json: { type: "boolean", default: false },
|
|
25
|
+
help: { type: "boolean", short: "h", default: false },
|
|
26
|
+
},
|
|
27
|
+
strict: true,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
if (args.help) {
|
|
31
|
+
console.log(`media-use transcript-cut — compile transcript edits into video cuts
|
|
32
|
+
|
|
33
|
+
Usage:
|
|
34
|
+
node transcript-cut.mjs --input in.mp4 --transcript transcript.json --remove "12-15" --out out.mp4
|
|
35
|
+
|
|
36
|
+
Options:
|
|
37
|
+
--input Source video/audio file
|
|
38
|
+
--transcript JSON word transcript, array or { words: [...] }
|
|
39
|
+
--remove Time ranges to remove, seconds: a-b,c-d
|
|
40
|
+
--remove-words Word-index ranges to remove: 12-18,40-41
|
|
41
|
+
--remove-fillers Comma list of filler words to remove
|
|
42
|
+
--cut-silence Remove inter-word gaps longer than this many seconds
|
|
43
|
+
--keep Inverse mode: direct kept ranges, mutually exclusive with removal
|
|
44
|
+
--copy Use stream copy for faster, keyframe-snapped cuts
|
|
45
|
+
--plan Print kept segment JSON and exit without ffmpeg
|
|
46
|
+
--out Output file
|
|
47
|
+
--json Output JSON status
|
|
48
|
+
--help, -h Show this help`);
|
|
49
|
+
process.exit(0);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
run();
|
|
54
|
+
await track("media_use_transcript_cut", {
|
|
55
|
+
mode: args.plan ? "plan" : "encode",
|
|
56
|
+
remove_fillers: !!args["remove-fillers"],
|
|
57
|
+
cut_silence: !!args["cut-silence"],
|
|
58
|
+
ranges: !!args.remove,
|
|
59
|
+
keep: !!args.keep,
|
|
60
|
+
});
|
|
61
|
+
} catch (err) {
|
|
62
|
+
if (args.json) console.log(JSON.stringify({ ok: false, error: err.message }));
|
|
63
|
+
else console.error(`error: ${err.message}`);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function run() {
|
|
68
|
+
if (!args.transcript) throw new Error("--transcript is required");
|
|
69
|
+
const transcript = JSON.parse(readFileSync(resolve(args.transcript), "utf8"));
|
|
70
|
+
const segments = compileCutList(transcript, {
|
|
71
|
+
remove: args.remove,
|
|
72
|
+
removeWords: args["remove-words"],
|
|
73
|
+
removeFillers: args["remove-fillers"],
|
|
74
|
+
cutSilence: args["cut-silence"],
|
|
75
|
+
keep: args.keep,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
if (args.plan) {
|
|
79
|
+
console.log(JSON.stringify(segments));
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!args.input || !args.out)
|
|
84
|
+
throw new Error("--input and --out are required unless --plan is set");
|
|
85
|
+
if (segments.length === 0) throw new Error("cut list has no kept segments");
|
|
86
|
+
|
|
87
|
+
const inputPath = resolve(args.input);
|
|
88
|
+
const outPath = resolve(args.out);
|
|
89
|
+
mkdirSync(dirname(outPath), { recursive: true });
|
|
90
|
+
const tmpDir = mkdtempSync(join(tmpdir(), "media-use-cut-"));
|
|
91
|
+
const keptSeconds = sumDurations(segments);
|
|
92
|
+
const totalSeconds = probeDuration(inputPath);
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
const parts = segments.map((segment, index) => {
|
|
96
|
+
// Intermediates carry PCM audio, not the final codec. Encoding each
|
|
97
|
+
// segment to a lossy codec separately makes the encoder pad every segment
|
|
98
|
+
// with priming silence (~25-35ms for AAC), which concat then bakes in as a
|
|
99
|
+
// gap at each cut -- a defect distinct from, and surviving, the fades
|
|
100
|
+
// below. PCM has no priming, so audio is encoded exactly once, at concat.
|
|
101
|
+
const ext = args.copy ? extname(outPath) || ".mp4" : isAudioOnly(outPath) ? ".wav" : ".mkv";
|
|
102
|
+
const out = join(tmpDir, `segment-${String(index).padStart(4, "0")}${ext}`);
|
|
103
|
+
// --copy stays fade-free (stream copy cannot filter). A segment's true
|
|
104
|
+
// start/end (index 0's start, the last segment's end) borders nothing
|
|
105
|
+
// kept, so only an interior splice edge gets a ramp.
|
|
106
|
+
const fade = args.copy
|
|
107
|
+
? null
|
|
108
|
+
: fadeFilterFor(segment.end - segment.start, {
|
|
109
|
+
fadeIn: index > 0,
|
|
110
|
+
fadeOut: index < segments.length - 1,
|
|
111
|
+
});
|
|
112
|
+
cutSegment(inputPath, segment, out, args.copy, fade);
|
|
113
|
+
return out;
|
|
114
|
+
});
|
|
115
|
+
const listPath = join(tmpDir, "list.txt");
|
|
116
|
+
writeFileSync(
|
|
117
|
+
listPath,
|
|
118
|
+
parts.map((part) => `file '${escapeConcatPath(part)}'`).join("\n") + "\n",
|
|
119
|
+
);
|
|
120
|
+
// Encode to a sibling temp (same extension so ffmpeg picks the right muxer),
|
|
121
|
+
// then atomic-rename so a SIGKILL mid-encode can't leave a truncated outPath.
|
|
122
|
+
const tmpOut = `${outPath}.part${extname(outPath) || ".mp4"}`;
|
|
123
|
+
// --copy already produced final-codec segments, so concat can stream-copy.
|
|
124
|
+
// Otherwise the PCM intermediates are encoded here, once, for the whole file.
|
|
125
|
+
const concatCodecs = args.copy
|
|
126
|
+
? ["-c", "copy"]
|
|
127
|
+
: isAudioOnly(outPath)
|
|
128
|
+
? encodeArgsFor(extname(outPath).toLowerCase())
|
|
129
|
+
: ["-c:v", "copy", "-c:a", "aac", "-b:a", "192k", "-movflags", "+faststart"];
|
|
130
|
+
execFileSync(
|
|
131
|
+
"ffmpeg",
|
|
132
|
+
["-y", "-f", "concat", "-safe", "0", "-i", listPath, ...concatCodecs, tmpOut],
|
|
133
|
+
{
|
|
134
|
+
stdio: "ignore",
|
|
135
|
+
},
|
|
136
|
+
);
|
|
137
|
+
renameSync(tmpOut, outPath);
|
|
138
|
+
} finally {
|
|
139
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Stream copy can only cut on keyframes; on sparse-keyframe footage the snap
|
|
143
|
+
// can silently swallow the whole cut. Compare, then surface the drift in BOTH
|
|
144
|
+
// the stderr warning (human) and the --json result (pipelines).
|
|
145
|
+
let copyDrift = null;
|
|
146
|
+
if (args.copy) {
|
|
147
|
+
const outSeconds = probeDuration(outPath);
|
|
148
|
+
if (Math.abs(outSeconds - keptSeconds) > 1) {
|
|
149
|
+
copyDrift = { produced_s: round3(outSeconds), expected_s: round3(keptSeconds) };
|
|
150
|
+
if (!args.json) {
|
|
151
|
+
console.error(
|
|
152
|
+
`warning: --copy keyframe snapping produced ${round3(outSeconds)}s instead of ${round3(keptSeconds)}s kept; drop --copy for frame-accurate cuts`,
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (args.json) {
|
|
159
|
+
console.log(
|
|
160
|
+
JSON.stringify({
|
|
161
|
+
ok: true,
|
|
162
|
+
input: inputPath,
|
|
163
|
+
out: outPath,
|
|
164
|
+
segments,
|
|
165
|
+
kept_s: round3(keptSeconds),
|
|
166
|
+
total_s: round3(totalSeconds),
|
|
167
|
+
...(copyDrift && { copy_drift: copyDrift }),
|
|
168
|
+
}),
|
|
169
|
+
);
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
console.log(
|
|
174
|
+
`cut ${inputPath} -> ${outPath} (${segments.length} segments, ${fmt(keptSeconds)}s kept of ${fmt(
|
|
175
|
+
totalSeconds,
|
|
176
|
+
)}s)`,
|
|
177
|
+
);
|
|
178
|
+
console.log(`next: resolve --from ${outPath} --type <type>`);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function cutSegment(inputPath, segment, outPath, copy, fade) {
|
|
182
|
+
const argv = [
|
|
183
|
+
"-y",
|
|
184
|
+
"-nostdin",
|
|
185
|
+
"-ss",
|
|
186
|
+
fmt(segment.start),
|
|
187
|
+
"-i",
|
|
188
|
+
inputPath,
|
|
189
|
+
"-to",
|
|
190
|
+
fmt(segment.end - segment.start),
|
|
191
|
+
];
|
|
192
|
+
if (copy) {
|
|
193
|
+
argv.push("-c", "copy", "-avoid_negative_ts", "make_zero");
|
|
194
|
+
} else if (extname(outPath).toLowerCase() === ".mkv") {
|
|
195
|
+
// Concat splices raw segment edges together; without a short ramp the
|
|
196
|
+
// waveform steps discontinuously at every boundary and you hear a click.
|
|
197
|
+
if (fade) argv.push("-af", fade);
|
|
198
|
+
// Video intermediate: keep the picture cheap and the audio uncompressed.
|
|
199
|
+
argv.push("-c:v", "libx264", "-preset", "veryfast", "-crf", "18", "-c:a", "pcm_s16le");
|
|
200
|
+
} else {
|
|
201
|
+
if (fade) argv.push("-af", fade);
|
|
202
|
+
argv.push("-c:a", "pcm_s16le");
|
|
203
|
+
}
|
|
204
|
+
argv.push(outPath);
|
|
205
|
+
execFileSync("ffmpeg", argv, { stdio: "ignore" });
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Codec set per output container. Audio-only outputs must not get the
|
|
209
|
+
// video-centric aac/x264 set (aac inside .wav breaks timing entirely).
|
|
210
|
+
function isAudioOnly(filePath) {
|
|
211
|
+
return [".wav", ".mp3", ".m4a", ".aac", ".flac"].includes(extname(filePath).toLowerCase());
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function encodeArgsFor(ext) {
|
|
215
|
+
if (ext === ".wav") return ["-c:a", "pcm_s16le"];
|
|
216
|
+
if (ext === ".mp3") return ["-c:a", "libmp3lame", "-q:a", "2"];
|
|
217
|
+
if (ext === ".m4a" || ext === ".aac") return ["-c:a", "aac"];
|
|
218
|
+
if (ext === ".flac") return ["-c:a", "flac"];
|
|
219
|
+
return [
|
|
220
|
+
"-c:v",
|
|
221
|
+
"libx264",
|
|
222
|
+
"-preset",
|
|
223
|
+
"veryfast",
|
|
224
|
+
"-crf",
|
|
225
|
+
"18",
|
|
226
|
+
"-c:a",
|
|
227
|
+
"aac",
|
|
228
|
+
"-movflags",
|
|
229
|
+
"+faststart",
|
|
230
|
+
];
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function probeDuration(filePath) {
|
|
234
|
+
const raw = execFileSync(
|
|
235
|
+
"ffprobe",
|
|
236
|
+
[
|
|
237
|
+
"-v",
|
|
238
|
+
"error",
|
|
239
|
+
"-show_entries",
|
|
240
|
+
"format=duration",
|
|
241
|
+
"-of",
|
|
242
|
+
"default=noprint_wrappers=1:nokey=1",
|
|
243
|
+
"--",
|
|
244
|
+
filePath,
|
|
245
|
+
],
|
|
246
|
+
{ encoding: "utf8" },
|
|
247
|
+
);
|
|
248
|
+
const duration = Number(raw.trim());
|
|
249
|
+
if (!Number.isFinite(duration) || duration <= 0)
|
|
250
|
+
throw new Error(`could not probe duration: ${filePath}`);
|
|
251
|
+
return duration;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function escapeConcatPath(filePath) {
|
|
255
|
+
return filePath.replace(/'/g, "'\\''");
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
function sumDurations(segments) {
|
|
259
|
+
return segments.reduce((sum, segment) => sum + (segment.end - segment.start), 0);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function fmt(n) {
|
|
263
|
+
return round3(n)
|
|
264
|
+
.toFixed(3)
|
|
265
|
+
.replace(/\.?0+$/, "");
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
function round3(n) {
|
|
269
|
+
return Math.round(Number(n) * 1000) / 1000;
|
|
270
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
3
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import test from "node:test";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
|
|
9
|
+
const SCRIPT = fileURLToPath(new URL("./transcript-cut.mjs", import.meta.url));
|
|
10
|
+
const HAS_FFMPEG =
|
|
11
|
+
spawnSync("ffmpeg", ["-version"], { stdio: "ignore" }).status === 0 &&
|
|
12
|
+
spawnSync("ffprobe", ["-version"], { stdio: "ignore" }).status === 0;
|
|
13
|
+
|
|
14
|
+
const SAMPLE_RATE = 44100;
|
|
15
|
+
// A continuous tone's own slope between samples never exceeds amplitude * 2*pi*f/rate
|
|
16
|
+
// (~2054 for 440Hz at full scale here); a raw splice between two independently-cut
|
|
17
|
+
// points on the same tone lands at two unrelated phases, so an unfaded join jumps far
|
|
18
|
+
// past that. This threshold sits well above normal tone motion and well below a splice.
|
|
19
|
+
const MAX_CONTINUOUS_STEP = 6000;
|
|
20
|
+
const MIN_SUSPICIOUS_ZERO_RUN = 20;
|
|
21
|
+
|
|
22
|
+
function fixture() {
|
|
23
|
+
const dir = mkdtempSync(join(tmpdir(), "media-use-transcript-cut-"));
|
|
24
|
+
return { dir, cleanup: () => rmSync(dir, { recursive: true, force: true }) };
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function run(args) {
|
|
28
|
+
return spawnSync(process.execPath, [SCRIPT, ...args], { encoding: "utf8" });
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function readPcm(filePath) {
|
|
32
|
+
const raw = execFileSync("ffmpeg", [
|
|
33
|
+
"-hide_banner",
|
|
34
|
+
"-loglevel",
|
|
35
|
+
"error",
|
|
36
|
+
"-i",
|
|
37
|
+
filePath,
|
|
38
|
+
"-f",
|
|
39
|
+
"s16le",
|
|
40
|
+
"-ac",
|
|
41
|
+
"1",
|
|
42
|
+
"-ar",
|
|
43
|
+
String(SAMPLE_RATE),
|
|
44
|
+
"-",
|
|
45
|
+
]);
|
|
46
|
+
const samples = new Int16Array(raw.buffer, raw.byteOffset, raw.length / 2);
|
|
47
|
+
return samples;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
test(
|
|
51
|
+
"keeps a spliced tone continuous at every cut, with no raw phase jump or silence gap",
|
|
52
|
+
{ skip: !HAS_FFMPEG },
|
|
53
|
+
(t) => {
|
|
54
|
+
const { dir, cleanup } = fixture();
|
|
55
|
+
t.after(cleanup);
|
|
56
|
+
|
|
57
|
+
const source = join(dir, "tone.wav");
|
|
58
|
+
execFileSync("ffmpeg", [
|
|
59
|
+
"-y",
|
|
60
|
+
"-hide_banner",
|
|
61
|
+
"-loglevel",
|
|
62
|
+
"error",
|
|
63
|
+
"-f",
|
|
64
|
+
"lavfi",
|
|
65
|
+
"-i",
|
|
66
|
+
`sine=frequency=440:duration=6:sample_rate=${SAMPLE_RATE}`,
|
|
67
|
+
source,
|
|
68
|
+
]);
|
|
69
|
+
|
|
70
|
+
const transcriptPath = join(dir, "transcript.json");
|
|
71
|
+
writeFileSync(transcriptPath, JSON.stringify({ words: [{ text: "tone", start: 0, end: 6 }] }));
|
|
72
|
+
|
|
73
|
+
const output = join(dir, "out.wav");
|
|
74
|
+
// Two "ugly" removal ranges: neither aligned to the 440Hz period, so the kept
|
|
75
|
+
// segments' cut edges land at unrelated phases of the same continuous tone --
|
|
76
|
+
// exactly the shape that clicks without a fade, and the shape jrusso1020's
|
|
77
|
+
// review proved this branch never actually fades.
|
|
78
|
+
const result = run([
|
|
79
|
+
"--input",
|
|
80
|
+
source,
|
|
81
|
+
"--transcript",
|
|
82
|
+
transcriptPath,
|
|
83
|
+
"--remove",
|
|
84
|
+
"1.37-1.83,3.29-3.71",
|
|
85
|
+
"--out",
|
|
86
|
+
output,
|
|
87
|
+
"--json",
|
|
88
|
+
]);
|
|
89
|
+
assert.equal(result.status, 0, result.stderr || result.stdout);
|
|
90
|
+
|
|
91
|
+
const samples = readPcm(output);
|
|
92
|
+
assert.ok(samples.length > SAMPLE_RATE, "expected several seconds of audio");
|
|
93
|
+
|
|
94
|
+
let maxStep = 0;
|
|
95
|
+
let zeroRun = 0;
|
|
96
|
+
let maxZeroRun = 0;
|
|
97
|
+
for (let i = 1; i < samples.length; i++) {
|
|
98
|
+
const step = Math.abs(samples[i] - samples[i - 1]);
|
|
99
|
+
if (step > maxStep) maxStep = step;
|
|
100
|
+
if (samples[i] === 0) {
|
|
101
|
+
zeroRun++;
|
|
102
|
+
if (zeroRun > maxZeroRun) maxZeroRun = zeroRun;
|
|
103
|
+
} else {
|
|
104
|
+
zeroRun = 0;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
assert.ok(
|
|
109
|
+
maxStep <= MAX_CONTINUOUS_STEP,
|
|
110
|
+
`largest sample-to-sample step was ${maxStep}, expected <= ${MAX_CONTINUOUS_STEP} (a raw, unfaded splice)`,
|
|
111
|
+
);
|
|
112
|
+
assert.ok(
|
|
113
|
+
maxZeroRun < MIN_SUSPICIOUS_ZERO_RUN,
|
|
114
|
+
`found a run of ${maxZeroRun} consecutive zero samples, expected < ${MIN_SUSPICIOUS_ZERO_RUN} (a priming-silence gap)`,
|
|
115
|
+
);
|
|
116
|
+
},
|
|
117
|
+
);
|