@vibeframe/cli 0.54.0 → 0.55.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 (481) hide show
  1. package/dist/index.js +63452 -233
  2. package/package.json +11 -6
  3. package/dist/agent/adapters/claude.d.ts +0 -15
  4. package/dist/agent/adapters/claude.d.ts.map +0 -1
  5. package/dist/agent/adapters/claude.js +0 -119
  6. package/dist/agent/adapters/claude.js.map +0 -1
  7. package/dist/agent/adapters/gemini.d.ts +0 -15
  8. package/dist/agent/adapters/gemini.d.ts.map +0 -1
  9. package/dist/agent/adapters/gemini.js +0 -132
  10. package/dist/agent/adapters/gemini.js.map +0 -1
  11. package/dist/agent/adapters/index.d.ts +0 -28
  12. package/dist/agent/adapters/index.d.ts.map +0 -1
  13. package/dist/agent/adapters/index.js +0 -43
  14. package/dist/agent/adapters/index.js.map +0 -1
  15. package/dist/agent/adapters/ollama.d.ts +0 -20
  16. package/dist/agent/adapters/ollama.d.ts.map +0 -1
  17. package/dist/agent/adapters/ollama.js +0 -186
  18. package/dist/agent/adapters/ollama.js.map +0 -1
  19. package/dist/agent/adapters/openai.d.ts +0 -15
  20. package/dist/agent/adapters/openai.d.ts.map +0 -1
  21. package/dist/agent/adapters/openai.js +0 -92
  22. package/dist/agent/adapters/openai.js.map +0 -1
  23. package/dist/agent/adapters/openrouter.d.ts +0 -16
  24. package/dist/agent/adapters/openrouter.d.ts.map +0 -1
  25. package/dist/agent/adapters/openrouter.js +0 -100
  26. package/dist/agent/adapters/openrouter.js.map +0 -1
  27. package/dist/agent/adapters/openrouter.test.d.ts +0 -5
  28. package/dist/agent/adapters/openrouter.test.d.ts.map +0 -1
  29. package/dist/agent/adapters/openrouter.test.js +0 -73
  30. package/dist/agent/adapters/openrouter.test.js.map +0 -1
  31. package/dist/agent/adapters/xai.d.ts +0 -15
  32. package/dist/agent/adapters/xai.d.ts.map +0 -1
  33. package/dist/agent/adapters/xai.js +0 -95
  34. package/dist/agent/adapters/xai.js.map +0 -1
  35. package/dist/agent/index.d.ts +0 -69
  36. package/dist/agent/index.d.ts.map +0 -1
  37. package/dist/agent/index.js +0 -180
  38. package/dist/agent/index.js.map +0 -1
  39. package/dist/agent/memory/index.d.ts +0 -70
  40. package/dist/agent/memory/index.d.ts.map +0 -1
  41. package/dist/agent/memory/index.js +0 -132
  42. package/dist/agent/memory/index.js.map +0 -1
  43. package/dist/agent/prompts/system.d.ts +0 -6
  44. package/dist/agent/prompts/system.d.ts.map +0 -1
  45. package/dist/agent/prompts/system.js +0 -103
  46. package/dist/agent/prompts/system.js.map +0 -1
  47. package/dist/agent/tools/ai-editing.d.ts +0 -15
  48. package/dist/agent/tools/ai-editing.d.ts.map +0 -1
  49. package/dist/agent/tools/ai-editing.js +0 -763
  50. package/dist/agent/tools/ai-editing.js.map +0 -1
  51. package/dist/agent/tools/ai-generation.d.ts +0 -13
  52. package/dist/agent/tools/ai-generation.d.ts.map +0 -1
  53. package/dist/agent/tools/ai-generation.js +0 -973
  54. package/dist/agent/tools/ai-generation.js.map +0 -1
  55. package/dist/agent/tools/ai-pipeline.d.ts +0 -14
  56. package/dist/agent/tools/ai-pipeline.d.ts.map +0 -1
  57. package/dist/agent/tools/ai-pipeline.js +0 -961
  58. package/dist/agent/tools/ai-pipeline.js.map +0 -1
  59. package/dist/agent/tools/ai.d.ts +0 -13
  60. package/dist/agent/tools/ai.d.ts.map +0 -1
  61. package/dist/agent/tools/ai.js +0 -19
  62. package/dist/agent/tools/ai.js.map +0 -1
  63. package/dist/agent/tools/batch.d.ts +0 -6
  64. package/dist/agent/tools/batch.d.ts.map +0 -1
  65. package/dist/agent/tools/batch.js +0 -383
  66. package/dist/agent/tools/batch.js.map +0 -1
  67. package/dist/agent/tools/e2e.test.d.ts +0 -26
  68. package/dist/agent/tools/e2e.test.d.ts.map +0 -1
  69. package/dist/agent/tools/e2e.test.js +0 -397
  70. package/dist/agent/tools/e2e.test.js.map +0 -1
  71. package/dist/agent/tools/export.d.ts +0 -6
  72. package/dist/agent/tools/export.d.ts.map +0 -1
  73. package/dist/agent/tools/export.js +0 -171
  74. package/dist/agent/tools/export.js.map +0 -1
  75. package/dist/agent/tools/filesystem.d.ts +0 -6
  76. package/dist/agent/tools/filesystem.d.ts.map +0 -1
  77. package/dist/agent/tools/filesystem.js +0 -212
  78. package/dist/agent/tools/filesystem.js.map +0 -1
  79. package/dist/agent/tools/index.d.ts +0 -66
  80. package/dist/agent/tools/index.d.ts.map +0 -1
  81. package/dist/agent/tools/index.js +0 -123
  82. package/dist/agent/tools/index.js.map +0 -1
  83. package/dist/agent/tools/integration.test.d.ts +0 -11
  84. package/dist/agent/tools/integration.test.d.ts.map +0 -1
  85. package/dist/agent/tools/integration.test.js +0 -659
  86. package/dist/agent/tools/integration.test.js.map +0 -1
  87. package/dist/agent/tools/media.d.ts +0 -6
  88. package/dist/agent/tools/media.d.ts.map +0 -1
  89. package/dist/agent/tools/media.js +0 -616
  90. package/dist/agent/tools/media.js.map +0 -1
  91. package/dist/agent/tools/project.d.ts +0 -6
  92. package/dist/agent/tools/project.d.ts.map +0 -1
  93. package/dist/agent/tools/project.js +0 -284
  94. package/dist/agent/tools/project.js.map +0 -1
  95. package/dist/agent/tools/scene.d.ts +0 -17
  96. package/dist/agent/tools/scene.d.ts.map +0 -1
  97. package/dist/agent/tools/scene.js +0 -263
  98. package/dist/agent/tools/scene.js.map +0 -1
  99. package/dist/agent/tools/scene.test.d.ts +0 -2
  100. package/dist/agent/tools/scene.test.d.ts.map +0 -1
  101. package/dist/agent/tools/scene.test.js +0 -139
  102. package/dist/agent/tools/scene.test.js.map +0 -1
  103. package/dist/agent/tools/timeline.d.ts +0 -6
  104. package/dist/agent/tools/timeline.d.ts.map +0 -1
  105. package/dist/agent/tools/timeline.js +0 -875
  106. package/dist/agent/tools/timeline.js.map +0 -1
  107. package/dist/agent/types.d.ts +0 -59
  108. package/dist/agent/types.d.ts.map +0 -1
  109. package/dist/agent/types.js +0 -5
  110. package/dist/agent/types.js.map +0 -1
  111. package/dist/commands/_shared/scene-html-emit.d.ts +0 -120
  112. package/dist/commands/_shared/scene-html-emit.d.ts.map +0 -1
  113. package/dist/commands/_shared/scene-html-emit.js +0 -422
  114. package/dist/commands/_shared/scene-html-emit.js.map +0 -1
  115. package/dist/commands/_shared/scene-html-emit.test.d.ts +0 -2
  116. package/dist/commands/_shared/scene-html-emit.test.d.ts.map +0 -1
  117. package/dist/commands/_shared/scene-html-emit.test.js +0 -396
  118. package/dist/commands/_shared/scene-html-emit.test.js.map +0 -1
  119. package/dist/commands/_shared/scene-lint.d.ts +0 -110
  120. package/dist/commands/_shared/scene-lint.d.ts.map +0 -1
  121. package/dist/commands/_shared/scene-lint.js +0 -207
  122. package/dist/commands/_shared/scene-lint.js.map +0 -1
  123. package/dist/commands/_shared/scene-lint.test.d.ts +0 -2
  124. package/dist/commands/_shared/scene-lint.test.d.ts.map +0 -1
  125. package/dist/commands/_shared/scene-lint.test.js +0 -208
  126. package/dist/commands/_shared/scene-lint.test.js.map +0 -1
  127. package/dist/commands/_shared/scene-project.d.ts +0 -101
  128. package/dist/commands/_shared/scene-project.d.ts.map +0 -1
  129. package/dist/commands/_shared/scene-project.js +0 -281
  130. package/dist/commands/_shared/scene-project.js.map +0 -1
  131. package/dist/commands/_shared/scene-project.test.d.ts +0 -2
  132. package/dist/commands/_shared/scene-project.test.d.ts.map +0 -1
  133. package/dist/commands/_shared/scene-project.test.js +0 -203
  134. package/dist/commands/_shared/scene-project.test.js.map +0 -1
  135. package/dist/commands/_shared/scene-render.d.ts +0 -79
  136. package/dist/commands/_shared/scene-render.d.ts.map +0 -1
  137. package/dist/commands/_shared/scene-render.js +0 -138
  138. package/dist/commands/_shared/scene-render.js.map +0 -1
  139. package/dist/commands/_shared/scene-render.test.d.ts +0 -2
  140. package/dist/commands/_shared/scene-render.test.d.ts.map +0 -1
  141. package/dist/commands/_shared/scene-render.test.js +0 -145
  142. package/dist/commands/_shared/scene-render.test.js.map +0 -1
  143. package/dist/commands/_shared/segments-to-scenes.d.ts +0 -85
  144. package/dist/commands/_shared/segments-to-scenes.d.ts.map +0 -1
  145. package/dist/commands/_shared/segments-to-scenes.js +0 -202
  146. package/dist/commands/_shared/segments-to-scenes.js.map +0 -1
  147. package/dist/commands/_shared/segments-to-scenes.test.d.ts +0 -2
  148. package/dist/commands/_shared/segments-to-scenes.test.d.ts.map +0 -1
  149. package/dist/commands/_shared/segments-to-scenes.test.js +0 -219
  150. package/dist/commands/_shared/segments-to-scenes.test.js.map +0 -1
  151. package/dist/commands/_shared/tts-resolve.d.ts +0 -75
  152. package/dist/commands/_shared/tts-resolve.d.ts.map +0 -1
  153. package/dist/commands/_shared/tts-resolve.js +0 -89
  154. package/dist/commands/_shared/tts-resolve.js.map +0 -1
  155. package/dist/commands/_shared/tts-resolve.test.d.ts +0 -6
  156. package/dist/commands/_shared/tts-resolve.test.d.ts.map +0 -1
  157. package/dist/commands/_shared/tts-resolve.test.js +0 -147
  158. package/dist/commands/_shared/tts-resolve.test.js.map +0 -1
  159. package/dist/commands/agent.d.ts +0 -21
  160. package/dist/commands/agent.d.ts.map +0 -1
  161. package/dist/commands/agent.js +0 -285
  162. package/dist/commands/agent.js.map +0 -1
  163. package/dist/commands/ai-analyze.d.ts +0 -106
  164. package/dist/commands/ai-analyze.d.ts.map +0 -1
  165. package/dist/commands/ai-analyze.js +0 -320
  166. package/dist/commands/ai-analyze.js.map +0 -1
  167. package/dist/commands/ai-animated-caption.d.ts +0 -64
  168. package/dist/commands/ai-animated-caption.d.ts.map +0 -1
  169. package/dist/commands/ai-animated-caption.js +0 -272
  170. package/dist/commands/ai-animated-caption.js.map +0 -1
  171. package/dist/commands/ai-audio.d.ts +0 -98
  172. package/dist/commands/ai-audio.d.ts.map +0 -1
  173. package/dist/commands/ai-audio.js +0 -1059
  174. package/dist/commands/ai-audio.js.map +0 -1
  175. package/dist/commands/ai-broll.d.ts +0 -15
  176. package/dist/commands/ai-broll.d.ts.map +0 -1
  177. package/dist/commands/ai-broll.js +0 -421
  178. package/dist/commands/ai-broll.js.map +0 -1
  179. package/dist/commands/ai-edit-cli.d.ts +0 -14
  180. package/dist/commands/ai-edit-cli.d.ts.map +0 -1
  181. package/dist/commands/ai-edit-cli.js +0 -585
  182. package/dist/commands/ai-edit-cli.js.map +0 -1
  183. package/dist/commands/ai-edit.d.ts +0 -398
  184. package/dist/commands/ai-edit.d.ts.map +0 -1
  185. package/dist/commands/ai-edit.js +0 -1060
  186. package/dist/commands/ai-edit.js.map +0 -1
  187. package/dist/commands/ai-fill-gaps.d.ts +0 -14
  188. package/dist/commands/ai-fill-gaps.d.ts.map +0 -1
  189. package/dist/commands/ai-fill-gaps.js +0 -447
  190. package/dist/commands/ai-fill-gaps.js.map +0 -1
  191. package/dist/commands/ai-helpers.d.ts +0 -20
  192. package/dist/commands/ai-helpers.d.ts.map +0 -1
  193. package/dist/commands/ai-helpers.js +0 -59
  194. package/dist/commands/ai-helpers.js.map +0 -1
  195. package/dist/commands/ai-highlights.d.ts +0 -127
  196. package/dist/commands/ai-highlights.d.ts.map +0 -1
  197. package/dist/commands/ai-highlights.js +0 -1053
  198. package/dist/commands/ai-highlights.js.map +0 -1
  199. package/dist/commands/ai-image.d.ts +0 -76
  200. package/dist/commands/ai-image.d.ts.map +0 -1
  201. package/dist/commands/ai-image.js +0 -858
  202. package/dist/commands/ai-image.js.map +0 -1
  203. package/dist/commands/ai-motion.d.ts +0 -50
  204. package/dist/commands/ai-motion.d.ts.map +0 -1
  205. package/dist/commands/ai-motion.js +0 -297
  206. package/dist/commands/ai-motion.js.map +0 -1
  207. package/dist/commands/ai-narrate.d.ts +0 -66
  208. package/dist/commands/ai-narrate.d.ts.map +0 -1
  209. package/dist/commands/ai-narrate.js +0 -332
  210. package/dist/commands/ai-narrate.js.map +0 -1
  211. package/dist/commands/ai-review.d.ts +0 -57
  212. package/dist/commands/ai-review.d.ts.map +0 -1
  213. package/dist/commands/ai-review.js +0 -270
  214. package/dist/commands/ai-review.js.map +0 -1
  215. package/dist/commands/ai-script-pipeline-cli.d.ts +0 -9
  216. package/dist/commands/ai-script-pipeline-cli.d.ts.map +0 -1
  217. package/dist/commands/ai-script-pipeline-cli.js +0 -502
  218. package/dist/commands/ai-script-pipeline-cli.js.map +0 -1
  219. package/dist/commands/ai-script-pipeline.d.ts +0 -305
  220. package/dist/commands/ai-script-pipeline.d.ts.map +0 -1
  221. package/dist/commands/ai-script-pipeline.js +0 -1546
  222. package/dist/commands/ai-script-pipeline.js.map +0 -1
  223. package/dist/commands/ai-suggest-edit.d.ts +0 -14
  224. package/dist/commands/ai-suggest-edit.d.ts.map +0 -1
  225. package/dist/commands/ai-suggest-edit.js +0 -215
  226. package/dist/commands/ai-suggest-edit.js.map +0 -1
  227. package/dist/commands/ai-video-fx.d.ts +0 -14
  228. package/dist/commands/ai-video-fx.d.ts.map +0 -1
  229. package/dist/commands/ai-video-fx.js +0 -396
  230. package/dist/commands/ai-video-fx.js.map +0 -1
  231. package/dist/commands/ai-video.d.ts +0 -91
  232. package/dist/commands/ai-video.d.ts.map +0 -1
  233. package/dist/commands/ai-video.js +0 -1055
  234. package/dist/commands/ai-video.js.map +0 -1
  235. package/dist/commands/ai-viral.d.ts +0 -15
  236. package/dist/commands/ai-viral.d.ts.map +0 -1
  237. package/dist/commands/ai-viral.js +0 -507
  238. package/dist/commands/ai-viral.js.map +0 -1
  239. package/dist/commands/ai-visual-fx.d.ts +0 -14
  240. package/dist/commands/ai-visual-fx.d.ts.map +0 -1
  241. package/dist/commands/ai-visual-fx.js +0 -521
  242. package/dist/commands/ai-visual-fx.js.map +0 -1
  243. package/dist/commands/ai.d.ts +0 -38
  244. package/dist/commands/ai.d.ts.map +0 -1
  245. package/dist/commands/ai.js +0 -225
  246. package/dist/commands/ai.js.map +0 -1
  247. package/dist/commands/ai.test.d.ts +0 -2
  248. package/dist/commands/ai.test.d.ts.map +0 -1
  249. package/dist/commands/ai.test.js +0 -557
  250. package/dist/commands/ai.test.js.map +0 -1
  251. package/dist/commands/analyze.d.ts +0 -16
  252. package/dist/commands/analyze.d.ts.map +0 -1
  253. package/dist/commands/analyze.js +0 -247
  254. package/dist/commands/analyze.js.map +0 -1
  255. package/dist/commands/audio.d.ts +0 -18
  256. package/dist/commands/audio.d.ts.map +0 -1
  257. package/dist/commands/audio.js +0 -539
  258. package/dist/commands/audio.js.map +0 -1
  259. package/dist/commands/batch.d.ts +0 -3
  260. package/dist/commands/batch.d.ts.map +0 -1
  261. package/dist/commands/batch.js +0 -419
  262. package/dist/commands/batch.js.map +0 -1
  263. package/dist/commands/batch.test.d.ts +0 -2
  264. package/dist/commands/batch.test.d.ts.map +0 -1
  265. package/dist/commands/batch.test.js +0 -203
  266. package/dist/commands/batch.test.js.map +0 -1
  267. package/dist/commands/context.d.ts +0 -7
  268. package/dist/commands/context.d.ts.map +0 -1
  269. package/dist/commands/context.js +0 -66
  270. package/dist/commands/context.js.map +0 -1
  271. package/dist/commands/demo.d.ts +0 -7
  272. package/dist/commands/demo.d.ts.map +0 -1
  273. package/dist/commands/demo.js +0 -192
  274. package/dist/commands/demo.js.map +0 -1
  275. package/dist/commands/detect.d.ts +0 -56
  276. package/dist/commands/detect.d.ts.map +0 -1
  277. package/dist/commands/detect.js +0 -464
  278. package/dist/commands/detect.js.map +0 -1
  279. package/dist/commands/doctor.d.ts +0 -6
  280. package/dist/commands/doctor.d.ts.map +0 -1
  281. package/dist/commands/doctor.js +0 -322
  282. package/dist/commands/doctor.js.map +0 -1
  283. package/dist/commands/edit-cmd.d.ts +0 -112
  284. package/dist/commands/edit-cmd.d.ts.map +0 -1
  285. package/dist/commands/edit-cmd.js +0 -1041
  286. package/dist/commands/edit-cmd.js.map +0 -1
  287. package/dist/commands/export.d.ts +0 -61
  288. package/dist/commands/export.d.ts.map +0 -1
  289. package/dist/commands/export.js +0 -980
  290. package/dist/commands/export.js.map +0 -1
  291. package/dist/commands/export.test.d.ts +0 -2
  292. package/dist/commands/export.test.d.ts.map +0 -1
  293. package/dist/commands/export.test.js +0 -107
  294. package/dist/commands/export.test.js.map +0 -1
  295. package/dist/commands/generate.d.ts +0 -84
  296. package/dist/commands/generate.d.ts.map +0 -1
  297. package/dist/commands/generate.js +0 -2030
  298. package/dist/commands/generate.js.map +0 -1
  299. package/dist/commands/media.d.ts +0 -3
  300. package/dist/commands/media.d.ts.map +0 -1
  301. package/dist/commands/media.js +0 -163
  302. package/dist/commands/media.js.map +0 -1
  303. package/dist/commands/output.d.ts +0 -51
  304. package/dist/commands/output.d.ts.map +0 -1
  305. package/dist/commands/output.js +0 -219
  306. package/dist/commands/output.js.map +0 -1
  307. package/dist/commands/output.test.d.ts +0 -2
  308. package/dist/commands/output.test.d.ts.map +0 -1
  309. package/dist/commands/output.test.js +0 -151
  310. package/dist/commands/output.test.js.map +0 -1
  311. package/dist/commands/pipeline.d.ts +0 -19
  312. package/dist/commands/pipeline.d.ts.map +0 -1
  313. package/dist/commands/pipeline.js +0 -345
  314. package/dist/commands/pipeline.js.map +0 -1
  315. package/dist/commands/project.d.ts +0 -3
  316. package/dist/commands/project.d.ts.map +0 -1
  317. package/dist/commands/project.js +0 -181
  318. package/dist/commands/project.js.map +0 -1
  319. package/dist/commands/project.test.d.ts +0 -2
  320. package/dist/commands/project.test.d.ts.map +0 -1
  321. package/dist/commands/project.test.js +0 -105
  322. package/dist/commands/project.test.js.map +0 -1
  323. package/dist/commands/run.d.ts +0 -15
  324. package/dist/commands/run.d.ts.map +0 -1
  325. package/dist/commands/run.js +0 -204
  326. package/dist/commands/run.js.map +0 -1
  327. package/dist/commands/sanitize.d.ts +0 -21
  328. package/dist/commands/sanitize.d.ts.map +0 -1
  329. package/dist/commands/sanitize.js +0 -56
  330. package/dist/commands/sanitize.js.map +0 -1
  331. package/dist/commands/scene.d.ts +0 -86
  332. package/dist/commands/scene.d.ts.map +0 -1
  333. package/dist/commands/scene.js +0 -719
  334. package/dist/commands/scene.js.map +0 -1
  335. package/dist/commands/scene.test.d.ts +0 -2
  336. package/dist/commands/scene.test.d.ts.map +0 -1
  337. package/dist/commands/scene.test.js +0 -219
  338. package/dist/commands/scene.test.js.map +0 -1
  339. package/dist/commands/schema.d.ts +0 -13
  340. package/dist/commands/schema.d.ts.map +0 -1
  341. package/dist/commands/schema.js +0 -218
  342. package/dist/commands/schema.js.map +0 -1
  343. package/dist/commands/setup.d.ts +0 -6
  344. package/dist/commands/setup.d.ts.map +0 -1
  345. package/dist/commands/setup.js +0 -461
  346. package/dist/commands/setup.js.map +0 -1
  347. package/dist/commands/timeline.d.ts +0 -3
  348. package/dist/commands/timeline.d.ts.map +0 -1
  349. package/dist/commands/timeline.js +0 -609
  350. package/dist/commands/timeline.js.map +0 -1
  351. package/dist/commands/timeline.test.d.ts +0 -2
  352. package/dist/commands/timeline.test.d.ts.map +0 -1
  353. package/dist/commands/timeline.test.js +0 -334
  354. package/dist/commands/timeline.test.js.map +0 -1
  355. package/dist/commands/validate.d.ts +0 -34
  356. package/dist/commands/validate.d.ts.map +0 -1
  357. package/dist/commands/validate.js +0 -70
  358. package/dist/commands/validate.js.map +0 -1
  359. package/dist/config/config.test.d.ts +0 -2
  360. package/dist/config/config.test.d.ts.map +0 -1
  361. package/dist/config/config.test.js +0 -164
  362. package/dist/config/config.test.js.map +0 -1
  363. package/dist/config/index.d.ts +0 -35
  364. package/dist/config/index.d.ts.map +0 -1
  365. package/dist/config/index.js +0 -101
  366. package/dist/config/index.js.map +0 -1
  367. package/dist/config/schema.d.ts +0 -52
  368. package/dist/config/schema.d.ts.map +0 -1
  369. package/dist/config/schema.js +0 -44
  370. package/dist/config/schema.js.map +0 -1
  371. package/dist/engine/index.d.ts +0 -3
  372. package/dist/engine/index.d.ts.map +0 -1
  373. package/dist/engine/index.js +0 -2
  374. package/dist/engine/index.js.map +0 -1
  375. package/dist/engine/project.d.ts +0 -84
  376. package/dist/engine/project.d.ts.map +0 -1
  377. package/dist/engine/project.js +0 -355
  378. package/dist/engine/project.js.map +0 -1
  379. package/dist/engine/project.test.d.ts +0 -2
  380. package/dist/engine/project.test.d.ts.map +0 -1
  381. package/dist/engine/project.test.js +0 -599
  382. package/dist/engine/project.test.js.map +0 -1
  383. package/dist/index.d.ts +0 -7
  384. package/dist/index.d.ts.map +0 -1
  385. package/dist/index.js.map +0 -1
  386. package/dist/pipeline/executor.d.ts +0 -19
  387. package/dist/pipeline/executor.d.ts.map +0 -1
  388. package/dist/pipeline/executor.js +0 -397
  389. package/dist/pipeline/executor.js.map +0 -1
  390. package/dist/pipeline/index.d.ts +0 -4
  391. package/dist/pipeline/index.d.ts.map +0 -1
  392. package/dist/pipeline/index.js +0 -2
  393. package/dist/pipeline/index.js.map +0 -1
  394. package/dist/pipeline/renderers/__tests__/html-template.test.d.ts +0 -2
  395. package/dist/pipeline/renderers/__tests__/html-template.test.d.ts.map +0 -1
  396. package/dist/pipeline/renderers/__tests__/html-template.test.js +0 -170
  397. package/dist/pipeline/renderers/__tests__/html-template.test.js.map +0 -1
  398. package/dist/pipeline/renderers/__tests__/integration.test.d.ts +0 -2
  399. package/dist/pipeline/renderers/__tests__/integration.test.d.ts.map +0 -1
  400. package/dist/pipeline/renderers/__tests__/integration.test.js +0 -175
  401. package/dist/pipeline/renderers/__tests__/integration.test.js.map +0 -1
  402. package/dist/pipeline/renderers/chrome.d.ts +0 -26
  403. package/dist/pipeline/renderers/chrome.d.ts.map +0 -1
  404. package/dist/pipeline/renderers/chrome.js +0 -48
  405. package/dist/pipeline/renderers/chrome.js.map +0 -1
  406. package/dist/pipeline/renderers/html-clips.d.ts +0 -20
  407. package/dist/pipeline/renderers/html-clips.d.ts.map +0 -1
  408. package/dist/pipeline/renderers/html-clips.js +0 -50
  409. package/dist/pipeline/renderers/html-clips.js.map +0 -1
  410. package/dist/pipeline/renderers/html-runtime.d.ts +0 -7
  411. package/dist/pipeline/renderers/html-runtime.d.ts.map +0 -1
  412. package/dist/pipeline/renderers/html-runtime.js +0 -80
  413. package/dist/pipeline/renderers/html-runtime.js.map +0 -1
  414. package/dist/pipeline/renderers/html-template.d.ts +0 -3
  415. package/dist/pipeline/renderers/html-template.d.ts.map +0 -1
  416. package/dist/pipeline/renderers/html-template.js +0 -36
  417. package/dist/pipeline/renderers/html-template.js.map +0 -1
  418. package/dist/pipeline/renderers/hyperframes.d.ts +0 -8
  419. package/dist/pipeline/renderers/hyperframes.d.ts.map +0 -1
  420. package/dist/pipeline/renderers/hyperframes.js +0 -63
  421. package/dist/pipeline/renderers/hyperframes.js.map +0 -1
  422. package/dist/pipeline/renderers/project-builder.d.ts +0 -8
  423. package/dist/pipeline/renderers/project-builder.d.ts.map +0 -1
  424. package/dist/pipeline/renderers/project-builder.js +0 -65
  425. package/dist/pipeline/renderers/project-builder.js.map +0 -1
  426. package/dist/pipeline/renderers/types.d.ts +0 -41
  427. package/dist/pipeline/renderers/types.d.ts.map +0 -1
  428. package/dist/pipeline/renderers/types.js +0 -11
  429. package/dist/pipeline/renderers/types.js.map +0 -1
  430. package/dist/pipeline/resolver.d.ts +0 -20
  431. package/dist/pipeline/resolver.d.ts.map +0 -1
  432. package/dist/pipeline/resolver.js +0 -74
  433. package/dist/pipeline/resolver.js.map +0 -1
  434. package/dist/pipeline/types.d.ts +0 -82
  435. package/dist/pipeline/types.d.ts.map +0 -1
  436. package/dist/pipeline/types.js +0 -8
  437. package/dist/pipeline/types.js.map +0 -1
  438. package/dist/utils/api-key.d.ts +0 -33
  439. package/dist/utils/api-key.d.ts.map +0 -1
  440. package/dist/utils/api-key.js +0 -228
  441. package/dist/utils/api-key.js.map +0 -1
  442. package/dist/utils/api-key.test.d.ts +0 -2
  443. package/dist/utils/api-key.test.d.ts.map +0 -1
  444. package/dist/utils/api-key.test.js +0 -35
  445. package/dist/utils/api-key.test.js.map +0 -1
  446. package/dist/utils/audio.d.ts +0 -23
  447. package/dist/utils/audio.d.ts.map +0 -1
  448. package/dist/utils/audio.js +0 -79
  449. package/dist/utils/audio.js.map +0 -1
  450. package/dist/utils/exec-safe.d.ts +0 -22
  451. package/dist/utils/exec-safe.d.ts.map +0 -1
  452. package/dist/utils/exec-safe.js +0 -62
  453. package/dist/utils/exec-safe.js.map +0 -1
  454. package/dist/utils/first-run.d.ts +0 -17
  455. package/dist/utils/first-run.d.ts.map +0 -1
  456. package/dist/utils/first-run.js +0 -73
  457. package/dist/utils/first-run.js.map +0 -1
  458. package/dist/utils/input-validation.d.ts +0 -27
  459. package/dist/utils/input-validation.d.ts.map +0 -1
  460. package/dist/utils/input-validation.js +0 -67
  461. package/dist/utils/input-validation.js.map +0 -1
  462. package/dist/utils/provider-resolver.d.ts +0 -19
  463. package/dist/utils/provider-resolver.d.ts.map +0 -1
  464. package/dist/utils/provider-resolver.js +0 -75
  465. package/dist/utils/provider-resolver.js.map +0 -1
  466. package/dist/utils/remotion.d.ts +0 -231
  467. package/dist/utils/remotion.d.ts.map +0 -1
  468. package/dist/utils/remotion.js +0 -879
  469. package/dist/utils/remotion.js.map +0 -1
  470. package/dist/utils/subtitle.d.ts +0 -65
  471. package/dist/utils/subtitle.d.ts.map +0 -1
  472. package/dist/utils/subtitle.js +0 -135
  473. package/dist/utils/subtitle.js.map +0 -1
  474. package/dist/utils/subtitle.test.d.ts +0 -2
  475. package/dist/utils/subtitle.test.d.ts.map +0 -1
  476. package/dist/utils/subtitle.test.js +0 -175
  477. package/dist/utils/subtitle.test.js.map +0 -1
  478. package/dist/utils/tty.d.ts +0 -45
  479. package/dist/utils/tty.d.ts.map +0 -1
  480. package/dist/utils/tty.js +0 -231
  481. package/dist/utils/tty.js.map +0 -1
