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.
Files changed (453) hide show
  1. package/README.md +34 -0
  2. package/bin/voxflow.js +27 -0
  3. package/dist/index.js +1 -1
  4. package/dist/remotion-bundle/02a2fb2eb80bc7bf.woff2 +0 -0
  5. package/dist/remotion-bundle/052ca5351e5e06ba.woff2 +0 -0
  6. package/dist/remotion-bundle/05853dd28f4019cb.woff2 +0 -0
  7. package/dist/remotion-bundle/072ead3737f7c0d0.woff2 +0 -0
  8. package/dist/remotion-bundle/07d4248613c86a2e.woff2 +0 -0
  9. package/dist/remotion-bundle/0884a5c2d1d2d99b.woff2 +0 -0
  10. package/dist/remotion-bundle/0b0e185b2752095e.woff2 +0 -0
  11. package/dist/remotion-bundle/0e66c11bde067d91.woff2 +0 -0
  12. package/dist/remotion-bundle/0f7794cfba2c5d21.woff2 +0 -0
  13. package/dist/remotion-bundle/0fdbae5a4365783a.woff2 +0 -0
  14. package/dist/remotion-bundle/112.bundle.js +11 -0
  15. package/dist/remotion-bundle/112.bundle.js.map +1 -0
  16. package/dist/remotion-bundle/113.bundle.js +11 -0
  17. package/dist/remotion-bundle/113.bundle.js.map +1 -0
  18. package/dist/remotion-bundle/119cae0c4c16f7ed.woff2 +0 -0
  19. package/dist/remotion-bundle/14725f649fd1e78c.woff2 +0 -0
  20. package/dist/remotion-bundle/14abe9e3f95f7888.woff2 +0 -0
  21. package/dist/remotion-bundle/163.bundle.js +14678 -0
  22. package/dist/remotion-bundle/163.bundle.js.map +1 -0
  23. package/dist/remotion-bundle/1808c54072bf6d14.woff2 +0 -0
  24. package/dist/remotion-bundle/18948bec3e3012fe.woff2 +0 -0
  25. package/dist/remotion-bundle/1a661c60d0fc84fc.woff2 +0 -0
  26. package/dist/remotion-bundle/1af94941e1bc7e1e.woff2 +0 -0
  27. package/dist/remotion-bundle/1bee0219595f606c.woff2 +0 -0
  28. package/dist/remotion-bundle/1bfd5da7ce9d4ec4.woff2 +0 -0
  29. package/dist/remotion-bundle/1c158d56f1884f3f.woff2 +0 -0
  30. package/dist/remotion-bundle/1cf5e88e667610eb.woff2 +0 -0
  31. package/dist/remotion-bundle/1d431bd10f53c481.woff2 +0 -0
  32. package/dist/remotion-bundle/1d701a81a7670db2.woff2 +0 -0
  33. package/dist/remotion-bundle/1da0fecad4240f16.woff2 +0 -0
  34. package/dist/remotion-bundle/1ed14d3d0c5c63fe.woff2 +0 -0
  35. package/dist/remotion-bundle/1edfecf40e586f53.woff2 +0 -0
  36. package/dist/remotion-bundle/1f479711bc34b054.woff +0 -0
  37. package/dist/remotion-bundle/1f86e54a0ff5fcd1.woff2 +0 -0
  38. package/dist/remotion-bundle/2043ea87d9aabd11.woff2 +0 -0
  39. package/dist/remotion-bundle/20563c39ee8a0e40.woff2 +0 -0
  40. package/dist/remotion-bundle/20c231590fd12c44.woff2 +0 -0
  41. package/dist/remotion-bundle/20ce61713f754c07.woff2 +0 -0
  42. package/dist/remotion-bundle/21eb9306fce24bb1.woff2 +0 -0
  43. package/dist/remotion-bundle/244bf71c0cc851af.woff2 +0 -0
  44. package/dist/remotion-bundle/274d4cfc02bffbcb.woff2 +0 -0
  45. package/dist/remotion-bundle/275.bundle.js +21 -0
  46. package/dist/remotion-bundle/275.bundle.js.map +1 -0
  47. package/dist/remotion-bundle/2958f540b39513dc.woff2 +0 -0
  48. package/dist/remotion-bundle/2a168b98fd97722e.woff2 +0 -0
  49. package/dist/remotion-bundle/2d1f6373937ab55f.woff2 +0 -0
  50. package/dist/remotion-bundle/2d213ae47ff6daa9.woff2 +0 -0
  51. package/dist/remotion-bundle/2e4b1f04fcd05047.woff2 +0 -0
  52. package/dist/remotion-bundle/304170d98f4c4563.woff2 +0 -0
  53. package/dist/remotion-bundle/30d02e136e7a5642.woff2 +0 -0
  54. package/dist/remotion-bundle/3135562b52a714cd.woff2 +0 -0
  55. package/dist/remotion-bundle/313713af2c8144e9.woff2 +0 -0
  56. package/dist/remotion-bundle/325fa4108d2285b9.woff2 +0 -0
  57. package/dist/remotion-bundle/338e927ed3345e0c.woff2 +0 -0
  58. package/dist/remotion-bundle/35fc6b190365bc17.woff2 +0 -0
  59. package/dist/remotion-bundle/37a51f1122d4efc5.woff2 +0 -0
  60. package/dist/remotion-bundle/39a4d63e02736f5e.woff2 +0 -0
  61. package/dist/remotion-bundle/3a00e0d62dfc4171.woff2 +0 -0
  62. package/dist/remotion-bundle/3a6955e6561affe1.woff2 +0 -0
  63. package/dist/remotion-bundle/3c573945aef49b89.woff2 +0 -0
  64. package/dist/remotion-bundle/3cdbfbfa23b516a5.woff2 +0 -0
  65. package/dist/remotion-bundle/3e42f85a9e64ca8a.woff2 +0 -0
  66. package/dist/remotion-bundle/3e83eaf1ec859415.woff2 +0 -0
  67. package/dist/remotion-bundle/3f3c8c90de1250ee.woff2 +0 -0
  68. package/dist/remotion-bundle/434.bundle.js +205 -0
  69. package/dist/remotion-bundle/434.bundle.js.map +1 -0
  70. package/dist/remotion-bundle/44ffc6ca4d781692.woff2 +0 -0
  71. package/dist/remotion-bundle/4670d9c4580b09eb.woff2 +0 -0
  72. package/dist/remotion-bundle/479756881b302824.woff2 +0 -0
  73. package/dist/remotion-bundle/481b82134bfa9c82.woff2 +0 -0
  74. package/dist/remotion-bundle/48d27029626f4328.woff2 +0 -0
  75. package/dist/remotion-bundle/49b7b2a30329c511.woff2 +0 -0
  76. package/dist/remotion-bundle/4c8b25a1a9337045.woff2 +0 -0
  77. package/dist/remotion-bundle/4cba14788ca9259b.woff2 +0 -0
  78. package/dist/remotion-bundle/4cd6c589c004a6a7.woff2 +0 -0
  79. package/dist/remotion-bundle/4cd8d79c1021608d.woff2 +0 -0
  80. package/dist/remotion-bundle/4d8fa99b3f00f9f0.woff2 +0 -0
  81. package/dist/remotion-bundle/4e7805a643f86d53.woff2 +0 -0
  82. package/dist/remotion-bundle/4ff91be454542e3f.woff2 +0 -0
  83. package/dist/remotion-bundle/504cbcba1f63591b.woff2 +0 -0
  84. package/dist/remotion-bundle/5202d792e5791d6c.woff2 +0 -0
  85. package/dist/remotion-bundle/534db5ad4770cc1d.woff2 +0 -0
  86. package/dist/remotion-bundle/53b9568eb85f866b.woff2 +0 -0
  87. package/dist/remotion-bundle/543ad386ca171de9.woff2 +0 -0
  88. package/dist/remotion-bundle/54798e55bbf7976e.woff2 +0 -0
  89. package/dist/remotion-bundle/580.bundle.js +11 -0
  90. package/dist/remotion-bundle/580.bundle.js.map +1 -0
  91. package/dist/remotion-bundle/58d174d1193af6d1.woff2 +0 -0
  92. package/dist/remotion-bundle/591d29ff3ff53c80.woff2 +0 -0
  93. package/dist/remotion-bundle/5c28c4f4824383c6.woff2 +0 -0
  94. package/dist/remotion-bundle/5da9740d2ce894c8.woff2 +0 -0
  95. package/dist/remotion-bundle/6197735364642360.woff2 +0 -0
  96. package/dist/remotion-bundle/6265a4335724080f.woff2 +0 -0
  97. package/dist/remotion-bundle/633f5e4f6394daa7.woff2 +0 -0
  98. package/dist/remotion-bundle/637d95ace6a69c49.woff2 +0 -0
  99. package/dist/remotion-bundle/648e04a04dacff8f.woff2 +0 -0
  100. package/dist/remotion-bundle/64a6e83045a008b2.woff2 +0 -0
  101. package/dist/remotion-bundle/651.bundle.js +11 -0
  102. package/dist/remotion-bundle/651.bundle.js.map +1 -0
  103. package/dist/remotion-bundle/65e2a988c070facc.woff2 +0 -0
  104. package/dist/remotion-bundle/66a2f6ce5cc69105.woff2 +0 -0
  105. package/dist/remotion-bundle/690.bundle.js +3479 -0
  106. package/dist/remotion-bundle/690.bundle.js.map +1 -0
  107. package/dist/remotion-bundle/690ff55252ca715d.woff2 +0 -0
  108. package/dist/remotion-bundle/6a01a1cff49314fc.woff2 +0 -0
  109. package/dist/remotion-bundle/6cbc32670982986c.woff2 +0 -0
  110. package/dist/remotion-bundle/6d3cc42ae547f454.woff2 +0 -0
  111. package/dist/remotion-bundle/6d8f4cfa1ddc0830.woff2 +0 -0
  112. package/dist/remotion-bundle/6e4d7c6ae65e2dc3.woff2 +0 -0
  113. package/dist/remotion-bundle/6e86418bbcefb2e8.woff2 +0 -0
  114. package/dist/remotion-bundle/6ee02884b29cf7fb.woff2 +0 -0
  115. package/dist/remotion-bundle/6f436a74c9e3252c.woff2 +0 -0
  116. package/dist/remotion-bundle/78c8022f1657618b.woff2 +0 -0
  117. package/dist/remotion-bundle/7c5444169792bca4.woff2 +0 -0
  118. package/dist/remotion-bundle/7c86bddd9d997212.woff2 +0 -0
  119. package/dist/remotion-bundle/7e1284684767f584.woff2 +0 -0
  120. package/dist/remotion-bundle/7e81c17522d182b2.woff2 +0 -0
  121. package/dist/remotion-bundle/7eb87be198f7858c.woff2 +0 -0
  122. package/dist/remotion-bundle/8060c928f948aab5.woff2 +0 -0
  123. package/dist/remotion-bundle/80bc9dfbea2b35ae.woff2 +0 -0
  124. package/dist/remotion-bundle/811b83f69963bb48.woff2 +0 -0
  125. package/dist/remotion-bundle/813.bundle.js +117511 -0
  126. package/dist/remotion-bundle/813.bundle.js.map +1 -0
  127. package/dist/remotion-bundle/84df492e349f82e9.woff2 +0 -0
  128. package/dist/remotion-bundle/8501bfd73eb36f2b.woff2 +0 -0
  129. package/dist/remotion-bundle/854236a8376093fe.woff2 +0 -0
  130. package/dist/remotion-bundle/8571d74529082753.woff2 +0 -0
  131. package/dist/remotion-bundle/860bf44f8e6f4b5d.woff2 +0 -0
  132. package/dist/remotion-bundle/879.bundle.js +64 -0
  133. package/dist/remotion-bundle/879.bundle.js.map +1 -0
  134. package/dist/remotion-bundle/887dd482f848d56f.woff2 +0 -0
  135. package/dist/remotion-bundle/89b2132e85fbbb5a.woff2 +0 -0
  136. package/dist/remotion-bundle/8ba60d6c306010c2.woff2 +0 -0
  137. package/dist/remotion-bundle/8c7c4dadea897806.woff2 +0 -0
  138. package/dist/remotion-bundle/8c943f9999706f61.woff2 +0 -0
  139. package/dist/remotion-bundle/8f2a718c90575cc9.woff2 +0 -0
  140. package/dist/remotion-bundle/906b6edb3e1772c9.woff2 +0 -0
  141. package/dist/remotion-bundle/930ff9daccdf14eb.woff2 +0 -0
  142. package/dist/remotion-bundle/934db2f1c403c4d0.woff2 +0 -0
  143. package/dist/remotion-bundle/938.bundle.js +451 -0
  144. package/dist/remotion-bundle/938.bundle.js.map +1 -0
  145. package/dist/remotion-bundle/967.bundle.js +4462 -0
  146. package/dist/remotion-bundle/967.bundle.js.map +1 -0
  147. package/dist/remotion-bundle/9684a1093d3c02ce.woff2 +0 -0
  148. package/dist/remotion-bundle/973dcd0faa6116cc.woff2 +0 -0
  149. package/dist/remotion-bundle/9745400694e76cd8.woff2 +0 -0
  150. package/dist/remotion-bundle/999ef957bed3bdca.woff2 +0 -0
  151. package/dist/remotion-bundle/99a3d67c8b0f43e3.woff2 +0 -0
  152. package/dist/remotion-bundle/a0586c3e03127283.woff2 +0 -0
  153. package/dist/remotion-bundle/a0eb654fdae46269.woff2 +0 -0
  154. package/dist/remotion-bundle/a20e35d3b08f7994.woff2 +0 -0
  155. package/dist/remotion-bundle/a2dcaced7c8c25ab.woff2 +0 -0
  156. package/dist/remotion-bundle/a79255a972a2681a.woff2 +0 -0
  157. package/dist/remotion-bundle/a804b352cb9fec1a.woff2 +0 -0
  158. package/dist/remotion-bundle/aae7117164e1eabc.woff2 +0 -0
  159. package/dist/remotion-bundle/affd121385d0442d.woff2 +0 -0
  160. package/dist/remotion-bundle/b19a6083987ee0d7.woff2 +0 -0
  161. package/dist/remotion-bundle/b1b2bd04d8637981.woff2 +0 -0
  162. package/dist/remotion-bundle/b2c07f341486be87.woff2 +0 -0
  163. package/dist/remotion-bundle/b33d8f82e575c4ce.woff2 +0 -0
  164. package/dist/remotion-bundle/b366c0bed35ef491.woff2 +0 -0
  165. package/dist/remotion-bundle/b41e857ec1b85642.woff2 +0 -0
  166. package/dist/remotion-bundle/b420bb34ccf23e7f.woff2 +0 -0
  167. package/dist/remotion-bundle/b4f7bf4efb0c0ccf.woff2 +0 -0
  168. package/dist/remotion-bundle/b60fe5eca03cff93.woff2 +0 -0
  169. package/dist/remotion-bundle/b6bd31a336e64bce.woff2 +0 -0
  170. package/dist/remotion-bundle/b6d2befba3dfefeb.woff2 +0 -0
  171. package/dist/remotion-bundle/b75f39ab06c43bf4.woff2 +0 -0
  172. package/dist/remotion-bundle/b77880e8c413d4fd.woff2 +0 -0
  173. package/dist/remotion-bundle/b7e38ec441e4a77a.woff2 +0 -0
  174. package/dist/remotion-bundle/b83baa383ff0bf2b.woff2 +0 -0
  175. package/dist/remotion-bundle/b9ad7b6c0a11450a.woff2 +0 -0
  176. package/dist/remotion-bundle/baf84486e8ae3aaf.woff2 +0 -0
  177. package/dist/remotion-bundle/bc047b1f6869cffa.woff2 +0 -0
  178. package/dist/remotion-bundle/bf4f3ac6e93f33aa.woff2 +0 -0
  179. package/dist/remotion-bundle/bf6835ffec5897a2.woff2 +0 -0
  180. package/dist/remotion-bundle/bf8885f581eb1724.woff2 +0 -0
  181. package/dist/remotion-bundle/bundle.js +83376 -0
  182. package/dist/remotion-bundle/bundle.js.map +1 -0
  183. package/dist/remotion-bundle/c03f046bccd789d0.woff2 +0 -0
  184. package/dist/remotion-bundle/c0bb1f8962b73bc3.woff2 +0 -0
  185. package/dist/remotion-bundle/c1003f9a7db6e1cf.woff2 +0 -0
  186. package/dist/remotion-bundle/c15d83fb1e199515.woff2 +0 -0
  187. package/dist/remotion-bundle/c28e7e5d310f73ef.woff2 +0 -0
  188. package/dist/remotion-bundle/c2b840274db78aea.woff2 +0 -0
  189. package/dist/remotion-bundle/c3000e3299d4e45f.woff2 +0 -0
  190. package/dist/remotion-bundle/c83ce886e5288510.woff2 +0 -0
  191. package/dist/remotion-bundle/c87a5a64d4ac0918.woff2 +0 -0
  192. package/dist/remotion-bundle/c8a7e0d049e965fa.woff2 +0 -0
  193. package/dist/remotion-bundle/c949a35d3a3b1faf.woff2 +0 -0
  194. package/dist/remotion-bundle/c9618c9b9ac2bc78.woff2 +0 -0
  195. package/dist/remotion-bundle/ca3add3b84152d5b.woff2 +0 -0
  196. package/dist/remotion-bundle/cad9dd036408d707.woff2 +0 -0
  197. package/dist/remotion-bundle/cbb24916619df439.woff2 +0 -0
  198. package/dist/remotion-bundle/cc054f0b5514e177.woff2 +0 -0
  199. package/dist/remotion-bundle/ccc248ed9312bc71.woff2 +0 -0
  200. package/dist/remotion-bundle/cd9d623aa07af925.woff2 +0 -0
  201. package/dist/remotion-bundle/ce2ba7a321bd1247.woff2 +0 -0
  202. package/dist/remotion-bundle/cf72455f79a29b14.woff2 +0 -0
  203. package/dist/remotion-bundle/d267cbfefab452ac.woff2 +0 -0
  204. package/dist/remotion-bundle/d435cff46a64955f.woff +0 -0
  205. package/dist/remotion-bundle/d494d07f67e363f6.woff2 +0 -0
  206. package/dist/remotion-bundle/d7aa0cc1fa47bf38.woff2 +0 -0
  207. package/dist/remotion-bundle/d7c5ca93d885160a.woff2 +0 -0
  208. package/dist/remotion-bundle/d855d3e252db74e2.woff2 +0 -0
  209. package/dist/remotion-bundle/d8f13d47f02f82c2.woff2 +0 -0
  210. package/dist/remotion-bundle/d9567cce2ee11019.woff2 +0 -0
  211. package/dist/remotion-bundle/db8d4456fc75dd86.woff +0 -0
  212. package/dist/remotion-bundle/dc274628378c47ee.woff2 +0 -0
  213. package/dist/remotion-bundle/dc3e06947bb69903.woff2 +0 -0
  214. package/dist/remotion-bundle/dd67040ac3b6d523.woff2 +0 -0
  215. package/dist/remotion-bundle/e0b04bd488f953f4.woff2 +0 -0
  216. package/dist/remotion-bundle/e2a572ff95089370.woff2 +0 -0
  217. package/dist/remotion-bundle/e2e18a86b1c2b0cc.woff2 +0 -0
  218. package/dist/remotion-bundle/e3a78ee2fc9c6931.woff2 +0 -0
  219. package/dist/remotion-bundle/e654c9d547605a9f.woff2 +0 -0
  220. package/dist/remotion-bundle/e67a3a64c129927c.woff2 +0 -0
  221. package/dist/remotion-bundle/e6be28b4203cd6ce.woff2 +0 -0
  222. package/dist/remotion-bundle/e841907ad9b0a191.woff +0 -0
  223. package/dist/remotion-bundle/e889d1541c69fffa.woff2 +0 -0
  224. package/dist/remotion-bundle/e88ef8c76373a9e2.woff2 +0 -0
  225. package/dist/remotion-bundle/e9c72f4bc37defef.woff2 +0 -0
  226. package/dist/remotion-bundle/e9e35f863403a255.woff2 +0 -0
  227. package/dist/remotion-bundle/eb23b37b009375da.woff2 +0 -0
  228. package/dist/remotion-bundle/ee1342b741625721.woff2 +0 -0
  229. package/dist/remotion-bundle/f07da88543a57ec9.woff2 +0 -0
  230. package/dist/remotion-bundle/f522982115306f8a.woff2 +0 -0
  231. package/dist/remotion-bundle/f8449bd864e6d8bc.woff2 +0 -0
  232. package/dist/remotion-bundle/f906dd5bd95ff9ab.woff2 +0 -0
  233. package/dist/remotion-bundle/f9e9e9413e3c38bb.woff2 +0 -0
  234. package/dist/remotion-bundle/fa5a5b16280994a8.woff2 +0 -0
  235. package/dist/remotion-bundle/favicon.ico +0 -0
  236. package/dist/remotion-bundle/fb19c0517725599b.woff2 +0 -0
  237. package/dist/remotion-bundle/fcaf24232f684b9b.woff2 +0 -0
  238. package/dist/remotion-bundle/fe09e084a3eea8cf.woff2 +0 -0
  239. package/dist/remotion-bundle/ff38d5317df7345a.woff2 +0 -0
  240. package/dist/remotion-bundle/ffe7ea1ea08f455a.woff2 +0 -0
  241. package/dist/remotion-bundle/index.html +49 -0
  242. package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaomei/communication/0.mp3 +0 -0
  243. package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaomei/communication/1.mp3 +0 -0
  244. package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaomei/communication/2.mp3 +0 -0
  245. package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaomei/communication/3.mp3 +0 -0
  246. package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoxin/career/0.mp3 +0 -0
  247. package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoxin/career/1.mp3 +0 -0
  248. package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoxin/career/2.mp3 +0 -0
  249. package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoxin/career/3.mp3 +0 -0
  250. package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoyue/parenting/0.mp3 +0 -0
  251. package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoyue/parenting/1.mp3 +0 -0
  252. package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoyue/parenting/2.mp3 +0 -0
  253. package/dist/remotion-bundle/public/paper-slide/female-kefu-xiaoyue/parenting/3.mp3 +0 -0
  254. package/dist/remotion-bundle/public/paper-slide/male-kefu-xiaoxu/time-trap/0.mp3 +0 -0
  255. package/dist/remotion-bundle/public/paper-slide/male-kefu-xiaoxu/time-trap/1.mp3 +0 -0
  256. package/dist/remotion-bundle/public/paper-slide/male-kefu-xiaoxu/time-trap/2.mp3 +0 -0
  257. package/dist/remotion-bundle/public/paper-slide/male-kefu-xiaoxu/time-trap/3.mp3 +0 -0
  258. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/cognition/0.mp3 +0 -0
  259. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/cognition/1.mp3 +0 -0
  260. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/cognition/2.mp3 +0 -0
  261. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/cognition/3.mp3 +0 -0
  262. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/growth/0.mp3 +0 -0
  263. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/growth/1.mp3 +0 -0
  264. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/growth/2.mp3 +0 -0
  265. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/growth/3.mp3 +0 -0
  266. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/parenting/0.mp3 +0 -0
  267. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/parenting/1.mp3 +0 -0
  268. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/parenting/2.mp3 +0 -0
  269. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/parenting/3.mp3 +0 -0
  270. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/soothing/0.mp3 +0 -0
  271. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/soothing/1.mp3 +0 -0
  272. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/soothing/2.mp3 +0 -0
  273. package/dist/remotion-bundle/public/paper-slide/v-female-A6b7WpG3/soothing/3.mp3 +0 -0
  274. package/dist/remotion-bundle/public/paper-slide/v-female-R2s4N9qJ/cognition/0.mp3 +0 -0
  275. package/dist/remotion-bundle/public/paper-slide/v-female-R2s4N9qJ/cognition/1.mp3 +0 -0
  276. package/dist/remotion-bundle/public/paper-slide/v-female-R2s4N9qJ/cognition/2.mp3 +0 -0
  277. package/dist/remotion-bundle/public/paper-slide/v-female-R2s4N9qJ/cognition/3.mp3 +0 -0
  278. package/dist/remotion-bundle/public/paper-slide/v-male-Bk7vD3xP/decision/0.mp3 +0 -0
  279. package/dist/remotion-bundle/public/paper-slide/v-male-Bk7vD3xP/decision/1.mp3 +0 -0
  280. package/dist/remotion-bundle/public/paper-slide/v-male-Bk7vD3xP/decision/2.mp3 +0 -0
  281. package/dist/remotion-bundle/public/paper-slide/v-male-Bk7vD3xP/decision/3.mp3 +0 -0
  282. package/dist/remotion-bundle/public/paper-slide/v-male-W1tH9jVc/manager/0.mp3 +0 -0
  283. package/dist/remotion-bundle/public/paper-slide/v-male-W1tH9jVc/manager/1.mp3 +0 -0
  284. package/dist/remotion-bundle/public/paper-slide/v-male-W1tH9jVc/manager/2.mp3 +0 -0
  285. package/dist/remotion-bundle/public/paper-slide/v-male-W1tH9jVc/manager/3.mp3 +0 -0
  286. package/dist/remotion-bundle/public/paper-slide/v-male-W1tH9jVc/manager/4.mp3 +0 -0
  287. package/dist/remotion-bundle/public/paper-slide/v-male-s5NqE0rZ/founder/0.mp3 +0 -0
  288. package/dist/remotion-bundle/public/paper-slide/v-male-s5NqE0rZ/founder/1.mp3 +0 -0
  289. package/dist/remotion-bundle/public/paper-slide/v-male-s5NqE0rZ/founder/2.mp3 +0 -0
  290. package/dist/remotion-bundle/public/paper-slide/v-male-s5NqE0rZ/founder/3.mp3 +0 -0
  291. package/dist/remotion-bundle/public/paper-slide-experiments/career-advice/0.mp3 +0 -0
  292. package/dist/remotion-bundle/public/paper-slide-experiments/career-advice/1.mp3 +0 -0
  293. package/dist/remotion-bundle/public/paper-slide-experiments/career-advice/2.mp3 +0 -0
  294. package/dist/remotion-bundle/public/paper-slide-experiments/career-advice/3.mp3 +0 -0
  295. package/dist/remotion-bundle/public/paper-slide-experiments/career-advice/4.mp3 +0 -0
  296. package/dist/remotion-bundle/public/paper-slide-experiments/founder-lesson/0.mp3 +0 -0
  297. package/dist/remotion-bundle/public/paper-slide-experiments/founder-lesson/1.mp3 +0 -0
  298. package/dist/remotion-bundle/public/paper-slide-experiments/founder-lesson/2.mp3 +0 -0
  299. package/dist/remotion-bundle/public/paper-slide-experiments/founder-lesson/3.mp3 +0 -0
  300. package/dist/remotion-bundle/public/paper-slide-experiments/founder-lesson/4.mp3 +0 -0
  301. package/dist/remotion-bundle/public/paper-slide-experiments/incident-review/0.mp3 +0 -0
  302. package/dist/remotion-bundle/public/paper-slide-experiments/incident-review/1.mp3 +0 -0
  303. package/dist/remotion-bundle/public/paper-slide-experiments/incident-review/2.mp3 +0 -0
  304. package/dist/remotion-bundle/public/paper-slide-experiments/incident-review/3.mp3 +0 -0
  305. package/dist/remotion-bundle/public/paper-slide-experiments/incident-review/4.mp3 +0 -0
  306. package/dist/remotion-bundle/public/paper-slide-experiments/learning-loop/0.mp3 +0 -0
  307. package/dist/remotion-bundle/public/paper-slide-experiments/learning-loop/1.mp3 +0 -0
  308. package/dist/remotion-bundle/public/paper-slide-experiments/learning-loop/2.mp3 +0 -0
  309. package/dist/remotion-bundle/public/paper-slide-experiments/learning-loop/3.mp3 +0 -0
  310. package/dist/remotion-bundle/public/paper-slide-experiments/learning-loop/4.mp3 +0 -0
  311. package/dist/remotion-bundle/public/paper-slide-experiments/meeting-closure/0.mp3 +0 -0
  312. package/dist/remotion-bundle/public/paper-slide-experiments/meeting-closure/1.mp3 +0 -0
  313. package/dist/remotion-bundle/public/paper-slide-experiments/meeting-closure/2.mp3 +0 -0
  314. package/dist/remotion-bundle/public/paper-slide-experiments/meeting-closure/3.mp3 +0 -0
  315. package/dist/remotion-bundle/public/paper-slide-experiments/product-update/0.mp3 +0 -0
  316. package/dist/remotion-bundle/public/paper-slide-experiments/product-update/1.mp3 +0 -0
  317. package/dist/remotion-bundle/public/paper-slide-experiments/product-update/2.mp3 +0 -0
  318. package/dist/remotion-bundle/public/paper-slide-experiments/product-update/3.mp3 +0 -0
  319. package/dist/remotion-bundle/public/paper-slide-experiments/research-reading/0.mp3 +0 -0
  320. package/dist/remotion-bundle/public/paper-slide-experiments/research-reading/1.mp3 +0 -0
  321. package/dist/remotion-bundle/public/paper-slide-experiments/research-reading/2.mp3 +0 -0
  322. package/dist/remotion-bundle/public/paper-slide-experiments/research-reading/3.mp3 +0 -0
  323. package/dist/remotion-bundle/public/paper-slide-experiments/sales-enablement/0.mp3 +0 -0
  324. package/dist/remotion-bundle/public/paper-slide-experiments/sales-enablement/1.mp3 +0 -0
  325. package/dist/remotion-bundle/public/paper-slide-experiments/sales-enablement/2.mp3 +0 -0
  326. package/dist/remotion-bundle/public/paper-slide-experiments/sales-enablement/3.mp3 +0 -0
  327. package/dist/remotion-bundle/public/paper-slide-experiments/sales-enablement/4.mp3 +0 -0
  328. package/dist/remotion-bundle/public/voiceover/ai-life/card-0.mp3 +0 -0
  329. package/dist/remotion-bundle/public/voiceover/ai-life/card-1.mp3 +0 -0
  330. package/dist/remotion-bundle/public/voiceover/ai-life/card-2.mp3 +0 -0
  331. package/dist/remotion-bundle/public/voiceover/ai-life/card-3.mp3 +0 -0
  332. package/dist/remotion-bundle/public/voiceover/ai-life/card-4.mp3 +0 -0
  333. package/dist/remotion-bundle/public/voiceover/ai-life/card-5.mp3 +0 -0
  334. package/dist/remotion-bundle/public/voiceover/coffee-science/card-0.mp3 +0 -0
  335. package/dist/remotion-bundle/public/voiceover/coffee-science/card-1.mp3 +0 -0
  336. package/dist/remotion-bundle/public/voiceover/coffee-science/card-2.mp3 +0 -0
  337. package/dist/remotion-bundle/public/voiceover/coffee-science/card-3.mp3 +0 -0
  338. package/dist/remotion-bundle/public/voiceover/coffee-science/card-4.mp3 +0 -0
  339. package/dist/remotion-bundle/public/voiceover/coffee-science/card-5.mp3 +0 -0
  340. package/dist/remotion-bundle/public/voiceover/coffee-science/card-6.mp3 +0 -0
  341. package/dist/remotion-bundle/public/voiceover/reading-secrets/card-0.mp3 +0 -0
  342. package/dist/remotion-bundle/public/voiceover/reading-secrets/card-1.mp3 +0 -0
  343. package/dist/remotion-bundle/public/voiceover/reading-secrets/card-2.mp3 +0 -0
  344. package/dist/remotion-bundle/public/voiceover/reading-secrets/card-3.mp3 +0 -0
  345. package/dist/remotion-bundle/public/voiceover/reading-secrets/card-4.mp3 +0 -0
  346. package/dist/remotion-bundle/public/voiceover/reading-secrets/card-5.mp3 +0 -0
  347. package/dist/remotion-bundle/public/voiceover/reading-secrets/card-6.mp3 +0 -0
  348. package/dist/remotion-bundle/public/voiceover/remote-work/card-0.mp3 +0 -0
  349. package/dist/remotion-bundle/public/voiceover/remote-work/card-1.mp3 +0 -0
  350. package/dist/remotion-bundle/public/voiceover/remote-work/card-2.mp3 +0 -0
  351. package/dist/remotion-bundle/public/voiceover/remote-work/card-3.mp3 +0 -0
  352. package/dist/remotion-bundle/public/voiceover/remote-work/card-4.mp3 +0 -0
  353. package/dist/remotion-bundle/public/voiceover/remote-work/card-5.mp3 +0 -0
  354. package/dist/remotion-bundle/source-map-helper.wasm +0 -0
  355. package/lib/cli.js +270 -0
  356. package/lib/commands/_registry.js +48 -0
  357. package/lib/commands/add.js +242 -0
  358. package/lib/commands/asr/azure-transcribe.js +336 -0
  359. package/lib/commands/asr/cloud-transcribe.js +384 -0
  360. package/lib/commands/asr/helpers.js +76 -0
  361. package/lib/commands/asr/index.js +236 -0
  362. package/lib/commands/asr/local-transcribe.js +125 -0
  363. package/lib/commands/asr-jobs.js +257 -0
  364. package/lib/commands/asr.js +11 -0
  365. package/lib/commands/auth-cmds.js +358 -0
  366. package/lib/commands/dub.js +542 -0
  367. package/lib/commands/explain.js +512 -0
  368. package/lib/commands/feedback.js +152 -0
  369. package/lib/commands/image.js +207 -0
  370. package/lib/commands/mcp-key.js +166 -0
  371. package/lib/commands/narrate.js +639 -0
  372. package/lib/commands/picstory-templates.js +276 -0
  373. package/lib/commands/picstory.js +547 -0
  374. package/lib/commands/podcast/dialogue.js +109 -0
  375. package/lib/commands/podcast/generate.js +127 -0
  376. package/lib/commands/podcast/index.js +561 -0
  377. package/lib/commands/podcast/synthesize.js +188 -0
  378. package/lib/commands/podcast.js +11 -0
  379. package/lib/commands/present.js +519 -0
  380. package/lib/commands/publish.js +415 -0
  381. package/lib/commands/skills.js +473 -0
  382. package/lib/commands/slice-render.js +282 -0
  383. package/lib/commands/slice-stage.js +264 -0
  384. package/lib/commands/slice.js +346 -0
  385. package/lib/commands/slides/constants.js +108 -0
  386. package/lib/commands/slides/html-renderer.js +338 -0
  387. package/lib/commands/slides/index.js +345 -0
  388. package/lib/commands/slides.js +11 -0
  389. package/lib/commands/story.js +302 -0
  390. package/lib/commands/summarize.js +532 -0
  391. package/lib/commands/synthesize.js +261 -0
  392. package/lib/commands/translate.js +593 -0
  393. package/lib/commands/upgrade.js +249 -0
  394. package/lib/commands/video-translate.js +577 -0
  395. package/lib/commands/voices.js +292 -0
  396. package/lib/core/agent-env.js +104 -0
  397. package/lib/core/args.js +107 -0
  398. package/lib/core/asr-client.js +448 -0
  399. package/lib/core/asr-jobs-client.js +126 -0
  400. package/lib/core/asr-jobs-store.js +105 -0
  401. package/lib/core/asr-r2-upload.js +181 -0
  402. package/lib/core/asr-upload.js +132 -0
  403. package/lib/core/audio-extract.js +150 -0
  404. package/lib/core/audio.js +219 -0
  405. package/lib/core/auth.js +880 -0
  406. package/lib/core/config.js +197 -0
  407. package/lib/core/feedback.js +64 -0
  408. package/lib/core/ffmpeg.js +476 -0
  409. package/lib/core/http.js +188 -0
  410. package/lib/core/image-client.js +55 -0
  411. package/lib/core/intent-params.js +11 -0
  412. package/lib/core/llm-client.js +76 -0
  413. package/lib/core/logger.js +208 -0
  414. package/lib/core/mic-recorder.js +182 -0
  415. package/lib/core/pause-markers.js +94 -0
  416. package/lib/core/podcast-pacing.js +118 -0
  417. package/lib/core/spinner.js +33 -0
  418. package/lib/core/srt.js +394 -0
  419. package/lib/core/telemetry.js +100 -0
  420. package/lib/core/timeline.js +92 -0
  421. package/lib/core/tts-synthesizer.js +70 -0
  422. package/lib/core/update-check.js +185 -0
  423. package/lib/core/url-download.js +148 -0
  424. package/lib/core/whisper-local.js +279 -0
  425. package/lib/internal/deck-validator.js +488 -0
  426. package/lib/internal/slice-themes.json +370 -0
  427. package/lib/stage-core/cloud-render.js +170 -0
  428. package/lib/stage-core/deck-format.js +133 -0
  429. package/lib/stage-core/edit-prompt.js +104 -0
  430. package/lib/stage-core/event-bus.js +31 -0
  431. package/lib/stage-core/port.js +46 -0
  432. package/lib/stage-core/server.js +352 -0
  433. package/lib/stage-core/snapshot-store.js +198 -0
  434. package/lib/stage-core/watcher.js +106 -0
  435. package/lib/stage-ui/slice/template.js +1672 -0
  436. package/package.json +9 -4
  437. package/skills/.claude-plugin/marketplace.json +22 -0
  438. package/skills/.claude-plugin/plugin.json +25 -0
  439. package/skills/LICENSE +21 -0
  440. package/skills/README.md +120 -0
  441. package/skills/hub/SKILL.md +317 -0
  442. package/skills/podcast/SKILL.md +146 -0
  443. package/skills/slice/SKILL.md +205 -0
  444. package/skills/slice/agents/openai.yaml +4 -0
  445. package/skills/slice/references/deck-schema.md +183 -0
  446. package/skills/slice/references/example-decks.md +108 -0
  447. package/skills/slice/references/themes.md +172 -0
  448. package/skills/transcribe/SKILL.md +473 -0
  449. package/skills/video/SKILL.md +261 -0
  450. package/skills/voxflow-slice/SKILL.md +271 -0
  451. package/skills/voxflow-slice/examples/article.md +13 -0
  452. package/skills/voxflow-slice/examples/expected-deck.json +39 -0
  453. 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
+ };