voxflow 1.14.0 → 1.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (454) hide show
  1. package/README.md +69 -2
  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-preview.js +266 -0
  383. package/lib/commands/slice-render.js +282 -0
  384. package/lib/commands/slice-stage.js +264 -0
  385. package/lib/commands/slice.js +343 -0
  386. package/lib/commands/slides/constants.js +108 -0
  387. package/lib/commands/slides/html-renderer.js +338 -0
  388. package/lib/commands/slides/index.js +345 -0
  389. package/lib/commands/slides.js +11 -0
  390. package/lib/commands/story.js +302 -0
  391. package/lib/commands/summarize.js +532 -0
  392. package/lib/commands/synthesize.js +261 -0
  393. package/lib/commands/translate.js +593 -0
  394. package/lib/commands/upgrade.js +249 -0
  395. package/lib/commands/video-translate.js +577 -0
  396. package/lib/commands/voices.js +292 -0
  397. package/lib/core/agent-env.js +104 -0
  398. package/lib/core/args.js +107 -0
  399. package/lib/core/asr-client.js +448 -0
  400. package/lib/core/asr-jobs-client.js +126 -0
  401. package/lib/core/asr-jobs-store.js +105 -0
  402. package/lib/core/asr-r2-upload.js +181 -0
  403. package/lib/core/asr-upload.js +132 -0
  404. package/lib/core/audio-extract.js +150 -0
  405. package/lib/core/audio.js +219 -0
  406. package/lib/core/auth.js +880 -0
  407. package/lib/core/config.js +197 -0
  408. package/lib/core/feedback.js +64 -0
  409. package/lib/core/ffmpeg.js +476 -0
  410. package/lib/core/http.js +188 -0
  411. package/lib/core/image-client.js +55 -0
  412. package/lib/core/intent-params.js +11 -0
  413. package/lib/core/llm-client.js +76 -0
  414. package/lib/core/logger.js +208 -0
  415. package/lib/core/mic-recorder.js +182 -0
  416. package/lib/core/pause-markers.js +94 -0
  417. package/lib/core/podcast-pacing.js +118 -0
  418. package/lib/core/spinner.js +33 -0
  419. package/lib/core/srt.js +394 -0
  420. package/lib/core/telemetry.js +100 -0
  421. package/lib/core/timeline.js +92 -0
  422. package/lib/core/tts-synthesizer.js +70 -0
  423. package/lib/core/update-check.js +185 -0
  424. package/lib/core/url-download.js +148 -0
  425. package/lib/core/whisper-local.js +279 -0
  426. package/lib/internal/deck-validator.js +488 -0
  427. package/lib/internal/slice-themes.json +370 -0
  428. package/lib/stage-core/cloud-render.js +170 -0
  429. package/lib/stage-core/deck-format.js +133 -0
  430. package/lib/stage-core/edit-prompt.js +104 -0
  431. package/lib/stage-core/event-bus.js +31 -0
  432. package/lib/stage-core/port.js +46 -0
  433. package/lib/stage-core/server.js +352 -0
  434. package/lib/stage-core/snapshot-store.js +198 -0
  435. package/lib/stage-core/watcher.js +106 -0
  436. package/lib/stage-ui/slice/template.js +1672 -0
  437. package/package.json +9 -4
  438. package/skills/.claude-plugin/marketplace.json +22 -0
  439. package/skills/.claude-plugin/plugin.json +25 -0
  440. package/skills/LICENSE +21 -0
  441. package/skills/README.md +120 -0
  442. package/skills/hub/SKILL.md +317 -0
  443. package/skills/podcast/SKILL.md +146 -0
  444. package/skills/slice/SKILL.md +205 -0
  445. package/skills/slice/agents/openai.yaml +4 -0
  446. package/skills/slice/references/deck-schema.md +183 -0
  447. package/skills/slice/references/example-decks.md +108 -0
  448. package/skills/slice/references/themes.md +172 -0
  449. package/skills/transcribe/SKILL.md +473 -0
  450. package/skills/video/SKILL.md +261 -0
  451. package/skills/voxflow-slice/SKILL.md +271 -0
  452. package/skills/voxflow-slice/examples/article.md +13 -0
  453. package/skills/voxflow-slice/examples/expected-deck.json +39 -0
  454. package/skills/voxflow-slice/examples/validate.mjs +46 -0
