@vibeframe/cli 0.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (420) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.turbo/turbo-lint.log +21 -0
  3. package/.turbo/turbo-test.log +689 -0
  4. package/dist/agent/adapters/claude.d.ts +15 -0
  5. package/dist/agent/adapters/claude.d.ts.map +1 -0
  6. package/dist/agent/adapters/claude.js +119 -0
  7. package/dist/agent/adapters/claude.js.map +1 -0
  8. package/dist/agent/adapters/gemini.d.ts +15 -0
  9. package/dist/agent/adapters/gemini.d.ts.map +1 -0
  10. package/dist/agent/adapters/gemini.js +132 -0
  11. package/dist/agent/adapters/gemini.js.map +1 -0
  12. package/dist/agent/adapters/index.d.ts +27 -0
  13. package/dist/agent/adapters/index.d.ts.map +1 -0
  14. package/dist/agent/adapters/index.js +38 -0
  15. package/dist/agent/adapters/index.js.map +1 -0
  16. package/dist/agent/adapters/ollama.d.ts +20 -0
  17. package/dist/agent/adapters/ollama.d.ts.map +1 -0
  18. package/dist/agent/adapters/ollama.js +186 -0
  19. package/dist/agent/adapters/ollama.js.map +1 -0
  20. package/dist/agent/adapters/openai.d.ts +15 -0
  21. package/dist/agent/adapters/openai.d.ts.map +1 -0
  22. package/dist/agent/adapters/openai.js +92 -0
  23. package/dist/agent/adapters/openai.js.map +1 -0
  24. package/dist/agent/adapters/xai.d.ts +15 -0
  25. package/dist/agent/adapters/xai.d.ts.map +1 -0
  26. package/dist/agent/adapters/xai.js +95 -0
  27. package/dist/agent/adapters/xai.js.map +1 -0
  28. package/dist/agent/index.d.ts +69 -0
  29. package/dist/agent/index.d.ts.map +1 -0
  30. package/dist/agent/index.js +180 -0
  31. package/dist/agent/index.js.map +1 -0
  32. package/dist/agent/memory/index.d.ts +70 -0
  33. package/dist/agent/memory/index.d.ts.map +1 -0
  34. package/dist/agent/memory/index.js +132 -0
  35. package/dist/agent/memory/index.js.map +1 -0
  36. package/dist/agent/prompts/system.d.ts +6 -0
  37. package/dist/agent/prompts/system.d.ts.map +1 -0
  38. package/dist/agent/prompts/system.js +103 -0
  39. package/dist/agent/prompts/system.js.map +1 -0
  40. package/dist/agent/tools/ai-editing.d.ts +15 -0
  41. package/dist/agent/tools/ai-editing.d.ts.map +1 -0
  42. package/dist/agent/tools/ai-editing.js +763 -0
  43. package/dist/agent/tools/ai-editing.js.map +1 -0
  44. package/dist/agent/tools/ai-generation.d.ts +13 -0
  45. package/dist/agent/tools/ai-generation.d.ts.map +1 -0
  46. package/dist/agent/tools/ai-generation.js +973 -0
  47. package/dist/agent/tools/ai-generation.js.map +1 -0
  48. package/dist/agent/tools/ai-pipeline.d.ts +14 -0
  49. package/dist/agent/tools/ai-pipeline.d.ts.map +1 -0
  50. package/dist/agent/tools/ai-pipeline.js +961 -0
  51. package/dist/agent/tools/ai-pipeline.js.map +1 -0
  52. package/dist/agent/tools/ai.d.ts +13 -0
  53. package/dist/agent/tools/ai.d.ts.map +1 -0
  54. package/dist/agent/tools/ai.js +19 -0
  55. package/dist/agent/tools/ai.js.map +1 -0
  56. package/dist/agent/tools/batch.d.ts +6 -0
  57. package/dist/agent/tools/batch.d.ts.map +1 -0
  58. package/dist/agent/tools/batch.js +383 -0
  59. package/dist/agent/tools/batch.js.map +1 -0
  60. package/dist/agent/tools/e2e.test.d.ts +26 -0
  61. package/dist/agent/tools/e2e.test.d.ts.map +1 -0
  62. package/dist/agent/tools/e2e.test.js +397 -0
  63. package/dist/agent/tools/e2e.test.js.map +1 -0
  64. package/dist/agent/tools/export.d.ts +6 -0
  65. package/dist/agent/tools/export.d.ts.map +1 -0
  66. package/dist/agent/tools/export.js +171 -0
  67. package/dist/agent/tools/export.js.map +1 -0
  68. package/dist/agent/tools/filesystem.d.ts +6 -0
  69. package/dist/agent/tools/filesystem.d.ts.map +1 -0
  70. package/dist/agent/tools/filesystem.js +212 -0
  71. package/dist/agent/tools/filesystem.js.map +1 -0
  72. package/dist/agent/tools/index.d.ts +65 -0
  73. package/dist/agent/tools/index.d.ts.map +1 -0
  74. package/dist/agent/tools/index.js +120 -0
  75. package/dist/agent/tools/index.js.map +1 -0
  76. package/dist/agent/tools/integration.test.d.ts +11 -0
  77. package/dist/agent/tools/integration.test.d.ts.map +1 -0
  78. package/dist/agent/tools/integration.test.js +659 -0
  79. package/dist/agent/tools/integration.test.js.map +1 -0
  80. package/dist/agent/tools/media.d.ts +6 -0
  81. package/dist/agent/tools/media.d.ts.map +1 -0
  82. package/dist/agent/tools/media.js +616 -0
  83. package/dist/agent/tools/media.js.map +1 -0
  84. package/dist/agent/tools/project.d.ts +6 -0
  85. package/dist/agent/tools/project.d.ts.map +1 -0
  86. package/dist/agent/tools/project.js +284 -0
  87. package/dist/agent/tools/project.js.map +1 -0
  88. package/dist/agent/tools/timeline.d.ts +6 -0
  89. package/dist/agent/tools/timeline.d.ts.map +1 -0
  90. package/dist/agent/tools/timeline.js +873 -0
  91. package/dist/agent/tools/timeline.js.map +1 -0
  92. package/dist/agent/types.d.ts +59 -0
  93. package/dist/agent/types.d.ts.map +1 -0
  94. package/dist/agent/types.js +5 -0
  95. package/dist/agent/types.js.map +1 -0
  96. package/dist/commands/agent.d.ts +21 -0
  97. package/dist/commands/agent.d.ts.map +1 -0
  98. package/dist/commands/agent.js +290 -0
  99. package/dist/commands/agent.js.map +1 -0
  100. package/dist/commands/ai-analyze.d.ts +106 -0
  101. package/dist/commands/ai-analyze.d.ts.map +1 -0
  102. package/dist/commands/ai-analyze.js +327 -0
  103. package/dist/commands/ai-analyze.js.map +1 -0
  104. package/dist/commands/ai-animated-caption.d.ts +64 -0
  105. package/dist/commands/ai-animated-caption.d.ts.map +1 -0
  106. package/dist/commands/ai-animated-caption.js +272 -0
  107. package/dist/commands/ai-animated-caption.js.map +1 -0
  108. package/dist/commands/ai-audio.d.ts +20 -0
  109. package/dist/commands/ai-audio.d.ts.map +1 -0
  110. package/dist/commands/ai-audio.js +808 -0
  111. package/dist/commands/ai-audio.js.map +1 -0
  112. package/dist/commands/ai-broll.d.ts +15 -0
  113. package/dist/commands/ai-broll.d.ts.map +1 -0
  114. package/dist/commands/ai-broll.js +406 -0
  115. package/dist/commands/ai-broll.js.map +1 -0
  116. package/dist/commands/ai-edit-cli.d.ts +14 -0
  117. package/dist/commands/ai-edit-cli.d.ts.map +1 -0
  118. package/dist/commands/ai-edit-cli.js +579 -0
  119. package/dist/commands/ai-edit-cli.js.map +1 -0
  120. package/dist/commands/ai-edit.d.ts +398 -0
  121. package/dist/commands/ai-edit.d.ts.map +1 -0
  122. package/dist/commands/ai-edit.js +1019 -0
  123. package/dist/commands/ai-edit.js.map +1 -0
  124. package/dist/commands/ai-fill-gaps.d.ts +14 -0
  125. package/dist/commands/ai-fill-gaps.d.ts.map +1 -0
  126. package/dist/commands/ai-fill-gaps.js +451 -0
  127. package/dist/commands/ai-fill-gaps.js.map +1 -0
  128. package/dist/commands/ai-helpers.d.ts +20 -0
  129. package/dist/commands/ai-helpers.d.ts.map +1 -0
  130. package/dist/commands/ai-helpers.js +59 -0
  131. package/dist/commands/ai-helpers.js.map +1 -0
  132. package/dist/commands/ai-highlights.d.ts +127 -0
  133. package/dist/commands/ai-highlights.d.ts.map +1 -0
  134. package/dist/commands/ai-highlights.js +1026 -0
  135. package/dist/commands/ai-highlights.js.map +1 -0
  136. package/dist/commands/ai-image.d.ts +34 -0
  137. package/dist/commands/ai-image.d.ts.map +1 -0
  138. package/dist/commands/ai-image.js +653 -0
  139. package/dist/commands/ai-image.js.map +1 -0
  140. package/dist/commands/ai-motion.d.ts +50 -0
  141. package/dist/commands/ai-motion.d.ts.map +1 -0
  142. package/dist/commands/ai-motion.js +271 -0
  143. package/dist/commands/ai-motion.js.map +1 -0
  144. package/dist/commands/ai-narrate.d.ts +66 -0
  145. package/dist/commands/ai-narrate.d.ts.map +1 -0
  146. package/dist/commands/ai-narrate.js +329 -0
  147. package/dist/commands/ai-narrate.js.map +1 -0
  148. package/dist/commands/ai-review.d.ts +57 -0
  149. package/dist/commands/ai-review.d.ts.map +1 -0
  150. package/dist/commands/ai-review.js +251 -0
  151. package/dist/commands/ai-review.js.map +1 -0
  152. package/dist/commands/ai-script-pipeline-cli.d.ts +9 -0
  153. package/dist/commands/ai-script-pipeline-cli.d.ts.map +1 -0
  154. package/dist/commands/ai-script-pipeline-cli.js +1494 -0
  155. package/dist/commands/ai-script-pipeline-cli.js.map +1 -0
  156. package/dist/commands/ai-script-pipeline.d.ts +259 -0
  157. package/dist/commands/ai-script-pipeline.d.ts.map +1 -0
  158. package/dist/commands/ai-script-pipeline.js +1027 -0
  159. package/dist/commands/ai-script-pipeline.js.map +1 -0
  160. package/dist/commands/ai-suggest-edit.d.ts +14 -0
  161. package/dist/commands/ai-suggest-edit.d.ts.map +1 -0
  162. package/dist/commands/ai-suggest-edit.js +220 -0
  163. package/dist/commands/ai-suggest-edit.js.map +1 -0
  164. package/dist/commands/ai-video-fx.d.ts +14 -0
  165. package/dist/commands/ai-video-fx.d.ts.map +1 -0
  166. package/dist/commands/ai-video-fx.js +395 -0
  167. package/dist/commands/ai-video-fx.js.map +1 -0
  168. package/dist/commands/ai-video.d.ts +15 -0
  169. package/dist/commands/ai-video.d.ts.map +1 -0
  170. package/dist/commands/ai-video.js +785 -0
  171. package/dist/commands/ai-video.js.map +1 -0
  172. package/dist/commands/ai-viral.d.ts +15 -0
  173. package/dist/commands/ai-viral.d.ts.map +1 -0
  174. package/dist/commands/ai-viral.js +519 -0
  175. package/dist/commands/ai-viral.js.map +1 -0
  176. package/dist/commands/ai-visual-fx.d.ts +14 -0
  177. package/dist/commands/ai-visual-fx.d.ts.map +1 -0
  178. package/dist/commands/ai-visual-fx.js +505 -0
  179. package/dist/commands/ai-visual-fx.js.map +1 -0
  180. package/dist/commands/ai.d.ts +38 -0
  181. package/dist/commands/ai.d.ts.map +1 -0
  182. package/dist/commands/ai.js +225 -0
  183. package/dist/commands/ai.js.map +1 -0
  184. package/dist/commands/ai.test.d.ts +2 -0
  185. package/dist/commands/ai.test.d.ts.map +1 -0
  186. package/dist/commands/ai.test.js +554 -0
  187. package/dist/commands/ai.test.js.map +1 -0
  188. package/dist/commands/analyze.d.ts +16 -0
  189. package/dist/commands/analyze.d.ts.map +1 -0
  190. package/dist/commands/analyze.js +247 -0
  191. package/dist/commands/analyze.js.map +1 -0
  192. package/dist/commands/audio.d.ts +18 -0
  193. package/dist/commands/audio.d.ts.map +1 -0
  194. package/dist/commands/audio.js +539 -0
  195. package/dist/commands/audio.js.map +1 -0
  196. package/dist/commands/batch.d.ts +3 -0
  197. package/dist/commands/batch.d.ts.map +1 -0
  198. package/dist/commands/batch.js +366 -0
  199. package/dist/commands/batch.js.map +1 -0
  200. package/dist/commands/batch.test.d.ts +2 -0
  201. package/dist/commands/batch.test.d.ts.map +1 -0
  202. package/dist/commands/batch.test.js +203 -0
  203. package/dist/commands/batch.test.js.map +1 -0
  204. package/dist/commands/detect.d.ts +3 -0
  205. package/dist/commands/detect.d.ts.map +1 -0
  206. package/dist/commands/detect.js +273 -0
  207. package/dist/commands/detect.js.map +1 -0
  208. package/dist/commands/doctor.d.ts +6 -0
  209. package/dist/commands/doctor.d.ts.map +1 -0
  210. package/dist/commands/doctor.js +191 -0
  211. package/dist/commands/doctor.js.map +1 -0
  212. package/dist/commands/edit-cmd.d.ts +26 -0
  213. package/dist/commands/edit-cmd.d.ts.map +1 -0
  214. package/dist/commands/edit-cmd.js +870 -0
  215. package/dist/commands/edit-cmd.js.map +1 -0
  216. package/dist/commands/export.d.ts +39 -0
  217. package/dist/commands/export.d.ts.map +1 -0
  218. package/dist/commands/export.js +730 -0
  219. package/dist/commands/export.js.map +1 -0
  220. package/dist/commands/generate.d.ts +25 -0
  221. package/dist/commands/generate.d.ts.map +1 -0
  222. package/dist/commands/generate.js +1885 -0
  223. package/dist/commands/generate.js.map +1 -0
  224. package/dist/commands/media.d.ts +3 -0
  225. package/dist/commands/media.d.ts.map +1 -0
  226. package/dist/commands/media.js +165 -0
  227. package/dist/commands/media.js.map +1 -0
  228. package/dist/commands/output.d.ts +45 -0
  229. package/dist/commands/output.d.ts.map +1 -0
  230. package/dist/commands/output.js +122 -0
  231. package/dist/commands/output.js.map +1 -0
  232. package/dist/commands/pipeline.d.ts +19 -0
  233. package/dist/commands/pipeline.d.ts.map +1 -0
  234. package/dist/commands/pipeline.js +345 -0
  235. package/dist/commands/pipeline.js.map +1 -0
  236. package/dist/commands/project.d.ts +3 -0
  237. package/dist/commands/project.d.ts.map +1 -0
  238. package/dist/commands/project.js +139 -0
  239. package/dist/commands/project.js.map +1 -0
  240. package/dist/commands/project.test.d.ts +2 -0
  241. package/dist/commands/project.test.d.ts.map +1 -0
  242. package/dist/commands/project.test.js +105 -0
  243. package/dist/commands/project.test.js.map +1 -0
  244. package/dist/commands/sanitize.d.ts +21 -0
  245. package/dist/commands/sanitize.d.ts.map +1 -0
  246. package/dist/commands/sanitize.js +56 -0
  247. package/dist/commands/sanitize.js.map +1 -0
  248. package/dist/commands/schema.d.ts +11 -0
  249. package/dist/commands/schema.d.ts.map +1 -0
  250. package/dist/commands/schema.js +101 -0
  251. package/dist/commands/schema.js.map +1 -0
  252. package/dist/commands/setup.d.ts +6 -0
  253. package/dist/commands/setup.d.ts.map +1 -0
  254. package/dist/commands/setup.js +440 -0
  255. package/dist/commands/setup.js.map +1 -0
  256. package/dist/commands/timeline.d.ts +3 -0
  257. package/dist/commands/timeline.d.ts.map +1 -0
  258. package/dist/commands/timeline.js +469 -0
  259. package/dist/commands/timeline.js.map +1 -0
  260. package/dist/commands/timeline.test.d.ts +2 -0
  261. package/dist/commands/timeline.test.d.ts.map +1 -0
  262. package/dist/commands/timeline.test.js +320 -0
  263. package/dist/commands/timeline.test.js.map +1 -0
  264. package/dist/commands/validate.d.ts +32 -0
  265. package/dist/commands/validate.d.ts.map +1 -0
  266. package/dist/commands/validate.js +63 -0
  267. package/dist/commands/validate.js.map +1 -0
  268. package/dist/config/config.test.d.ts +2 -0
  269. package/dist/config/config.test.d.ts.map +1 -0
  270. package/dist/config/config.test.js +164 -0
  271. package/dist/config/config.test.js.map +1 -0
  272. package/dist/config/index.d.ts +35 -0
  273. package/dist/config/index.d.ts.map +1 -0
  274. package/dist/config/index.js +101 -0
  275. package/dist/config/index.js.map +1 -0
  276. package/dist/config/schema.d.ts +43 -0
  277. package/dist/config/schema.d.ts.map +1 -0
  278. package/dist/config/schema.js +42 -0
  279. package/dist/config/schema.js.map +1 -0
  280. package/dist/engine/index.d.ts +3 -0
  281. package/dist/engine/index.d.ts.map +1 -0
  282. package/dist/engine/index.js +2 -0
  283. package/dist/engine/index.js.map +1 -0
  284. package/dist/engine/project.d.ts +84 -0
  285. package/dist/engine/project.d.ts.map +1 -0
  286. package/dist/engine/project.js +355 -0
  287. package/dist/engine/project.js.map +1 -0
  288. package/dist/engine/project.test.d.ts +2 -0
  289. package/dist/engine/project.test.d.ts.map +1 -0
  290. package/dist/engine/project.test.js +599 -0
  291. package/dist/engine/project.test.js.map +1 -0
  292. package/dist/index.d.ts +7 -0
  293. package/dist/index.d.ts.map +1 -0
  294. package/dist/index.js +131 -0
  295. package/dist/index.js.map +1 -0
  296. package/dist/utils/api-key.d.ts +36 -0
  297. package/dist/utils/api-key.d.ts.map +1 -0
  298. package/dist/utils/api-key.js +211 -0
  299. package/dist/utils/api-key.js.map +1 -0
  300. package/dist/utils/api-key.test.d.ts +2 -0
  301. package/dist/utils/api-key.test.d.ts.map +1 -0
  302. package/dist/utils/api-key.test.js +35 -0
  303. package/dist/utils/api-key.test.js.map +1 -0
  304. package/dist/utils/audio.d.ts +23 -0
  305. package/dist/utils/audio.d.ts.map +1 -0
  306. package/dist/utils/audio.js +79 -0
  307. package/dist/utils/audio.js.map +1 -0
  308. package/dist/utils/exec-safe.d.ts +22 -0
  309. package/dist/utils/exec-safe.d.ts.map +1 -0
  310. package/dist/utils/exec-safe.js +62 -0
  311. package/dist/utils/exec-safe.js.map +1 -0
  312. package/dist/utils/first-run.d.ts +13 -0
  313. package/dist/utils/first-run.d.ts.map +1 -0
  314. package/dist/utils/first-run.js +48 -0
  315. package/dist/utils/first-run.js.map +1 -0
  316. package/dist/utils/provider-resolver.d.ts +15 -0
  317. package/dist/utils/provider-resolver.d.ts.map +1 -0
  318. package/dist/utils/provider-resolver.js +42 -0
  319. package/dist/utils/provider-resolver.js.map +1 -0
  320. package/dist/utils/remotion.d.ts +210 -0
  321. package/dist/utils/remotion.d.ts.map +1 -0
  322. package/dist/utils/remotion.js +731 -0
  323. package/dist/utils/remotion.js.map +1 -0
  324. package/dist/utils/subtitle.d.ts +65 -0
  325. package/dist/utils/subtitle.d.ts.map +1 -0
  326. package/dist/utils/subtitle.js +135 -0
  327. package/dist/utils/subtitle.js.map +1 -0
  328. package/dist/utils/subtitle.test.d.ts +2 -0
  329. package/dist/utils/subtitle.test.d.ts.map +1 -0
  330. package/dist/utils/subtitle.test.js +175 -0
  331. package/dist/utils/subtitle.test.js.map +1 -0
  332. package/dist/utils/tty.d.ts +45 -0
  333. package/dist/utils/tty.d.ts.map +1 -0
  334. package/dist/utils/tty.js +172 -0
  335. package/dist/utils/tty.js.map +1 -0
  336. package/package.json +102 -0
  337. package/src/agent/adapters/claude.ts +143 -0
  338. package/src/agent/adapters/gemini.ts +159 -0
  339. package/src/agent/adapters/index.ts +61 -0
  340. package/src/agent/adapters/ollama.ts +231 -0
  341. package/src/agent/adapters/openai.ts +116 -0
  342. package/src/agent/adapters/xai.ts +119 -0
  343. package/src/agent/index.ts +251 -0
  344. package/src/agent/memory/index.ts +151 -0
  345. package/src/agent/prompts/system.ts +106 -0
  346. package/src/agent/tools/ai-editing.ts +845 -0
  347. package/src/agent/tools/ai-generation.ts +1073 -0
  348. package/src/agent/tools/ai-pipeline.ts +1055 -0
  349. package/src/agent/tools/ai.ts +21 -0
  350. package/src/agent/tools/batch.ts +429 -0
  351. package/src/agent/tools/e2e.test.ts +545 -0
  352. package/src/agent/tools/export.ts +184 -0
  353. package/src/agent/tools/filesystem.ts +237 -0
  354. package/src/agent/tools/index.ts +150 -0
  355. package/src/agent/tools/integration.test.ts +775 -0
  356. package/src/agent/tools/media.ts +697 -0
  357. package/src/agent/tools/project.ts +313 -0
  358. package/src/agent/tools/timeline.ts +951 -0
  359. package/src/agent/types.ts +68 -0
  360. package/src/commands/agent.ts +340 -0
  361. package/src/commands/ai-analyze.ts +429 -0
  362. package/src/commands/ai-animated-caption.ts +390 -0
  363. package/src/commands/ai-audio.ts +941 -0
  364. package/src/commands/ai-broll.ts +490 -0
  365. package/src/commands/ai-edit-cli.ts +658 -0
  366. package/src/commands/ai-edit.ts +1542 -0
  367. package/src/commands/ai-fill-gaps.ts +566 -0
  368. package/src/commands/ai-helpers.ts +65 -0
  369. package/src/commands/ai-highlights.ts +1303 -0
  370. package/src/commands/ai-image.ts +761 -0
  371. package/src/commands/ai-motion.ts +347 -0
  372. package/src/commands/ai-narrate.ts +451 -0
  373. package/src/commands/ai-review.ts +309 -0
  374. package/src/commands/ai-script-pipeline-cli.ts +1710 -0
  375. package/src/commands/ai-script-pipeline.ts +1365 -0
  376. package/src/commands/ai-suggest-edit.ts +264 -0
  377. package/src/commands/ai-video-fx.ts +445 -0
  378. package/src/commands/ai-video.ts +915 -0
  379. package/src/commands/ai-viral.ts +595 -0
  380. package/src/commands/ai-visual-fx.ts +601 -0
  381. package/src/commands/ai.test.ts +627 -0
  382. package/src/commands/ai.ts +307 -0
  383. package/src/commands/analyze.ts +282 -0
  384. package/src/commands/audio.ts +644 -0
  385. package/src/commands/batch.test.ts +279 -0
  386. package/src/commands/batch.ts +440 -0
  387. package/src/commands/detect.ts +329 -0
  388. package/src/commands/doctor.ts +237 -0
  389. package/src/commands/edit-cmd.ts +1014 -0
  390. package/src/commands/export.ts +918 -0
  391. package/src/commands/generate.ts +2146 -0
  392. package/src/commands/media.ts +177 -0
  393. package/src/commands/output.ts +142 -0
  394. package/src/commands/pipeline.ts +398 -0
  395. package/src/commands/project.test.ts +127 -0
  396. package/src/commands/project.ts +149 -0
  397. package/src/commands/sanitize.ts +60 -0
  398. package/src/commands/schema.ts +130 -0
  399. package/src/commands/setup.ts +509 -0
  400. package/src/commands/timeline.test.ts +499 -0
  401. package/src/commands/timeline.ts +529 -0
  402. package/src/commands/validate.ts +77 -0
  403. package/src/config/config.test.ts +197 -0
  404. package/src/config/index.ts +125 -0
  405. package/src/config/schema.ts +82 -0
  406. package/src/engine/index.ts +2 -0
  407. package/src/engine/project.test.ts +702 -0
  408. package/src/engine/project.ts +439 -0
  409. package/src/index.ts +146 -0
  410. package/src/utils/api-key.test.ts +41 -0
  411. package/src/utils/api-key.ts +247 -0
  412. package/src/utils/audio.ts +83 -0
  413. package/src/utils/exec-safe.ts +75 -0
  414. package/src/utils/first-run.ts +52 -0
  415. package/src/utils/provider-resolver.ts +56 -0
  416. package/src/utils/remotion.ts +951 -0
  417. package/src/utils/subtitle.test.ts +227 -0
  418. package/src/utils/subtitle.ts +169 -0
  419. package/src/utils/tty.ts +196 -0
  420. package/tsconfig.json +20 -0