@@ -1,879 +0,0 @@
1
- /**
2
- * Remotion rendering and compositing utilities.
3
- *
4
- * Uses `npx remotion` on-demand — Remotion is NOT a package dependency.
5
- * Scaffolds a temporary project, renders H264 MP4, and muxes audio separately.
6
- *
7
- * Strategy:
8
- * - Images/Videos are embedded NATIVELY inside the Remotion component using
9
- * <Img> / <Video> from Remotion (copied to public/).
10
- * - No transparent WebM rendering. No FFmpeg overlay compositing.
11
- * - Final output is always a standard H264 MP4.
12
- */
13
- import { writeFile, mkdir, rm, copyFile } from "node:fs/promises";
14
- import { existsSync } from "node:fs";
15
- import { join } from "node:path";
16
- import { tmpdir } from "node:os";
17
- import { createHash } from "node:crypto";
18
- import { execSafe } from "./exec-safe.js";
19
- /** Pinned Remotion version for reproducible renders */
20
- const REMOTION_VERSION = "4.0.447";
21
- /** Cached node_modules directory to avoid repeated npm install */
22
- const REMOTION_CACHE_DIR = join(tmpdir(), "vibe_remotion_cache");
23
- // ── Helpers ────────────────────────────────────────────────────────────────
24
- /**
25
- * Check that `npx remotion` is available. Returns an error message if not.
26
- */
27
- export async function ensureRemotionInstalled() {
28
- try {
29
- await execSafe("npx", ["--yes", "remotion", "--help"], { timeout: 60_000 });
30
- return null;
31
- }
32
- catch (error) {
33
- const detail = error instanceof Error ? error.message : String(error);
34
- console.error(`[Remotion] ensureRemotionInstalled failed: ${detail.slice(0, 300)}`);
35
- return [
36
- "Remotion CLI not found or failed to initialize.",
37
- ` Debug: ${detail.slice(0, 200)}`,
38
- " Fix: npm install -g @remotion/cli",
39
- " Or ensure npx is available and can download @remotion/cli on demand.",
40
- ].join("\n");
41
- }
42
- }
43
- /**
44
- * Create a minimal Remotion project in a temp directory.
45
- * Returns the directory path.
46
- *
47
- * @param useMediaPackage - Include @remotion/media for <Video> support (default: false)
48
- */
49
- export async function scaffoldRemotionProject(componentCode, componentName, opts) {
50
- const dir = join(tmpdir(), `vibe_motion_${Date.now()}`);
51
- await mkdir(dir, { recursive: true });
52
- // package.json — remotion + react deps (pinned versions)
53
- const deps = {
54
- remotion: REMOTION_VERSION,
55
- "@remotion/cli": REMOTION_VERSION,
56
- react: "^18.0.0",
57
- "react-dom": "^18.0.0",
58
- "@types/react": "^18.0.0",
59
- };
60
- // @remotion/media is needed for the <Video> component (per Remotion docs)
61
- if (opts.useMediaPackage) {
62
- deps["@remotion/media"] = REMOTION_VERSION;
63
- }
64
- const packageJson = {
65
- name: "vibe-motion-render",
66
- version: "1.0.0",
67
- private: true,
68
- dependencies: deps,
69
- };
70
- const packageJsonStr = JSON.stringify(packageJson, null, 2);
71
- await writeFile(join(dir, "package.json"), packageJsonStr);
72
- // tsconfig.json — minimal config for TSX
73
- const tsconfig = {
74
- compilerOptions: {
75
- target: "ES2020",
76
- module: "ESNext",
77
- moduleResolution: "bundler",
78
- jsx: "react-jsx",
79
- strict: false,
80
- esModuleInterop: true,
81
- skipLibCheck: true,
82
- },
83
- };
84
- await writeFile(join(dir, "tsconfig.json"), JSON.stringify(tsconfig, null, 2));
85
- // Component.tsx — the AI-generated (and optionally wrapped) component
86
- await writeFile(join(dir, "Component.tsx"), componentCode);
87
- // Root.tsx — Remotion entry point
88
- const rootCode = `import { registerRoot, Composition } from "remotion";
89
- import { ${componentName} } from "./Component";
90
-
91
- const Root = () => {
92
- return (
93
- <Composition
94
- id="${componentName}"
95
- component={${componentName}}
96
- durationInFrames={${opts.durationInFrames}}
97
- fps={${opts.fps}}
98
- width={${opts.width}}
99
- height={${opts.height}}
100
- />
101
- );
102
- };
103
-
104
- registerRoot(Root);
105
- `;
106
- await writeFile(join(dir, "Root.tsx"), rootCode);
107
- // Install deps — use cached node_modules if deps match
108
- const depsHash = createHash("md5").update(packageJsonStr).digest("hex").slice(0, 12);
109
- const cacheMarker = join(REMOTION_CACHE_DIR, `.deps-${depsHash}`);
110
- const cachedModules = join(REMOTION_CACHE_DIR, "node_modules");
111
- if (existsSync(cacheMarker) && existsSync(cachedModules)) {
112
- // Symlink cached node_modules to avoid re-install
113
- const { symlink } = await import("node:fs/promises");
114
- try {
115
- await symlink(cachedModules, join(dir, "node_modules"), "dir");
116
- }
117
- catch {
118
- // Symlink failed (e.g., cross-device), fall back to npm install
119
- await this_npmInstall(dir);
120
- }
121
- }
122
- else {
123
- // Install fresh and cache
124
- await this_npmInstall(dir);
125
- // Cache the node_modules for future renders
126
- try {
127
- await mkdir(REMOTION_CACHE_DIR, { recursive: true });
128
- // Copy package.json to cache for reference, then move node_modules
129
- await writeFile(join(REMOTION_CACHE_DIR, "package.json"), packageJsonStr);
130
- if (existsSync(join(dir, "node_modules"))) {
131
- // Move node_modules to cache, then symlink back
132
- const { rename, symlink } = await import("node:fs/promises");
133
- await rename(join(dir, "node_modules"), cachedModules).catch(() => { });
134
- await symlink(cachedModules, join(dir, "node_modules"), "dir").catch(() => { });
135
- await writeFile(cacheMarker, depsHash);
136
- }
137
- }
138
- catch {
139
- // Caching is best-effort, don't fail the render
140
- }
141
- }
142
- return dir;
143
- }
144
- async function this_npmInstall(dir) {
145
- const { execFile } = await import("node:child_process");
146
- const { promisify } = await import("node:util");
147
- const execFileAsync = promisify(execFile);
148
- try {
149
- await execFileAsync("npm", ["install", "--prefer-offline", "--no-audit", "--no-fund"], {
150
- cwd: dir,
151
- timeout: 180_000,
152
- });
153
- }
154
- catch (error) {
155
- const msg = error instanceof Error ? error.stderr || error.message : String(error);
156
- console.error(`[Remotion] npm install failed: ${msg.slice(0, 300)}`);
157
- throw error;
158
- }
159
- }
160
- // ── Standalone Motion Render ───────────────────────────────────────────────
161
- /**
162
- * Render a standalone Remotion composition to video (no base media).
163
- * When transparent: tries VP8 then VP9.
164
- * When opaque: renders H264 MP4.
165
- */
166
- export async function renderMotion(options) {
167
- const transparent = options.transparent !== false;
168
- const dir = await scaffoldRemotionProject(options.componentCode, options.componentName, {
169
- width: options.width,
170
- height: options.height,
171
- fps: options.fps,
172
- durationInFrames: options.durationInFrames,
173
- });
174
- try {
175
- const entryPoint = join(dir, "Root.tsx");
176
- const { execFile } = await import("node:child_process");
177
- const { promisify } = await import("node:util");
178
- const execFileAsync = promisify(execFile);
179
- if (transparent) {
180
- const webmOut = options.outputPath.replace(/\.\w+$/, ".webm");
181
- try {
182
- await execFileAsync("npx", [
183
- "remotion", "render", entryPoint, options.componentName, webmOut,
184
- "--codec", "vp8", "--image-format", "png", "--pixel-format", "yuva420p",
185
- ], { cwd: dir, timeout: 300_000 });
186
- return { success: true, outputPath: webmOut };
187
- }
188
- catch {
189
- // VP8 failed, try VP9
190
- }
191
- try {
192
- await execFileAsync("npx", [
193
- "remotion", "render", entryPoint, options.componentName, webmOut,
194
- "--codec", "vp9", "--image-format", "png", "--pixel-format", "yuva420p",
195
- ], { cwd: dir, timeout: 300_000 });
196
- return { success: true, outputPath: webmOut };
197
- }
198
- catch (error) {
199
- const msg = error instanceof Error ? error.message : String(error);
200
- return { success: false, error: `Transparent render failed (VP8 & VP9): ${msg}` };
201
- }
202
- }
203
- // Non-transparent: H264 MP4
204
- const mp4Out = options.outputPath.replace(/\.\w+$/, ".mp4");
205
- await execFileAsync("npx", [
206
- "remotion", "render", entryPoint, options.componentName, mp4Out,
207
- "--codec", "h264", "--crf", "18",
208
- ], { cwd: dir, timeout: 300_000 });
209
- return { success: true, outputPath: mp4Out };
210
- }
211
- catch (error) {
212
- const errObj = error;
213
- const stderr = errObj.stderr?.slice(0, 500) || "";
214
- const msg = error instanceof Error ? error.message : String(error);
215
- console.error(`[Remotion] Render failed:\n ${msg.slice(0, 300)}${stderr ? `\n stderr: ${stderr}` : ""}`);
216
- return { success: false, error: `Remotion render failed: ${msg}` };
217
- }
218
- finally {
219
- await rm(dir, { recursive: true, force: true }).catch(() => { });
220
- }
221
- }
222
- // ── Pre-render code validator & auto-fixer ────────────────────────────────
223
- /**
224
- * Validates and auto-fixes common LLM-generated Remotion code bugs before
225
- * attempting to render. Returns fixed code and a list of applied fixes.
226
- *
227
- * Known patterns fixed:
228
- * 1. interpolate(x, [a,b], scalar, num) → interpolate(x, [a,b], [scalar, num])
229
- * Cause: outputRange must be an array, not a bare scalar.
230
- * 2. interpolate(x, [a,b], scalar) where scalar is a variable name
231
- * Cause: same — LLM passes a single number variable instead of [from, to].
232
- */
233
- export function validateAndFixMotionCode(code) {
234
- const fixes = [];
235
- let fixed = code;
236
- // Pattern 1: interpolate(expr, [a, b], varName, numericLiteral)
237
- // where varName is a JS identifier and numericLiteral is a number
238
- // This is the exact bug seen in practice: interpolate(exitEase, [0, 1], barH, 0)
239
- const pattern1 = /interpolate\(([^,]+),\s*(\[[^\]]+\]),\s*([a-zA-Z_$][a-zA-Z0-9_$.]*),\s*(-?[\d.]+)\s*\)/g;
240
- fixed = fixed.replace(pattern1, (_match, val, inputRange, outVar, outNum) => {
241
- const fix = `interpolate(${val}, ${inputRange}, [${outVar}, ${outNum}])`;
242
- fixes.push(`Fixed scalar outputRange: interpolate(..., ${outVar}, ${outNum}) → [..., [${outVar}, ${outNum}]]`);
243
- return fix;
244
- });
245
- // Pattern 2: interpolate(expr, [a, b], singleIdentifier) — no options arg
246
- // e.g. interpolate(frame, [0, 30], progress) where progress is not an array
247
- // Heuristic: if the third arg is a plain identifier (not starting with [) and
248
- // there's no fourth arg, we can't safely auto-fix without knowing the intent,
249
- // so just log a warning in the fixes list for visibility.
250
- const pattern2 = /interpolate\(([^,]+),\s*(\[[^\]]+\]),\s*([a-zA-Z_$][a-zA-Z0-9_$.]*)\s*\)/g;
251
- let p2match;
252
- while ((p2match = pattern2.exec(fixed)) !== null) {
253
- // Only warn if the identifier doesn't look like an array variable name
254
- const varName = p2match[3];
255
- if (!varName.includes("[")) {
256
- fixes.push(`Warning: interpolate third arg "${varName}" may not be an array — verify outputRange is [from, to]`);
257
- }
258
- }
259
- return { code: fixed, fixes };
260
- }
261
- // ── Import injection helper ────────────────────────────────────────────────
262
- /**
263
- * Inject additional named imports into the existing `from 'remotion'`
264
- * import statement in the component code.
265
- * Avoids duplicate identifier errors when the component already imports
266
- * some of the same names (e.g. AbsoluteFill).
267
- */
268
- function injectRemotionImports(code, additions) {
269
- return code.replace(/import\s*\{([^}]+)\}\s*from\s*['"]remotion['"]/, (match, imports) => {
270
- const existing = imports
271
- .split(",")
272
- .map((s) => s.trim())
273
- .filter(Boolean);
274
- const toAdd = additions.filter((a) => !existing.includes(a));
275
- if (toAdd.length === 0)
276
- return match;
277
- return `import { ${[...existing, ...toAdd].join(", ")} } from "remotion"`;
278
- });
279
- }
280
- // ── Native Image Embed ─────────────────────────────────────────────────────
281
- /**
282
- * Wrap an overlay component to embed a static image as background.
283
- * Uses Remotion's <Img> component (required per Remotion docs — ensures
284
- * image is fully loaded before each frame renders).
285
- *
286
- * Injects Img and staticFile into the component's existing remotion import
287
- * to avoid duplicate identifier errors.
288
- */
289
- export function wrapComponentWithImage(componentCode, componentName, imageFileName) {
290
- const wrappedName = "ImageComposite";
291
- // Inject Img and staticFile into the existing remotion import
292
- const modifiedCode = injectRemotionImports(componentCode, ["Img", "staticFile"]);
293
- const code = `${modifiedCode}
294
-
295
- export const ${wrappedName}: React.FC = () => {
296
- return (
297
- <AbsoluteFill>
298
- <Img
299
- src={staticFile("${imageFileName}")}
300
- style={{ width: "100%", height: "100%", objectFit: "cover" }}
301
- />
302
- <AbsoluteFill>
303
- <${componentName} />
304
- </AbsoluteFill>
305
- </AbsoluteFill>
306
- );
307
- };
308
- `;
309
- return { code, name: wrappedName };
310
- }
311
- /**
312
- * Render a Remotion component that embeds a static image as background.
313
- * Copies image to public/, renders H264 MP4 directly — no transparency needed.
314
- */
315
- export async function renderWithEmbeddedImage(options) {
316
- const dir = await scaffoldRemotionProject(options.componentCode, options.componentName, {
317
- width: options.width,
318
- height: options.height,
319
- fps: options.fps,
320
- durationInFrames: options.durationInFrames,
321
- useMediaPackage: false,
322
- });
323
- try {
324
- // Copy image to public/ so staticFile() can access it
325
- const publicDir = join(dir, "public");
326
- await mkdir(publicDir, { recursive: true });
327
- await copyFile(options.imagePath, join(publicDir, options.imageFileName));
328
- const entryPoint = join(dir, "Root.tsx");
329
- const mp4Out = options.outputPath.replace(/\.\w+$/, ".mp4");
330
- const { execFile: execFileImg } = await import("node:child_process");
331
- const { promisify: promisifyImg } = await import("node:util");
332
- const execFileAsyncImg = promisifyImg(execFileImg);
333
- await execFileAsyncImg("npx", [
334
- "remotion", "render", entryPoint, options.componentName, mp4Out,
335
- "--codec", "h264", "--crf", "18",
336
- ], { cwd: dir, timeout: 600_000, maxBuffer: 50 * 1024 * 1024 });
337
- return { success: true, outputPath: mp4Out };
338
- }
339
- catch (error) {
340
- const msg = error instanceof Error ? error.message : String(error);
341
- return { success: false, error: `Remotion image embed render failed: ${msg}` };
342
- }
343
- finally {
344
- await rm(dir, { recursive: true, force: true }).catch(() => { });
345
- }
346
- }
347
- // ── Native Video Embed ─────────────────────────────────────────────────────
348
- /**
349
- * Wrap an overlay component to embed a video as background.
350
- * Uses <Video> from @remotion/media (required per Remotion docs).
351
- * Video is muted — audio is muxed back via FFmpeg after rendering.
352
- *
353
- * Injects staticFile into the component's existing remotion import to avoid
354
- * duplicate identifier errors. Video is imported from @remotion/media
355
- * (different module — no conflict).
356
- */
357
- export function wrapComponentWithVideo(componentCode, componentName, videoFileName) {
358
- const wrappedName = "VideoComposite";
359
- // Inject staticFile into the existing remotion import
360
- const modifiedCode = injectRemotionImports(componentCode, ["staticFile"]);
361
- // Prepend @remotion/media import (different module, no conflict)
362
- const code = `import { Video } from "@remotion/media";
363
- ${modifiedCode}
364
-
365
- export const ${wrappedName}: React.FC = () => {
366
- return (
367
- <AbsoluteFill>
368
- <Video
369
- src={staticFile("${videoFileName}")}
370
- style={{ width: "100%", height: "100%" }}
371
- muted
372
- />
373
- <AbsoluteFill>
374
- <${componentName} />
375
- </AbsoluteFill>
376
- </AbsoluteFill>
377
- );
378
- };
379
- `;
380
- return { code, name: wrappedName };
381
- }
382
- /**
383
- * Render a Remotion component that embeds the video directly.
384
- * Uses @remotion/media's <Video> component (official Remotion approach).
385
- * After rendering, muxes audio from the original video back into the output.
386
- */
387
- export async function renderWithEmbeddedVideo(options) {
388
- const dir = await scaffoldRemotionProject(options.componentCode, options.componentName, {
389
- width: options.width,
390
- height: options.height,
391
- fps: options.fps,
392
- durationInFrames: options.durationInFrames,
393
- useMediaPackage: true,
394
- });
395
- try {
396
- // Copy video to public/ so staticFile() can access it
397
- const publicDir = join(dir, "public");
398
- await mkdir(publicDir, { recursive: true });
399
- await copyFile(options.videoPath, join(publicDir, options.videoFileName));
400
- const entryPoint = join(dir, "Root.tsx");
401
- const mp4VideoOnly = options.outputPath.replace(/\.\w+$/, "_video_only.mp4");
402
- // Render H264 (video-only, audio muted inside component)
403
- const { execFile: execFileVid } = await import("node:child_process");
404
- const { promisify: promisifyVid } = await import("node:util");
405
- const execFileAsyncVid = promisifyVid(execFileVid);
406
- await execFileAsyncVid("npx", [
407
- "remotion", "render", entryPoint, options.componentName, mp4VideoOnly,
408
- "--codec", "h264", "--crf", "18",
409
- ], { cwd: dir, timeout: 600_000, maxBuffer: 50 * 1024 * 1024 });
410
- // Mux: rendered video + original audio
411
- const mp4Out = options.outputPath.replace(/\.\w+$/, ".mp4");
412
- await execSafe("ffmpeg", [
413
- "-y", "-i", mp4VideoOnly, "-i", options.videoPath,
414
- "-map", "0:v:0", "-map", "1:a:0?", "-c:v", "copy", "-c:a", "copy", "-shortest", mp4Out,
415
- ], { timeout: 120_000 });
416
- await rm(mp4VideoOnly, { force: true }).catch(() => { });
417
- return { success: true, outputPath: mp4Out };
418
- }
419
- catch (error) {
420
- const msg = error instanceof Error ? error.message : String(error);
421
- return { success: false, error: `Remotion video embed render failed: ${msg}` };
422
- }
423
- finally {
424
- await rm(dir, { recursive: true, force: true }).catch(() => { });
425
- }
426
- }
427
- /**
428
- * Generate a Remotion TSX component for text overlays.
429
- * Fallback for when FFmpeg drawtext filter (libfreetype) is unavailable.
430
- */
431
- export function generateTextOverlayComponent(options) {
432
- const { texts, style, fontSize, fontColor, startTime, endTime, fadeDuration, width, height, videoFileName } = options;
433
- const name = "TextOverlay";
434
- const textsJSON = JSON.stringify(texts);
435
- const styleMap = {
436
- "lower-third": {
437
- justify: "flex-end",
438
- align: "flex-start",
439
- padding: `paddingBottom: ${Math.round(height * 0.12)}, paddingLeft: ${Math.round(width * 0.05)},`,
440
- extraCss: `backgroundColor: "rgba(0,0,0,0.5)", padding: "8px 20px", borderRadius: 4,`,
441
- },
442
- "center-bold": {
443
- justify: "center",
444
- align: "center",
445
- padding: "",
446
- extraCss: `fontWeight: "bold" as const, textShadow: "3px 3px 6px rgba(0,0,0,0.9)",`,
447
- },
448
- "subtitle": {
449
- justify: "flex-end",
450
- align: "center",
451
- padding: `paddingBottom: ${Math.round(height * 0.08)},`,
452
- extraCss: `backgroundColor: "rgba(0,0,0,0.6)", padding: "6px 16px", borderRadius: 4,`,
453
- },
454
- "minimal": {
455
- justify: "flex-start",
456
- align: "flex-start",
457
- padding: `paddingTop: ${Math.round(height * 0.05)}, paddingLeft: ${Math.round(width * 0.05)},`,
458
- extraCss: `opacity: 0.85,`,
459
- },
460
- };
461
- const s = styleMap[style];
462
- const scaledFontSize = style === "center-bold" ? Math.round(fontSize * 1.5) : fontSize;
463
- const code = `import { AbsoluteFill, useCurrentFrame, useVideoConfig, interpolate, staticFile } from "remotion";
464
- import { Video } from "@remotion/media";
465
-
466
- const texts: string[] = ${textsJSON};
467
- const START_TIME = ${startTime};
468
- const END_TIME = ${endTime};
469
- const FADE_DURATION = ${fadeDuration};
470
-
471
- export const ${name} = () => {
472
- const frame = useCurrentFrame();
473
- const { fps } = useVideoConfig();
474
- const currentTime = frame / fps;
475
-
476
- const visible = currentTime >= START_TIME && currentTime <= END_TIME;
477
-
478
- const opacity = visible
479
- ? interpolate(
480
- currentTime,
481
- [START_TIME, START_TIME + FADE_DURATION, END_TIME - FADE_DURATION, END_TIME],
482
- [0, 1, 1, 0],
483
- { extrapolateLeft: "clamp", extrapolateRight: "clamp" }
484
- )
485
- : 0;
486
-
487
- return (
488
- <AbsoluteFill>
489
- <Video src={staticFile("${videoFileName}")} style={{ width: "100%", height: "100%" }} muted />
490
- {visible && (
491
- <AbsoluteFill
492
- style={{
493
- display: "flex",
494
- flexDirection: "column",
495
- justifyContent: "${s.justify}",
496
- alignItems: "${s.align}",
497
- ${s.padding}
498
- opacity,
499
- }}
500
- >
501
- <div
502
- style={{
503
- fontSize: ${scaledFontSize},
504
- fontFamily: "Arial, Helvetica, sans-serif",
505
- color: "${fontColor}",
506
- lineHeight: 1.4,
507
- maxWidth: "${Math.round(width * 0.9)}px",
508
- ${s.extraCss}
509
- }}
510
- >
511
- {texts.map((text, i) => (
512
- <div key={i}>{text}</div>
513
- ))}
514
- </div>
515
- </AbsoluteFill>
516
- )}
517
- </AbsoluteFill>
518
- );
519
- };
520
- `;
521
- return { code, name };
522
- }
523
- /**
524
- * Generate a Remotion TSX component that renders styled captions.
525
- * No LLM call — purely programmatic from SRT segments + style config.
526
- */
527
- export function generateCaptionComponent(options) {
528
- const { segments, style, fontSize, fontColor, position, width, videoFileName } = options;
529
- const name = videoFileName ? "VideoCaptioned" : "CaptionOverlay";
530
- const segmentsJSON = JSON.stringify(segments.map((s) => ({ start: s.start, end: s.end, text: s.text })));
531
- const styleMap = {
532
- bold: `
533
- fontWeight: "bold" as const,
534
- color: "${fontColor === "yellow" ? "#FFFF00" : "#FFFFFF"}",
535
- textShadow: "3px 3px 6px rgba(0,0,0,0.9), -1px -1px 3px rgba(0,0,0,0.7)",
536
- WebkitTextStroke: "1px rgba(0,0,0,0.5)",
537
- `,
538
- minimal: `
539
- fontWeight: "normal" as const,
540
- color: "#FFFFFF",
541
- textShadow: "1px 1px 3px rgba(0,0,0,0.5)",
542
- `,
543
- outline: `
544
- fontWeight: "bold" as const,
545
- color: "#FFFFFF",
546
- WebkitTextStroke: "2px #FF0000",
547
- textShadow: "none",
548
- `,
549
- karaoke: `
550
- fontWeight: "bold" as const,
551
- color: "#00FFFF",
552
- textShadow: "2px 2px 4px rgba(0,0,0,0.8), -1px -1px 2px rgba(0,0,0,0.6)",
553
- `,
554
- };
555
- const justifyContent = position === "top" ? "flex-start" : position === "center" ? "center" : "flex-end";
556
- const paddingDir = position === "top" ? "paddingTop" : position === "bottom" ? "paddingBottom" : "";
557
- const paddingVal = position === "center" ? "" : `${paddingDir}: 40,`;
558
- const videoImport = videoFileName ? `, staticFile` : "";
559
- const videoElement = videoFileName
560
- ? `<Video src={staticFile("${videoFileName}")} style={{ width: "100%", height: "100%" }} muted />`
561
- : "";
562
- const videoMediaImport = videoFileName
563
- ? `import { Video } from "@remotion/media";\n`
564
- : "";
565
- const code = `import { AbsoluteFill, useCurrentFrame, useVideoConfig${videoImport} } from "remotion";
566
- ${videoMediaImport}
567
- interface Segment {
568
- start: number;
569
- end: number;
570
- text: string;
571
- }
572
-
573
- const segments: Segment[] = ${segmentsJSON};
574
-
575
- export const ${name} = () => {
576
- const frame = useCurrentFrame();
577
- const { fps } = useVideoConfig();
578
- const currentTime = frame / fps;
579
-
580
- const activeSegment = segments.find(
581
- (s) => currentTime >= s.start && currentTime < s.end
582
- );
583
-
584
- return (
585
- <AbsoluteFill>
586
- ${videoElement}
587
- {activeSegment && (
588
- <AbsoluteFill
589
- style={{
590
- display: "flex",
591
- justifyContent: "${justifyContent}",
592
- alignItems: "center",
593
- ${paddingVal}
594
- }}
595
- >
596
- <div
597
- style={{
598
- fontSize: ${fontSize},
599
- fontFamily: "Arial, Helvetica, sans-serif",
600
- textAlign: "center" as const,
601
- maxWidth: "${Math.round(width * 0.9)}px",
602
- lineHeight: 1.3,
603
- padding: "8px 16px",
604
- ${styleMap[style]}
605
- }}
606
- >
607
- {activeSegment.text}
608
- </div>
609
- </AbsoluteFill>
610
- )}
611
- </AbsoluteFill>
612
- );
613
- };
614
- `;
615
- return { code, name };
616
- }
617
- /**
618
- * Generate a Remotion TSX component for word-level animated captions.
619
- * Each style creates different visual effects per word.
620
- */
621
- export function generateAnimatedCaptionComponent(options) {
622
- const { groups, style, highlightColor, fontSize, position, width, fps, videoFileName } = options;
623
- const name = videoFileName ? "VideoAnimatedCaption" : "AnimatedCaptionOverlay";
624
- const groupsJSON = JSON.stringify(groups.map((g) => ({
625
- words: g.words.map((w) => ({ word: w.word, start: w.start, end: w.end })),
626
- startTime: g.startTime,
627
- endTime: g.endTime,
628
- text: g.text,
629
- })));
630
- const justifyContent = position === "top" ? "flex-start" : position === "center" ? "center" : "flex-end";
631
- const paddingDir = position === "top" ? "paddingTop" : position === "bottom" ? "paddingBottom" : "";
632
- const paddingVal = position === "center" ? "" : `${paddingDir}: 40,`;
633
- const videoImport = videoFileName ? `, staticFile` : "";
634
- const videoElement = videoFileName
635
- ? `<Video src={staticFile("${videoFileName}")} style={{ width: "100%", height: "100%" }} muted />`
636
- : "";
637
- const videoMediaImport = videoFileName
638
- ? `import { Video } from "@remotion/media";\n`
639
- : "";
640
- // Style-specific word rendering
641
- let wordRenderer;
642
- switch (style) {
643
- case "highlight":
644
- wordRenderer = `
645
- const isActive = currentTime >= w.start && currentTime < w.end;
646
- const bgOpacity = isActive ? 1 : 0;
647
- return (
648
- <span
649
- key={wi}
650
- style={{
651
- display: "inline-block",
652
- padding: "2px 6px",
653
- margin: "0 2px",
654
- borderRadius: 4,
655
- backgroundColor: isActive ? "${highlightColor}" : "transparent",
656
- color: isActive ? "#000000" : "#FFFFFF",
657
- transition: "background-color 0.1s",
658
- fontWeight: "bold",
659
- textShadow: isActive ? "none" : "2px 2px 4px rgba(0,0,0,0.8)",
660
- }}
661
- >
662
- {w.word}
663
- </span>
664
- );`;
665
- break;
666
- case "bounce":
667
- wordRenderer = `
668
- const isActive = currentTime >= w.start && currentTime < w.end;
669
- const entryFrame = w.start * ${fps};
670
- const progress = Math.min(1, Math.max(0, (frame - entryFrame) / 5));
671
- const springVal = isActive
672
- ? 1 + Math.sin(progress * Math.PI) * 0.15
673
- : 1;
674
- const translateY = isActive
675
- ? -Math.sin(progress * Math.PI) * 8
676
- : 0;
677
- return (
678
- <span
679
- key={wi}
680
- style={{
681
- display: "inline-block",
682
- margin: "0 3px",
683
- transform: \`scale(\${springVal}) translateY(\${translateY}px)\`,
684
- color: isActive ? "${highlightColor}" : "#FFFFFF",
685
- fontWeight: "bold",
686
- textShadow: "2px 2px 4px rgba(0,0,0,0.8)",
687
- }}
688
- >
689
- {w.word}
690
- </span>
691
- );`;
692
- break;
693
- case "pop-in":
694
- wordRenderer = `
695
- const entryFrame = w.start * ${fps};
696
- const scale = frame >= entryFrame
697
- ? Math.min(1, (frame - entryFrame) / 5)
698
- : 0;
699
- const isActive = currentTime >= w.start && currentTime < w.end;
700
- return (
701
- <span
702
- key={wi}
703
- style={{
704
- display: "inline-block",
705
- margin: "0 3px",
706
- transform: \`scale(\${scale})\`,
707
- opacity: scale,
708
- color: isActive ? "${highlightColor}" : "#FFFFFF",
709
- fontWeight: "bold",
710
- textShadow: "2px 2px 4px rgba(0,0,0,0.8)",
711
- }}
712
- >
713
- {w.word}
714
- </span>
715
- );`;
716
- break;
717
- case "neon":
718
- wordRenderer = `
719
- const isActive = currentTime >= w.start && currentTime < w.end;
720
- const pulse = isActive ? 0.8 + Math.sin(frame * 0.3) * 0.2 : 0.5;
721
- const glowSize = isActive ? 15 : 0;
722
- return (
723
- <span
724
- key={wi}
725
- style={{
726
- display: "inline-block",
727
- margin: "0 3px",
728
- color: isActive ? "${highlightColor}" : "#FFFFFF",
729
- fontWeight: "bold",
730
- opacity: isActive ? 1 : pulse,
731
- textShadow: isActive
732
- ? \`0 0 \${glowSize}px ${highlightColor}, 0 0 \${glowSize * 2}px ${highlightColor}, 0 0 \${glowSize * 3}px ${highlightColor}\`
733
- : "2px 2px 4px rgba(0,0,0,0.8)",
734
- }}
735
- >
736
- {w.word}
737
- </span>
738
- );`;
739
- break;
740
- }
741
- const code = `import { AbsoluteFill, useCurrentFrame, useVideoConfig${videoImport} } from "remotion";
742
- ${videoMediaImport}
743
- interface Word {
744
- word: string;
745
- start: number;
746
- end: number;
747
- }
748
-
749
- interface WordGroup {
750
- words: Word[];
751
- startTime: number;
752
- endTime: number;
753
- text: string;
754
- }
755
-
756
- const groups: WordGroup[] = ${groupsJSON};
757
-
758
- export const ${name} = () => {
759
- const frame = useCurrentFrame();
760
- const { fps } = useVideoConfig();
761
- const currentTime = frame / fps;
762
-
763
- const activeGroup = groups.find(
764
- (g) => currentTime >= g.startTime && currentTime < g.endTime
765
- );
766
-
767
- const renderWord = (w: Word, wi: number) => {
768
- ${wordRenderer}
769
- };
770
-
771
- return (
772
- <AbsoluteFill>
773
- ${videoElement}
774
- {activeGroup && (
775
- <AbsoluteFill
776
- style={{
777
- display: "flex",
778
- justifyContent: "${justifyContent}",
779
- alignItems: "center",
780
- ${paddingVal}
781
- }}
782
- >
783
- <div
784
- style={{
785
- fontSize: ${fontSize},
786
- fontFamily: "Arial, Helvetica, sans-serif",
787
- textAlign: "center" as const,
788
- maxWidth: "${Math.round(width * 0.9)}px",
789
- lineHeight: 1.5,
790
- padding: "8px 16px",
791
- display: "flex",
792
- flexWrap: "wrap" as const,
793
- justifyContent: "center",
794
- gap: "0px",
795
- }}
796
- >
797
- {activeGroup.words.map((w, wi) => renderWord(w, wi))}
798
- </div>
799
- </AbsoluteFill>
800
- )}
801
- </AbsoluteFill>
802
- );
803
- };
804
- `;
805
- return { code, name };
806
- }
807
- // ── Legacy composite helpers (kept for backward compat) ───────────────────
808
- /**
809
- * Composite a transparent overlay on top of a base video using FFmpeg.
810
- * @deprecated Use renderWithEmbeddedVideo() for new code.
811
- */
812
- export async function compositeOverlay(options) {
813
- try {
814
- await execSafe("ffmpeg", [
815
- "-y", "-i", options.baseVideo, "-i", options.overlayPath,
816
- "-filter_complex", "[0:v][1:v]overlay=0:0:shortest=1[out]",
817
- "-map", "[out]", "-map", "0:a?", "-c:a", "copy",
818
- "-c:v", "libx264", "-crf", "18", "-pix_fmt", "yuv420p",
819
- options.outputPath,
820
- ], { timeout: 300_000 });
821
- return { success: true, outputPath: options.outputPath };
822
- }
823
- catch (error) {
824
- const msg = error instanceof Error ? error.message : String(error);
825
- return { success: false, error: `FFmpeg composite failed: ${msg}` };
826
- }
827
- }
828
- /**
829
- * Composite a transparent overlay on top of a static image using FFmpeg.
830
- * @deprecated Use renderWithEmbeddedImage() for new code.
831
- */
832
- export async function compositeWithImage(options) {
833
- try {
834
- const fps = options.fps || 30;
835
- await execSafe("ffmpeg", [
836
- "-y", "-loop", "1", "-framerate", String(fps), "-i", options.baseImage,
837
- "-i", options.overlayPath,
838
- "-filter_complex", "[0:v]scale=iw:ih[base];[base][1:v]overlay=0:0:shortest=1[out]",
839
- "-map", "[out]",
840
- "-c:v", "libx264", "-crf", "18", "-pix_fmt", "yuv420p",
841
- "-t", String(options.durationSeconds),
842
- options.outputPath,
843
- ], { timeout: 300_000 });
844
- return { success: true, outputPath: options.outputPath };
845
- }
846
- catch (error) {
847
- const msg = error instanceof Error ? error.message : String(error);
848
- return { success: false, error: `FFmpeg image composite failed: ${msg}` };
849
- }
850
- }
851
- /**
852
- * Full pipeline: render motion graphic → composite onto base video.
853
- * @deprecated Use renderWithEmbeddedVideo() for new code.
854
- */
855
- export async function renderAndComposite(motionOpts, baseVideo, finalOutput) {
856
- const renderOpts = {
857
- ...motionOpts,
858
- transparent: !!baseVideo,
859
- outputPath: baseVideo
860
- ? motionOpts.outputPath.replace(/\.\w+$/, "_overlay.webm")
861
- : motionOpts.outputPath,
862
- };
863
- const renderResult = await renderMotion(renderOpts);
864
- if (!renderResult.success || !renderResult.outputPath) {
865
- return renderResult;
866
- }
867
- if (!baseVideo) {
868
- return renderResult;
869
- }
870
- const output = finalOutput || motionOpts.outputPath;
871
- const compositeResult = await compositeOverlay({
872
- baseVideo,
873
- overlayPath: renderResult.outputPath,
874
- outputPath: output,
875
- });
876
- await rm(renderResult.outputPath, { force: true }).catch(() => { });
877
- return compositeResult;
878
- }
879
- //# sourceMappingURL=remotion.js.map