@@ -0,0 +1,292 @@
1
+ /**
2
+ * VoxFlow CLI — Voices command
3
+ *
4
+ * Browse and filter available TTS voices. By default queries the public catalog
5
+ * (no auth). `--mine` switches to the authenticated `/api/voice/list` endpoint
6
+ * to show the signed-in user's cloned voices.
7
+ */
8
+
9
+ const { request, throwNetworkError, throwApiError, ApiError } = require('../core/http');
10
+
11
+ /**
12
+ * Fetch and display available TTS voices.
13
+ *
14
+ * @param {object} opts
15
+ * @param {string} opts.api - API base URL
16
+ * @param {string} [opts.search] - Search query (matches name, tone, style, scenarios)
17
+ * @param {string} [opts.gender] - Filter by gender: male/m/female/f
18
+ * @param {string} [opts.language] - Filter by language code: zh, en, etc.
19
+ * @param {boolean} [opts.json] - Output raw JSON
20
+ * @param {boolean} [opts.extended] - Include extended voice library
21
+ * @param {boolean} [opts.mine] - List the signed-in user's cloned voices
22
+ * @param {string} [opts.token] - Bearer token (required when mine=true)
23
+ */
24
+ async function voices(opts) {
25
+ const api = opts.api;
26
+
27
+ if (opts.mine) {
28
+ return listMyClonedVoices(opts);
29
+ }
30
+
31
+ const includeExtended = opts.extended ? 'true' : 'false';
32
+
33
+ // Fetch voices (public endpoint, no auth)
34
+ let status, data;
35
+ try {
36
+ ({ status, data } = await request(
37
+ `${api}/api/tts/voices?includeExtended=${includeExtended}`,
38
+ { method: 'GET' }
39
+ ));
40
+ } catch (err) {
41
+ throwNetworkError(err, api);
42
+ }
43
+
44
+ if (status !== 200) {
45
+ throw new Error(`Failed to fetch voices (${status}): ${data?.message || 'unknown error'}`);
46
+ }
47
+
48
+ // Public endpoint returns { voices: [...] } directly (no code wrapper)
49
+ let voiceList = data.voices || data.data?.voices || [];
50
+
51
+ // Apply filters
52
+ if (opts.gender) {
53
+ const normalized = normalizeGender(opts.gender);
54
+ if (!normalized) {
55
+ throw new Error(`--gender must be one of: male, m, female, f (got: "${opts.gender}")`);
56
+ }
57
+ voiceList = voiceList.filter((v) => {
58
+ const vGender = (v.gender || '').toLowerCase();
59
+ return vGender === normalized;
60
+ });
61
+ }
62
+
63
+ if (opts.language) {
64
+ const lang = opts.language.toLowerCase();
65
+ voiceList = voiceList.filter((v) => (v.language || '').toLowerCase() === lang);
66
+ }
67
+
68
+ if (opts.search) {
69
+ const query = opts.search.toLowerCase();
70
+ voiceList = voiceList.filter((v) => {
71
+ const searchable = [
72
+ v.name, v.nameEn, v.tone, v.style,
73
+ v.description, v.scenarios,
74
+ ].filter(Boolean).join(' ').toLowerCase();
75
+ return searchable.includes(query);
76
+ });
77
+ }
78
+
79
+ if (opts.useCase) {
80
+ const tag = opts.useCase.toLowerCase();
81
+ voiceList = voiceList.filter((v) => Array.isArray(v.recommendedFor) && v.recommendedFor.map(String).map(s => s.toLowerCase()).includes(tag));
82
+ }
83
+
84
+ // Output
85
+ if (voiceList.length === 0) {
86
+ console.log('No voices match your criteria.');
87
+ return;
88
+ }
89
+
90
+ if (opts.json) {
91
+ console.log(JSON.stringify(voiceList, null, 2));
92
+ } else {
93
+ printTable(voiceList);
94
+ }
95
+
96
+ console.log(`\nFound ${voiceList.length} voice${voiceList.length === 1 ? '' : 's'}.`);
97
+ }
98
+
99
+ /**
100
+ * Fetch and print the user's cloned voices via the authenticated endpoint.
101
+ */
102
+ async function listMyClonedVoices(opts) {
103
+ const { api, token } = opts;
104
+ if (!token) {
105
+ throw new ApiError('Not authenticated — run `voxflow login` first.', 'token_missing', 401);
106
+ }
107
+
108
+ let status, data;
109
+ try {
110
+ ({ status, data } = await request(
111
+ `${api}/api/voice/list`,
112
+ { method: 'GET', headers: { Authorization: `Bearer ${token}` } }
113
+ ));
114
+ } catch (err) {
115
+ throwNetworkError(err, api);
116
+ }
117
+
118
+ if (status === 401) {
119
+ throwApiError(401, data, 'voices --mine');
120
+ }
121
+
122
+ if (status !== 200 || data?.code !== 'success') {
123
+ throw new Error(`Failed to fetch cloned voices (${status}): ${data?.message || 'unknown error'}`);
124
+ }
125
+
126
+ const list = (data.voices || []).map((v) => ({
127
+ id: v.voice_id,
128
+ name: v.voice_name || '(unnamed)',
129
+ language: v.language || '',
130
+ gender: v.gender || '',
131
+ durationSec: v.audio_duration ? Number(v.audio_duration).toFixed(1) : '',
132
+ createdAt: v.created_at ? v.created_at.replace('T', ' ').slice(0, 19) : '',
133
+ usageCount: v.usage_count || 0,
134
+ model: v.model || '',
135
+ }));
136
+
137
+ if (list.length === 0) {
138
+ console.log('No cloned voices yet. Create one with:');
139
+ console.log(' voxflow clone --input recording.wav --name "My Voice"');
140
+ console.log(`Used 0/${data.limit ?? '?'} clone slots.`);
141
+ return;
142
+ }
143
+
144
+ if (opts.json) {
145
+ console.log(JSON.stringify(list, null, 2));
146
+ } else {
147
+ printMineTable(list);
148
+ console.log(`\nUsed ${data.used ?? list.length}/${data.limit ?? '?'} clone slots.`);
149
+ console.log('Use a voice: voxflow say "..." --voice <id>');
150
+ }
151
+ }
152
+
153
+ /**
154
+ * Normalize gender input to lowercase standard form.
155
+ * @returns {'male'|'female'|null}
156
+ */
157
+ function normalizeGender(input) {
158
+ const g = (input || '').toLowerCase().trim();
159
+ if (g === 'male' || g === 'm') return 'male';
160
+ if (g === 'female' || g === 'f') return 'female';
161
+ return null;
162
+ }
163
+
164
+ /**
165
+ * Print voices as a formatted table.
166
+ */
167
+ function printTable(voiceList) {
168
+ // Column widths
169
+ const colPick = 2;
170
+ const colId = 24;
171
+ const colName = 14;
172
+ const colGender = 8;
173
+ const colTone = 22;
174
+ const colStyle = 20;
175
+
176
+ // Header — ★ marks editorial-curated podcast picks (recommendedFor:['podcast'])
177
+ const header = [
178
+ '★'.padEnd(colPick),
179
+ 'ID'.padEnd(colId),
180
+ 'Name'.padEnd(colName),
181
+ 'Gender'.padEnd(colGender),
182
+ 'Tone'.padEnd(colTone),
183
+ 'Style'.padEnd(colStyle),
184
+ ].join(' ');
185
+
186
+ console.log(`\n${header}`);
187
+ console.log('-'.repeat(header.length));
188
+
189
+ // Rows
190
+ for (const v of voiceList) {
191
+ const isPodcast = Array.isArray(v.recommendedFor) && v.recommendedFor.includes('podcast');
192
+ const row = [
193
+ (isPodcast ? '★' : ' ').padEnd(colPick),
194
+ truncate(v.id || '', colId).padEnd(colId),
195
+ truncate(v.name || '', colName).padEnd(colName),
196
+ truncate(v.gender || '', colGender).padEnd(colGender),
197
+ truncate(v.tone || '', colTone).padEnd(colTone),
198
+ truncate(v.style || '', colStyle).padEnd(colStyle),
199
+ ].join(' ');
200
+ console.log(row);
201
+ }
202
+ }
203
+
204
+ function printMineTable(voiceList) {
205
+ const colId = 40;
206
+ const colName = 18;
207
+ const colDur = 7;
208
+ const colCreated = 19;
209
+
210
+ const header = [
211
+ 'ID'.padEnd(colId),
212
+ 'Name'.padEnd(colName),
213
+ 'Sec'.padEnd(colDur),
214
+ 'Created'.padEnd(colCreated),
215
+ ].join(' ');
216
+
217
+ console.log(`\n${header}`);
218
+ console.log('-'.repeat(header.length));
219
+
220
+ for (const v of voiceList) {
221
+ const row = [
222
+ truncate(v.id, colId).padEnd(colId),
223
+ truncate(v.name, colName).padEnd(colName),
224
+ String(v.durationSec).padEnd(colDur),
225
+ truncate(v.createdAt, colCreated).padEnd(colCreated),
226
+ ].join(' ');
227
+ console.log(row);
228
+ }
229
+ }
230
+
231
+ /**
232
+ * Truncate a string to max length, adding ellipsis if needed.
233
+ */
234
+ function truncate(str, maxLen) {
235
+ if (str.length <= maxLen) return str;
236
+ return str.slice(0, maxLen - 1) + '…';
237
+ }
238
+
239
+ // ─── CLI Handler ────────────────────────────────────────────────────────────
240
+
241
+ async function handle(args) {
242
+ const { parseFlag, parseBoolFlag, runWithRetry } = require('../core/args');
243
+ const { API_BASE } = require('../core/config');
244
+ const { getToken } = require('../core/auth');
245
+
246
+ const api = parseFlag(args, '--api') || API_BASE;
247
+ const explicitToken = parseFlag(args, '--token');
248
+
249
+ const opts = {
250
+ api,
251
+ search: parseFlag(args, '--search'),
252
+ gender: parseFlag(args, '--gender'),
253
+ language: parseFlag(args, '--language'),
254
+ useCase: parseFlag(args, '--use-case'),
255
+ json: parseBoolFlag(args, '--json'),
256
+ extended: parseBoolFlag(args, '--extended'),
257
+ mine: parseBoolFlag(args, '--mine'),
258
+ };
259
+
260
+ if (opts.mine) {
261
+ opts.token = explicitToken || await getToken({ api });
262
+ await runWithRetry(voices, opts, api, explicitToken);
263
+ return;
264
+ }
265
+
266
+ // Public catalog — no auth, no retry
267
+ await voices(opts);
268
+ }
269
+
270
+ const meta = {
271
+ voices: {
272
+ usage: '[opts]',
273
+ description: 'Browse and search available TTS voices (use --mine for your cloned voices)',
274
+ options: [
275
+ `--mine List your cloned voices (requires login)`,
276
+ `--search <query> Search by name, tone, style, description`,
277
+ `--gender <m|f> Filter by gender: male/m or female/f`,
278
+ `--language <code> Filter by language: zh, en, etc.`,
279
+ `--use-case <tag> Filter by editorial-curated use case (e.g. podcast)`,
280
+ `--extended Include extended voice library (380+ voices)`,
281
+ `--json Output raw JSON instead of table`,
282
+ ],
283
+ examples: [
284
+ 'voxflow voices --mine # list my cloned voices',
285
+ 'voxflow voices --search "温柔" --gender female',
286
+ 'voxflow voices --use-case podcast # editorial podcast picks',
287
+ 'voxflow voices --extended --json',
288
+ ],
289
+ },
290
+ };
291
+
292
+ module.exports = { voices, handle, meta };
@@ -0,0 +1,104 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * AI agent environment detection.
5
+ *
6
+ * The CLI may be invoked directly by a human in a terminal, OR delegated by
7
+ * an AI agent (Claude Code / Cursor / Codex / Gemini CLI / WorkBuddy / OpenClaw).
8
+ * Auth, prompts, and timeouts behave differently in each case:
9
+ * - Human: open browser, 3-minute timeout, single-line "🔐 Login required" notice
10
+ * - Agent: print a structured USER-ACTION panel that the agent can clearly
11
+ * relay to the user, longer 10-minute timeout, do not assume the
12
+ * browser auto-open will land on the user's machine.
13
+ *
14
+ * Detection is environment-variable driven. Each agent sets at least one of
15
+ * these markers when it spawns subprocesses; they're stable enough to rely on.
16
+ */
17
+
18
+ const env = process.env;
19
+
20
+ /**
21
+ * Detect whether we're running inside a known AI agent. Returns the agent's
22
+ * display name, or null when running directly in a terminal.
23
+ *
24
+ * Order matters: more specific markers are checked first so a single-purpose
25
+ * env var wins over a more generic terminal hint.
26
+ */
27
+ function detectAIAgent(_env = env) {
28
+ if (_env.CLAUDECODE) return 'Claude Code';
29
+ if (_env.CURSOR_AGENT || _env.CURSOR_TRACE_ID) return 'Cursor';
30
+ if (_env.CODEX_SANDBOX || _env.CODEX_AGENT || _env.OPENAI_CODEX) return 'Codex';
31
+ if (_env.GEMINI_CLI || _env.GEMINI_AGENT) return 'Gemini CLI';
32
+ if (_env.WORKBUDDY || _env.WORKBUDDY_AGENT) return 'WorkBuddy';
33
+ if (_env.OPENCLAW || _env.OPENCLAW_AGENT) return 'OpenClaw';
34
+
35
+ // Generic AI-agent hint — when an agent doesn't set its own marker but
36
+ // does export a generic AI flag.
37
+ if (_env.AI_AGENT) return _env.AI_AGENT;
38
+
39
+ return null;
40
+ }
41
+
42
+ /**
43
+ * True when running in any AI-agent context. Convenience wrapper.
44
+ */
45
+ function isAIAgent(_env = env) {
46
+ return detectAIAgent(_env) !== null;
47
+ }
48
+
49
+ /**
50
+ * Build a structured "USER ACTION REQUIRED" panel for the given login URL.
51
+ * The panel is designed to stand out in agent transcripts — agents can quote
52
+ * it verbatim and the user immediately sees what they need to do.
53
+ *
54
+ * @param {object} opts
55
+ * @param {string} opts.loginUrl The URL the user should open
56
+ * @param {string} [opts.agentName] Display name from detectAIAgent()
57
+ * @param {number} [opts.timeoutSec] Timeout in seconds (default 600)
58
+ * @param {string} [opts.userCode] Optional pairing code displayed prominently
59
+ * @returns {string}
60
+ */
61
+ function buildUserActionPanel({ loginUrl, agentName, timeoutSec = 600, userCode }) {
62
+ const min = Math.round(timeoutSec / 60);
63
+ const heading = agentName
64
+ ? `USER ACTION REQUIRED (you are running inside ${agentName})`
65
+ : `USER ACTION REQUIRED`;
66
+
67
+ const lines = [
68
+ '',
69
+ '╔══════════════════════════════════════════════════════════════════╗',
70
+ `║ 👤 ${heading.padEnd(60)} ║`,
71
+ '╠══════════════════════════════════════════════════════════════════╣',
72
+ '║ 1. Open this URL in your browser to authorize voxflow CLI: ║',
73
+ '║ ║',
74
+ `║ ${loginUrl}`,
75
+ '║ ║',
76
+ ];
77
+
78
+ if (userCode) {
79
+ lines.push(
80
+ `║ Pairing code (verify it matches the page): ${userCode}`,
81
+ '║ ║',
82
+ );
83
+ }
84
+
85
+ lines.push(
86
+ `║ 2. After login, this command will continue automatically (waiting ${String(min).padStart(2)} min). ║`,
87
+ '║ ║',
88
+ '║ Skip this entirely: ║',
89
+ '║ export VOXFLOW_TOKEN=<your-jwt> # then re-run ║',
90
+ '║ ║',
91
+ '║ Already logged in but stuck? ║',
92
+ '║ rm ~/.config/voxflow/token.json # then re-run `voxflow login` ║',
93
+ '╚══════════════════════════════════════════════════════════════════╝',
94
+ '',
95
+ );
96
+
97
+ return lines.join('\n');
98
+ }
99
+
100
+ module.exports = {
101
+ detectAIAgent,
102
+ isAIAgent,
103
+ buildUserActionPanel,
104
+ };
@@ -0,0 +1,107 @@
1
+ /**
2
+ * VoxFlow CLI — Argument parsing & validation utilities
3
+ *
4
+ * Shared helpers extracted from cli.js for use by all command handlers.
5
+ */
6
+
7
+ const { getToken } = require('./auth');
8
+ const { ApiError } = require('./http');
9
+
10
+ // ─── Arg Parsing ────────────────────────────────────────────────────────────
11
+
12
+ function parseFlag(args, ...flags) {
13
+ for (const flag of flags) {
14
+ const idx = args.indexOf(flag);
15
+ if (idx !== -1 && idx + 1 < args.length) return args[idx + 1];
16
+ }
17
+ return null;
18
+ }
19
+
20
+ function parseIntFlag(args, ...flags) {
21
+ const val = parseFlag(args, ...flags);
22
+ return val != null ? parseInt(val, 10) : undefined;
23
+ }
24
+
25
+ function parseFloatFlag(args, ...flags) {
26
+ const val = parseFlag(args, ...flags);
27
+ return val != null ? parseFloat(val) : undefined;
28
+ }
29
+
30
+ function parseBoolFlag(args, ...flags) {
31
+ return flags.some((f) => args.includes(f));
32
+ }
33
+
34
+ // ─── Validation Helpers ─────────────────────────────────────────────────────
35
+
36
+ function validateSpeed(args, speed) {
37
+ if (speed !== undefined) {
38
+ if (isNaN(speed) || speed < 0.5 || speed > 2.0) {
39
+ console.error(`Error: --speed must be between 0.5 and 2.0 (got: "${parseFlag(args, '--speed')}")`);
40
+ process.exit(1);
41
+ }
42
+ }
43
+ }
44
+
45
+ function validateSilence(args, silence) {
46
+ if (silence !== undefined) {
47
+ if (isNaN(silence) || silence < 0 || silence > 5.0) {
48
+ console.error(`Error: --silence must be between 0 and 5.0 (got: "${parseFlag(args, '--silence')}")`);
49
+ process.exit(1);
50
+ }
51
+ }
52
+ }
53
+
54
+ function validateOutput(output, _format) {
55
+ if (output) {
56
+ const validExts = ['.wav', '.mp3'];
57
+ const hasValidExt = validExts.some(ext => output.toLowerCase().endsWith(ext));
58
+ if (!hasValidExt) {
59
+ console.error('Error: --output path must end with .wav or .mp3');
60
+ process.exit(1);
61
+ }
62
+ }
63
+ }
64
+
65
+ function validateFormat(format) {
66
+ if (format && !['pcm', 'wav', 'mp3'].includes(format)) {
67
+ console.error(`Error: --format must be one of: pcm, wav, mp3 (got: "${format}")`);
68
+ process.exit(1);
69
+ }
70
+ }
71
+
72
+ function assertFileExists(filePath, label) {
73
+ const resolved = require('path').resolve(filePath);
74
+ if (!require('fs').existsSync(resolved)) {
75
+ console.error(`Error: ${label} file not found: ${resolved}`);
76
+ process.exit(1);
77
+ }
78
+ }
79
+
80
+ // ─── Retry with token refresh ───────────────────────────────────────────────
81
+
82
+ async function runWithRetry(fn, opts, api, explicitToken) {
83
+ try {
84
+ return await fn(opts);
85
+ } catch (err) {
86
+ if (err instanceof ApiError && err.code === 'token_expired' && !explicitToken) {
87
+ console.log('\nToken expired, refreshing...');
88
+ opts.token = await getToken({ api, refresh: true });
89
+ return await fn(opts);
90
+ } else {
91
+ throw err;
92
+ }
93
+ }
94
+ }
95
+
96
+ module.exports = {
97
+ parseFlag,
98
+ parseIntFlag,
99
+ parseFloatFlag,
100
+ parseBoolFlag,
101
+ validateSpeed,
102
+ validateSilence,
103
+ validateOutput,
104
+ validateFormat,
105
+ assertFileExists,
106
+ runWithRetry,
107
+ };