@@ -0,0 +1,775 @@
1
+ /**
2
+ * Integration Tests: CLI ↔ Agent Tool Synchronization
3
+ *
4
+ * These tests verify that:
5
+ * 1. All Agent tools are properly registered
6
+ * 2. Agent tools correctly wrap CLI functions
7
+ * 3. Parameter schemas match between CLI and Agent
8
+ * 4. Tool handlers produce expected output formats
9
+ */
10
+
11
+ import { describe, it, expect, beforeEach, vi } from "vitest";
12
+ import { ToolRegistry } from "./index.js";
13
+ import { registerProjectTools } from "./project.js";
14
+ import { registerTimelineTools } from "./timeline.js";
15
+ import { registerFilesystemTools } from "./filesystem.js";
16
+ import { registerMediaTools } from "./media.js";
17
+ import { registerAITools } from "./ai.js";
18
+ import { registerExportTools } from "./export.js";
19
+ import { registerBatchTools } from "./batch.js";
20
+ // Mock the imported CLI functions to avoid actual API calls
21
+ vi.mock("../../commands/ai-script-pipeline.js", () => ({
22
+ executeScriptToVideo: vi.fn().mockResolvedValue({
23
+ success: true,
24
+ outputDir: "/test/output",
25
+ scenes: 3,
26
+ storyboardPath: "/test/output/storyboard.json",
27
+ projectPath: "/test/output/project.vibe.json",
28
+ narrations: ["/test/output/narration-1.mp3"],
29
+ images: ["/test/output/scene-1.png"],
30
+ videos: ["/test/output/scene-1.mp4"],
31
+ totalDuration: 30,
32
+ failedScenes: [],
33
+ }),
34
+ executeRegenerateScene: vi.fn().mockResolvedValue({ success: true }),
35
+ }));
36
+
37
+ vi.mock("../../commands/ai-highlights.js", () => ({
38
+ executeHighlights: vi.fn().mockResolvedValue({
39
+ success: true,
40
+ highlights: [
41
+ {
42
+ index: 1,
43
+ startTime: 10,
44
+ endTime: 25,
45
+ duration: 15,
46
+ category: "emotional",
47
+ confidence: 0.95,
48
+ reason: "Test highlight",
49
+ transcript: "Test transcript",
50
+ },
51
+ ],
52
+ totalDuration: 120,
53
+ totalHighlightDuration: 15,
54
+ }),
55
+ executeAutoShorts: vi.fn().mockResolvedValue({
56
+ success: true,
57
+ shorts: [
58
+ {
59
+ index: 1,
60
+ startTime: 30,
61
+ endTime: 60,
62
+ duration: 30,
63
+ confidence: 0.9,
64
+ reason: "Viral moment",
65
+ outputPath: "/test/short-1.mp4",
66
+ },
67
+ ],
68
+ }),
69
+ }));
70
+
71
+ vi.mock("../../commands/ai-animated-caption.js", () => ({
72
+ executeAnimatedCaption: vi.fn().mockResolvedValue({
73
+ success: true,
74
+ outputPath: "/test/captioned.mp4",
75
+ wordCount: 42,
76
+ groupCount: 10,
77
+ style: "highlight",
78
+ tier: "remotion",
79
+ }),
80
+ }));
81
+
82
+ vi.mock("../../commands/ai-analyze.js", () => ({
83
+ executeGeminiVideo: vi.fn().mockResolvedValue({
84
+ success: true,
85
+ response: "This is a test video summary.",
86
+ model: "gemini-3-flash-preview",
87
+ totalTokens: 1000,
88
+ }),
89
+ executeAnalyze: vi.fn().mockResolvedValue({
90
+ success: true,
91
+ response: "Test analysis",
92
+ }),
93
+ }));
94
+
95
+ vi.mock("../../commands/ai-edit.js", () => ({
96
+ executeSilenceCut: vi.fn().mockResolvedValue({
97
+ success: true,
98
+ outputPath: "/test/video-cut.mp4",
99
+ totalDuration: 120,
100
+ silentPeriods: [
101
+ { start: 10, end: 15, duration: 5 },
102
+ { start: 60, end: 63, duration: 3 },
103
+ ],
104
+ silentDuration: 8,
105
+ }),
106
+ executeJumpCut: vi.fn().mockResolvedValue({
107
+ success: true,
108
+ outputPath: "/test/video-jumpcut.mp4",
109
+ totalDuration: 120,
110
+ fillerCount: 5,
111
+ fillerDuration: 3.2,
112
+ fillers: [
113
+ { word: "um", start: 5.1, end: 5.6 },
114
+ { word: "like", start: 12.3, end: 12.8 },
115
+ ],
116
+ }),
117
+ executeCaption: vi.fn().mockResolvedValue({
118
+ success: true,
119
+ outputPath: "/test/video-captioned.mp4",
120
+ srtPath: "/test/video-captioned.srt",
121
+ segmentCount: 12,
122
+ }),
123
+ executeNoiseReduce: vi.fn().mockResolvedValue({
124
+ success: true,
125
+ outputPath: "/test/audio-denoised.mp4",
126
+ inputDuration: 60,
127
+ }),
128
+ executeFade: vi.fn().mockResolvedValue({
129
+ success: true,
130
+ outputPath: "/test/video-faded.mp4",
131
+ totalDuration: 120,
132
+ fadeInApplied: true,
133
+ fadeOutApplied: true,
134
+ }),
135
+ executeTranslateSrt: vi.fn().mockResolvedValue({
136
+ success: true,
137
+ outputPath: "/test/subtitles-ko.srt",
138
+ segmentCount: 20,
139
+ sourceLanguage: "en",
140
+ targetLanguage: "ko",
141
+ }),
142
+ executeTextOverlay: vi.fn().mockResolvedValue({
143
+ success: true,
144
+ outputPath: "/test/video-overlay.mp4",
145
+ }),
146
+ DEFAULT_FILLER_WORDS: ["um", "uh", "like", "you know"],
147
+ detectFillerRanges: vi.fn(),
148
+ }));
149
+
150
+ vi.mock("../../commands/ai-review.js", () => ({
151
+ executeReview: vi.fn().mockResolvedValue({
152
+ success: true,
153
+ issues: [],
154
+ }),
155
+ }));
156
+
157
+ vi.mock("../../commands/ai-image.js", () => ({
158
+ executeThumbnailBestFrame: vi.fn().mockResolvedValue({
159
+ success: true,
160
+ outputPath: "/test/video-thumbnail.png",
161
+ timestamp: 15.5,
162
+ reason: "Best composed frame",
163
+ }),
164
+ executeGeminiEdit: vi.fn().mockResolvedValue({
165
+ success: true,
166
+ outputPath: "/test/edited.png",
167
+ }),
168
+ }));
169
+
170
+ describe("CLI ↔ Agent Tool Synchronization", () => {
171
+ let registry: ToolRegistry;
172
+
173
+ beforeEach(() => {
174
+ registry = new ToolRegistry();
175
+ registerProjectTools(registry);
176
+ registerTimelineTools(registry);
177
+ registerFilesystemTools(registry);
178
+ registerMediaTools(registry);
179
+ registerAITools(registry);
180
+ registerExportTools(registry);
181
+ registerBatchTools(registry);
182
+ });
183
+
184
+ describe("Tool Registration", () => {
185
+ it("should register all 57 tools", () => {
186
+ const tools = registry.getAll();
187
+ expect(tools.length).toBe(58);
188
+ });
189
+
190
+ it("should register all project tools (5)", () => {
191
+ const projectTools = [
192
+ "project_create",
193
+ "project_info",
194
+ "project_set",
195
+ "project_open",
196
+ "project_save",
197
+ ];
198
+ for (const name of projectTools) {
199
+ expect(registry.get(name)).toBeDefined();
200
+ }
201
+ });
202
+
203
+ it("should register all timeline tools (11)", () => {
204
+ const timelineTools = [
205
+ "timeline_add_source",
206
+ "timeline_add_clip",
207
+ "timeline_add_track",
208
+ "timeline_add_effect",
209
+ "timeline_trim",
210
+ "timeline_split",
211
+ "timeline_move",
212
+ "timeline_clear",
213
+ "timeline_delete",
214
+ "timeline_duplicate",
215
+ "timeline_list",
216
+ ];
217
+ for (const name of timelineTools) {
218
+ expect(registry.get(name)).toBeDefined();
219
+ }
220
+ });
221
+
222
+ it("should register all filesystem tools (4)", () => {
223
+ const fsTools = ["fs_list", "fs_read", "fs_write", "fs_exists"];
224
+ for (const name of fsTools) {
225
+ expect(registry.get(name)).toBeDefined();
226
+ }
227
+ });
228
+
229
+ it("should register all media tools (8)", () => {
230
+ const mediaTools = [
231
+ "media_info",
232
+ "detect_scenes",
233
+ "detect_silence",
234
+ "detect_beats",
235
+ "audio_transcribe",
236
+ "media_compress",
237
+ "media_convert",
238
+ "media_concat",
239
+ ];
240
+ for (const name of mediaTools) {
241
+ expect(registry.get(name)).toBeDefined();
242
+ }
243
+ });
244
+
245
+ it("should register all batch tools (3)", () => {
246
+ const batchTools = [
247
+ "batch_import",
248
+ "batch_concat",
249
+ "batch_apply_effect",
250
+ ];
251
+ for (const name of batchTools) {
252
+ expect(registry.get(name)).toBeDefined();
253
+ }
254
+ });
255
+
256
+ it("should register all AI tools (23)", () => {
257
+ const aiTools = [
258
+ // Generation tools (8)
259
+ "generate_image",
260
+ "generate_video",
261
+ "generate_speech",
262
+ "generate_sound_effect",
263
+ "generate_music",
264
+ "generate_storyboard",
265
+ "generate_motion",
266
+ "generate_thumbnail",
267
+ // Edit tools (8)
268
+ "edit_text_overlay",
269
+ "edit_silence_cut",
270
+ "edit_jump_cut",
271
+ "edit_caption",
272
+ "edit_noise_reduce",
273
+ "edit_fade",
274
+ "edit_translate_srt",
275
+ "edit_image",
276
+ // Analyze tools (3)
277
+ "analyze_review",
278
+ "analyze_video",
279
+ "analyze_media",
280
+ // Pipeline tools (4)
281
+ "pipeline_script_to_video",
282
+ "pipeline_highlights",
283
+ "pipeline_auto_shorts",
284
+ "pipeline_regenerate_scene",
285
+ ];
286
+ for (const name of aiTools) {
287
+ expect(registry.get(name)).toBeDefined();
288
+ }
289
+ });
290
+
291
+ it("should register all export tools (3)", () => {
292
+ const exportTools = ["export_video", "export_audio", "export_subtitles"];
293
+ for (const name of exportTools) {
294
+ expect(registry.get(name)).toBeDefined();
295
+ }
296
+ });
297
+ });
298
+
299
+ describe("Tool Definition Schema Validation", () => {
300
+ it("all tools should have valid definitions", () => {
301
+ const tools = registry.getAll();
302
+ for (const tool of tools) {
303
+ expect(tool.name).toBeTruthy();
304
+ expect(tool.description).toBeTruthy();
305
+ expect(tool.parameters).toBeDefined();
306
+ expect(tool.parameters.type).toBe("object");
307
+ expect(tool.parameters.properties).toBeDefined();
308
+ }
309
+ });
310
+
311
+ it("all tools should have required parameters listed", () => {
312
+ const tools = registry.getAll();
313
+ for (const tool of tools) {
314
+ if (tool.parameters.required && tool.parameters.required.length > 0) {
315
+ for (const requiredParam of tool.parameters.required) {
316
+ expect(tool.parameters.properties[requiredParam]).toBeDefined();
317
+ }
318
+ }
319
+ }
320
+ });
321
+
322
+ it("all parameter properties should have type and description", () => {
323
+ const tools = registry.getAll();
324
+ for (const tool of tools) {
325
+ for (const paramDef of Object.values(
326
+ tool.parameters.properties
327
+ )) {
328
+ const param = paramDef as { type?: string; description?: string };
329
+ expect(param.type).toBeTruthy();
330
+ expect(param.description).toBeTruthy();
331
+ }
332
+ }
333
+ });
334
+ });
335
+
336
+ describe("AI Pipeline Tools - Parameter Mapping", () => {
337
+ describe("pipeline_script_to_video", () => {
338
+ it("should have all CLI options as parameters", () => {
339
+ const tool = registry.get("pipeline_script_to_video");
340
+ expect(tool).toBeDefined();
341
+
342
+ const params = tool!.parameters.properties;
343
+ // Required
344
+ expect(params.script).toBeDefined();
345
+ // Optional (matching CLI options)
346
+ expect(params.outputDir).toBeDefined();
347
+ expect(params.duration).toBeDefined();
348
+ expect(params.voice).toBeDefined();
349
+ expect(params.generator).toBeDefined();
350
+ expect(params.imageProvider).toBeDefined();
351
+ expect(params.aspectRatio).toBeDefined();
352
+ expect(params.imagesOnly).toBeDefined();
353
+ expect(params.noVoiceover).toBeDefined();
354
+ expect(params.retries).toBeDefined();
355
+ });
356
+
357
+ it("should have correct enum values for generator", () => {
358
+ const tool = registry.get("pipeline_script_to_video");
359
+ const generator = tool!.parameters.properties.generator as {
360
+ enum?: string[];
361
+ };
362
+ expect(generator.enum).toContain("runway");
363
+ expect(generator.enum).toContain("kling");
364
+ });
365
+
366
+ it("should have correct enum values for imageProvider", () => {
367
+ const tool = registry.get("pipeline_script_to_video");
368
+ const imageProvider = tool!.parameters.properties.imageProvider as {
369
+ enum?: string[];
370
+ };
371
+ expect(imageProvider.enum).toContain("openai");
372
+ expect(imageProvider.enum).toContain("gemini");
373
+ });
374
+
375
+ it("should have correct enum values for aspectRatio", () => {
376
+ const tool = registry.get("pipeline_script_to_video");
377
+ const aspectRatio = tool!.parameters.properties.aspectRatio as {
378
+ enum?: string[];
379
+ };
380
+ expect(aspectRatio.enum).toContain("16:9");
381
+ expect(aspectRatio.enum).toContain("9:16");
382
+ expect(aspectRatio.enum).toContain("1:1");
383
+ });
384
+ });
385
+
386
+ describe("pipeline_highlights", () => {
387
+ it("should have all CLI options as parameters", () => {
388
+ const tool = registry.get("pipeline_highlights");
389
+ expect(tool).toBeDefined();
390
+
391
+ const params = tool!.parameters.properties;
392
+ // Required
393
+ expect(params.media).toBeDefined();
394
+ // Optional (matching CLI options)
395
+ expect(params.output).toBeDefined();
396
+ expect(params.project).toBeDefined();
397
+ expect(params.duration).toBeDefined();
398
+ expect(params.count).toBeDefined();
399
+ expect(params.threshold).toBeDefined();
400
+ expect(params.criteria).toBeDefined();
401
+ expect(params.language).toBeDefined();
402
+ expect(params.useGemini).toBeDefined();
403
+ expect(params.lowRes).toBeDefined();
404
+ });
405
+
406
+ it("should have correct enum values for criteria", () => {
407
+ const tool = registry.get("pipeline_highlights");
408
+ const criteria = tool!.parameters.properties.criteria as {
409
+ enum?: string[];
410
+ };
411
+ expect(criteria.enum).toContain("emotional");
412
+ expect(criteria.enum).toContain("informative");
413
+ expect(criteria.enum).toContain("funny");
414
+ expect(criteria.enum).toContain("all");
415
+ });
416
+ });
417
+
418
+ describe("pipeline_auto_shorts", () => {
419
+ it("should have all CLI options as parameters", () => {
420
+ const tool = registry.get("pipeline_auto_shorts");
421
+ expect(tool).toBeDefined();
422
+
423
+ const params = tool!.parameters.properties;
424
+ // Required
425
+ expect(params.video).toBeDefined();
426
+ // Optional (matching CLI options)
427
+ expect(params.outputDir).toBeDefined();
428
+ expect(params.duration).toBeDefined();
429
+ expect(params.count).toBeDefined();
430
+ expect(params.aspect).toBeDefined();
431
+ expect(params.addCaptions).toBeDefined();
432
+ expect(params.captionStyle).toBeDefined();
433
+ expect(params.analyzeOnly).toBeDefined();
434
+ expect(params.language).toBeDefined();
435
+ expect(params.useGemini).toBeDefined();
436
+ expect(params.lowRes).toBeDefined();
437
+ });
438
+
439
+ it("should have correct enum values for aspect", () => {
440
+ const tool = registry.get("pipeline_auto_shorts");
441
+ const aspect = tool!.parameters.properties.aspect as { enum?: string[] };
442
+ expect(aspect.enum).toContain("9:16");
443
+ expect(aspect.enum).toContain("1:1");
444
+ });
445
+
446
+ it("should have correct enum values for captionStyle", () => {
447
+ const tool = registry.get("pipeline_auto_shorts");
448
+ const captionStyle = tool!.parameters.properties.captionStyle as {
449
+ enum?: string[];
450
+ };
451
+ expect(captionStyle.enum).toContain("minimal");
452
+ expect(captionStyle.enum).toContain("bold");
453
+ expect(captionStyle.enum).toContain("animated");
454
+ });
455
+ });
456
+
457
+ describe("analyze_video", () => {
458
+ it("should have all CLI options as parameters", () => {
459
+ const tool = registry.get("analyze_video");
460
+ expect(tool).toBeDefined();
461
+
462
+ const params = tool!.parameters.properties;
463
+ // Required
464
+ expect(params.source).toBeDefined();
465
+ expect(params.prompt).toBeDefined();
466
+ // Optional (matching CLI options)
467
+ expect(params.model).toBeDefined();
468
+ expect(params.fps).toBeDefined();
469
+ expect(params.start).toBeDefined();
470
+ expect(params.end).toBeDefined();
471
+ expect(params.lowRes).toBeDefined();
472
+ });
473
+
474
+ it("should have correct enum values for model", () => {
475
+ const tool = registry.get("analyze_video");
476
+ const model = tool!.parameters.properties.model as { enum?: string[] };
477
+ expect(model.enum).toContain("flash");
478
+ expect(model.enum).toContain("flash-2.5");
479
+ expect(model.enum).toContain("pro");
480
+ });
481
+ });
482
+ });
483
+
484
+ describe("Tool Handler Execution (Mocked)", () => {
485
+ const mockContext = {
486
+ workingDirectory: "/test/workdir",
487
+ projectPath: "/test/project.vibe.json",
488
+ };
489
+
490
+ describe("pipeline_script_to_video handler", () => {
491
+ it("should call executeScriptToVideo with correct parameters", async () => {
492
+ const { executeScriptToVideo } = await import("../../commands/ai-script-pipeline.js");
493
+ const handler = registry.getHandler("pipeline_script_to_video");
494
+ expect(handler).toBeDefined();
495
+
496
+ const result = await handler!(
497
+ {
498
+ script: "Test script. Scene two. Conclusion.",
499
+ outputDir: "output",
500
+ generator: "runway",
501
+ imageProvider: "gemini",
502
+ aspectRatio: "16:9",
503
+ },
504
+ mockContext
505
+ );
506
+
507
+ expect(executeScriptToVideo).toHaveBeenCalledWith(
508
+ expect.objectContaining({
509
+ script: "Test script. Scene two. Conclusion.",
510
+ generator: "runway",
511
+ imageProvider: "gemini",
512
+ aspectRatio: "16:9",
513
+ })
514
+ );
515
+ expect(result.success).toBe(true);
516
+ expect(result.output).toContain("Script-to-Video complete");
517
+ });
518
+
519
+ it("should handle failure gracefully", async () => {
520
+ const { executeScriptToVideo } = await import("../../commands/ai-script-pipeline.js");
521
+ vi.mocked(executeScriptToVideo).mockResolvedValueOnce({
522
+ success: false,
523
+ outputDir: "/test/output",
524
+ scenes: 0,
525
+ error: "API key missing",
526
+ });
527
+
528
+ const handler = registry.getHandler("pipeline_script_to_video");
529
+ const result = await handler!({ script: "Test" }, mockContext);
530
+
531
+ expect(result.success).toBe(false);
532
+ expect(result.error).toContain("API key missing");
533
+ });
534
+ });
535
+
536
+ describe("pipeline_highlights handler", () => {
537
+ it("should call executeHighlights with correct parameters", async () => {
538
+ const { executeHighlights } = await import("../../commands/ai-highlights.js");
539
+ const handler = registry.getHandler("pipeline_highlights");
540
+ expect(handler).toBeDefined();
541
+
542
+ const result = await handler!(
543
+ {
544
+ media: "video.mp4",
545
+ duration: 60,
546
+ criteria: "emotional",
547
+ useGemini: true,
548
+ },
549
+ mockContext
550
+ );
551
+
552
+ expect(executeHighlights).toHaveBeenCalledWith(
553
+ expect.objectContaining({
554
+ media: "/test/workdir/video.mp4",
555
+ duration: 60,
556
+ criteria: "emotional",
557
+ useGemini: true,
558
+ })
559
+ );
560
+ expect(result.success).toBe(true);
561
+ expect(result.output).toContain("Found 1 highlights");
562
+ });
563
+ });
564
+
565
+ describe("pipeline_auto_shorts handler", () => {
566
+ it("should call executeAutoShorts with correct parameters", async () => {
567
+ const { executeAutoShorts } = await import("../../commands/ai-highlights.js");
568
+ const handler = registry.getHandler("pipeline_auto_shorts");
569
+ expect(handler).toBeDefined();
570
+
571
+ const result = await handler!(
572
+ {
573
+ video: "long-video.mp4",
574
+ count: 3,
575
+ duration: 45,
576
+ aspect: "9:16",
577
+ },
578
+ mockContext
579
+ );
580
+
581
+ expect(executeAutoShorts).toHaveBeenCalledWith(
582
+ expect.objectContaining({
583
+ video: "/test/workdir/long-video.mp4",
584
+ count: 3,
585
+ duration: 45,
586
+ aspect: "9:16",
587
+ })
588
+ );
589
+ expect(result.success).toBe(true);
590
+ expect(result.output).toContain("Generated 1 short");
591
+ });
592
+
593
+ it("should handle analyzeOnly mode", async () => {
594
+ const handler = registry.getHandler("pipeline_auto_shorts");
595
+ const result = await handler!(
596
+ {
597
+ video: "video.mp4",
598
+ analyzeOnly: true,
599
+ },
600
+ mockContext
601
+ );
602
+
603
+ expect(result.success).toBe(true);
604
+ });
605
+ });
606
+
607
+ describe("analyze_video handler", () => {
608
+ it("should call executeGeminiVideo with correct parameters", async () => {
609
+ const { executeGeminiVideo } = await import("../../commands/ai-analyze.js");
610
+ const handler = registry.getHandler("analyze_video");
611
+ expect(handler).toBeDefined();
612
+
613
+ const result = await handler!(
614
+ {
615
+ source: "video.mp4",
616
+ prompt: "Summarize this video",
617
+ model: "flash",
618
+ },
619
+ mockContext
620
+ );
621
+
622
+ expect(executeGeminiVideo).toHaveBeenCalledWith(
623
+ expect.objectContaining({
624
+ source: "/test/workdir/video.mp4",
625
+ prompt: "Summarize this video",
626
+ model: "flash",
627
+ })
628
+ );
629
+ expect(result.success).toBe(true);
630
+ expect(result.output).toContain("test video summary");
631
+ });
632
+
633
+ it("should handle YouTube URLs without modification", async () => {
634
+ const { executeGeminiVideo } = await import("../../commands/ai-analyze.js");
635
+ const handler = registry.getHandler("analyze_video");
636
+
637
+ await handler!(
638
+ {
639
+ source: "https://youtube.com/watch?v=test",
640
+ prompt: "Summarize",
641
+ },
642
+ mockContext
643
+ );
644
+
645
+ expect(executeGeminiVideo).toHaveBeenCalledWith(
646
+ expect.objectContaining({
647
+ source: "https://youtube.com/watch?v=test",
648
+ })
649
+ );
650
+ });
651
+ });
652
+ });
653
+
654
+ describe("Tool Categories Match CLAUDE.md Documentation", () => {
655
+ it("should have correct tool counts per category", () => {
656
+ const allTools = registry.getAll();
657
+
658
+ const projectTools = allTools.filter((t) => t.name.startsWith("project_"));
659
+ const timelineTools = allTools.filter((t) =>
660
+ t.name.startsWith("timeline_")
661
+ );
662
+ const fsTools = allTools.filter((t) => t.name.startsWith("fs_"));
663
+ const mediaTools = allTools.filter(
664
+ (t) =>
665
+ t.name.startsWith("media_") ||
666
+ t.name.startsWith("detect_") ||
667
+ t.name.startsWith("audio_")
668
+ );
669
+ const generateTools = allTools.filter((t) => t.name.startsWith("generate_"));
670
+ const editTools = allTools.filter((t) => t.name.startsWith("edit_"));
671
+ const analyzeTools = allTools.filter((t) => t.name.startsWith("analyze_"));
672
+ const pipelineTools = allTools.filter((t) => t.name.startsWith("pipeline_"));
673
+ const exportTools = allTools.filter((t) => t.name.startsWith("export_"));
674
+ const batchTools = allTools.filter((t) => t.name.startsWith("batch_"));
675
+
676
+ expect(projectTools.length).toBe(5);
677
+ expect(timelineTools.length).toBe(11); // Added timeline_clear
678
+ expect(fsTools.length).toBe(4);
679
+ expect(mediaTools.length).toBe(8); // Added media_compress, media_convert, media_concat
680
+ expect(generateTools.length).toBe(8); // image, video, speech, sound_effect, music, storyboard, motion, thumbnail
681
+ expect(editTools.length).toBe(8); // text_overlay, silence_cut, jump_cut, caption, noise_reduce, fade, translate_srt, image
682
+ expect(analyzeTools.length).toBe(3); // video, media, review
683
+ expect(pipelineTools.length).toBe(5); // script_to_video, highlights, auto_shorts, regenerate_scene, animated_caption
684
+ expect(exportTools.length).toBe(3);
685
+ expect(batchTools.length).toBe(3);
686
+
687
+ // Total: 5+11+4+8+8+8+3+4+3+3 = 57
688
+ const totalTools = projectTools.length +
689
+ timelineTools.length +
690
+ fsTools.length +
691
+ mediaTools.length +
692
+ generateTools.length +
693
+ editTools.length +
694
+ analyzeTools.length +
695
+ pipelineTools.length +
696
+ exportTools.length +
697
+ batchTools.length;
698
+ expect(totalTools).toBe(58);
699
+ });
700
+ });
701
+ });
702
+
703
+ describe("Exported CLI Functions", () => {
704
+ describe("Function signatures match Agent tool parameters", () => {
705
+ it("executeScriptToVideo accepts ScriptToVideoOptions", async () => {
706
+ // Type check - this will fail at compile time if signatures don't match
707
+ const { executeScriptToVideo } = await import("../../commands/ai-script-pipeline.js");
708
+ expect(typeof executeScriptToVideo).toBe("function");
709
+ });
710
+
711
+ it("executeHighlights accepts HighlightsOptions", async () => {
712
+ const { executeHighlights } = await import("../../commands/ai-highlights.js");
713
+ expect(typeof executeHighlights).toBe("function");
714
+ });
715
+
716
+ it("executeAutoShorts accepts AutoShortsOptions", async () => {
717
+ const { executeAutoShorts } = await import("../../commands/ai-highlights.js");
718
+ expect(typeof executeAutoShorts).toBe("function");
719
+ });
720
+
721
+ it("executeGeminiVideo accepts GeminiVideoOptions", async () => {
722
+ const { executeGeminiVideo } = await import("../../commands/ai-analyze.js");
723
+ expect(typeof executeGeminiVideo).toBe("function");
724
+ });
725
+ });
726
+ });
727
+
728
+ describe("Tool Name Consistency", () => {
729
+ let registry: ToolRegistry;
730
+
731
+ beforeEach(() => {
732
+ registry = new ToolRegistry();
733
+ registerProjectTools(registry);
734
+ registerTimelineTools(registry);
735
+ registerFilesystemTools(registry);
736
+ registerMediaTools(registry);
737
+ registerAITools(registry);
738
+ registerExportTools(registry);
739
+ registerBatchTools(registry);
740
+ });
741
+
742
+ it("all tool names should follow naming convention", () => {
743
+ const tools = registry.getAll();
744
+ const validPrefixes = [
745
+ "project_",
746
+ "timeline_",
747
+ "fs_",
748
+ "media_",
749
+ "detect_",
750
+ "audio_",
751
+ "generate_",
752
+ "edit_",
753
+ "analyze_",
754
+ "pipeline_",
755
+ "export_",
756
+ "batch_",
757
+ ];
758
+
759
+ for (const tool of tools) {
760
+ const hasValidPrefix = validPrefixes.some((prefix) =>
761
+ tool.name.startsWith(prefix)
762
+ );
763
+ expect(hasValidPrefix).toBe(true);
764
+ }
765
+ });
766
+
767
+ it("all tool names should be lowercase with underscores", () => {
768
+ const tools = registry.getAll();
769
+ const validNamePattern = /^[a-z_]+$/;
770
+
771
+ for (const tool of tools) {
772
+ expect(tool.name).toMatch(validNamePattern);
773
+ }
774
+ });
775
+ });