voxflow 1.15.0 → 1.15.2
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.md +34 -0
- package/bin/voxflow.js +27 -0
- package/dist/index.js +1 -1
- package/dist/remotion-bundle/02a2fb2eb80bc7bf.woff2 +0 -0
- package/dist/remotion-bundle/052ca5351e5e06ba.woff2 +0 -0
- package/dist/remotion-bundle/05853dd28f4019cb.woff2 +0 -0
- package/dist/remotion-bundle/072ead3737f7c0d0.woff2 +0 -0
- package/dist/remotion-bundle/07d4248613c86a2e.woff2 +0 -0
- package/dist/remotion-bundle/0884a5c2d1d2d99b.woff2 +0 -0
- package/dist/remotion-bundle/0b0e185b2752095e.woff2 +0 -0
- package/dist/remotion-bundle/0e66c11bde067d91.woff2 +0 -0
- package/dist/remotion-bundle/0f7794cfba2c5d21.woff2 +0 -0
- package/dist/remotion-bundle/0fdbae5a4365783a.woff2 +0 -0
- package/dist/remotion-bundle/112.bundle.js +11 -0
- package/dist/remotion-bundle/112.bundle.js.map +1 -0
- package/dist/remotion-bundle/113.bundle.js +11 -0
- package/dist/remotion-bundle/113.bundle.js.map +1 -0
- package/dist/remotion-bundle/119cae0c4c16f7ed.woff2 +0 -0
- package/dist/remotion-bundle/14725f649fd1e78c.woff2 +0 -0
- package/dist/remotion-bundle/14abe9e3f95f7888.woff2 +0 -0
- package/dist/remotion-bundle/163.bundle.js +14678 -0
- package/dist/remotion-bundle/163.bundle.js.map +1 -0
- package/dist/remotion-bundle/1808c54072bf6d14.woff2 +0 -0
- package/dist/remotion-bundle/18948bec3e3012fe.woff2 +0 -0
- package/dist/remotion-bundle/1a661c60d0fc84fc.woff2 +0 -0
- package/dist/remotion-bundle/1af94941e1bc7e1e.woff2 +0 -0
- package/dist/remotion-bundle/1bee0219595f606c.woff2 +0 -0
- package/dist/remotion-bundle/1bfd5da7ce9d4ec4.woff2 +0 -0
- package/dist/remotion-bundle/1c158d56f1884f3f.woff2 +0 -0
- package/dist/remotion-bundle/1cf5e88e667610eb.woff2 +0 -0
- package/dist/remotion-bundle/1d431bd10f53c481.woff2 +0 -0
- package/dist/remotion-bundle/1d701a81a7670db2.woff2 +0 -0
- package/dist/remotion-bundle/1da0fecad4240f16.woff2 +0 -0
- package/dist/remotion-bundle/1ed14d3d0c5c63fe.woff2 +0 -0
- package/dist/remotion-bundle/1edfecf40e586f53.woff2 +0 -0
- package/dist/remotion-bundle/1f479711bc34b054.woff +0 -0
- package/dist/remotion-bundle/1f86e54a0ff5fcd1.woff2 +0 -0
- package/dist/remotion-bundle/2043ea87d9aabd11.woff2 +0 -0
- package/dist/remotion-bundle/20563c39ee8a0e40.woff2 +0 -0
- package/dist/remotion-bundle/20c231590fd12c44.woff2 +0 -0
- package/dist/remotion-bundle/20ce61713f754c07.woff2 +0 -0
- package/dist/remotion-bundle/21eb9306fce24bb1.woff2 +0 -0
- package/dist/remotion-bundle/244bf71c0cc851af.woff2 +0 -0
- package/dist/remotion-bundle/274d4cfc02bffbcb.woff2 +0 -0
- package/dist/remotion-bundle/275.bundle.js +21 -0
- package/dist/remotion-bundle/275.bundle.js.map +1 -0
- package/dist/remotion-bundle/2958f540b39513dc.woff2 +0 -0
- package/dist/remotion-bundle/2a168b98fd97722e.woff2 +0 -0
- package/dist/remotion-bundle/2d1f6373937ab55f.woff2 +0 -0
- package/dist/remotion-bundle/2d213ae47ff6daa9.woff2 +0 -0
- package/dist/remotion-bundle/2e4b1f04fcd05047.woff2 +0 -0
- package/dist/remotion-bundle/304170d98f4c4563.woff2 +0 -0
- package/dist/remotion-bundle/30d02e136e7a5642.woff2 +0 -0
- package/dist/remotion-bundle/3135562b52a714cd.woff2 +0 -0
- package/dist/remotion-bundle/313713af2c8144e9.woff2 +0 -0
- package/dist/remotion-bundle/325fa4108d2285b9.woff2 +0 -0
- package/dist/remotion-bundle/338e927ed3345e0c.woff2 +0 -0
- package/dist/remotion-bundle/35fc6b190365bc17.woff2 +0 -0
- package/dist/remotion-bundle/37a51f1122d4efc5.woff2 +0 -0
- package/dist/remotion-bundle/39a4d63e02736f5e.woff2 +0 -0
- package/dist/remotion-bundle/3a00e0d62dfc4171.woff2 +0 -0
- package/dist/remotion-bundle/3a6955e6561affe1.woff2 +0 -0
- package/dist/remotion-bundle/3c573945aef49b89.woff2 +0 -0
- package/dist/remotion-bundle/3cdbfbfa23b516a5.woff2 +0 -0
- package/dist/remotion-bundle/3e42f85a9e64ca8a.woff2 +0 -0
- package/dist/remotion-bundle/3e83eaf1ec859415.woff2 +0 -0
- package/dist/remotion-bundle/3f3c8c90de1250ee.woff2 +0 -0
- package/dist/remotion-bundle/434.bundle.js +205 -0
- package/dist/remotion-bundle/434.bundle.js.map +1 -0
- package/dist/remotion-bundle/44ffc6ca4d781692.woff2 +0 -0
- package/dist/remotion-bundle/4670d9c4580b09eb.woff2 +0 -0
- package/dist/remotion-bundle/479756881b302824.woff2 +0 -0
- package/dist/remotion-bundle/481b82134bfa9c82.woff2 +0 -0
- package/dist/remotion-bundle/48d27029626f4328.woff2 +0 -0
- package/dist/remotion-bundle/49b7b2a30329c511.woff2 +0 -0
- package/dist/remotion-bundle/4c8b25a1a9337045.woff2 +0 -0
- package/dist/remotion-bundle/4cba14788ca9259b.woff2 +0 -0
- package/dist/remotion-bundle/4cd6c589c004a6a7.woff2 +0 -0
- package/dist/remotion-bundle/4cd8d79c1021608d.woff2 +0 -0
- package/dist/remotion-bundle/4d8fa99b3f00f9f0.woff2 +0 -0
- package/dist/remotion-bundle/4e7805a643f86d53.woff2 +0 -0
- package/dist/remotion-bundle/4ff91be454542e3f.woff2 +0 -0
- package/dist/remotion-bundle/504cbcba1f63591b.woff2 +0 -0
- package/dist/remotion-bundle/5202d792e5791d6c.woff2 +0 -0
- package/dist/remotion-bundle/534db5ad4770cc1d.woff2 +0 -0
- package/dist/remotion-bundle/53b9568eb85f866b.woff2 +0 -0
- package/dist/remotion-bundle/543ad386ca171de9.woff2 +0 -0
- package/dist/remotion-bundle/54798e55bbf7976e.woff2 +0 -0
- package/dist/remotion-bundle/580.bundle.js +11 -0
- package/dist/remotion-bundle/580.bundle.js.map +1 -0
- package/dist/remotion-bundle/58d174d1193af6d1.woff2 +0 -0
- package/dist/remotion-bundle/591d29ff3ff53c80.woff2 +0 -0
- package/dist/remotion-bundle/5c28c4f4824383c6.woff2 +0 -0
- package/dist/remotion-bundle/5da9740d2ce894c8.woff2 +0 -0
- package/dist/remotion-bundle/6197735364642360.woff2 +0 -0
- package/dist/remotion-bundle/6265a4335724080f.woff2 +0 -0
- package/dist/remotion-bundle/633f5e4f6394daa7.woff2 +0 -0
- package/dist/remotion-bundle/637d95ace6a69c49.woff2 +0 -0
- package/dist/remotion-bundle/648e04a04dacff8f.woff2 +0 -0
- package/dist/remotion-bundle/64a6e83045a008b2.woff2 +0 -0
- package/dist/remotion-bundle/651.bundle.js +11 -0
- package/dist/remotion-bundle/651.bundle.js.map +1 -0
- package/dist/remotion-bundle/65e2a988c070facc.woff2 +0 -0
- package/dist/remotion-bundle/66a2f6ce5cc69105.woff2 +0 -0
- package/dist/remotion-bundle/690.bundle.js +3479 -0
- package/dist/remotion-bundle/690.bundle.js.map +1 -0
- package/dist/remotion-bundle/690ff55252ca715d.woff2 +0 -0
- package/dist/remotion-bundle/6a01a1cff49314fc.woff2 +0 -0
- package/dist/remotion-bundle/6cbc32670982986c.woff2 +0 -0
- package/dist/remotion-bundle/6d3cc42ae547f454.woff2 +0 -0
- package/dist/remotion-bundle/6d8f4cfa1ddc0830.woff2 +0 -0
- package/dist/remotion-bundle/6e4d7c6ae65e2dc3.woff2 +0 -0
- package/dist/remotion-bundle/6e86418bbcefb2e8.woff2 +0 -0
- package/dist/remotion-bundle/6ee02884b29cf7fb.woff2 +0 -0
- package/dist/remotion-bundle/6f436a74c9e3252c.woff2 +0 -0
- package/dist/remotion-bundle/78c8022f1657618b.woff2 +0 -0
- package/dist/remotion-bundle/7c5444169792bca4.woff2 +0 -0
- package/dist/remotion-bundle/7c86bddd9d997212.woff2 +0 -0
- package/dist/remotion-bundle/7e1284684767f584.woff2 +0 -0
- package/dist/remotion-bundle/7e81c17522d182b2.woff2 +0 -0
- package/dist/remotion-bundle/7eb87be198f7858c.woff2 +0 -0
- package/dist/remotion-bundle/8060c928f948aab5.woff2 +0 -0
- package/dist/remotion-bundle/80bc9dfbea2b35ae.woff2 +0 -0
- package/dist/remotion-bundle/811b83f69963bb48.woff2 +0 -0
- package/dist/remotion-bundle/813.bundle.js +117511 -0
- package/dist/remotion-bundle/813.bundle.js.map +1 -0
- package/dist/remotion-bundle/84df492e349f82e9.woff2 +0 -0
- package/dist/remotion-bundle/8501bfd73eb36f2b.woff2 +0 -0
- package/dist/remotion-bundle/854236a8376093fe.woff2 +0 -0
- package/dist/remotion-bundle/8571d74529082753.woff2 +0 -0
- package/dist/remotion-bundle/860bf44f8e6f4b5d.woff2 +0 -0
- package/dist/remotion-bundle/879.bundle.js +64 -0
- package/dist/remotion-bundle/879.bundle.js.map +1 -0
- package/dist/remotion-bundle/887dd482f848d56f.woff2 +0 -0
- package/dist/remotion-bundle/89b2132e85fbbb5a.woff2 +0 -0
- package/dist/remotion-bundle/8ba60d6c306010c2.woff2 +0 -0
- package/dist/remotion-bundle/8c7c4dadea897806.woff2 +0 -0
- package/dist/remotion-bundle/8c943f9999706f61.woff2 +0 -0
- package/dist/remotion-bundle/8f2a718c90575cc9.woff2 +0 -0
- package/dist/remotion-bundle/906b6edb3e1772c9.woff2 +0 -0
- package/dist/remotion-bundle/930ff9daccdf14eb.woff2 +0 -0
- package/dist/remotion-bundle/934db2f1c403c4d0.woff2 +0 -0
- package/dist/remotion-bundle/938.bundle.js +451 -0
- package/dist/remotion-bundle/938.bundle.js.map +1 -0
- package/dist/remotion-bundle/967.bundle.js +4462 -0
- package/dist/remotion-bundle/967.bundle.js.map +1 -0
- package/dist/remotion-bundle/9684a1093d3c02ce.woff2 +0 -0
- package/dist/remotion-bundle/973dcd0faa6116cc.woff2 +0 -0
- package/dist/remotion-bundle/9745400694e76cd8.woff2 +0 -0
- package/dist/remotion-bundle/999ef957bed3bdca.woff2 +0 -0
- package/dist/remotion-bundle/99a3d67c8b0f43e3.woff2 +0 -0
- package/dist/remotion-bundle/a0586c3e03127283.woff2 +0 -0
- package/dist/remotion-bundle/a0eb654fdae46269.woff2 +0 -0
- package/dist/remotion-bundle/a20e35d3b08f7994.woff2 +0 -0
- package/dist/remotion-bundle/a2dcaced7c8c25ab.woff2 +0 -0
- package/dist/remotion-bundle/a79255a972a2681a.woff2 +0 -0
- package/dist/remotion-bundle/a804b352cb9fec1a.woff2 +0 -0
- package/dist/remotion-bundle/aae7117164e1eabc.woff2 +0 -0
- package/dist/remotion-bundle/affd121385d0442d.woff2 +0 -0
- package/dist/remotion-bundle/b19a6083987ee0d7.woff2 +0 -0
- package/dist/remotion-bundle/b1b2bd04d8637981.woff2 +0 -0
- package/dist/remotion-bundle/b2c07f341486be87.woff2 +0 -0
- package/dist/remotion-bundle/b33d8f82e575c4ce.woff2 +0 -0
- package/dist/remotion-bundle/b366c0bed35ef491.woff2 +0 -0
- package/dist/remotion-bundle/b41e857ec1b85642.woff2 +0 -0
- package/dist/remotion-bundle/b420bb34ccf23e7f.woff2 +0 -0
- package/dist/remotion-bundle/b4f7bf4efb0c0ccf.woff2 +0 -0
- package/dist/remotion-bundle/b60fe5eca03cff93.woff2 +0 -0
- package/dist/remotion-bundle/b6bd31a336e64bce.woff2 +0 -0
- package/dist/remotion-bundle/b6d2befba3dfefeb.woff2 +0 -0
- package/dist/remotion-bundle/b75f39ab06c43bf4.woff2 +0 -0
- package/dist/remotion-bundle/b77880e8c413d4fd.woff2 +0 -0
- package/dist/remotion-bundle/b7e38ec441e4a77a.woff2 +0 -0
- package/dist/remotion-bundle/b83baa383ff0bf2b.woff2 +0 -0
- package/dist/remotion-bundle/b9ad7b6c0a11450a.woff2 +0 -0
- package/dist/remotion-bundle/baf84486e8ae3aaf.woff2 +0 -0
- package/dist/remotion-bundle/bc047b1f6869cffa.woff2 +0 -0
- package/dist/remotion-bundle/bf4f3ac6e93f33aa.woff2 +0 -0
- package/dist/remotion-bundle/bf6835ffec5897a2.woff2 +0 -0
- package/dist/remotion-bundle/bf8885f581eb1724.woff2 +0 -0
- package/dist/remotion-bundle/bundle.js +83376 -0
- package/dist/remotion-bundle/bundle.js.map +1 -0
- package/dist/remotion-bundle/c03f046bccd789d0.woff2 +0 -0
- package/dist/remotion-bundle/c0bb1f8962b73bc3.woff2 +0 -0
- package/dist/remotion-bundle/c1003f9a7db6e1cf.woff2 +0 -0
- package/dist/remotion-bundle/c15d83fb1e199515.woff2 +0 -0
- package/dist/remotion-bundle/c28e7e5d310f73ef.woff2 +0 -0
- package/dist/remotion-bundle/c2b840274db78aea.woff2 +0 -0
- package/dist/remotion-bundle/c3000e3299d4e45f.woff2 +0 -0
- package/dist/remotion-bundle/c83ce886e5288510.woff2 +0 -0
- package/dist/remotion-bundle/c87a5a64d4ac0918.woff2 +0 -0
- package/dist/remotion-bundle/c8a7e0d049e965fa.woff2 +0 -0
- package/dist/remotion-bundle/c949a35d3a3b1faf.woff2 +0 -0
- package/dist/remotion-bundle/c9618c9b9ac2bc78.woff2 +0 -0
- package/dist/remotion-bundle/ca3add3b84152d5b.woff2 +0 -0
- package/dist/remotion-bundle/cad9dd036408d707.woff2 +0 -0
- package/dist/remotion-bundle/cbb24916619df439.woff2 +0 -0
- package/dist/remotion-bundle/cc054f0b5514e177.woff2 +0 -0
- package/dist/remotion-bundle/ccc248ed9312bc71.woff2 +0 -0
- package/dist/remotion-bundle/cd9d623aa07af925.woff2 +0 -0
- package/dist/remotion-bundle/ce2ba7a321bd1247.woff2 +0 -0
- package/dist/remotion-bundle/cf72455f79a29b14.woff2 +0 -0
- package/dist/remotion-bundle/d267cbfefab452ac.woff2 +0 -0
- package/dist/remotion-bundle/d435cff46a64955f.woff +0 -0
- package/dist/remotion-bundle/d494d07f67e363f6.woff2 +0 -0
- package/dist/remotion-bundle/d7aa0cc1fa47bf38.woff2 +0 -0
- package/dist/remotion-bundle/d7c5ca93d885160a.woff2 +0 -0
- package/dist/remotion-bundle/d855d3e252db74e2.woff2 +0 -0
- package/dist/remotion-bundle/d8f13d47f02f82c2.woff2 +0 -0
- package/dist/remotion-bundle/d9567cce2ee11019.woff2 +0 -0
- package/dist/remotion-bundle/db8d4456fc75dd86.woff +0 -0
- package/dist/remotion-bundle/dc274628378c47ee.woff2 +0 -0
- package/dist/remotion-bundle/dc3e06947bb69903.woff2 +0 -0
- package/dist/remotion-bundle/dd67040ac3b6d523.woff2 +0 -0
- package/dist/remotion-bundle/e0b04bd488f953f4.woff2 +0 -0
- package/dist/remotion-bundle/e2a572ff95089370.woff2 +0 -0
- package/dist/remotion-bundle/e2e18a86b1c2b0cc.woff2 +0 -0
- package/dist/remotion-bundle/e3a78ee2fc9c6931.woff2 +0 -0
- package/dist/remotion-bundle/e654c9d547605a9f.woff2 +0 -0
- package/dist/remotion-bundle/e67a3a64c129927c.woff2 +0 -0
- package/dist/remotion-bundle/e6be28b4203cd6ce.woff2 +0 -0
- package/dist/remotion-bundle/e841907ad9b0a191.woff +0 -0
- package/dist/remotion-bundle/e889d1541c69fffa.woff2 +0 -0
- package/dist/remotion-bundle/e88ef8c76373a9e2.woff2 +0 -0
- package/dist/remotion-bundle/e9c72f4bc37defef.woff2 +0 -0
- package/dist/remotion-bundle/e9e35f863403a255.woff2 +0 -0
- package/dist/remotion-bundle/eb23b37b009375da.woff2 +0 -0
- package/dist/remotion-bundle/ee1342b741625721.woff2 +0 -0
- package/dist/remotion-bundle/f07da88543a57ec9.woff2 +0 -0
- package/dist/remotion-bundle/f522982115306f8a.woff2 +0 -0
- package/dist/remotion-bundle/f8449bd864e6d8bc.woff2 +0 -0
- package/dist/remotion-bundle/f906dd5bd95ff9ab.woff2 +0 -0
- package/dist/remotion-bundle/f9e9e9413e3c38bb.woff2 +0 -0
- package/dist/remotion-bundle/fa5a5b16280994a8.woff2 +0 -0
- package/dist/remotion-bundle/favicon.ico +0 -0
- package/dist/remotion-bundle/fb19c0517725599b.woff2 +0 -0
- package/dist/remotion-bundle/fcaf24232f684b9b.woff2 +0 -0
- package/dist/remotion-bundle/fe09e084a3eea8cf.woff2 +0 -0
- package/dist/remotion-bundle/ff38d5317df7345a.woff2 +0 -0
- package/dist/remotion-bundle/ffe7ea1ea08f455a.woff2 +0 -0
- package/dist/remotion-bundle/index.html +49 -0
- package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaomei/communication/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaomei/communication/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaomei/communication/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaomei/communication/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoxin/career/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoxin/career/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoxin/career/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoxin/career/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoyue/parenting/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoyue/parenting/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoyue/parenting/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoyue/parenting/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/male-kefu-xiaoxu/time-trap/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/male-kefu-xiaoxu/time-trap/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/male-kefu-xiaoxu/time-trap/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/male-kefu-xiaoxu/time-trap/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/cognition/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/cognition/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/cognition/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/cognition/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/growth/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/growth/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/growth/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/growth/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/parenting/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/parenting/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/parenting/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/parenting/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/soothing/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/soothing/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/soothing/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/soothing/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-R2s4N9qJ/cognition/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-R2s4N9qJ/cognition/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-R2s4N9qJ/cognition/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-female-R2s4N9qJ/cognition/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-male-Bk7vD3xP/decision/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-male-Bk7vD3xP/decision/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-male-Bk7vD3xP/decision/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-male-Bk7vD3xP/decision/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-male-W1tH9jVc/manager/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-male-W1tH9jVc/manager/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-male-W1tH9jVc/manager/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-male-W1tH9jVc/manager/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-male-W1tH9jVc/manager/4.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-male-s5NqE0rZ/founder/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-male-s5NqE0rZ/founder/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-male-s5NqE0rZ/founder/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide/v-male-s5NqE0rZ/founder/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/career-advice/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/career-advice/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/career-advice/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/career-advice/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/career-advice/4.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/founder-lesson/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/founder-lesson/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/founder-lesson/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/founder-lesson/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/founder-lesson/4.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/incident-review/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/incident-review/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/incident-review/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/incident-review/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/incident-review/4.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/learning-loop/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/learning-loop/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/learning-loop/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/learning-loop/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/learning-loop/4.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/meeting-closure/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/meeting-closure/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/meeting-closure/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/meeting-closure/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/product-update/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/product-update/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/product-update/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/product-update/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/research-reading/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/research-reading/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/research-reading/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/research-reading/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/sales-enablement/0.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/sales-enablement/1.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/sales-enablement/2.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/sales-enablement/3.mp3 +0 -0
- package/dist/remotion-bundle/public/paper-slide-experiments/sales-enablement/4.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/ai-life/card-0.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/ai-life/card-1.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/ai-life/card-2.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/ai-life/card-3.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/ai-life/card-4.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/ai-life/card-5.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/coffee-science/card-0.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/coffee-science/card-1.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/coffee-science/card-2.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/coffee-science/card-3.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/coffee-science/card-4.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/coffee-science/card-5.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/coffee-science/card-6.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/reading-secrets/card-0.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/reading-secrets/card-1.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/reading-secrets/card-2.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/reading-secrets/card-3.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/reading-secrets/card-4.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/reading-secrets/card-5.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/reading-secrets/card-6.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/remote-work/card-0.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/remote-work/card-1.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/remote-work/card-2.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/remote-work/card-3.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/remote-work/card-4.mp3 +0 -0
- package/dist/remotion-bundle/public/voiceover/remote-work/card-5.mp3 +0 -0
- package/dist/remotion-bundle/source-map-helper.wasm +0 -0
- package/lib/cli.js +270 -0
- package/lib/commands/_registry.js +48 -0
- package/lib/commands/add.js +242 -0
- package/lib/commands/asr/azure-transcribe.js +336 -0
- package/lib/commands/asr/cloud-transcribe.js +384 -0
- package/lib/commands/asr/helpers.js +76 -0
- package/lib/commands/asr/index.js +236 -0
- package/lib/commands/asr/local-transcribe.js +125 -0
- package/lib/commands/asr-jobs.js +257 -0
- package/lib/commands/asr.js +11 -0
- package/lib/commands/auth-cmds.js +358 -0
- package/lib/commands/dub.js +542 -0
- package/lib/commands/explain.js +512 -0
- package/lib/commands/feedback.js +152 -0
- package/lib/commands/image.js +207 -0
- package/lib/commands/mcp-key.js +166 -0
- package/lib/commands/narrate.js +639 -0
- package/lib/commands/picstory-templates.js +276 -0
- package/lib/commands/picstory.js +547 -0
- package/lib/commands/podcast/dialogue.js +109 -0
- package/lib/commands/podcast/generate.js +127 -0
- package/lib/commands/podcast/index.js +561 -0
- package/lib/commands/podcast/synthesize.js +188 -0
- package/lib/commands/podcast.js +11 -0
- package/lib/commands/present.js +519 -0
- package/lib/commands/publish.js +415 -0
- package/lib/commands/skills.js +473 -0
- package/lib/commands/slice-render.js +282 -0
- package/lib/commands/slice-stage.js +264 -0
- package/lib/commands/slice.js +346 -0
- package/lib/commands/slides/constants.js +108 -0
- package/lib/commands/slides/html-renderer.js +338 -0
- package/lib/commands/slides/index.js +345 -0
- package/lib/commands/slides.js +11 -0
- package/lib/commands/story.js +302 -0
- package/lib/commands/summarize.js +532 -0
- package/lib/commands/synthesize.js +261 -0
- package/lib/commands/translate.js +593 -0
- package/lib/commands/upgrade.js +249 -0
- package/lib/commands/video-translate.js +577 -0
- package/lib/commands/voices.js +292 -0
- package/lib/core/agent-env.js +104 -0
- package/lib/core/args.js +107 -0
- package/lib/core/asr-client.js +448 -0
- package/lib/core/asr-jobs-client.js +126 -0
- package/lib/core/asr-jobs-store.js +105 -0
- package/lib/core/asr-r2-upload.js +181 -0
- package/lib/core/asr-upload.js +132 -0
- package/lib/core/audio-extract.js +150 -0
- package/lib/core/audio.js +219 -0
- package/lib/core/auth.js +880 -0
- package/lib/core/config.js +197 -0
- package/lib/core/feedback.js +64 -0
- package/lib/core/ffmpeg.js +476 -0
- package/lib/core/http.js +188 -0
- package/lib/core/image-client.js +55 -0
- package/lib/core/intent-params.js +11 -0
- package/lib/core/llm-client.js +76 -0
- package/lib/core/logger.js +208 -0
- package/lib/core/mic-recorder.js +182 -0
- package/lib/core/pause-markers.js +94 -0
- package/lib/core/podcast-pacing.js +118 -0
- package/lib/core/spinner.js +33 -0
- package/lib/core/srt.js +394 -0
- package/lib/core/telemetry.js +100 -0
- package/lib/core/timeline.js +92 -0
- package/lib/core/tts-synthesizer.js +70 -0
- package/lib/core/update-check.js +185 -0
- package/lib/core/url-download.js +148 -0
- package/lib/core/whisper-local.js +279 -0
- package/lib/internal/deck-validator.js +488 -0
- package/lib/internal/slice-themes.json +370 -0
- package/lib/stage-core/cloud-render.js +170 -0
- package/lib/stage-core/deck-format.js +133 -0
- package/lib/stage-core/edit-prompt.js +104 -0
- package/lib/stage-core/event-bus.js +31 -0
- package/lib/stage-core/port.js +46 -0
- package/lib/stage-core/server.js +352 -0
- package/lib/stage-core/snapshot-store.js +198 -0
- package/lib/stage-core/watcher.js +106 -0
- package/lib/stage-ui/slice/template.js +1672 -0
- package/package.json +9 -4
- package/skills/.claude-plugin/marketplace.json +22 -0
- package/skills/.claude-plugin/plugin.json +25 -0
- package/skills/LICENSE +21 -0
- package/skills/README.md +120 -0
- package/skills/hub/SKILL.md +317 -0
- package/skills/podcast/SKILL.md +146 -0
- package/skills/slice/SKILL.md +205 -0
- package/skills/slice/agents/openai.yaml +4 -0
- package/skills/slice/references/deck-schema.md +183 -0
- package/skills/slice/references/example-decks.md +108 -0
- package/skills/slice/references/themes.md +172 -0
- package/skills/transcribe/SKILL.md +473 -0
- package/skills/video/SKILL.md +261 -0
- package/skills/voxflow-slice/SKILL.md +271 -0
- package/skills/voxflow-slice/examples/article.md +13 -0
- package/skills/voxflow-slice/examples/expected-deck.json +39 -0
- package/skills/voxflow-slice/examples/validate.mjs +46 -0
package/lib/cli.js
ADDED
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VoxFlow CLI — Subcommand router
|
|
3
|
+
*
|
|
4
|
+
* Thin dispatcher: parses the top-level command, loads the matching module,
|
|
5
|
+
* and delegates to its `handle(args)` function. Help text is assembled
|
|
6
|
+
* lazily from each command's `meta` export.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const pkg = require('../package.json');
|
|
10
|
+
const { logger, parseVerbosityFromArgv } = require('./core/logger');
|
|
11
|
+
|
|
12
|
+
// ─── Command Registry (auto-discovered, issue #2389) ────────────────────────
|
|
13
|
+
//
|
|
14
|
+
// Command modules live in ./commands/. Every module whose `meta` export is an
|
|
15
|
+
// object mapping `commandName → { description, usage, options, examples }` is
|
|
16
|
+
// picked up automatically. Aliases are meta entries with `{ alias: 'canonical' }`
|
|
17
|
+
// — no need to maintain them separately.
|
|
18
|
+
//
|
|
19
|
+
// Two special-case shapes we still handle explicitly:
|
|
20
|
+
// - `auth-cmds.js` exports named handlers (handleLogin etc.) instead of a
|
|
21
|
+
// single `handle()` — dispatched via AUTH_HANDLERS.
|
|
22
|
+
// - Files without a `meta` export (e.g. `picstory-templates.js` shared helper)
|
|
23
|
+
// are skipped.
|
|
24
|
+
|
|
25
|
+
// Auth-cmds handler name mapping (multi-handler module)
|
|
26
|
+
const AUTH_HANDLERS = {
|
|
27
|
+
login: 'handleLogin',
|
|
28
|
+
logout: 'handleLogout',
|
|
29
|
+
status: 'handleStatus',
|
|
30
|
+
dashboard: 'handleDashboard',
|
|
31
|
+
clone: 'handleClone',
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Static registry — see commands/_registry.js for why this exists.
|
|
35
|
+
// In dev cli.js is loaded from source and `lib/commands/` is on disk; in
|
|
36
|
+
// the published bundle (ncc) there is no such directory, so we always
|
|
37
|
+
// resolve through the registry instead of `fs.readdirSync`.
|
|
38
|
+
const COMMAND_REGISTRY = require('./commands/_registry');
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Build the meta registry by walking COMMAND_REGISTRY. Each entry is a
|
|
42
|
+
* lazy thunk so loading a single command does not transitively pull in
|
|
43
|
+
* every other command's deps (ffmpeg/audio/llm).
|
|
44
|
+
* Returns { COMMAND_MAP, ALIASES, META }.
|
|
45
|
+
*/
|
|
46
|
+
function discoverCommands() {
|
|
47
|
+
// Maps command name (canonical or alias) → already-loaded module reference.
|
|
48
|
+
// Storing the module directly (vs. a path string) is what makes the slow
|
|
49
|
+
// path work in the ncc-bundled dist: in dist/index.js, dynamic
|
|
50
|
+
// `require('./commands/synthesize')` strings have no on-disk path to
|
|
51
|
+
// resolve and crash with "Cannot find module". The loader thunks were
|
|
52
|
+
// already bundled at build time, so once we've called loader() we have a
|
|
53
|
+
// valid object reference that survives the bundle.
|
|
54
|
+
const COMMAND_MAP = {};
|
|
55
|
+
const ALIASES = {};
|
|
56
|
+
const META = {};
|
|
57
|
+
|
|
58
|
+
for (const [fileBase, loader] of Object.entries(COMMAND_REGISTRY)) {
|
|
59
|
+
const mod = loader();
|
|
60
|
+
if (!mod || typeof mod.meta !== 'object') continue;
|
|
61
|
+
|
|
62
|
+
for (const [name, info] of Object.entries(mod.meta)) {
|
|
63
|
+
if (!info || typeof info !== 'object') continue;
|
|
64
|
+
COMMAND_MAP[name] = mod;
|
|
65
|
+
META[name] = info;
|
|
66
|
+
// fileBase is the canonical command for this module (matches the
|
|
67
|
+
// registry key); meta entries marked `alias` point to it via name.
|
|
68
|
+
void fileBase;
|
|
69
|
+
if (typeof info.alias === 'string') {
|
|
70
|
+
ALIASES[name] = info.alias;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return { COMMAND_MAP, ALIASES, META };
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Lazy registry — scanned on first access, memoized thereafter. Hot path
|
|
80
|
+
* (canonical command dispatch) skips this entirely via fastResolveCommand.
|
|
81
|
+
*/
|
|
82
|
+
let _registry = null;
|
|
83
|
+
function getRegistry() {
|
|
84
|
+
if (!_registry) _registry = discoverCommands();
|
|
85
|
+
return _registry;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Fast path: if `<command>` is a canonical entry in COMMAND_REGISTRY (not
|
|
90
|
+
* an alias), load and return its module without iterating the rest. Returns
|
|
91
|
+
* `null` for aliases, auth-cmds handlers, and unknown commands — those fall
|
|
92
|
+
* back to the full registry scan.
|
|
93
|
+
*/
|
|
94
|
+
function fastResolveCommand(command) {
|
|
95
|
+
if (!/^[a-z][a-z0-9-]*$/i.test(command)) return null; // guard against path traversal
|
|
96
|
+
const loader = COMMAND_REGISTRY[command];
|
|
97
|
+
if (!loader) return null;
|
|
98
|
+
const mod = loader();
|
|
99
|
+
if (!mod || typeof mod.meta !== 'object') return null;
|
|
100
|
+
const entry = mod.meta[command];
|
|
101
|
+
if (!entry || entry.alias) return null;
|
|
102
|
+
return mod;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// ─── Runner ─────────────────────────────────────────────────────────────────
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Parse argv and dispatch to the appropriate handler.
|
|
109
|
+
*/
|
|
110
|
+
async function run(argv) {
|
|
111
|
+
const rawArgs = argv || process.argv.slice(2);
|
|
112
|
+
|
|
113
|
+
// Strip global verbosity flags (-v / -vv / -vvv / --verbose[=level])
|
|
114
|
+
// BEFORE the subcommand sees them. Also honours DEBUG=voxflow:*.
|
|
115
|
+
// Subcommands get a clean argv so their own flag parsers don't choke.
|
|
116
|
+
// Note: `--version`/`-v` is a special case — if the first arg IS `-v`
|
|
117
|
+
// AND it's the only arg, treat it as version (legacy behaviour).
|
|
118
|
+
if (rawArgs.length === 1 && (rawArgs[0] === '--version' || rawArgs[0] === '-v')) {
|
|
119
|
+
console.log(pkg.version);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const { level, rest: args } = parseVerbosityFromArgv(rawArgs);
|
|
123
|
+
logger.setLevel(level);
|
|
124
|
+
const command = args[0];
|
|
125
|
+
|
|
126
|
+
// Global flags
|
|
127
|
+
if (!command || command === '--help' || command === '-h') {
|
|
128
|
+
printHelp();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (command === '--version') {
|
|
133
|
+
console.log(pkg.version);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Handle --help for any subcommand before dispatching (no login required)
|
|
138
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
139
|
+
printSubcommandHelp(command);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Auth commands share a single module with multiple handlers — resolve
|
|
144
|
+
// directly without touching the registry.
|
|
145
|
+
if (AUTH_HANDLERS[command]) {
|
|
146
|
+
const mod = require('./commands/auth-cmds');
|
|
147
|
+
return mod[AUTH_HANDLERS[command]](args.slice(1));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Hot path: canonical command name maps 1:1 to a file. Skip the full
|
|
151
|
+
// scan of ./commands/ — this shaves ~30 ms off startup for common calls
|
|
152
|
+
// (voxflow synthesize, voxflow podcast, ...).
|
|
153
|
+
let handler = fastResolveCommand(command);
|
|
154
|
+
let canonical = null;
|
|
155
|
+
|
|
156
|
+
if (!handler) {
|
|
157
|
+
// Slow path: alias or unknown command — need the full registry to
|
|
158
|
+
// resolve. Pays the discovery cost once, cached for the rest of the
|
|
159
|
+
// process lifetime.
|
|
160
|
+
const { COMMAND_MAP, ALIASES } = getRegistry();
|
|
161
|
+
const mod = COMMAND_MAP[command];
|
|
162
|
+
if (!mod) {
|
|
163
|
+
console.error(`Unknown command: ${command}\nRun voxflow --help for usage.`);
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
canonical = ALIASES[command] || null;
|
|
167
|
+
handler = canonical ? COMMAND_MAP[canonical] : mod;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
await handler.handle(args.slice(1));
|
|
171
|
+
|
|
172
|
+
// Post-command feedback prompt (non-blocking, skip silently on error)
|
|
173
|
+
try {
|
|
174
|
+
const { promptFeedback } = require('./core/feedback');
|
|
175
|
+
await promptFeedback(canonical || command);
|
|
176
|
+
} catch { /* feedback is optional — never block the CLI */ }
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// ─── Help ───────────────────────────────────────────────────────────────────
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Return the auto-discovered meta registry (see discoverCommands above).
|
|
183
|
+
* Alias entries are injected by each command's own `meta` object now —
|
|
184
|
+
* no more hardcoded list in this file (issue #2389).
|
|
185
|
+
*/
|
|
186
|
+
function getAllMeta() {
|
|
187
|
+
return { ...getRegistry().META };
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function printHelp() {
|
|
191
|
+
const COMMANDS = getAllMeta();
|
|
192
|
+
|
|
193
|
+
const lines = [
|
|
194
|
+
`\nvoxflow v${pkg.version} — AI audio content creation CLI`,
|
|
195
|
+
'',
|
|
196
|
+
'Usage:',
|
|
197
|
+
' voxflow <command> [options]',
|
|
198
|
+
'',
|
|
199
|
+
'Commands:',
|
|
200
|
+
];
|
|
201
|
+
|
|
202
|
+
for (const [name, cmd] of Object.entries(COMMANDS)) {
|
|
203
|
+
if (cmd.alias) continue; // skip aliases in command list
|
|
204
|
+
const padded = (name + (cmd.usage ? ' ' + cmd.usage : '')).padEnd(18);
|
|
205
|
+
lines.push(` ${padded} ${cmd.description}`);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
lines.push('');
|
|
209
|
+
for (const [name, cmd] of Object.entries(COMMANDS)) {
|
|
210
|
+
if (cmd.alias || !cmd.options) continue;
|
|
211
|
+
const label = cmd.aliasOf ? `${name} options (alias: ${cmd.aliasOf}):` : `${name} options:`;
|
|
212
|
+
// Capitalize first letter
|
|
213
|
+
lines.push(label.charAt(0).toUpperCase() + label.slice(1));
|
|
214
|
+
lines.push(...cmd.options.map(o => ' ' + o));
|
|
215
|
+
lines.push('');
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
lines.push(
|
|
219
|
+
'Common options:',
|
|
220
|
+
' --help, -h Show help (use with a command for command-specific help)',
|
|
221
|
+
' --version, -v Show version',
|
|
222
|
+
'',
|
|
223
|
+
'Advanced options:',
|
|
224
|
+
' --api <url> Override API endpoint (for self-hosted servers)',
|
|
225
|
+
' --token <jwt> Use explicit token (CI/CD, skip browser login)',
|
|
226
|
+
'',
|
|
227
|
+
'Examples:',
|
|
228
|
+
);
|
|
229
|
+
|
|
230
|
+
for (const [, cmd] of Object.entries(COMMANDS)) {
|
|
231
|
+
if (cmd.alias || !cmd.examples) continue;
|
|
232
|
+
lines.push(...cmd.examples.map(e => ' ' + e));
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
console.log(lines.join('\n'));
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Per-subcommand help — shows usage, options, and examples for a single command.
|
|
240
|
+
* Falls back to global help for unknown commands.
|
|
241
|
+
*/
|
|
242
|
+
function printSubcommandHelp(command) {
|
|
243
|
+
const COMMANDS = getAllMeta();
|
|
244
|
+
const cmd = COMMANDS[command];
|
|
245
|
+
if (!cmd) { printHelp(); return; }
|
|
246
|
+
// Resolve alias first, then check for options
|
|
247
|
+
const resolved = cmd.alias ? COMMANDS[cmd.alias] : cmd;
|
|
248
|
+
if (!resolved || !resolved.options) { printHelp(); return; }
|
|
249
|
+
const name = cmd.alias || command;
|
|
250
|
+
|
|
251
|
+
const lines = [
|
|
252
|
+
`\nvoxflow ${name} — ${resolved.description}`,
|
|
253
|
+
'',
|
|
254
|
+
'Usage:',
|
|
255
|
+
` voxflow ${name}${resolved.usage ? ' ' + resolved.usage : ''}`,
|
|
256
|
+
'',
|
|
257
|
+
'Options:',
|
|
258
|
+
...resolved.options.map(o => ' ' + o),
|
|
259
|
+
' --api <url> Override API endpoint',
|
|
260
|
+
' --token <jwt> Use explicit token (skip browser login)',
|
|
261
|
+
];
|
|
262
|
+
|
|
263
|
+
if (resolved.examples && resolved.examples.length > 0) {
|
|
264
|
+
lines.push('', 'Examples:', ...resolved.examples.map(e => ' ' + e));
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
console.log(lines.join('\n'));
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
module.exports = { run };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Static registry of canonical command modules.
|
|
3
|
+
*
|
|
4
|
+
* Required because cli/dist/index.js (the published artifact) is produced
|
|
5
|
+
* by `ncc build` which bundles every `require()` it can statically detect.
|
|
6
|
+
* The previous auto-discovery (PR #2465) used `fs.readdirSync` against
|
|
7
|
+
* `lib/commands/` — fine in dev (where the directory exists) but invariant
|
|
8
|
+
* post-bundle: ncc has no directory to read, so every command lookup blew
|
|
9
|
+
* up with `ENOENT: no such file or directory, scandir 'dist/commands'`.
|
|
10
|
+
* That's how voxflow@1.8.2 shipped to npm and made every subcommand fail.
|
|
11
|
+
*
|
|
12
|
+
* Each entry is a thunk so we keep the lazy-load behaviour the auto-
|
|
13
|
+
* discovery refactor was designed for — the command module is only
|
|
14
|
+
* required when its name is dispatched.
|
|
15
|
+
*
|
|
16
|
+
* Adding a new command:
|
|
17
|
+
* 1. Create lib/commands/<name>.js with a `meta` export
|
|
18
|
+
* 2. Add `<name>: () => require('./<name>'),` here
|
|
19
|
+
* 3. The `cli registry parity` test will fail until both match
|
|
20
|
+
*/
|
|
21
|
+
'use strict';
|
|
22
|
+
|
|
23
|
+
module.exports = {
|
|
24
|
+
add: () => require('./add'),
|
|
25
|
+
asr: () => require('./asr'),
|
|
26
|
+
'asr-jobs': () => require('./asr-jobs'),
|
|
27
|
+
'auth-cmds': () => require('./auth-cmds'),
|
|
28
|
+
dub: () => require('./dub'),
|
|
29
|
+
explain: () => require('./explain'),
|
|
30
|
+
feedback: () => require('./feedback'),
|
|
31
|
+
image: () => require('./image'),
|
|
32
|
+
'mcp-key': () => require('./mcp-key'),
|
|
33
|
+
narrate: () => require('./narrate'),
|
|
34
|
+
picstory: () => require('./picstory'),
|
|
35
|
+
podcast: () => require('./podcast'),
|
|
36
|
+
present: () => require('./present'),
|
|
37
|
+
publish: () => require('./publish'),
|
|
38
|
+
skills: () => require('./skills'),
|
|
39
|
+
slice: () => require('./slice'),
|
|
40
|
+
slides: () => require('./slides'),
|
|
41
|
+
story: () => require('./story'),
|
|
42
|
+
summarize: () => require('./summarize'),
|
|
43
|
+
synthesize: () => require('./synthesize'),
|
|
44
|
+
translate: () => require('./translate'),
|
|
45
|
+
upgrade: () => require('./upgrade'),
|
|
46
|
+
'video-translate': () => require('./video-translate'),
|
|
47
|
+
voices: () => require('./voices'),
|
|
48
|
+
};
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VoxFlow CLI — `voxflow add <name>`
|
|
3
|
+
*
|
|
4
|
+
* Pulls a flow / voice-recipe / preset from the configured registry into
|
|
5
|
+
* the local project. Day-1 MVP: no dependsOn cascading, no ETag cache,
|
|
6
|
+
* no private-registry token — those are RFC §3.2/§4.2/§4.3 territory and
|
|
7
|
+
* land in Phase 2.
|
|
8
|
+
*
|
|
9
|
+
* Resolution rule (per RFC §7.3):
|
|
10
|
+
* - input "foo" → ${defaultAuthor}/foo
|
|
11
|
+
* - input "owner/foo" → owner/foo
|
|
12
|
+
*
|
|
13
|
+
* Type → local folder:
|
|
14
|
+
* - voxflow:flow → flows/<name>/...
|
|
15
|
+
* - voxflow:voice-recipe → recipes/<name>/...
|
|
16
|
+
* - voxflow:preset → presets/<name>/...
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
'use strict';
|
|
20
|
+
|
|
21
|
+
const fs = require('fs');
|
|
22
|
+
const path = require('path');
|
|
23
|
+
const http = require('http');
|
|
24
|
+
const https = require('https');
|
|
25
|
+
const { URL } = require('url');
|
|
26
|
+
|
|
27
|
+
const DEFAULT_REGISTRY = 'https://raw.githubusercontent.com/VoxFlowStudio/skills/main';
|
|
28
|
+
const DEFAULT_AUTHOR = 'voxflow';
|
|
29
|
+
|
|
30
|
+
const TYPE_TO_DIR = {
|
|
31
|
+
'voxflow:flow': 'flows',
|
|
32
|
+
'voxflow:voice-recipe': 'recipes',
|
|
33
|
+
'voxflow:preset': 'presets',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// ─── HTTP fetch (raw text, distinct from core/http.js which JSON.parses) ────
|
|
37
|
+
|
|
38
|
+
function fetchText(url) {
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
const u = new URL(url);
|
|
41
|
+
const mod = u.protocol === 'https:' ? https : http;
|
|
42
|
+
mod.get(u, (res) => {
|
|
43
|
+
if (res.statusCode === 301 || res.statusCode === 302) {
|
|
44
|
+
// Follow one redirect (raw.githubusercontent.com sometimes does this)
|
|
45
|
+
if (res.headers.location) {
|
|
46
|
+
fetchText(res.headers.location).then(resolve, reject);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (res.statusCode !== 200) {
|
|
51
|
+
reject(new Error(`HTTP ${res.statusCode} fetching ${url}`));
|
|
52
|
+
res.resume();
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const chunks = [];
|
|
56
|
+
res.on('data', (c) => chunks.push(c));
|
|
57
|
+
res.on('end', () => resolve(Buffer.concat(chunks).toString('utf8')));
|
|
58
|
+
}).on('error', (err) => reject(err));
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ─── Pure helpers (exported for tests) ──────────────────────────────────────
|
|
63
|
+
|
|
64
|
+
function resolveItemName(input, defaultAuthor) {
|
|
65
|
+
if (input.includes('/')) {
|
|
66
|
+
const [author, name] = input.split('/', 2);
|
|
67
|
+
return { author, name, key: `${author}/${name}` };
|
|
68
|
+
}
|
|
69
|
+
return { author: defaultAuthor, name: input, key: `${defaultAuthor}/${input}` };
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function localTargetForFile(item, filePath) {
|
|
73
|
+
// Registry path: <author>/<name>/<rest> → strip prefix
|
|
74
|
+
const prefix = `${item.author}/${item.name}/`;
|
|
75
|
+
const rest = filePath.startsWith(prefix) ? filePath.slice(prefix.length) : filePath;
|
|
76
|
+
const baseDir = TYPE_TO_DIR[item.type] || 'voxflow-items';
|
|
77
|
+
return path.join(baseDir, item.name, rest);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function findItem(registry, author, name) {
|
|
81
|
+
return registry.items.find(
|
|
82
|
+
(it) => (it.author || DEFAULT_AUTHOR) === author && it.name === name
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function suggestNearby(registry, name) {
|
|
87
|
+
const all = registry.items.map((it) => `${it.author || DEFAULT_AUTHOR}/${it.name}`);
|
|
88
|
+
// Naive substring suggestion — enough for human readable error
|
|
89
|
+
return all.filter((slug) => slug.includes(name) || name.includes(slug.split('/')[1])).slice(0, 5);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// ─── Main entry ─────────────────────────────────────────────────────────────
|
|
93
|
+
|
|
94
|
+
async function add(opts) {
|
|
95
|
+
const {
|
|
96
|
+
name: rawName,
|
|
97
|
+
registry: registryUrl = DEFAULT_REGISTRY,
|
|
98
|
+
defaultAuthor = DEFAULT_AUTHOR,
|
|
99
|
+
targetRoot = process.cwd(),
|
|
100
|
+
force = false,
|
|
101
|
+
log = console.log,
|
|
102
|
+
} = opts;
|
|
103
|
+
|
|
104
|
+
if (!rawName) {
|
|
105
|
+
throw new Error(`add_missing_name: voxflow add <name> — see voxflow add --help`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const { author, name, key } = resolveItemName(rawName, defaultAuthor);
|
|
109
|
+
|
|
110
|
+
// 1. Fetch registry index
|
|
111
|
+
log(`◆ Fetching registry index: ${registryUrl}/registry.json`);
|
|
112
|
+
let indexRaw;
|
|
113
|
+
try {
|
|
114
|
+
indexRaw = await fetchText(`${registryUrl}/registry.json`);
|
|
115
|
+
} catch (err) {
|
|
116
|
+
throw new Error(`registry_unreachable: ${err.message}\n fix: check network or pass --registry <url>`);
|
|
117
|
+
}
|
|
118
|
+
let registry;
|
|
119
|
+
try {
|
|
120
|
+
registry = JSON.parse(indexRaw);
|
|
121
|
+
} catch (err) {
|
|
122
|
+
throw new Error(`registry_invalid_json: ${registryUrl}/registry.json\n fix: check the registry repo is healthy`);
|
|
123
|
+
}
|
|
124
|
+
if (!registry || !Array.isArray(registry.items)) {
|
|
125
|
+
throw new Error(`registry_invalid_shape: missing items[] in registry.json`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// 2. Locate item
|
|
129
|
+
const item = findItem(registry, author, name);
|
|
130
|
+
if (!item) {
|
|
131
|
+
const nearby = suggestNearby(registry, name);
|
|
132
|
+
const suggestion = nearby.length
|
|
133
|
+
? `\n did you mean: ${nearby.join(', ')}`
|
|
134
|
+
: `\n fix: voxflow add --list to see available items`;
|
|
135
|
+
throw new Error(`item_not_found: ${key}${suggestion}`);
|
|
136
|
+
}
|
|
137
|
+
if (!Array.isArray(item.files) || item.files.length === 0) {
|
|
138
|
+
throw new Error(`item_empty_files: ${key} declares no files in registry`);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// 3. Download each file
|
|
142
|
+
log(`◆ Resolving ${key} (${item.type}) v${item.version || 'unversioned'}`);
|
|
143
|
+
const written = [];
|
|
144
|
+
const skipped = [];
|
|
145
|
+
for (const filePath of item.files) {
|
|
146
|
+
const target = path.join(targetRoot, localTargetForFile(item, filePath));
|
|
147
|
+
if (fs.existsSync(target) && !force) {
|
|
148
|
+
skipped.push(target);
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
const fileUrl = `${registryUrl}/${filePath}`;
|
|
152
|
+
let body;
|
|
153
|
+
try {
|
|
154
|
+
body = await fetchText(fileUrl);
|
|
155
|
+
} catch (err) {
|
|
156
|
+
throw new Error(`file_fetch_failed: ${fileUrl}\n ${err.message}`);
|
|
157
|
+
}
|
|
158
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
159
|
+
fs.writeFileSync(target, body);
|
|
160
|
+
written.push(target);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// 4. Print summary
|
|
164
|
+
log(`✓ Added ${key} (${item.type})${item.version ? ' v' + item.version : ''}`);
|
|
165
|
+
for (const w of written) {
|
|
166
|
+
log(` ${path.relative(targetRoot, w)}`);
|
|
167
|
+
}
|
|
168
|
+
if (skipped.length) {
|
|
169
|
+
log(`\n Skipped (use --force to overwrite):`);
|
|
170
|
+
for (const s of skipped) {
|
|
171
|
+
log(` ${path.relative(targetRoot, s)}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
if (item.tryWith) {
|
|
175
|
+
log(`\nTry it:\n ${item.tryWith}`);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
return { item, written, skipped };
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ─── CLI handle ─────────────────────────────────────────────────────────────
|
|
182
|
+
|
|
183
|
+
async function handle(args) {
|
|
184
|
+
// Sub-flags
|
|
185
|
+
const opts = {};
|
|
186
|
+
// First positional that isn't a flag → name
|
|
187
|
+
const flagless = args.filter((a, i) => {
|
|
188
|
+
if (a.startsWith('--')) return false;
|
|
189
|
+
if (i > 0 && args[i - 1].startsWith('--') && !args[i - 1].includes('=')) return false;
|
|
190
|
+
return true;
|
|
191
|
+
});
|
|
192
|
+
opts.name = flagless[0];
|
|
193
|
+
|
|
194
|
+
for (let i = 0; i < args.length; i++) {
|
|
195
|
+
if (args[i] === '--registry' && args[i + 1]) opts.registry = args[++i];
|
|
196
|
+
else if (args[i] === '--default-author' && args[i + 1]) opts.defaultAuthor = args[++i];
|
|
197
|
+
else if (args[i] === '--force') opts.force = true;
|
|
198
|
+
else if (args[i] === '--list') opts.list = true;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// --list short-circuits before name validation
|
|
202
|
+
if (opts.list) {
|
|
203
|
+
const url = (opts.registry || DEFAULT_REGISTRY) + '/registry.json';
|
|
204
|
+
const indexRaw = await fetchText(url);
|
|
205
|
+
const registry = JSON.parse(indexRaw);
|
|
206
|
+
console.log(`Registry: ${registry.name} v${registry.version || 'unversioned'}\n`);
|
|
207
|
+
for (const it of registry.items) {
|
|
208
|
+
const slug = `${it.author || DEFAULT_AUTHOR}/${it.name}`;
|
|
209
|
+
console.log(` ${slug.padEnd(36)} ${it.type.padEnd(22)} ${it.description || ''}`);
|
|
210
|
+
}
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
await add(opts);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const meta = {
|
|
218
|
+
add: {
|
|
219
|
+
usage: '<name> [opts]',
|
|
220
|
+
description: 'Pull a flow / voice-recipe / preset from the registry into the current project',
|
|
221
|
+
options: [
|
|
222
|
+
`--registry <url> Override registry URL (default: ${DEFAULT_REGISTRY})`,
|
|
223
|
+
`--default-author <name> Resolve unscoped names against this author (default: ${DEFAULT_AUTHOR})`,
|
|
224
|
+
`--force Overwrite existing local files`,
|
|
225
|
+
`--list List all items in the registry`,
|
|
226
|
+
],
|
|
227
|
+
examples: [
|
|
228
|
+
'voxflow add dub-anime-jp-zh',
|
|
229
|
+
'voxflow add chico/my-custom-recipe',
|
|
230
|
+
'voxflow add --list',
|
|
231
|
+
'voxflow add foo --registry https://example.com/voxflow-registry/main',
|
|
232
|
+
],
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
module.exports = {
|
|
237
|
+
add,
|
|
238
|
+
handle,
|
|
239
|
+
meta,
|
|
240
|
+
// Exported for tests
|
|
241
|
+
_internal: { resolveItemName, localTargetForFile, findItem, suggestNearby },
|
|
242
|
+
};
|