@prestyj/editor 0.7.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 (1057) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +457 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +278 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/core/ass.d.ts +75 -0
  8. package/dist/core/ass.d.ts.map +1 -0
  9. package/dist/core/ass.js +128 -0
  10. package/dist/core/ass.js.map +1 -0
  11. package/dist/core/ass.test.d.ts +2 -0
  12. package/dist/core/ass.test.d.ts.map +1 -0
  13. package/dist/core/ass.test.js +112 -0
  14. package/dist/core/ass.test.js.map +1 -0
  15. package/dist/core/audio-cleanup.d.ts +16 -0
  16. package/dist/core/audio-cleanup.d.ts.map +1 -0
  17. package/dist/core/audio-cleanup.js +79 -0
  18. package/dist/core/audio-cleanup.js.map +1 -0
  19. package/dist/core/audio-cleanup.test.d.ts +2 -0
  20. package/dist/core/audio-cleanup.test.d.ts.map +1 -0
  21. package/dist/core/audio-cleanup.test.js +41 -0
  22. package/dist/core/audio-cleanup.test.js.map +1 -0
  23. package/dist/core/audio-mix.d.ts +89 -0
  24. package/dist/core/audio-mix.d.ts.map +1 -0
  25. package/dist/core/audio-mix.js +163 -0
  26. package/dist/core/audio-mix.js.map +1 -0
  27. package/dist/core/audio-mix.test.d.ts +2 -0
  28. package/dist/core/audio-mix.test.d.ts.map +1 -0
  29. package/dist/core/audio-mix.test.js +91 -0
  30. package/dist/core/audio-mix.test.js.map +1 -0
  31. package/dist/core/auth/api-keys.d.ts +18 -0
  32. package/dist/core/auth/api-keys.d.ts.map +1 -0
  33. package/dist/core/auth/api-keys.js +73 -0
  34. package/dist/core/auth/api-keys.js.map +1 -0
  35. package/dist/core/auth/index.d.ts +20 -0
  36. package/dist/core/auth/index.d.ts.map +1 -0
  37. package/dist/core/auth/index.js +18 -0
  38. package/dist/core/auth/index.js.map +1 -0
  39. package/dist/core/auth/login.d.ts +13 -0
  40. package/dist/core/auth/login.d.ts.map +1 -0
  41. package/dist/core/auth/login.js +176 -0
  42. package/dist/core/auth/login.js.map +1 -0
  43. package/dist/core/auth/types.d.ts +22 -0
  44. package/dist/core/auth/types.d.ts.map +1 -0
  45. package/dist/core/auth/types.js +12 -0
  46. package/dist/core/auth/types.js.map +1 -0
  47. package/dist/core/beats.d.ts +59 -0
  48. package/dist/core/beats.d.ts.map +1 -0
  49. package/dist/core/beats.js +122 -0
  50. package/dist/core/beats.js.map +1 -0
  51. package/dist/core/beats.test.d.ts +2 -0
  52. package/dist/core/beats.test.d.ts.map +1 -0
  53. package/dist/core/beats.test.js +86 -0
  54. package/dist/core/beats.test.js.map +1 -0
  55. package/dist/core/brand-kit.d.ts +80 -0
  56. package/dist/core/brand-kit.d.ts.map +1 -0
  57. package/dist/core/brand-kit.js +96 -0
  58. package/dist/core/brand-kit.js.map +1 -0
  59. package/dist/core/brand-kit.test.d.ts +2 -0
  60. package/dist/core/brand-kit.test.d.ts.map +1 -0
  61. package/dist/core/brand-kit.test.js +76 -0
  62. package/dist/core/brand-kit.test.js.map +1 -0
  63. package/dist/core/bundled-sfx.d.ts +64 -0
  64. package/dist/core/bundled-sfx.d.ts.map +1 -0
  65. package/dist/core/bundled-sfx.js +218 -0
  66. package/dist/core/bundled-sfx.js.map +1 -0
  67. package/dist/core/bundled-sfx.test.d.ts +2 -0
  68. package/dist/core/bundled-sfx.test.d.ts.map +1 -0
  69. package/dist/core/bundled-sfx.test.js +81 -0
  70. package/dist/core/bundled-sfx.test.js.map +1 -0
  71. package/dist/core/child-abort.d.ts +57 -0
  72. package/dist/core/child-abort.d.ts.map +1 -0
  73. package/dist/core/child-abort.js +95 -0
  74. package/dist/core/child-abort.js.map +1 -0
  75. package/dist/core/child-abort.test.d.ts +2 -0
  76. package/dist/core/child-abort.test.d.ts.map +1 -0
  77. package/dist/core/child-abort.test.js +88 -0
  78. package/dist/core/child-abort.test.js.map +1 -0
  79. package/dist/core/cli-banner.d.ts +16 -0
  80. package/dist/core/cli-banner.d.ts.map +1 -0
  81. package/dist/core/cli-banner.js +75 -0
  82. package/dist/core/cli-banner.js.map +1 -0
  83. package/dist/core/clip-scoring.d.ts +44 -0
  84. package/dist/core/clip-scoring.d.ts.map +1 -0
  85. package/dist/core/clip-scoring.js +165 -0
  86. package/dist/core/clip-scoring.js.map +1 -0
  87. package/dist/core/clip-scoring.test.d.ts +2 -0
  88. package/dist/core/clip-scoring.test.d.ts.map +1 -0
  89. package/dist/core/clip-scoring.test.js +113 -0
  90. package/dist/core/clip-scoring.test.js.map +1 -0
  91. package/dist/core/clustering.d.ts +52 -0
  92. package/dist/core/clustering.d.ts.map +1 -0
  93. package/dist/core/clustering.js +163 -0
  94. package/dist/core/clustering.js.map +1 -0
  95. package/dist/core/clustering.test.d.ts +2 -0
  96. package/dist/core/clustering.test.d.ts.map +1 -0
  97. package/dist/core/clustering.test.js +112 -0
  98. package/dist/core/clustering.test.js.map +1 -0
  99. package/dist/core/color-match.d.ts +19 -0
  100. package/dist/core/color-match.d.ts.map +1 -0
  101. package/dist/core/color-match.js +119 -0
  102. package/dist/core/color-match.js.map +1 -0
  103. package/dist/core/color-match.test.d.ts +2 -0
  104. package/dist/core/color-match.test.d.ts.map +1 -0
  105. package/dist/core/color-match.test.js +40 -0
  106. package/dist/core/color-match.test.js.map +1 -0
  107. package/dist/core/doctor-render.d.ts +9 -0
  108. package/dist/core/doctor-render.d.ts.map +1 -0
  109. package/dist/core/doctor-render.js +145 -0
  110. package/dist/core/doctor-render.js.map +1 -0
  111. package/dist/core/doctor-render.test.d.ts +2 -0
  112. package/dist/core/doctor-render.test.d.ts.map +1 -0
  113. package/dist/core/doctor-render.test.js +151 -0
  114. package/dist/core/doctor-render.test.js.map +1 -0
  115. package/dist/core/doctor-runner.d.ts +17 -0
  116. package/dist/core/doctor-runner.d.ts.map +1 -0
  117. package/dist/core/doctor-runner.js +419 -0
  118. package/dist/core/doctor-runner.js.map +1 -0
  119. package/dist/core/doctor.d.ts +120 -0
  120. package/dist/core/doctor.d.ts.map +1 -0
  121. package/dist/core/doctor.js +413 -0
  122. package/dist/core/doctor.js.map +1 -0
  123. package/dist/core/doctor.test.d.ts +2 -0
  124. package/dist/core/doctor.test.d.ts.map +1 -0
  125. package/dist/core/doctor.test.js +131 -0
  126. package/dist/core/doctor.test.js.map +1 -0
  127. package/dist/core/ducking.d.ts +37 -0
  128. package/dist/core/ducking.d.ts.map +1 -0
  129. package/dist/core/ducking.js +71 -0
  130. package/dist/core/ducking.js.map +1 -0
  131. package/dist/core/ducking.test.d.ts +2 -0
  132. package/dist/core/ducking.test.d.ts.map +1 -0
  133. package/dist/core/ducking.test.js +38 -0
  134. package/dist/core/ducking.test.js.map +1 -0
  135. package/dist/core/edl-roundtrip.test.d.ts +2 -0
  136. package/dist/core/edl-roundtrip.test.d.ts.map +1 -0
  137. package/dist/core/edl-roundtrip.test.js +171 -0
  138. package/dist/core/edl-roundtrip.test.js.map +1 -0
  139. package/dist/core/edl.d.ts +41 -0
  140. package/dist/core/edl.d.ts.map +1 -0
  141. package/dist/core/edl.js +56 -0
  142. package/dist/core/edl.js.map +1 -0
  143. package/dist/core/edl.test.d.ts +2 -0
  144. package/dist/core/edl.test.d.ts.map +1 -0
  145. package/dist/core/edl.test.js +62 -0
  146. package/dist/core/edl.test.js.map +1 -0
  147. package/dist/core/emoji-captions.d.ts +45 -0
  148. package/dist/core/emoji-captions.d.ts.map +1 -0
  149. package/dist/core/emoji-captions.js +121 -0
  150. package/dist/core/emoji-captions.js.map +1 -0
  151. package/dist/core/envelope-sync.d.ts +52 -0
  152. package/dist/core/envelope-sync.d.ts.map +1 -0
  153. package/dist/core/envelope-sync.js +169 -0
  154. package/dist/core/envelope-sync.js.map +1 -0
  155. package/dist/core/envelope-sync.test.d.ts +2 -0
  156. package/dist/core/envelope-sync.test.d.ts.map +1 -0
  157. package/dist/core/envelope-sync.test.js +70 -0
  158. package/dist/core/envelope-sync.test.js.map +1 -0
  159. package/dist/core/face-reframe.d.ts +91 -0
  160. package/dist/core/face-reframe.d.ts.map +1 -0
  161. package/dist/core/face-reframe.js +141 -0
  162. package/dist/core/face-reframe.js.map +1 -0
  163. package/dist/core/face-reframe.test.d.ts +2 -0
  164. package/dist/core/face-reframe.test.d.ts.map +1 -0
  165. package/dist/core/face-reframe.test.js +171 -0
  166. package/dist/core/face-reframe.test.js.map +1 -0
  167. package/dist/core/fcpxml-roundtrip.test.d.ts +2 -0
  168. package/dist/core/fcpxml-roundtrip.test.d.ts.map +1 -0
  169. package/dist/core/fcpxml-roundtrip.test.js +251 -0
  170. package/dist/core/fcpxml-roundtrip.test.js.map +1 -0
  171. package/dist/core/fcpxml.d.ts +172 -0
  172. package/dist/core/fcpxml.d.ts.map +1 -0
  173. package/dist/core/fcpxml.js +406 -0
  174. package/dist/core/fcpxml.js.map +1 -0
  175. package/dist/core/fcpxml.test.d.ts +2 -0
  176. package/dist/core/fcpxml.test.d.ts.map +1 -0
  177. package/dist/core/fcpxml.test.js +360 -0
  178. package/dist/core/fcpxml.test.js.map +1 -0
  179. package/dist/core/filler-words.d.ts +155 -0
  180. package/dist/core/filler-words.d.ts.map +1 -0
  181. package/dist/core/filler-words.js +273 -0
  182. package/dist/core/filler-words.js.map +1 -0
  183. package/dist/core/filler-words.test.d.ts +2 -0
  184. package/dist/core/filler-words.test.d.ts.map +1 -0
  185. package/dist/core/filler-words.test.js +251 -0
  186. package/dist/core/filler-words.test.js.map +1 -0
  187. package/dist/core/format.d.ts +36 -0
  188. package/dist/core/format.d.ts.map +1 -0
  189. package/dist/core/format.js +57 -0
  190. package/dist/core/format.js.map +1 -0
  191. package/dist/core/format.test.d.ts +2 -0
  192. package/dist/core/format.test.d.ts.map +1 -0
  193. package/dist/core/format.test.js +81 -0
  194. package/dist/core/format.test.js.map +1 -0
  195. package/dist/core/frames.d.ts +35 -0
  196. package/dist/core/frames.d.ts.map +1 -0
  197. package/dist/core/frames.js +64 -0
  198. package/dist/core/frames.js.map +1 -0
  199. package/dist/core/hook-analysis.d.ts +90 -0
  200. package/dist/core/hook-analysis.d.ts.map +1 -0
  201. package/dist/core/hook-analysis.js +223 -0
  202. package/dist/core/hook-analysis.js.map +1 -0
  203. package/dist/core/hook-analysis.test.d.ts +2 -0
  204. package/dist/core/hook-analysis.test.d.ts.map +1 -0
  205. package/dist/core/hook-analysis.test.js +130 -0
  206. package/dist/core/hook-analysis.test.js.map +1 -0
  207. package/dist/core/hook-rewrite.d.ts +48 -0
  208. package/dist/core/hook-rewrite.d.ts.map +1 -0
  209. package/dist/core/hook-rewrite.js +151 -0
  210. package/dist/core/hook-rewrite.js.map +1 -0
  211. package/dist/core/hook-rewrite.test.d.ts +2 -0
  212. package/dist/core/hook-rewrite.test.d.ts.map +1 -0
  213. package/dist/core/hook-rewrite.test.js +58 -0
  214. package/dist/core/hook-rewrite.test.js.map +1 -0
  215. package/dist/core/hosts/detect.d.ts +17 -0
  216. package/dist/core/hosts/detect.d.ts.map +1 -0
  217. package/dist/core/hosts/detect.js +64 -0
  218. package/dist/core/hosts/detect.js.map +1 -0
  219. package/dist/core/hosts/detect.test.d.ts +2 -0
  220. package/dist/core/hosts/detect.test.d.ts.map +1 -0
  221. package/dist/core/hosts/detect.test.js +17 -0
  222. package/dist/core/hosts/detect.test.js.map +1 -0
  223. package/dist/core/hosts/index.d.ts +13 -0
  224. package/dist/core/hosts/index.d.ts.map +1 -0
  225. package/dist/core/hosts/index.js +30 -0
  226. package/dist/core/hosts/index.js.map +1 -0
  227. package/dist/core/hosts/lazy.d.ts +53 -0
  228. package/dist/core/hosts/lazy.d.ts.map +1 -0
  229. package/dist/core/hosts/lazy.js +143 -0
  230. package/dist/core/hosts/lazy.js.map +1 -0
  231. package/dist/core/hosts/lazy.test.d.ts +2 -0
  232. package/dist/core/hosts/lazy.test.d.ts.map +1 -0
  233. package/dist/core/hosts/lazy.test.js +117 -0
  234. package/dist/core/hosts/lazy.test.js.map +1 -0
  235. package/dist/core/hosts/none/adapter.d.ts +74 -0
  236. package/dist/core/hosts/none/adapter.d.ts.map +1 -0
  237. package/dist/core/hosts/none/adapter.js +99 -0
  238. package/dist/core/hosts/none/adapter.js.map +1 -0
  239. package/dist/core/hosts/premiere/adapter.d.ts +91 -0
  240. package/dist/core/hosts/premiere/adapter.d.ts.map +1 -0
  241. package/dist/core/hosts/premiere/adapter.js +219 -0
  242. package/dist/core/hosts/premiere/adapter.js.map +1 -0
  243. package/dist/core/hosts/premiere/bridge-source.d.ts +26 -0
  244. package/dist/core/hosts/premiere/bridge-source.d.ts.map +1 -0
  245. package/dist/core/hosts/premiere/bridge-source.js +374 -0
  246. package/dist/core/hosts/premiere/bridge-source.js.map +1 -0
  247. package/dist/core/hosts/premiere/bridge-source.test.d.ts +2 -0
  248. package/dist/core/hosts/premiere/bridge-source.test.d.ts.map +1 -0
  249. package/dist/core/hosts/premiere/bridge-source.test.js +36 -0
  250. package/dist/core/hosts/premiere/bridge-source.test.js.map +1 -0
  251. package/dist/core/hosts/premiere/bridge.d.ts +38 -0
  252. package/dist/core/hosts/premiere/bridge.d.ts.map +1 -0
  253. package/dist/core/hosts/premiere/bridge.js +238 -0
  254. package/dist/core/hosts/premiere/bridge.js.map +1 -0
  255. package/dist/core/hosts/premiere/http-bridge.d.ts +47 -0
  256. package/dist/core/hosts/premiere/http-bridge.d.ts.map +1 -0
  257. package/dist/core/hosts/premiere/http-bridge.js +82 -0
  258. package/dist/core/hosts/premiere/http-bridge.js.map +1 -0
  259. package/dist/core/hosts/premiere/http-bridge.test.d.ts +2 -0
  260. package/dist/core/hosts/premiere/http-bridge.test.d.ts.map +1 -0
  261. package/dist/core/hosts/premiere/http-bridge.test.js +113 -0
  262. package/dist/core/hosts/premiere/http-bridge.test.js.map +1 -0
  263. package/dist/core/hosts/premiere/ws-bridge.d.ts +91 -0
  264. package/dist/core/hosts/premiere/ws-bridge.d.ts.map +1 -0
  265. package/dist/core/hosts/premiere/ws-bridge.js +303 -0
  266. package/dist/core/hosts/premiere/ws-bridge.js.map +1 -0
  267. package/dist/core/hosts/premiere/ws-bridge.test.d.ts +2 -0
  268. package/dist/core/hosts/premiere/ws-bridge.test.d.ts.map +1 -0
  269. package/dist/core/hosts/premiere/ws-bridge.test.js +146 -0
  270. package/dist/core/hosts/premiere/ws-bridge.test.js.map +1 -0
  271. package/dist/core/hosts/resolve/adapter.d.ts +104 -0
  272. package/dist/core/hosts/resolve/adapter.d.ts.map +1 -0
  273. package/dist/core/hosts/resolve/adapter.js +195 -0
  274. package/dist/core/hosts/resolve/adapter.js.map +1 -0
  275. package/dist/core/hosts/resolve/bridge-source.d.ts +17 -0
  276. package/dist/core/hosts/resolve/bridge-source.d.ts.map +1 -0
  277. package/dist/core/hosts/resolve/bridge-source.js +1061 -0
  278. package/dist/core/hosts/resolve/bridge-source.js.map +1 -0
  279. package/dist/core/hosts/resolve/bridge.d.ts +52 -0
  280. package/dist/core/hosts/resolve/bridge.d.ts.map +1 -0
  281. package/dist/core/hosts/resolve/bridge.integration.test.d.ts +2 -0
  282. package/dist/core/hosts/resolve/bridge.integration.test.d.ts.map +1 -0
  283. package/dist/core/hosts/resolve/bridge.integration.test.js +810 -0
  284. package/dist/core/hosts/resolve/bridge.integration.test.js.map +1 -0
  285. package/dist/core/hosts/resolve/bridge.js +349 -0
  286. package/dist/core/hosts/resolve/bridge.js.map +1 -0
  287. package/dist/core/hosts/resolve/bridge.test.d.ts +2 -0
  288. package/dist/core/hosts/resolve/bridge.test.d.ts.map +1 -0
  289. package/dist/core/hosts/resolve/bridge.test.js +240 -0
  290. package/dist/core/hosts/resolve/bridge.test.js.map +1 -0
  291. package/dist/core/hosts/types.d.ts +254 -0
  292. package/dist/core/hosts/types.d.ts.map +1 -0
  293. package/dist/core/hosts/types.js +27 -0
  294. package/dist/core/hosts/types.js.map +1 -0
  295. package/dist/core/keyframes.d.ts +35 -0
  296. package/dist/core/keyframes.d.ts.map +1 -0
  297. package/dist/core/keyframes.js +90 -0
  298. package/dist/core/keyframes.js.map +1 -0
  299. package/dist/core/keyframes.test.d.ts +2 -0
  300. package/dist/core/keyframes.test.d.ts.map +1 -0
  301. package/dist/core/keyframes.test.js +73 -0
  302. package/dist/core/keyframes.test.js.map +1 -0
  303. package/dist/core/keyword-captions.d.ts +75 -0
  304. package/dist/core/keyword-captions.d.ts.map +1 -0
  305. package/dist/core/keyword-captions.js +285 -0
  306. package/dist/core/keyword-captions.js.map +1 -0
  307. package/dist/core/keyword-captions.test.d.ts +2 -0
  308. package/dist/core/keyword-captions.test.d.ts.map +1 -0
  309. package/dist/core/keyword-captions.test.js +90 -0
  310. package/dist/core/keyword-captions.test.js.map +1 -0
  311. package/dist/core/logger.d.ts +32 -0
  312. package/dist/core/logger.d.ts.map +1 -0
  313. package/dist/core/logger.js +188 -0
  314. package/dist/core/logger.js.map +1 -0
  315. package/dist/core/loop-match.d.ts +57 -0
  316. package/dist/core/loop-match.d.ts.map +1 -0
  317. package/dist/core/loop-match.js +91 -0
  318. package/dist/core/loop-match.js.map +1 -0
  319. package/dist/core/loudness.d.ts +52 -0
  320. package/dist/core/loudness.d.ts.map +1 -0
  321. package/dist/core/loudness.js +120 -0
  322. package/dist/core/loudness.js.map +1 -0
  323. package/dist/core/loudness.test.d.ts +2 -0
  324. package/dist/core/loudness.test.d.ts.map +1 -0
  325. package/dist/core/loudness.test.js +34 -0
  326. package/dist/core/loudness.test.js.map +1 -0
  327. package/dist/core/marker-colors.d.ts +39 -0
  328. package/dist/core/marker-colors.d.ts.map +1 -0
  329. package/dist/core/marker-colors.js +83 -0
  330. package/dist/core/marker-colors.js.map +1 -0
  331. package/dist/core/marker-colors.test.d.ts +2 -0
  332. package/dist/core/marker-colors.test.d.ts.map +1 -0
  333. package/dist/core/marker-colors.test.js +116 -0
  334. package/dist/core/marker-colors.test.js.map +1 -0
  335. package/dist/core/media/ffmpeg.d.ts +27 -0
  336. package/dist/core/media/ffmpeg.d.ts.map +1 -0
  337. package/dist/core/media/ffmpeg.js +64 -0
  338. package/dist/core/media/ffmpeg.js.map +1 -0
  339. package/dist/core/multi-format.d.ts +67 -0
  340. package/dist/core/multi-format.d.ts.map +1 -0
  341. package/dist/core/multi-format.js +127 -0
  342. package/dist/core/multi-format.js.map +1 -0
  343. package/dist/core/multi-format.test.d.ts +2 -0
  344. package/dist/core/multi-format.test.d.ts.map +1 -0
  345. package/dist/core/multi-format.test.js +151 -0
  346. package/dist/core/multi-format.test.js.map +1 -0
  347. package/dist/core/multicam.d.ts +40 -0
  348. package/dist/core/multicam.d.ts.map +1 -0
  349. package/dist/core/multicam.js +77 -0
  350. package/dist/core/multicam.js.map +1 -0
  351. package/dist/core/multicam.test.d.ts +2 -0
  352. package/dist/core/multicam.test.d.ts.map +1 -0
  353. package/dist/core/multicam.test.js +56 -0
  354. package/dist/core/multicam.test.js.map +1 -0
  355. package/dist/core/punch-in.d.ts +72 -0
  356. package/dist/core/punch-in.d.ts.map +1 -0
  357. package/dist/core/punch-in.js +133 -0
  358. package/dist/core/punch-in.js.map +1 -0
  359. package/dist/core/punch-in.test.d.ts +2 -0
  360. package/dist/core/punch-in.test.d.ts.map +1 -0
  361. package/dist/core/punch-in.test.js +118 -0
  362. package/dist/core/punch-in.test.js.map +1 -0
  363. package/dist/core/python/beats.py +61 -0
  364. package/dist/core/python/face_reframe.py +163 -0
  365. package/dist/core/python/sidecar-path.d.ts +13 -0
  366. package/dist/core/python/sidecar-path.d.ts.map +1 -0
  367. package/dist/core/python/sidecar-path.js +24 -0
  368. package/dist/core/python/sidecar-path.js.map +1 -0
  369. package/dist/core/python.d.ts +57 -0
  370. package/dist/core/python.d.ts.map +1 -0
  371. package/dist/core/python.js +107 -0
  372. package/dist/core/python.js.map +1 -0
  373. package/dist/core/python.test.d.ts +2 -0
  374. package/dist/core/python.test.d.ts.map +1 -0
  375. package/dist/core/python.test.js +129 -0
  376. package/dist/core/python.test.js.map +1 -0
  377. package/dist/core/reformat.d.ts +26 -0
  378. package/dist/core/reformat.d.ts.map +1 -0
  379. package/dist/core/reformat.js +31 -0
  380. package/dist/core/reformat.js.map +1 -0
  381. package/dist/core/reformat.test.d.ts +2 -0
  382. package/dist/core/reformat.test.d.ts.map +1 -0
  383. package/dist/core/reformat.test.js +29 -0
  384. package/dist/core/reformat.test.js.map +1 -0
  385. package/dist/core/reorder.d.ts +42 -0
  386. package/dist/core/reorder.d.ts.map +1 -0
  387. package/dist/core/reorder.js +80 -0
  388. package/dist/core/reorder.js.map +1 -0
  389. package/dist/core/reorder.test.d.ts +2 -0
  390. package/dist/core/reorder.test.d.ts.map +1 -0
  391. package/dist/core/reorder.test.js +88 -0
  392. package/dist/core/reorder.test.js.map +1 -0
  393. package/dist/core/retention-structure.d.ts +81 -0
  394. package/dist/core/retention-structure.d.ts.map +1 -0
  395. package/dist/core/retention-structure.js +206 -0
  396. package/dist/core/retention-structure.js.map +1 -0
  397. package/dist/core/retention-structure.test.d.ts +2 -0
  398. package/dist/core/retention-structure.test.d.ts.map +1 -0
  399. package/dist/core/retention-structure.test.js +88 -0
  400. package/dist/core/retention-structure.test.js.map +1 -0
  401. package/dist/core/review.d.ts +55 -0
  402. package/dist/core/review.d.ts.map +1 -0
  403. package/dist/core/review.js +124 -0
  404. package/dist/core/review.js.map +1 -0
  405. package/dist/core/review.test.d.ts +2 -0
  406. package/dist/core/review.test.d.ts.map +1 -0
  407. package/dist/core/review.test.js +76 -0
  408. package/dist/core/review.test.js.map +1 -0
  409. package/dist/core/safe-paths.d.ts +58 -0
  410. package/dist/core/safe-paths.d.ts.map +1 -0
  411. package/dist/core/safe-paths.js +118 -0
  412. package/dist/core/safe-paths.js.map +1 -0
  413. package/dist/core/safe-paths.test.d.ts +2 -0
  414. package/dist/core/safe-paths.test.d.ts.map +1 -0
  415. package/dist/core/safe-paths.test.js +92 -0
  416. package/dist/core/safe-paths.test.js.map +1 -0
  417. package/dist/core/sessions.d.ts +40 -0
  418. package/dist/core/sessions.d.ts.map +1 -0
  419. package/dist/core/sessions.js +61 -0
  420. package/dist/core/sessions.js.map +1 -0
  421. package/dist/core/sfx-on-cuts.d.ts +60 -0
  422. package/dist/core/sfx-on-cuts.d.ts.map +1 -0
  423. package/dist/core/sfx-on-cuts.js +90 -0
  424. package/dist/core/sfx-on-cuts.js.map +1 -0
  425. package/dist/core/sfx-on-cuts.test.d.ts +2 -0
  426. package/dist/core/sfx-on-cuts.test.d.ts.map +1 -0
  427. package/dist/core/sfx-on-cuts.test.js +53 -0
  428. package/dist/core/sfx-on-cuts.test.js.map +1 -0
  429. package/dist/core/silence.d.ts +41 -0
  430. package/dist/core/silence.d.ts.map +1 -0
  431. package/dist/core/silence.js +104 -0
  432. package/dist/core/silence.js.map +1 -0
  433. package/dist/core/silence.test.d.ts +2 -0
  434. package/dist/core/silence.test.d.ts.map +1 -0
  435. package/dist/core/silence.test.js +143 -0
  436. package/dist/core/silence.test.js.map +1 -0
  437. package/dist/core/skills-loader.d.ts +80 -0
  438. package/dist/core/skills-loader.d.ts.map +1 -0
  439. package/dist/core/skills-loader.js +161 -0
  440. package/dist/core/skills-loader.js.map +1 -0
  441. package/dist/core/skills-loader.test.d.ts +2 -0
  442. package/dist/core/skills-loader.test.d.ts.map +1 -0
  443. package/dist/core/skills-loader.test.js +130 -0
  444. package/dist/core/skills-loader.test.js.map +1 -0
  445. package/dist/core/skin-grade.d.ts +62 -0
  446. package/dist/core/skin-grade.d.ts.map +1 -0
  447. package/dist/core/skin-grade.js +271 -0
  448. package/dist/core/skin-grade.js.map +1 -0
  449. package/dist/core/skin-grade.test.d.ts +2 -0
  450. package/dist/core/skin-grade.test.d.ts.map +1 -0
  451. package/dist/core/skin-grade.test.js +182 -0
  452. package/dist/core/skin-grade.test.js.map +1 -0
  453. package/dist/core/speaker-changes.d.ts +30 -0
  454. package/dist/core/speaker-changes.d.ts.map +1 -0
  455. package/dist/core/speaker-changes.js +19 -0
  456. package/dist/core/speaker-changes.js.map +1 -0
  457. package/dist/core/speaker-changes.test.d.ts +2 -0
  458. package/dist/core/speaker-changes.test.d.ts.map +1 -0
  459. package/dist/core/speaker-changes.test.js +46 -0
  460. package/dist/core/speaker-changes.test.js.map +1 -0
  461. package/dist/core/speed-ramp.d.ts +60 -0
  462. package/dist/core/speed-ramp.d.ts.map +1 -0
  463. package/dist/core/speed-ramp.js +113 -0
  464. package/dist/core/speed-ramp.js.map +1 -0
  465. package/dist/core/speed-ramp.test.d.ts +2 -0
  466. package/dist/core/speed-ramp.test.d.ts.map +1 -0
  467. package/dist/core/speed-ramp.test.js +74 -0
  468. package/dist/core/speed-ramp.test.js.map +1 -0
  469. package/dist/core/srt.d.ts +91 -0
  470. package/dist/core/srt.d.ts.map +1 -0
  471. package/dist/core/srt.js +159 -0
  472. package/dist/core/srt.js.map +1 -0
  473. package/dist/core/srt.test.d.ts +2 -0
  474. package/dist/core/srt.test.d.ts.map +1 -0
  475. package/dist/core/srt.test.js +160 -0
  476. package/dist/core/srt.test.js.map +1 -0
  477. package/dist/core/stabilize.d.ts +15 -0
  478. package/dist/core/stabilize.d.ts.map +1 -0
  479. package/dist/core/stabilize.js +69 -0
  480. package/dist/core/stabilize.js.map +1 -0
  481. package/dist/core/styles-loader.d.ts +33 -0
  482. package/dist/core/styles-loader.d.ts.map +1 -0
  483. package/dist/core/styles-loader.js +67 -0
  484. package/dist/core/styles-loader.js.map +1 -0
  485. package/dist/core/styles-loader.test.d.ts +2 -0
  486. package/dist/core/styles-loader.test.d.ts.map +1 -0
  487. package/dist/core/styles-loader.test.js +72 -0
  488. package/dist/core/styles-loader.test.js.map +1 -0
  489. package/dist/core/text-overlay.d.ts +76 -0
  490. package/dist/core/text-overlay.d.ts.map +1 -0
  491. package/dist/core/text-overlay.js +233 -0
  492. package/dist/core/text-overlay.js.map +1 -0
  493. package/dist/core/text-overlay.test.d.ts +2 -0
  494. package/dist/core/text-overlay.test.d.ts.map +1 -0
  495. package/dist/core/text-overlay.test.js +103 -0
  496. package/dist/core/text-overlay.test.js.map +1 -0
  497. package/dist/core/thumbnail-compose.d.ts +58 -0
  498. package/dist/core/thumbnail-compose.d.ts.map +1 -0
  499. package/dist/core/thumbnail-compose.js +101 -0
  500. package/dist/core/thumbnail-compose.js.map +1 -0
  501. package/dist/core/thumbnail-promise.d.ts +46 -0
  502. package/dist/core/thumbnail-promise.d.ts.map +1 -0
  503. package/dist/core/thumbnail-promise.js +133 -0
  504. package/dist/core/thumbnail-promise.js.map +1 -0
  505. package/dist/core/thumbnail-promise.test.d.ts +2 -0
  506. package/dist/core/thumbnail-promise.test.d.ts.map +1 -0
  507. package/dist/core/thumbnail-promise.test.js +52 -0
  508. package/dist/core/thumbnail-promise.test.js.map +1 -0
  509. package/dist/core/version.d.ts +2 -0
  510. package/dist/core/version.d.ts.map +1 -0
  511. package/dist/core/version.js +26 -0
  512. package/dist/core/version.js.map +1 -0
  513. package/dist/core/viral-moments.d.ts +70 -0
  514. package/dist/core/viral-moments.d.ts.map +1 -0
  515. package/dist/core/viral-moments.js +192 -0
  516. package/dist/core/viral-moments.js.map +1 -0
  517. package/dist/core/viral-moments.test.d.ts +2 -0
  518. package/dist/core/viral-moments.test.d.ts.map +1 -0
  519. package/dist/core/viral-moments.test.js +153 -0
  520. package/dist/core/viral-moments.test.js.map +1 -0
  521. package/dist/core/vision.d.ts +53 -0
  522. package/dist/core/vision.d.ts.map +1 -0
  523. package/dist/core/vision.js +151 -0
  524. package/dist/core/vision.js.map +1 -0
  525. package/dist/core/vision.test.d.ts +2 -0
  526. package/dist/core/vision.test.d.ts.map +1 -0
  527. package/dist/core/vision.test.js +76 -0
  528. package/dist/core/vision.test.js.map +1 -0
  529. package/dist/core/whisper.d.ts +204 -0
  530. package/dist/core/whisper.d.ts.map +1 -0
  531. package/dist/core/whisper.js +448 -0
  532. package/dist/core/whisper.js.map +1 -0
  533. package/dist/core/whisper.test.d.ts +2 -0
  534. package/dist/core/whisper.test.d.ts.map +1 -0
  535. package/dist/core/whisper.test.js +372 -0
  536. package/dist/core/whisper.test.js.map +1 -0
  537. package/dist/core/youtube-metadata.d.ts +44 -0
  538. package/dist/core/youtube-metadata.d.ts.map +1 -0
  539. package/dist/core/youtube-metadata.js +168 -0
  540. package/dist/core/youtube-metadata.js.map +1 -0
  541. package/dist/core/youtube-metadata.test.d.ts +2 -0
  542. package/dist/core/youtube-metadata.test.d.ts.map +1 -0
  543. package/dist/core/youtube-metadata.test.js +132 -0
  544. package/dist/core/youtube-metadata.test.js.map +1 -0
  545. package/dist/index.d.ts +19 -0
  546. package/dist/index.d.ts.map +1 -0
  547. package/dist/index.js +17 -0
  548. package/dist/index.js.map +1 -0
  549. package/dist/prompt-commands.d.ts +24 -0
  550. package/dist/prompt-commands.d.ts.map +1 -0
  551. package/dist/prompt-commands.js +243 -0
  552. package/dist/prompt-commands.js.map +1 -0
  553. package/dist/prompt-commands.test.d.ts +2 -0
  554. package/dist/prompt-commands.test.d.ts.map +1 -0
  555. package/dist/prompt-commands.test.js +46 -0
  556. package/dist/prompt-commands.test.js.map +1 -0
  557. package/dist/skills.d.ts +18 -0
  558. package/dist/skills.d.ts.map +1 -0
  559. package/dist/skills.js +1780 -0
  560. package/dist/skills.js.map +1 -0
  561. package/dist/system-prompt.d.ts +35 -0
  562. package/dist/system-prompt.d.ts.map +1 -0
  563. package/dist/system-prompt.js +618 -0
  564. package/dist/system-prompt.js.map +1 -0
  565. package/dist/system-prompt.test.d.ts +2 -0
  566. package/dist/system-prompt.test.d.ts.map +1 -0
  567. package/dist/system-prompt.test.js +87 -0
  568. package/dist/system-prompt.test.js.map +1 -0
  569. package/dist/tools/add-fades.d.ts +13 -0
  570. package/dist/tools/add-fades.d.ts.map +1 -0
  571. package/dist/tools/add-fades.js +89 -0
  572. package/dist/tools/add-fades.js.map +1 -0
  573. package/dist/tools/add-marker.d.ts +31 -0
  574. package/dist/tools/add-marker.d.ts.map +1 -0
  575. package/dist/tools/add-marker.js +56 -0
  576. package/dist/tools/add-marker.js.map +1 -0
  577. package/dist/tools/add-sfx-at-cuts.d.ts +24 -0
  578. package/dist/tools/add-sfx-at-cuts.d.ts.map +1 -0
  579. package/dist/tools/add-sfx-at-cuts.js +145 -0
  580. package/dist/tools/add-sfx-at-cuts.js.map +1 -0
  581. package/dist/tools/add-sfx-to-timeline.d.ts +34 -0
  582. package/dist/tools/add-sfx-to-timeline.d.ts.map +1 -0
  583. package/dist/tools/add-sfx-to-timeline.js +169 -0
  584. package/dist/tools/add-sfx-to-timeline.js.map +1 -0
  585. package/dist/tools/add-sfx-to-timeline.test.d.ts +2 -0
  586. package/dist/tools/add-sfx-to-timeline.test.d.ts.map +1 -0
  587. package/dist/tools/add-sfx-to-timeline.test.js +181 -0
  588. package/dist/tools/add-sfx-to-timeline.test.js.map +1 -0
  589. package/dist/tools/add-track.d.ts +13 -0
  590. package/dist/tools/add-track.d.ts.map +1 -0
  591. package/dist/tools/add-track.js +26 -0
  592. package/dist/tools/add-track.js.map +1 -0
  593. package/dist/tools/analyze-hook.d.ts +28 -0
  594. package/dist/tools/analyze-hook.d.ts.map +1 -0
  595. package/dist/tools/analyze-hook.js +126 -0
  596. package/dist/tools/analyze-hook.js.map +1 -0
  597. package/dist/tools/append-clip.d.ts +10 -0
  598. package/dist/tools/append-clip.d.ts.map +1 -0
  599. package/dist/tools/append-clip.js +27 -0
  600. package/dist/tools/append-clip.js.map +1 -0
  601. package/dist/tools/apply-lut.d.ts +11 -0
  602. package/dist/tools/apply-lut.d.ts.map +1 -0
  603. package/dist/tools/apply-lut.js +33 -0
  604. package/dist/tools/apply-lut.js.map +1 -0
  605. package/dist/tools/audit-first-frame.d.ts +36 -0
  606. package/dist/tools/audit-first-frame.d.ts.map +1 -0
  607. package/dist/tools/audit-first-frame.js +181 -0
  608. package/dist/tools/audit-first-frame.js.map +1 -0
  609. package/dist/tools/audit-retention-structure.d.ts +20 -0
  610. package/dist/tools/audit-retention-structure.d.ts.map +1 -0
  611. package/dist/tools/audit-retention-structure.js +95 -0
  612. package/dist/tools/audit-retention-structure.js.map +1 -0
  613. package/dist/tools/audit-retention-structure.test.d.ts +2 -0
  614. package/dist/tools/audit-retention-structure.test.d.ts.map +1 -0
  615. package/dist/tools/audit-retention-structure.test.js +93 -0
  616. package/dist/tools/audit-retention-structure.test.js.map +1 -0
  617. package/dist/tools/bleep-words.d.ts +59 -0
  618. package/dist/tools/bleep-words.d.ts.map +1 -0
  619. package/dist/tools/bleep-words.js +211 -0
  620. package/dist/tools/bleep-words.js.map +1 -0
  621. package/dist/tools/bleep-words.test.d.ts +2 -0
  622. package/dist/tools/bleep-words.test.d.ts.map +1 -0
  623. package/dist/tools/bleep-words.test.js +96 -0
  624. package/dist/tools/bleep-words.test.js.map +1 -0
  625. package/dist/tools/burn-subtitles.d.ts +28 -0
  626. package/dist/tools/burn-subtitles.d.ts.map +1 -0
  627. package/dist/tools/burn-subtitles.js +92 -0
  628. package/dist/tools/burn-subtitles.js.map +1 -0
  629. package/dist/tools/clean-audio.d.ts +18 -0
  630. package/dist/tools/clean-audio.d.ts.map +1 -0
  631. package/dist/tools/clean-audio.js +55 -0
  632. package/dist/tools/clean-audio.js.map +1 -0
  633. package/dist/tools/clone-timeline.d.ts +9 -0
  634. package/dist/tools/clone-timeline.d.ts.map +1 -0
  635. package/dist/tools/clone-timeline.js +28 -0
  636. package/dist/tools/clone-timeline.js.map +1 -0
  637. package/dist/tools/cluster-takes.d.ts +11 -0
  638. package/dist/tools/cluster-takes.d.ts.map +1 -0
  639. package/dist/tools/cluster-takes.js +72 -0
  640. package/dist/tools/cluster-takes.js.map +1 -0
  641. package/dist/tools/color-match.d.ts +16 -0
  642. package/dist/tools/color-match.d.ts.map +1 -0
  643. package/dist/tools/color-match.js +55 -0
  644. package/dist/tools/color-match.js.map +1 -0
  645. package/dist/tools/compose-layered.d.ts +47 -0
  646. package/dist/tools/compose-layered.d.ts.map +1 -0
  647. package/dist/tools/compose-layered.js +104 -0
  648. package/dist/tools/compose-layered.js.map +1 -0
  649. package/dist/tools/compose-thumbnail-variants.d.ts +70 -0
  650. package/dist/tools/compose-thumbnail-variants.d.ts.map +1 -0
  651. package/dist/tools/compose-thumbnail-variants.js +274 -0
  652. package/dist/tools/compose-thumbnail-variants.js.map +1 -0
  653. package/dist/tools/compose-thumbnail.d.ts +28 -0
  654. package/dist/tools/compose-thumbnail.d.ts.map +1 -0
  655. package/dist/tools/compose-thumbnail.js +101 -0
  656. package/dist/tools/compose-thumbnail.js.map +1 -0
  657. package/dist/tools/concat-videos.d.ts +18 -0
  658. package/dist/tools/concat-videos.d.ts.map +1 -0
  659. package/dist/tools/concat-videos.js +87 -0
  660. package/dist/tools/concat-videos.js.map +1 -0
  661. package/dist/tools/concat-videos.test.d.ts +2 -0
  662. package/dist/tools/concat-videos.test.d.ts.map +1 -0
  663. package/dist/tools/concat-videos.test.js +103 -0
  664. package/dist/tools/concat-videos.test.js.map +1 -0
  665. package/dist/tools/copy-grade.d.ts +10 -0
  666. package/dist/tools/copy-grade.d.ts.map +1 -0
  667. package/dist/tools/copy-grade.js +29 -0
  668. package/dist/tools/copy-grade.js.map +1 -0
  669. package/dist/tools/create-timeline.d.ts +12 -0
  670. package/dist/tools/create-timeline.d.ts.map +1 -0
  671. package/dist/tools/create-timeline.js +35 -0
  672. package/dist/tools/create-timeline.js.map +1 -0
  673. package/dist/tools/crossfade-videos.d.ts +49 -0
  674. package/dist/tools/crossfade-videos.d.ts.map +1 -0
  675. package/dist/tools/crossfade-videos.js +122 -0
  676. package/dist/tools/crossfade-videos.js.map +1 -0
  677. package/dist/tools/cut-at.d.ts +10 -0
  678. package/dist/tools/cut-at.d.ts.map +1 -0
  679. package/dist/tools/cut-at.js +24 -0
  680. package/dist/tools/cut-at.js.map +1 -0
  681. package/dist/tools/cut-filler-words.d.ts +27 -0
  682. package/dist/tools/cut-filler-words.d.ts.map +1 -0
  683. package/dist/tools/cut-filler-words.js +182 -0
  684. package/dist/tools/cut-filler-words.js.map +1 -0
  685. package/dist/tools/detect-silence.d.ts +13 -0
  686. package/dist/tools/detect-silence.d.ts.map +1 -0
  687. package/dist/tools/detect-silence.js +98 -0
  688. package/dist/tools/detect-silence.js.map +1 -0
  689. package/dist/tools/detect-speaker-changes.d.ts +9 -0
  690. package/dist/tools/detect-speaker-changes.d.ts.map +1 -0
  691. package/dist/tools/detect-speaker-changes.js +43 -0
  692. package/dist/tools/detect-speaker-changes.js.map +1 -0
  693. package/dist/tools/duck-audio.d.ts +16 -0
  694. package/dist/tools/duck-audio.d.ts.map +1 -0
  695. package/dist/tools/duck-audio.js +73 -0
  696. package/dist/tools/duck-audio.js.map +1 -0
  697. package/dist/tools/extract-audio.d.ts +10 -0
  698. package/dist/tools/extract-audio.d.ts.map +1 -0
  699. package/dist/tools/extract-audio.js +36 -0
  700. package/dist/tools/extract-audio.js.map +1 -0
  701. package/dist/tools/extract-frame.d.ts +12 -0
  702. package/dist/tools/extract-frame.d.ts.map +1 -0
  703. package/dist/tools/extract-frame.js +70 -0
  704. package/dist/tools/extract-frame.js.map +1 -0
  705. package/dist/tools/face-reframe.d.ts +30 -0
  706. package/dist/tools/face-reframe.d.ts.map +1 -0
  707. package/dist/tools/face-reframe.js +143 -0
  708. package/dist/tools/face-reframe.js.map +1 -0
  709. package/dist/tools/face-reframe.test.d.ts +2 -0
  710. package/dist/tools/face-reframe.test.d.ts.map +1 -0
  711. package/dist/tools/face-reframe.test.js +139 -0
  712. package/dist/tools/face-reframe.test.js.map +1 -0
  713. package/dist/tools/find-viral-moments.d.ts +23 -0
  714. package/dist/tools/find-viral-moments.d.ts.map +1 -0
  715. package/dist/tools/find-viral-moments.js +176 -0
  716. package/dist/tools/find-viral-moments.js.map +1 -0
  717. package/dist/tools/find-viral-moments.test.d.ts +2 -0
  718. package/dist/tools/find-viral-moments.test.d.ts.map +1 -0
  719. package/dist/tools/find-viral-moments.test.js +144 -0
  720. package/dist/tools/find-viral-moments.test.js.map +1 -0
  721. package/dist/tools/fusion-comp.d.ts +49 -0
  722. package/dist/tools/fusion-comp.d.ts.map +1 -0
  723. package/dist/tools/fusion-comp.js +129 -0
  724. package/dist/tools/fusion-comp.js.map +1 -0
  725. package/dist/tools/generate-gif.d.ts +13 -0
  726. package/dist/tools/generate-gif.d.ts.map +1 -0
  727. package/dist/tools/generate-gif.js +111 -0
  728. package/dist/tools/generate-gif.js.map +1 -0
  729. package/dist/tools/generate-gif.test.d.ts +2 -0
  730. package/dist/tools/generate-gif.test.d.ts.map +1 -0
  731. package/dist/tools/generate-gif.test.js +115 -0
  732. package/dist/tools/generate-gif.test.js.map +1 -0
  733. package/dist/tools/generate-outro.d.ts +18 -0
  734. package/dist/tools/generate-outro.d.ts.map +1 -0
  735. package/dist/tools/generate-outro.js +175 -0
  736. package/dist/tools/generate-outro.js.map +1 -0
  737. package/dist/tools/generate-youtube-metadata.d.ts +23 -0
  738. package/dist/tools/generate-youtube-metadata.d.ts.map +1 -0
  739. package/dist/tools/generate-youtube-metadata.js +103 -0
  740. package/dist/tools/generate-youtube-metadata.js.map +1 -0
  741. package/dist/tools/generate-youtube-metadata.test.d.ts +2 -0
  742. package/dist/tools/generate-youtube-metadata.test.d.ts.map +1 -0
  743. package/dist/tools/generate-youtube-metadata.test.js +118 -0
  744. package/dist/tools/generate-youtube-metadata.test.js.map +1 -0
  745. package/dist/tools/get-markers.d.ts +13 -0
  746. package/dist/tools/get-markers.d.ts.map +1 -0
  747. package/dist/tools/get-markers.js +71 -0
  748. package/dist/tools/get-markers.js.map +1 -0
  749. package/dist/tools/get-timeline.d.ts +9 -0
  750. package/dist/tools/get-timeline.d.ts.map +1 -0
  751. package/dist/tools/get-timeline.js +43 -0
  752. package/dist/tools/get-timeline.js.map +1 -0
  753. package/dist/tools/grade-skin-tones.d.ts +31 -0
  754. package/dist/tools/grade-skin-tones.d.ts.map +1 -0
  755. package/dist/tools/grade-skin-tones.js +92 -0
  756. package/dist/tools/grade-skin-tones.js.map +1 -0
  757. package/dist/tools/host-eval.d.ts +35 -0
  758. package/dist/tools/host-eval.d.ts.map +1 -0
  759. package/dist/tools/host-eval.js +70 -0
  760. package/dist/tools/host-eval.js.map +1 -0
  761. package/dist/tools/host-info.d.ts +7 -0
  762. package/dist/tools/host-info.d.ts.map +1 -0
  763. package/dist/tools/host-info.js +33 -0
  764. package/dist/tools/host-info.js.map +1 -0
  765. package/dist/tools/host-tools.test.d.ts +2 -0
  766. package/dist/tools/host-tools.test.d.ts.map +1 -0
  767. package/dist/tools/host-tools.test.js +125 -0
  768. package/dist/tools/host-tools.test.js.map +1 -0
  769. package/dist/tools/import-edl.d.ts +9 -0
  770. package/dist/tools/import-edl.d.ts.map +1 -0
  771. package/dist/tools/import-edl.js +25 -0
  772. package/dist/tools/import-edl.js.map +1 -0
  773. package/dist/tools/import-subtitles.d.ts +9 -0
  774. package/dist/tools/import-subtitles.d.ts.map +1 -0
  775. package/dist/tools/import-subtitles.js +31 -0
  776. package/dist/tools/import-subtitles.js.map +1 -0
  777. package/dist/tools/import-to-media-pool.d.ts +10 -0
  778. package/dist/tools/import-to-media-pool.d.ts.map +1 -0
  779. package/dist/tools/import-to-media-pool.js +27 -0
  780. package/dist/tools/import-to-media-pool.js.map +1 -0
  781. package/dist/tools/index.d.ts +110 -0
  782. package/dist/tools/index.d.ts.map +1 -0
  783. package/dist/tools/index.js +380 -0
  784. package/dist/tools/index.js.map +1 -0
  785. package/dist/tools/index.test.d.ts +2 -0
  786. package/dist/tools/index.test.d.ts.map +1 -0
  787. package/dist/tools/index.test.js +158 -0
  788. package/dist/tools/index.test.js.map +1 -0
  789. package/dist/tools/insert-broll.d.ts +13 -0
  790. package/dist/tools/insert-broll.d.ts.map +1 -0
  791. package/dist/tools/insert-broll.js +56 -0
  792. package/dist/tools/insert-broll.js.map +1 -0
  793. package/dist/tools/ken-burns.d.ts +26 -0
  794. package/dist/tools/ken-burns.d.ts.map +1 -0
  795. package/dist/tools/ken-burns.js +126 -0
  796. package/dist/tools/ken-burns.js.map +1 -0
  797. package/dist/tools/list-render-presets.d.ts +7 -0
  798. package/dist/tools/list-render-presets.d.ts.map +1 -0
  799. package/dist/tools/list-render-presets.js +30 -0
  800. package/dist/tools/list-render-presets.js.map +1 -0
  801. package/dist/tools/loop-match-short.d.ts +22 -0
  802. package/dist/tools/loop-match-short.d.ts.map +1 -0
  803. package/dist/tools/loop-match-short.js +107 -0
  804. package/dist/tools/loop-match-short.js.map +1 -0
  805. package/dist/tools/match-clip-color.d.ts +29 -0
  806. package/dist/tools/match-clip-color.d.ts.map +1 -0
  807. package/dist/tools/match-clip-color.js +99 -0
  808. package/dist/tools/match-clip-color.js.map +1 -0
  809. package/dist/tools/measure-loudness.d.ts +8 -0
  810. package/dist/tools/measure-loudness.d.ts.map +1 -0
  811. package/dist/tools/measure-loudness.js +40 -0
  812. package/dist/tools/measure-loudness.js.map +1 -0
  813. package/dist/tools/mix-audio.d.ts +46 -0
  814. package/dist/tools/mix-audio.d.ts.map +1 -0
  815. package/dist/tools/mix-audio.js +102 -0
  816. package/dist/tools/mix-audio.js.map +1 -0
  817. package/dist/tools/multicam-sync.d.ts +14 -0
  818. package/dist/tools/multicam-sync.d.ts.map +1 -0
  819. package/dist/tools/multicam-sync.js +75 -0
  820. package/dist/tools/multicam-sync.js.map +1 -0
  821. package/dist/tools/new-tools.test.d.ts +2 -0
  822. package/dist/tools/new-tools.test.d.ts.map +1 -0
  823. package/dist/tools/new-tools.test.js +511 -0
  824. package/dist/tools/new-tools.test.js.map +1 -0
  825. package/dist/tools/normalize-loudness.d.ts +21 -0
  826. package/dist/tools/normalize-loudness.d.ts.map +1 -0
  827. package/dist/tools/normalize-loudness.js +95 -0
  828. package/dist/tools/normalize-loudness.js.map +1 -0
  829. package/dist/tools/open-page.d.ts +17 -0
  830. package/dist/tools/open-page.d.ts.map +1 -0
  831. package/dist/tools/open-page.js +27 -0
  832. package/dist/tools/open-page.js.map +1 -0
  833. package/dist/tools/overlay-watermark.d.ts +28 -0
  834. package/dist/tools/overlay-watermark.d.ts.map +1 -0
  835. package/dist/tools/overlay-watermark.js +99 -0
  836. package/dist/tools/overlay-watermark.js.map +1 -0
  837. package/dist/tools/path-traversal.test.d.ts +15 -0
  838. package/dist/tools/path-traversal.test.d.ts.map +1 -0
  839. package/dist/tools/path-traversal.test.js +223 -0
  840. package/dist/tools/path-traversal.test.js.map +1 -0
  841. package/dist/tools/pick-best-takes.d.ts +20 -0
  842. package/dist/tools/pick-best-takes.d.ts.map +1 -0
  843. package/dist/tools/pick-best-takes.js +148 -0
  844. package/dist/tools/pick-best-takes.js.map +1 -0
  845. package/dist/tools/post-tools.test.d.ts +2 -0
  846. package/dist/tools/post-tools.test.d.ts.map +1 -0
  847. package/dist/tools/post-tools.test.js +83 -0
  848. package/dist/tools/post-tools.test.js.map +1 -0
  849. package/dist/tools/pre-render-check.d.ts +23 -0
  850. package/dist/tools/pre-render-check.d.ts.map +1 -0
  851. package/dist/tools/pre-render-check.js +134 -0
  852. package/dist/tools/pre-render-check.js.map +1 -0
  853. package/dist/tools/probe-media.d.ts +8 -0
  854. package/dist/tools/probe-media.d.ts.map +1 -0
  855. package/dist/tools/probe-media.js +32 -0
  856. package/dist/tools/probe-media.js.map +1 -0
  857. package/dist/tools/punch-in.d.ts +30 -0
  858. package/dist/tools/punch-in.d.ts.map +1 -0
  859. package/dist/tools/punch-in.js +131 -0
  860. package/dist/tools/punch-in.js.map +1 -0
  861. package/dist/tools/read-skill.d.ts +9 -0
  862. package/dist/tools/read-skill.d.ts.map +1 -0
  863. package/dist/tools/read-skill.js +24 -0
  864. package/dist/tools/read-skill.js.map +1 -0
  865. package/dist/tools/read-transcript.d.ts +14 -0
  866. package/dist/tools/read-transcript.d.ts.map +1 -0
  867. package/dist/tools/read-transcript.js +86 -0
  868. package/dist/tools/read-transcript.js.map +1 -0
  869. package/dist/tools/read-transcript.test.d.ts +2 -0
  870. package/dist/tools/read-transcript.test.d.ts.map +1 -0
  871. package/dist/tools/read-transcript.test.js +136 -0
  872. package/dist/tools/read-transcript.test.js.map +1 -0
  873. package/dist/tools/reformat-timeline.d.ts +25 -0
  874. package/dist/tools/reformat-timeline.d.ts.map +1 -0
  875. package/dist/tools/reformat-timeline.js +61 -0
  876. package/dist/tools/reformat-timeline.js.map +1 -0
  877. package/dist/tools/render-multi-format.d.ts +35 -0
  878. package/dist/tools/render-multi-format.d.ts.map +1 -0
  879. package/dist/tools/render-multi-format.js +206 -0
  880. package/dist/tools/render-multi-format.js.map +1 -0
  881. package/dist/tools/render-multi-format.test.d.ts +2 -0
  882. package/dist/tools/render-multi-format.test.d.ts.map +1 -0
  883. package/dist/tools/render-multi-format.test.js +312 -0
  884. package/dist/tools/render-multi-format.test.js.map +1 -0
  885. package/dist/tools/render.d.ts +10 -0
  886. package/dist/tools/render.d.ts.map +1 -0
  887. package/dist/tools/render.js +26 -0
  888. package/dist/tools/render.js.map +1 -0
  889. package/dist/tools/reorder-timeline.d.ts +12 -0
  890. package/dist/tools/reorder-timeline.d.ts.map +1 -0
  891. package/dist/tools/reorder-timeline.js +66 -0
  892. package/dist/tools/reorder-timeline.js.map +1 -0
  893. package/dist/tools/replace-clip.d.ts +10 -0
  894. package/dist/tools/replace-clip.d.ts.map +1 -0
  895. package/dist/tools/replace-clip.js +28 -0
  896. package/dist/tools/replace-clip.js.map +1 -0
  897. package/dist/tools/review-edit.d.ts +23 -0
  898. package/dist/tools/review-edit.d.ts.map +1 -0
  899. package/dist/tools/review-edit.js +47 -0
  900. package/dist/tools/review-edit.js.map +1 -0
  901. package/dist/tools/rewrite-hook.d.ts +32 -0
  902. package/dist/tools/rewrite-hook.d.ts.map +1 -0
  903. package/dist/tools/rewrite-hook.js +65 -0
  904. package/dist/tools/rewrite-hook.js.map +1 -0
  905. package/dist/tools/ripple-delete.d.ts +11 -0
  906. package/dist/tools/ripple-delete.d.ts.map +1 -0
  907. package/dist/tools/ripple-delete.js +27 -0
  908. package/dist/tools/ripple-delete.js.map +1 -0
  909. package/dist/tools/save-project.d.ts +7 -0
  910. package/dist/tools/save-project.d.ts.map +1 -0
  911. package/dist/tools/save-project.js +22 -0
  912. package/dist/tools/save-project.js.map +1 -0
  913. package/dist/tools/score-clip.d.ts +30 -0
  914. package/dist/tools/score-clip.d.ts.map +1 -0
  915. package/dist/tools/score-clip.js +109 -0
  916. package/dist/tools/score-clip.js.map +1 -0
  917. package/dist/tools/score-clip.test.d.ts +2 -0
  918. package/dist/tools/score-clip.test.d.ts.map +1 -0
  919. package/dist/tools/score-clip.test.js +110 -0
  920. package/dist/tools/score-clip.test.js.map +1 -0
  921. package/dist/tools/score-shot.d.ts +18 -0
  922. package/dist/tools/score-shot.d.ts.map +1 -0
  923. package/dist/tools/score-shot.js +127 -0
  924. package/dist/tools/score-shot.js.map +1 -0
  925. package/dist/tools/search-tools.d.ts +34 -0
  926. package/dist/tools/search-tools.d.ts.map +1 -0
  927. package/dist/tools/search-tools.js +86 -0
  928. package/dist/tools/search-tools.js.map +1 -0
  929. package/dist/tools/search-tools.test.d.ts +2 -0
  930. package/dist/tools/search-tools.test.d.ts.map +1 -0
  931. package/dist/tools/search-tools.test.js +60 -0
  932. package/dist/tools/search-tools.test.js.map +1 -0
  933. package/dist/tools/set-clip-speed.d.ts +10 -0
  934. package/dist/tools/set-clip-speed.d.ts.map +1 -0
  935. package/dist/tools/set-clip-speed.js +28 -0
  936. package/dist/tools/set-clip-speed.js.map +1 -0
  937. package/dist/tools/set-clip-volume.d.ts +10 -0
  938. package/dist/tools/set-clip-volume.d.ts.map +1 -0
  939. package/dist/tools/set-clip-volume.js +33 -0
  940. package/dist/tools/set-clip-volume.js.map +1 -0
  941. package/dist/tools/set-primary-correction.d.ts +14 -0
  942. package/dist/tools/set-primary-correction.d.ts.map +1 -0
  943. package/dist/tools/set-primary-correction.js +45 -0
  944. package/dist/tools/set-primary-correction.js.map +1 -0
  945. package/dist/tools/smart-reframe.d.ts +22 -0
  946. package/dist/tools/smart-reframe.d.ts.map +1 -0
  947. package/dist/tools/smart-reframe.js +39 -0
  948. package/dist/tools/smart-reframe.js.map +1 -0
  949. package/dist/tools/snap-cuts-to-beats.d.ts +18 -0
  950. package/dist/tools/snap-cuts-to-beats.d.ts.map +1 -0
  951. package/dist/tools/snap-cuts-to-beats.js +110 -0
  952. package/dist/tools/snap-cuts-to-beats.js.map +1 -0
  953. package/dist/tools/snap-cuts-to-beats.test.d.ts +2 -0
  954. package/dist/tools/snap-cuts-to-beats.test.d.ts.map +1 -0
  955. package/dist/tools/snap-cuts-to-beats.test.js +99 -0
  956. package/dist/tools/snap-cuts-to-beats.test.js.map +1 -0
  957. package/dist/tools/speed-ramp.d.ts +14 -0
  958. package/dist/tools/speed-ramp.d.ts.map +1 -0
  959. package/dist/tools/speed-ramp.js +72 -0
  960. package/dist/tools/speed-ramp.js.map +1 -0
  961. package/dist/tools/stabilize-video.d.ts +12 -0
  962. package/dist/tools/stabilize-video.d.ts.map +1 -0
  963. package/dist/tools/stabilize-video.js +64 -0
  964. package/dist/tools/stabilize-video.js.map +1 -0
  965. package/dist/tools/suggest-broll.d.ts +34 -0
  966. package/dist/tools/suggest-broll.d.ts.map +1 -0
  967. package/dist/tools/suggest-broll.js +367 -0
  968. package/dist/tools/suggest-broll.js.map +1 -0
  969. package/dist/tools/suggest-broll.test.d.ts +2 -0
  970. package/dist/tools/suggest-broll.test.d.ts.map +1 -0
  971. package/dist/tools/suggest-broll.test.js +217 -0
  972. package/dist/tools/suggest-broll.test.js.map +1 -0
  973. package/dist/tools/text-based-cut.d.ts +33 -0
  974. package/dist/tools/text-based-cut.d.ts.map +1 -0
  975. package/dist/tools/text-based-cut.js +172 -0
  976. package/dist/tools/text-based-cut.js.map +1 -0
  977. package/dist/tools/text-based-cut.test.d.ts +2 -0
  978. package/dist/tools/text-based-cut.test.d.ts.map +1 -0
  979. package/dist/tools/text-based-cut.test.js +32 -0
  980. package/dist/tools/text-based-cut.test.js.map +1 -0
  981. package/dist/tools/transcribe.d.ts +29 -0
  982. package/dist/tools/transcribe.d.ts.map +1 -0
  983. package/dist/tools/transcribe.js +117 -0
  984. package/dist/tools/transcribe.js.map +1 -0
  985. package/dist/tools/transition-videos.d.ts +29 -0
  986. package/dist/tools/transition-videos.d.ts.map +1 -0
  987. package/dist/tools/transition-videos.js +130 -0
  988. package/dist/tools/transition-videos.js.map +1 -0
  989. package/dist/tools/trim-dead-air.d.ts +59 -0
  990. package/dist/tools/trim-dead-air.d.ts.map +1 -0
  991. package/dist/tools/trim-dead-air.js +215 -0
  992. package/dist/tools/trim-dead-air.js.map +1 -0
  993. package/dist/tools/trim-dead-air.test.d.ts +2 -0
  994. package/dist/tools/trim-dead-air.test.d.ts.map +1 -0
  995. package/dist/tools/trim-dead-air.test.js +75 -0
  996. package/dist/tools/trim-dead-air.test.js.map +1 -0
  997. package/dist/tools/verify-thumbnail-promise.d.ts +33 -0
  998. package/dist/tools/verify-thumbnail-promise.d.ts.map +1 -0
  999. package/dist/tools/verify-thumbnail-promise.js +112 -0
  1000. package/dist/tools/verify-thumbnail-promise.js.map +1 -0
  1001. package/dist/tools/verify-thumbnail-promise.test.d.ts +2 -0
  1002. package/dist/tools/verify-thumbnail-promise.test.d.ts.map +1 -0
  1003. package/dist/tools/verify-thumbnail-promise.test.js +38 -0
  1004. package/dist/tools/verify-thumbnail-promise.test.js.map +1 -0
  1005. package/dist/tools/write-ass.d.ts +34 -0
  1006. package/dist/tools/write-ass.d.ts.map +1 -0
  1007. package/dist/tools/write-ass.js +102 -0
  1008. package/dist/tools/write-ass.js.map +1 -0
  1009. package/dist/tools/write-edl.d.ts +24 -0
  1010. package/dist/tools/write-edl.d.ts.map +1 -0
  1011. package/dist/tools/write-edl.js +60 -0
  1012. package/dist/tools/write-edl.js.map +1 -0
  1013. package/dist/tools/write-fcpxml.d.ts +20 -0
  1014. package/dist/tools/write-fcpxml.d.ts.map +1 -0
  1015. package/dist/tools/write-fcpxml.js +53 -0
  1016. package/dist/tools/write-fcpxml.js.map +1 -0
  1017. package/dist/tools/write-keyword-captions.d.ts +43 -0
  1018. package/dist/tools/write-keyword-captions.d.ts.map +1 -0
  1019. package/dist/tools/write-keyword-captions.js +215 -0
  1020. package/dist/tools/write-keyword-captions.js.map +1 -0
  1021. package/dist/tools/write-lower-third.d.ts +34 -0
  1022. package/dist/tools/write-lower-third.d.ts.map +1 -0
  1023. package/dist/tools/write-lower-third.js +53 -0
  1024. package/dist/tools/write-lower-third.js.map +1 -0
  1025. package/dist/tools/write-srt.d.ts +20 -0
  1026. package/dist/tools/write-srt.d.ts.map +1 -0
  1027. package/dist/tools/write-srt.js +73 -0
  1028. package/dist/tools/write-srt.js.map +1 -0
  1029. package/dist/tools/write-title-card.d.ts +25 -0
  1030. package/dist/tools/write-title-card.d.ts.map +1 -0
  1031. package/dist/tools/write-title-card.js +58 -0
  1032. package/dist/tools/write-title-card.js.map +1 -0
  1033. package/dist/types.d.ts +83 -0
  1034. package/dist/types.d.ts.map +1 -0
  1035. package/dist/types.js +3 -0
  1036. package/dist/types.js.map +1 -0
  1037. package/dist/ui/App.d.ts +56 -0
  1038. package/dist/ui/App.d.ts.map +1 -0
  1039. package/dist/ui/App.js +524 -0
  1040. package/dist/ui/App.js.map +1 -0
  1041. package/dist/ui/components/Banner.d.ts +13 -0
  1042. package/dist/ui/components/Banner.d.ts.map +1 -0
  1043. package/dist/ui/components/Banner.js +59 -0
  1044. package/dist/ui/components/Banner.js.map +1 -0
  1045. package/dist/ui/render.d.ts +9 -0
  1046. package/dist/ui/render.d.ts.map +1 -0
  1047. package/dist/ui/render.js +56 -0
  1048. package/dist/ui/render.js.map +1 -0
  1049. package/dist/ui/tool-formatters.d.ts +30 -0
  1050. package/dist/ui/tool-formatters.d.ts.map +1 -0
  1051. package/dist/ui/tool-formatters.js +461 -0
  1052. package/dist/ui/tool-formatters.js.map +1 -0
  1053. package/dist/ui/tool-formatters.test.d.ts +2 -0
  1054. package/dist/ui/tool-formatters.test.d.ts.map +1 -0
  1055. package/dist/ui/tool-formatters.test.js +143 -0
  1056. package/dist/ui/tool-formatters.test.js.map +1 -0
  1057. package/package.json +51 -0
@@ -0,0 +1,1061 @@
1
+ /**
2
+ * Embedded Python source for the Resolve bridge. Written to a temp file at
3
+ * first launch and spawned with python3.
4
+ *
5
+ * Protocol: one JSON object per stdin line (request), one JSON object per
6
+ * stdout line (response). All Resolve API access is wrapped in try/except so
7
+ * a single failed call cannot kill the bridge.
8
+ *
9
+ * Request: {"id": "1", "method": "get_timeline", "params": {}}
10
+ * Response: {"id": "1", "ok": true, "result": {...}}
11
+ * {"id": "1", "ok": false, "error": "..."}
12
+ *
13
+ * The bridge keeps the resolve / project / timeline references fresh by
14
+ * re-fetching them per call (cheap, and handles the user switching projects).
15
+ */
16
+ export const BRIDGE_PY = String.raw `#!/usr/bin/env python3
17
+ import json
18
+ import os
19
+ import sys
20
+ import traceback
21
+
22
+ # Resolve loads its scripting module from a non-standard path. The TS wrapper
23
+ # guarantees PYTHONPATH already contains the right Modules dir, but we double-
24
+ # check here so the error is clear if not.
25
+ try:
26
+ import DaVinciResolveScript as dvr # type: ignore
27
+ except ModuleNotFoundError as e:
28
+ sys.stdout.write(json.dumps({
29
+ "id": "_bootstrap",
30
+ "ok": False,
31
+ "error": "DaVinciResolveScript not importable. Set RESOLVE_SCRIPT_API and PYTHONPATH. " + str(e),
32
+ }) + "\n")
33
+ sys.stdout.flush()
34
+ sys.exit(2)
35
+
36
+
37
+ def get_resolve():
38
+ r = dvr.scriptapp("Resolve")
39
+ if r is None:
40
+ raise RuntimeError("Could not connect to Resolve. Is the app running and is external scripting enabled in Preferences?")
41
+ return r
42
+
43
+
44
+ def get_project():
45
+ r = get_resolve()
46
+ pm = r.GetProjectManager()
47
+ p = pm.GetCurrentProject()
48
+ if p is None:
49
+ raise RuntimeError("No project open in Resolve.")
50
+ return p
51
+
52
+
53
+ def get_timeline_obj():
54
+ p = get_project()
55
+ t = p.GetCurrentTimeline()
56
+ if t is None:
57
+ raise RuntimeError("No timeline open in Resolve.")
58
+ return t
59
+
60
+
61
+ # ── Helpers ─────────────────────────────────────────────────
62
+
63
+
64
+ def _find_timeline_item(clip_id):
65
+ t = get_timeline_obj()
66
+ cid = str(clip_id)
67
+ for kind in ("video", "audio"):
68
+ try:
69
+ count = int(t.GetTrackCount(kind))
70
+ except Exception:
71
+ count = 0
72
+ for ti in range(1, count + 1):
73
+ for item in (t.GetItemListInTrack(kind, ti) or []):
74
+ try:
75
+ iid = str(item.GetUniqueId()) if hasattr(item, "GetUniqueId") else item.GetName()
76
+ except Exception:
77
+ iid = None
78
+ if iid == cid:
79
+ return item
80
+ raise RuntimeError(f"clip not found on timeline: {clip_id}")
81
+
82
+
83
+ # ── Method implementations ──────────────────────────────────
84
+
85
+ def m_ping(_params):
86
+ r = get_resolve()
87
+ return {"pong": True, "product": r.GetProductName(), "version": r.GetVersionString()}
88
+
89
+
90
+ def m_get_timeline(_params):
91
+ t = get_timeline_obj()
92
+ fr = float(t.GetSetting("timelineFrameRate") or 24.0)
93
+ start_frame = int(t.GetStartFrame())
94
+ end_frame = int(t.GetEndFrame())
95
+
96
+ clips = []
97
+ for kind in ("video", "audio"):
98
+ try:
99
+ count = int(t.GetTrackCount(kind))
100
+ except Exception:
101
+ count = 0
102
+ for ti in range(1, count + 1):
103
+ items = t.GetItemListInTrack(kind, ti) or []
104
+ for item in items:
105
+ try:
106
+ clips.append({
107
+ "id": str(item.GetUniqueId()) if hasattr(item, "GetUniqueId") else item.GetName(),
108
+ "track": ti,
109
+ "trackKind": kind,
110
+ "startFrame": int(item.GetStart()) - start_frame,
111
+ "endFrame": int(item.GetEnd()) - start_frame,
112
+ "name": item.GetName(),
113
+ })
114
+ except Exception:
115
+ # Skip clips we can't introspect (compound/timeline items)
116
+ pass
117
+
118
+ markers_dict = t.GetMarkers() or {}
119
+ markers = []
120
+ for frame_id, info in markers_dict.items():
121
+ markers.append({
122
+ "frame": int(frame_id),
123
+ "note": info.get("note", "") or info.get("name", ""),
124
+ "color": info.get("color"),
125
+ "durationFrames": int(info.get("duration", 1)),
126
+ })
127
+
128
+ return {
129
+ "name": t.GetName(),
130
+ "frameRate": fr,
131
+ "durationFrames": end_frame - start_frame,
132
+ "clips": clips,
133
+ "markers": markers,
134
+ }
135
+
136
+
137
+ def m_add_marker(params):
138
+ t = get_timeline_obj()
139
+ frame = int(params["frame"])
140
+ note = str(params.get("note", ""))
141
+ color = str(params.get("color", "Blue")).capitalize()
142
+ duration = int(params.get("durationFrames", 1) or 1)
143
+ # Resolve marker color names: Blue, Cyan, Green, Yellow, Red, Pink, Purple,
144
+ # Fuchsia, Rose, Lavender, Sky, Mint, Lemon, Sand, Cocoa, Cream
145
+ ok = t.AddMarker(frame, color, note[:60], note, duration, "")
146
+ if not ok:
147
+ raise RuntimeError("AddMarker returned False (frame may already have a marker, or be out of range).")
148
+ return None
149
+
150
+
151
+ def m_append_clip(params):
152
+ project = get_project()
153
+ media_pool = project.GetMediaPool()
154
+ media_path = params["mediaPath"]
155
+ track = int(params.get("track", 1))
156
+
157
+ # Import the file into the media pool first.
158
+ media_storage = get_resolve().GetMediaStorage()
159
+ items = media_storage.AddItemListToMediaPool([media_path]) or []
160
+ if not items:
161
+ raise RuntimeError(f"Failed to import {media_path} into the media pool.")
162
+
163
+ # AppendToTimeline appends to the end of whatever the current timeline is.
164
+ # Track index is honoured for audio-only / video-only items; for AV items
165
+ # the audio component goes to A1 by default.
166
+ appended = media_pool.AppendToTimeline(items) or []
167
+ if not appended:
168
+ raise RuntimeError("AppendToTimeline returned no items.")
169
+
170
+ item = appended[0]
171
+ t = get_timeline_obj()
172
+ start_frame = int(t.GetStartFrame())
173
+ return {
174
+ "id": str(item.GetUniqueId()) if hasattr(item, "GetUniqueId") else item.GetName(),
175
+ "track": track,
176
+ "trackKind": "video",
177
+ "startFrame": int(item.GetStart()) - start_frame,
178
+ "endFrame": int(item.GetEnd()) - start_frame,
179
+ "name": item.GetName(),
180
+ }
181
+
182
+
183
+ def m_import_timeline(params):
184
+ project = get_project()
185
+ media_pool = project.GetMediaPool()
186
+ file_path = params["filePath"]
187
+ timeline = media_pool.ImportTimelineFromFile(file_path, {})
188
+ if timeline is None:
189
+ raise RuntimeError(f"ImportTimelineFromFile returned None for {file_path}.")
190
+ return {"name": timeline.GetName()}
191
+
192
+
193
+ def m_render(params):
194
+ project = get_project()
195
+ preset = params["preset"]
196
+ output_path = params["output"]
197
+
198
+ if not project.LoadRenderPreset(preset):
199
+ # Try as a built-in preset key. List available so the agent can recover.
200
+ available = project.GetRenderPresetList() or []
201
+ raise RuntimeError(f"Render preset not found: {preset}. Available: {available[:10]}")
202
+
203
+ out_dir = os.path.dirname(output_path) or "."
204
+ out_file = os.path.basename(output_path)
205
+ project.SetRenderSettings({
206
+ "TargetDir": out_dir,
207
+ "CustomName": os.path.splitext(out_file)[0],
208
+ })
209
+
210
+ job_id = project.AddRenderJob()
211
+ if not job_id:
212
+ raise RuntimeError("AddRenderJob failed.")
213
+ project.StartRendering([job_id], False)
214
+
215
+ # Block until done.
216
+ import time
217
+ while project.IsRenderingInProgress():
218
+ time.sleep(0.5)
219
+
220
+ return {"jobId": job_id, "output": output_path}
221
+
222
+
223
+ def m_get_markers(_params):
224
+ t = get_timeline_obj()
225
+ markers_dict = t.GetMarkers() or {}
226
+ out = []
227
+ for frame_id, info in markers_dict.items():
228
+ out.append({
229
+ "frame": int(frame_id),
230
+ "note": info.get("note", "") or info.get("name", ""),
231
+ "color": info.get("color"),
232
+ "durationFrames": int(info.get("duration", 1)),
233
+ })
234
+ return out
235
+
236
+
237
+ def m_create_timeline(params):
238
+ project = get_project()
239
+ media_pool = project.GetMediaPool()
240
+ name = str(params["name"])
241
+ fps = params.get("fps")
242
+ width = params.get("width")
243
+ height = params.get("height")
244
+
245
+ # Project-level frame rate must be set BEFORE creating the timeline; once a
246
+ # project has timelines, the frame rate becomes locked. We try, and if it
247
+ # fails because timelines exist, the new timeline will inherit project fps.
248
+ if fps is not None:
249
+ try:
250
+ project.SetSetting("timelineFrameRate", str(float(fps)))
251
+ except Exception:
252
+ pass
253
+
254
+ timeline = media_pool.CreateEmptyTimeline(name)
255
+ if timeline is None:
256
+ raise RuntimeError("CreateEmptyTimeline returned None.")
257
+
258
+ if width is not None:
259
+ try:
260
+ timeline.SetSetting("useCustomSettings", "1")
261
+ timeline.SetSetting("timelineResolutionWidth", str(int(width)))
262
+ except Exception:
263
+ pass
264
+ if height is not None:
265
+ try:
266
+ timeline.SetSetting("timelineResolutionHeight", str(int(height)))
267
+ except Exception:
268
+ pass
269
+
270
+ return {"name": timeline.GetName()}
271
+
272
+
273
+ def m_import_to_media_pool(params):
274
+ project = get_project()
275
+ media_pool = project.GetMediaPool()
276
+ paths = list(params.get("paths") or [])
277
+ bin_name = params.get("bin")
278
+
279
+ if bin_name:
280
+ # Walk top-level bins for a name match; create if absent.
281
+ root = media_pool.GetRootFolder()
282
+ target = None
283
+ for sub in root.GetSubFolderList() or []:
284
+ if sub.GetName() == bin_name:
285
+ target = sub
286
+ break
287
+ if target is None:
288
+ target = media_pool.AddSubFolder(root, bin_name)
289
+ if target is not None:
290
+ media_pool.SetCurrentFolder(target)
291
+
292
+ media_storage = get_resolve().GetMediaStorage()
293
+ items = media_storage.AddItemListToMediaPool(paths) or []
294
+ return {"imported": len(items)}
295
+
296
+
297
+ def m_open_page(params):
298
+ r = get_resolve()
299
+ name = str(params["name"]).lower()
300
+ valid = {"media", "cut", "edit", "fusion", "color", "fairlight", "deliver"}
301
+ if name not in valid:
302
+ raise RuntimeError(f"unknown page: {name}; valid: {sorted(valid)}")
303
+ ok = r.OpenPage(name)
304
+ if not ok:
305
+ raise RuntimeError(f"OpenPage('{name}') returned False.")
306
+ return None
307
+
308
+
309
+ def m_set_clip_speed(params):
310
+ clip_id = str(params["clipId"])
311
+ speed = float(params["speed"])
312
+ if speed <= 0:
313
+ raise RuntimeError("speed must be > 0")
314
+ found = _find_timeline_item(clip_id)
315
+
316
+ last_err = None
317
+ # Try several APIs; Resolve versions differ.
318
+ for setter in (
319
+ lambda i: i.SetClipProperty("Speed", str(speed * 100.0)),
320
+ lambda i: i.SetProperty("Speed", speed),
321
+ lambda i: i.SetClipProperty("Speed", speed),
322
+ ):
323
+ try:
324
+ ok = setter(found)
325
+ if ok:
326
+ return {"clipId": clip_id, "speed": speed}
327
+ except Exception as e:
328
+ last_err = e
329
+ raise RuntimeError(
330
+ f"Resolve refused all clip-speed setters for this version. Last error: {last_err}. "
331
+ f"fix: rebuild via FCPXML with explicit timeMap."
332
+ )
333
+
334
+
335
+ def m_apply_lut(params):
336
+ import os as _os
337
+ clip_id = str(params["clipId"])
338
+ lut_path = str(params["lutPath"])
339
+ node_index = int(params.get("nodeIndex", 1) or 1)
340
+ if not _os.path.exists(lut_path):
341
+ raise RuntimeError(f"LUT file not found: {lut_path}")
342
+ item = _find_timeline_item(clip_id)
343
+ if not hasattr(item, "SetLUT"):
344
+ raise RuntimeError("this Resolve version's TimelineItem has no SetLUT")
345
+ ok = item.SetLUT(node_index, lut_path)
346
+ if not ok:
347
+ raise RuntimeError(
348
+ f"SetLUT returned False (node {node_index}, lut {lut_path}). "
349
+ f"fix: ensure node {node_index} exists; node 1 always does."
350
+ )
351
+ return {"clipId": clip_id, "lutPath": lut_path, "nodeIndex": node_index}
352
+
353
+
354
+ def _fmt3(triple):
355
+ return "%g %g %g" % (float(triple[0]), float(triple[1]), float(triple[2]))
356
+
357
+
358
+ def _ensure_color_page():
359
+ """Best-effort switch to the Color page when the current page isn't already
360
+ color. Returns True if we issued an OpenPage call, False otherwise. Used by
361
+ SetCDL / CopyGrades retry logic — those API calls silently no-op on the
362
+ wrong page even though the values land in the data model.
363
+ """
364
+ try:
365
+ r = get_resolve()
366
+ cur = r.GetCurrentPage() if hasattr(r, "GetCurrentPage") else None
367
+ if cur == "color":
368
+ return False
369
+ r.OpenPage("color")
370
+ return True
371
+ except Exception:
372
+ return False
373
+
374
+
375
+ def m_set_primary_correction(params):
376
+ clip_id = str(params["clipId"])
377
+ node_index = int(params.get("nodeIndex", 1) or 1)
378
+ item = _find_timeline_item(clip_id)
379
+ if not hasattr(item, "SetCDL"):
380
+ raise RuntimeError("this Resolve version's TimelineItem has no SetCDL")
381
+ cdl = {"NodeIndex": node_index}
382
+ if params.get("slope") is not None:
383
+ cdl["Slope"] = _fmt3(params["slope"])
384
+ if params.get("offset") is not None:
385
+ cdl["Offset"] = _fmt3(params["offset"])
386
+ if params.get("power") is not None:
387
+ cdl["Power"] = _fmt3(params["power"])
388
+ if params.get("saturation") is not None:
389
+ cdl["Saturation"] = "%g" % float(params["saturation"])
390
+ ok = item.SetCDL(cdl)
391
+ if not ok:
392
+ # Common cause: agent set CDL while user was on another page. Auto-
393
+ # switch to Color and retry once. If it fails again, the user/clip is
394
+ # genuinely the problem — surface the original message.
395
+ if _ensure_color_page():
396
+ ok = item.SetCDL(cdl)
397
+ if not ok:
398
+ raise RuntimeError(
399
+ f"SetCDL returned False for node {node_index}. "
400
+ f"fix: ensure the clip exists and the project's color page is reachable."
401
+ )
402
+ return {"clipId": clip_id, "nodeIndex": node_index}
403
+
404
+
405
+ def m_copy_grade(params):
406
+ source_id = str(params["sourceClipId"])
407
+ target_ids = [str(x) for x in (params.get("targetClipIds") or [])]
408
+ if not target_ids:
409
+ raise RuntimeError("targetClipIds must be a non-empty list")
410
+ src = _find_timeline_item(source_id)
411
+ targets = [_find_timeline_item(tid) for tid in target_ids]
412
+ if not hasattr(src, "CopyGrades"):
413
+ raise RuntimeError("this Resolve version's TimelineItem has no CopyGrades")
414
+ ok = src.CopyGrades(targets)
415
+ if not ok:
416
+ if _ensure_color_page():
417
+ ok = src.CopyGrades(targets)
418
+ if not ok:
419
+ raise RuntimeError(
420
+ "CopyGrades returned False. fix: ensure source + targets are valid timeline items."
421
+ )
422
+ return {"sourceClipId": source_id, "copied": len(targets)}
423
+
424
+
425
+ def m_list_render_presets(_params):
426
+ project = get_project()
427
+ presets = project.GetRenderPresetList() or []
428
+ return list(presets)
429
+
430
+
431
+ def m_replace_clip(params):
432
+ clip_id = str(params["clipId"])
433
+ media_path = str(params["mediaPath"])
434
+ item = _find_timeline_item(clip_id)
435
+ # Newer Resolve API: TimelineItem.ReplaceClip(media_path) or .ReplaceMedia.
436
+ last_err = None
437
+ for setter in (
438
+ lambda i: i.ReplaceClip(media_path) if hasattr(i, "ReplaceClip") else False,
439
+ lambda i: i.ReplaceMedia(media_path) if hasattr(i, "ReplaceMedia") else False,
440
+ ):
441
+ try:
442
+ ok = setter(item)
443
+ if ok:
444
+ return {"clipId": clip_id, "mediaPath": media_path}
445
+ except Exception as e:
446
+ last_err = e
447
+ raise RuntimeError(
448
+ f"replace_clip not supported by this Resolve version. Last error: {last_err}. "
449
+ f"fix: rebuild the segment via FCPXML with the new media reference."
450
+ )
451
+
452
+
453
+ def m_add_track(params):
454
+ t = get_timeline_obj()
455
+ kind = str(params.get("kind", "video"))
456
+ if kind not in ("video", "audio", "subtitle"):
457
+ raise RuntimeError(f"unknown track kind: {kind}")
458
+ if not hasattr(t, "AddTrack"):
459
+ raise RuntimeError("this Resolve version's Timeline has no AddTrack")
460
+ ok = t.AddTrack(kind)
461
+ if not ok:
462
+ raise RuntimeError(f"AddTrack({kind}) returned False")
463
+ try:
464
+ new_count = int(t.GetTrackCount(kind))
465
+ except Exception:
466
+ new_count = 0
467
+ return {"kind": kind, "track": new_count}
468
+
469
+
470
+ def m_set_clip_volume(params):
471
+ clip_id = str(params["clipId"])
472
+ volume_db = float(params["volumeDb"])
473
+ item = _find_timeline_item(clip_id)
474
+ # Resolve audio clips expose Volume as a clip property in dB. Some versions
475
+ # accept dB directly; older versions need linear (10**(dB/20)). Try both.
476
+ last_err = None
477
+ for setter in (
478
+ lambda i: i.SetClipProperty("Volume", str(volume_db)),
479
+ lambda i: i.SetClipProperty("Volume", volume_db),
480
+ lambda i: i.SetClipProperty("Volume", str(10 ** (volume_db / 20.0))),
481
+ ):
482
+ try:
483
+ ok = setter(item)
484
+ if ok:
485
+ return {"clipId": clip_id, "volumeDb": volume_db}
486
+ except Exception as e:
487
+ last_err = e
488
+ raise RuntimeError(
489
+ f"Resolve refused all volume setters. Last error: {last_err}. "
490
+ f"fix: adjust volume manually on the Fairlight page."
491
+ )
492
+
493
+
494
+ def m_clone_timeline(params):
495
+ project = get_project()
496
+ pm = get_resolve().GetProjectManager()
497
+ src = project.GetCurrentTimeline()
498
+ if src is None:
499
+ raise RuntimeError("No active timeline to clone.")
500
+ new_name = str(params["newName"])
501
+ # Resolve API: TimelineItem dup is via Timeline.DuplicateTimeline(name).
502
+ if not hasattr(src, "DuplicateTimeline"):
503
+ raise RuntimeError("this Resolve version's Timeline has no DuplicateTimeline")
504
+ new_tl = src.DuplicateTimeline(new_name)
505
+ if new_tl is None:
506
+ raise RuntimeError("DuplicateTimeline returned None")
507
+ project.SetCurrentTimeline(new_tl)
508
+ pm.SaveProject()
509
+ return {"name": new_tl.GetName()}
510
+
511
+
512
+ def m_save_project(_params):
513
+ pm = get_resolve().GetProjectManager()
514
+ ok = pm.SaveProject()
515
+ if not ok:
516
+ raise RuntimeError("SaveProject returned False")
517
+ return None
518
+
519
+
520
+ def m_insert_clip_on_track(params):
521
+ project = get_project()
522
+ media_pool = project.GetMediaPool()
523
+ media_path = str(params["mediaPath"])
524
+ track = int(params.get("track", 2))
525
+ record_frame = int(params["recordFrame"])
526
+
527
+ # Import media into the pool first.
528
+ media_storage = get_resolve().GetMediaStorage()
529
+ items = media_storage.AddItemListToMediaPool([media_path]) or []
530
+ if not items:
531
+ raise RuntimeError(f"failed to import {media_path} into media pool")
532
+ item = items[0]
533
+
534
+ # mediaKind selects video (1) or audio (2) timeline track. AppendToTimeline
535
+ # uses this to know which track family to operate on — critical for
536
+ # SFX/foley insertion onto Fairlight tracks (audio_only=2).
537
+ media_kind = str(params.get("mediaKind", "video")).lower()
538
+ media_type = 2 if media_kind == "audio" else 1
539
+ clip_info = {
540
+ "mediaPoolItem": item,
541
+ "mediaType": media_type,
542
+ "trackIndex": track,
543
+ "recordFrame": record_frame,
544
+ }
545
+ if params.get("sourceInFrame") is not None:
546
+ clip_info["startFrame"] = int(params["sourceInFrame"])
547
+ if params.get("sourceOutFrame") is not None:
548
+ clip_info["endFrame"] = int(params["sourceOutFrame"])
549
+
550
+ appended = media_pool.AppendToTimeline([clip_info]) or []
551
+ if not appended:
552
+ raise RuntimeError(
553
+ "AppendToTimeline returned no items; verify track index exists and recordFrame is within the timeline."
554
+ )
555
+ inserted = appended[0]
556
+ t = get_timeline_obj()
557
+ start_offset = int(t.GetStartFrame())
558
+ return {
559
+ "id": str(inserted.GetUniqueId()) if hasattr(inserted, "GetUniqueId") else inserted.GetName(),
560
+ "track": track,
561
+ "trackKind": "video",
562
+ "startFrame": int(inserted.GetStart()) - start_offset,
563
+ "endFrame": int(inserted.GetEnd()) - start_offset,
564
+ "name": inserted.GetName(),
565
+ }
566
+
567
+
568
+ def m_smart_reframe(params):
569
+ clip_id = str(params["clipId"])
570
+ aspect = str(params["aspect"])
571
+ frame_interest = str(params.get("frameInterest", "all"))
572
+ reference_frame = params.get("referenceFrame")
573
+ item = _find_timeline_item(clip_id)
574
+ if not hasattr(item, "SmartReframe"):
575
+ raise RuntimeError(
576
+ "this Resolve version's TimelineItem has no SmartReframe (Studio-only feature)"
577
+ )
578
+ # SmartReframe signature varies; pass aspect always, then optional kwargs.
579
+ try:
580
+ if reference_frame is not None and frame_interest == "reference-frame":
581
+ ok = item.SmartReframe(aspect, frame_interest, int(reference_frame))
582
+ else:
583
+ ok = item.SmartReframe(aspect, frame_interest)
584
+ except TypeError:
585
+ ok = item.SmartReframe(aspect)
586
+ if not ok:
587
+ raise RuntimeError(
588
+ "SmartReframe returned False. fix: ensure Resolve Studio (free version lacks AI), and the clip is on the active timeline."
589
+ )
590
+ return {"clipId": clip_id, "aspect": aspect}
591
+
592
+
593
+ def m_import_subtitles(params):
594
+ project = get_project()
595
+ media_pool = project.GetMediaPool()
596
+ srt_path = params["srtPath"]
597
+
598
+ items = media_pool.ImportMedia([srt_path]) or []
599
+ if not items:
600
+ raise RuntimeError(
601
+ f"ImportMedia returned no items for {srt_path}. fix: import the SRT manually via File > Import Subtitle."
602
+ )
603
+
604
+ t = get_timeline_obj()
605
+ # Make sure at least one subtitle track exists.
606
+ try:
607
+ sub_count = int(t.GetTrackCount("subtitle"))
608
+ except Exception:
609
+ sub_count = 0
610
+ if sub_count < 1:
611
+ try:
612
+ t.AddTrack("subtitle")
613
+ except Exception:
614
+ pass
615
+
616
+ # Anchor the SRT at the timeline's start. AppendToTimeline(items) without
617
+ # a clip-info dict appends to the END of existing content on the chosen
618
+ # track — so if the subtitle track already has clips, OR Resolve picks the
619
+ # video track's tail, the SRT's 0s cue lands at frame N>0 and every cue
620
+ # past (timelineLength - N) seconds falls past the end of the video and
621
+ # never renders. Forcing recordFrame=GetStartFrame() pins the SRT to the
622
+ # start so its internal timecodes line up with the video.
623
+ start_frame = int(t.GetStartFrame())
624
+ clip_info = {
625
+ "mediaPoolItem": items[0],
626
+ "recordFrame": start_frame,
627
+ }
628
+ appended = media_pool.AppendToTimeline([clip_info]) or []
629
+ if not appended:
630
+ # Fallback to the legacy raw-items form. Some Resolve builds reject the
631
+ # dict form for subtitle media — if so, the user gets the same
632
+ # end-append behaviour as before but at least the SRT lands somewhere.
633
+ appended = media_pool.AppendToTimeline(items) or []
634
+ if not appended:
635
+ return {
636
+ "imported": True,
637
+ "attached": False,
638
+ "note": "SRT imported to media pool but auto-attach failed; drag onto subtitle track manually.",
639
+ }
640
+ return {
641
+ "imported": True,
642
+ "attached": True,
643
+ "note": "SRT attached at end of timeline (Resolve rejected recordFrame=0). Move the subtitle clip back to frame 0 manually if cues appear past the video end.",
644
+ }
645
+ return {"imported": True, "attached": True}
646
+
647
+
648
+ # ── Fusion ──────────────────────────────────────────────────
649
+ #
650
+ # Fusion compositions live either at the timeline-clip level (every
651
+ # TimelineItem can carry one or more 'Fusion comps') OR at the project level
652
+ # via the standalone Fusion page. The agent operates on whichever the user
653
+ # is currently focused on — we resolve the comp once per call:
654
+ #
655
+ # - clipId given: item.GetFusionCompByIndex(1) on that timeline item.
656
+ # - no clipId: fusion.GetCurrentComp() on the active Fusion page.
657
+ #
658
+ # We deliberately keep the surface narrow (8 actions, the Fusion-page tools
659
+ # every short-form workflow needs) instead of mirroring the entire Fusion
660
+ # Python API. Power users have m_execute_code for the rest.
661
+
662
+
663
+ def _resolve_fusion_comp(clip_id):
664
+ if clip_id:
665
+ item = _find_timeline_item(clip_id)
666
+ if not hasattr(item, "GetFusionCompCount") or not hasattr(item, "GetFusionCompByIndex"):
667
+ raise RuntimeError("this Resolve version's TimelineItem has no Fusion comp accessors")
668
+ count = int(item.GetFusionCompCount() or 0)
669
+ if count < 1:
670
+ # Try to add one. Modern Resolve exposes AddFusionComp; older
671
+ # builds need the user to do it manually on the Fusion page.
672
+ if hasattr(item, "AddFusionComp"):
673
+ comp = item.AddFusionComp()
674
+ if comp is None:
675
+ raise RuntimeError(f"AddFusionComp returned None for clip {clip_id}")
676
+ return comp
677
+ raise RuntimeError(
678
+ f"clip {clip_id} has no Fusion comp; create one in Resolve (right-click → New Fusion Composition) first."
679
+ )
680
+ comp = item.GetFusionCompByIndex(1)
681
+ if comp is None:
682
+ raise RuntimeError(f"GetFusionCompByIndex(1) returned None for clip {clip_id}")
683
+ return comp
684
+ # No clip — use the active Fusion page comp.
685
+ r = get_resolve()
686
+ try:
687
+ fusion = r.Fusion()
688
+ except Exception as e:
689
+ raise RuntimeError(f"Resolve.Fusion() unavailable: {e}")
690
+ if fusion is None:
691
+ raise RuntimeError("Fusion is not available in this Resolve build")
692
+ comp = fusion.GetCurrentComp() if hasattr(fusion, "GetCurrentComp") else None
693
+ if comp is None:
694
+ raise RuntimeError(
695
+ "No active Fusion comp. fix: switch to the Fusion page (open_page('fusion')) on a clip with a comp, or pass clipId."
696
+ )
697
+ return comp
698
+
699
+
700
+ def _fusion_node_summary(node):
701
+ # Best-effort, never throws — the caller is reading a list of nodes.
702
+ try:
703
+ name = node.GetAttrs("TOOLS_Name") if hasattr(node, "GetAttrs") else None
704
+ except Exception:
705
+ name = None
706
+ try:
707
+ toolid = node.GetAttrs("TOOLS_RegID") if hasattr(node, "GetAttrs") else None
708
+ except Exception:
709
+ toolid = None
710
+ if not name and hasattr(node, "Name"):
711
+ try:
712
+ name = node.Name
713
+ except Exception:
714
+ pass
715
+ if not toolid and hasattr(node, "ID"):
716
+ try:
717
+ toolid = node.ID
718
+ except Exception:
719
+ pass
720
+ return {"name": name, "toolId": toolid}
721
+
722
+
723
+ def m_fusion_comp(params):
724
+ action = str(params.get("action") or "")
725
+ if not action:
726
+ raise RuntimeError("fusion_comp requires an 'action' field")
727
+ clip_id = params.get("clipId")
728
+ comp = _resolve_fusion_comp(str(clip_id) if clip_id else None)
729
+
730
+ if action == "list_nodes":
731
+ nodes = []
732
+ try:
733
+ tool_list = comp.GetToolList(False) or {}
734
+ except Exception as e:
735
+ raise RuntimeError(f"GetToolList failed: {e}")
736
+ # GetToolList returns a 1-indexed dict on some builds; iterate values.
737
+ try:
738
+ iterator = tool_list.values() if hasattr(tool_list, "values") else list(tool_list)
739
+ except Exception:
740
+ iterator = []
741
+ for node in iterator:
742
+ nodes.append(_fusion_node_summary(node))
743
+ return {"nodes": nodes, "count": len(nodes)}
744
+
745
+ if action == "add_node":
746
+ tool_id = str(params.get("toolId") or "")
747
+ if not tool_id:
748
+ raise RuntimeError("add_node requires 'toolId' (e.g. 'TextPlus', 'Background', 'Merge')")
749
+ if not hasattr(comp, "AddTool"):
750
+ raise RuntimeError("this Resolve build's Comp has no AddTool")
751
+ node = comp.AddTool(tool_id)
752
+ if node is None:
753
+ raise RuntimeError(f"AddTool('{tool_id}') returned None; verify the tool ID exists")
754
+ wanted_name = params.get("name")
755
+ if wanted_name and hasattr(node, "SetAttrs"):
756
+ try:
757
+ node.SetAttrs({"TOOLS_Name": str(wanted_name)})
758
+ except Exception:
759
+ pass
760
+ return _fusion_node_summary(node)
761
+
762
+ if action == "delete_node":
763
+ name = str(params.get("name") or "")
764
+ if not name:
765
+ raise RuntimeError("delete_node requires 'name'")
766
+ node = comp.FindTool(name) if hasattr(comp, "FindTool") else None
767
+ if node is None:
768
+ raise RuntimeError(f"node not found: {name}")
769
+ if not hasattr(node, "Delete"):
770
+ raise RuntimeError("this Resolve build's Tool has no Delete")
771
+ node.Delete()
772
+ return {"deleted": name}
773
+
774
+ if action == "connect":
775
+ from_name = str(params.get("fromNode") or "")
776
+ to_name = str(params.get("toNode") or "")
777
+ from_output = str(params.get("fromOutput") or "Output")
778
+ to_input = str(params.get("toInput") or "Input")
779
+ if not from_name or not to_name:
780
+ raise RuntimeError("connect requires 'fromNode' and 'toNode'")
781
+ a = comp.FindTool(from_name)
782
+ b = comp.FindTool(to_name)
783
+ if a is None or b is None:
784
+ raise RuntimeError(f"node not found (from={from_name}, to={to_name})")
785
+ try:
786
+ out = a.FindMainOutput(1) if from_output == "Output" else getattr(a, from_output, None)
787
+ except Exception:
788
+ out = None
789
+ if out is None:
790
+ raise RuntimeError(f"output '{from_output}' not found on {from_name}")
791
+ try:
792
+ inp = getattr(b, to_input, None)
793
+ if inp is None and hasattr(b, "FindMainInput"):
794
+ inp = b.FindMainInput(1)
795
+ except Exception:
796
+ inp = None
797
+ if inp is None:
798
+ raise RuntimeError(f"input '{to_input}' not found on {to_name}")
799
+ try:
800
+ inp.ConnectTo(out)
801
+ except Exception as e:
802
+ raise RuntimeError(f"ConnectTo failed: {e}")
803
+ return {"from": from_name, "to": to_name}
804
+
805
+ if action == "set_input":
806
+ name = str(params.get("node") or "")
807
+ input_name = str(params.get("input") or "")
808
+ if not name or not input_name:
809
+ raise RuntimeError("set_input requires 'node' and 'input'")
810
+ if "value" not in params:
811
+ raise RuntimeError("set_input requires 'value'")
812
+ node = comp.FindTool(name)
813
+ if node is None:
814
+ raise RuntimeError(f"node not found: {name}")
815
+ try:
816
+ attr = getattr(node, input_name)
817
+ except Exception:
818
+ raise RuntimeError(f"input '{input_name}' not found on {name}")
819
+ try:
820
+ # Fusion inputs accept assignment directly: node.Input = value.
821
+ setattr(node, input_name, params["value"])
822
+ except Exception as e:
823
+ raise RuntimeError(f"set_input failed: {e}")
824
+ return {"node": name, "input": input_name}
825
+
826
+ if action == "get_input":
827
+ name = str(params.get("node") or "")
828
+ input_name = str(params.get("input") or "")
829
+ if not name or not input_name:
830
+ raise RuntimeError("get_input requires 'node' and 'input'")
831
+ node = comp.FindTool(name)
832
+ if node is None:
833
+ raise RuntimeError(f"node not found: {name}")
834
+ try:
835
+ attr = getattr(node, input_name)
836
+ except Exception:
837
+ raise RuntimeError(f"input '{input_name}' not found on {name}")
838
+ value = None
839
+ try:
840
+ # Fusion inputs are callable for current-value access on some builds.
841
+ value = attr() if callable(attr) else attr
842
+ except Exception:
843
+ value = attr
844
+ try:
845
+ json.dumps(value)
846
+ except Exception:
847
+ value = repr(value)
848
+ return {"node": name, "input": input_name, "value": value}
849
+
850
+ if action == "set_keyframe":
851
+ name = str(params.get("node") or "")
852
+ input_name = str(params.get("input") or "")
853
+ frame = params.get("frame")
854
+ if frame is None or not name or not input_name or "value" not in params:
855
+ raise RuntimeError("set_keyframe requires 'node', 'input', 'frame', 'value'")
856
+ node = comp.FindTool(name)
857
+ if node is None:
858
+ raise RuntimeError(f"node not found: {name}")
859
+ try:
860
+ attr = getattr(node, input_name)
861
+ except Exception:
862
+ raise RuntimeError(f"input '{input_name}' not found on {name}")
863
+ try:
864
+ # Comp.SetKeyFrames is the canonical path; older builds use
865
+ # input.SetKeyFrames or .SetExpression. Try the modern one first.
866
+ ok = comp.SetKeyFrames({attr: {int(frame): params["value"]}})
867
+ except Exception:
868
+ ok = False
869
+ if not ok and hasattr(attr, "SetKeyFrames"):
870
+ try:
871
+ attr.SetKeyFrames({int(frame): params["value"]})
872
+ ok = True
873
+ except Exception:
874
+ ok = False
875
+ if not ok:
876
+ raise RuntimeError("could not set keyframe via Comp.SetKeyFrames or Input.SetKeyFrames")
877
+ return {"node": name, "input": input_name, "frame": int(frame)}
878
+
879
+ if action == "set_render_range":
880
+ start = params.get("start")
881
+ end = params.get("end")
882
+ if start is None or end is None:
883
+ raise RuntimeError("set_render_range requires 'start' and 'end'")
884
+ try:
885
+ comp.SetAttrs({"COMPN_RenderStart": int(start), "COMPN_RenderEnd": int(end)})
886
+ except Exception as e:
887
+ raise RuntimeError(f"SetAttrs failed: {e}")
888
+ return {"start": int(start), "end": int(end)}
889
+
890
+ raise RuntimeError(
891
+ f"unknown fusion_comp action: {action}; valid: list_nodes, add_node, delete_node, connect, set_input, get_input, set_keyframe, set_render_range"
892
+ )
893
+
894
+
895
+ def m_execute_code(params):
896
+ """Escape hatch: run arbitrary user code with the Resolve API pre-bound.
897
+
898
+ Pre-bound globals available to the snippet:
899
+ resolve, project, projectManager, mediaPool, mediaStorage, timeline,
900
+ fusion (lazy — None if Fusion comp is unavailable), dvr (the
901
+ DaVinciResolveScript module itself).
902
+
903
+ Result delivery (in priority order):
904
+ 1. Call set_result(value) — explicit, supports any JSON-serialisable value.
905
+ 2. Assign to a top-level 'result' variable.
906
+ 3. Otherwise: stdout text only.
907
+
908
+ stdout is captured and returned regardless. The snippet runs in the same
909
+ process as every other bridge call, so a crash here CAN take the bridge
910
+ down. We trap exceptions but a segfault in fusionscript.so cannot be caught.
911
+ """
912
+ code = params.get("code")
913
+ if not isinstance(code, str) or not code.strip():
914
+ raise RuntimeError("execute_code requires a non-empty 'code' string.")
915
+
916
+ import io
917
+ import contextlib
918
+
919
+ resolve = get_resolve()
920
+ project_manager = resolve.GetProjectManager()
921
+ project = project_manager.GetCurrentProject() if project_manager else None
922
+ media_pool = project.GetMediaPool() if project else None
923
+ media_storage = resolve.GetMediaStorage()
924
+ try:
925
+ timeline = project.GetCurrentTimeline() if project else None
926
+ except Exception:
927
+ timeline = None
928
+ try:
929
+ fusion = resolve.Fusion()
930
+ except Exception:
931
+ fusion = None
932
+
933
+ # JSON-serialisability check that won't crash on Resolve API objects (which
934
+ # are PyRemoteObject and not JSON-able). Anything non-serialisable is
935
+ # coerced to its repr so the agent at least sees what came back.
936
+ def _safe(value):
937
+ try:
938
+ json.dumps(value)
939
+ return value
940
+ except Exception:
941
+ return repr(value)
942
+
943
+ holder = {"result": None, "set": False}
944
+
945
+ def set_result(value):
946
+ holder["result"] = _safe(value)
947
+ holder["set"] = True
948
+
949
+ g = {
950
+ "__builtins__": __builtins__,
951
+ "resolve": resolve,
952
+ "project": project,
953
+ "projectManager": project_manager,
954
+ "mediaPool": media_pool,
955
+ "mediaStorage": media_storage,
956
+ "timeline": timeline,
957
+ "fusion": fusion,
958
+ "dvr": dvr,
959
+ "set_result": set_result,
960
+ "json": json,
961
+ }
962
+ l = {}
963
+
964
+ buf = io.StringIO()
965
+ with contextlib.redirect_stdout(buf):
966
+ try:
967
+ exec(code, g, l)
968
+ except Exception as ex:
969
+ # Re-raise with the captured stdout attached so the agent gets both
970
+ # the print() output that ran before the crash AND the error.
971
+ stdout = buf.getvalue()
972
+ tail = ("\nstdout: " + stdout[-1500:]) if stdout else ""
973
+ raise RuntimeError(f"{ex.__class__.__name__}: {ex}{tail}") from ex
974
+
975
+ stdout = buf.getvalue()
976
+
977
+ # Result resolution: explicit set_result wins; else top-level 'result'.
978
+ if holder["set"]:
979
+ result_value = holder["result"]
980
+ elif "result" in l:
981
+ result_value = _safe(l["result"])
982
+ else:
983
+ result_value = None
984
+
985
+ out = {"result": result_value}
986
+ if stdout:
987
+ # Cap stdout to keep tool output token-economical.
988
+ if len(stdout) > 4000:
989
+ stdout = stdout[:2000] + "\n…[truncated]…\n" + stdout[-1500:]
990
+ out["stdout"] = stdout
991
+ return out
992
+
993
+
994
+ METHODS = {
995
+ "ping": m_ping,
996
+ "get_timeline": m_get_timeline,
997
+ "add_marker": m_add_marker,
998
+ "append_clip": m_append_clip,
999
+ "import_timeline": m_import_timeline,
1000
+ "render": m_render,
1001
+ "get_markers": m_get_markers,
1002
+ "create_timeline": m_create_timeline,
1003
+ "import_to_media_pool": m_import_to_media_pool,
1004
+ "open_page": m_open_page,
1005
+ "set_clip_speed": m_set_clip_speed,
1006
+ "apply_lut": m_apply_lut,
1007
+ "set_primary_correction": m_set_primary_correction,
1008
+ "copy_grade": m_copy_grade,
1009
+ "list_render_presets": m_list_render_presets,
1010
+ "replace_clip": m_replace_clip,
1011
+ "smart_reframe": m_smart_reframe,
1012
+ "insert_clip_on_track": m_insert_clip_on_track,
1013
+ "clone_timeline": m_clone_timeline,
1014
+ "save_project": m_save_project,
1015
+ "add_track": m_add_track,
1016
+ "set_clip_volume": m_set_clip_volume,
1017
+ "import_subtitles": m_import_subtitles,
1018
+ "fusion_comp": m_fusion_comp,
1019
+ "execute_code": m_execute_code,
1020
+ }
1021
+
1022
+
1023
+ def main():
1024
+ # Signal we're alive.
1025
+ sys.stdout.write(json.dumps({"id": "_ready", "ok": True, "result": {"ready": True}}) + "\n")
1026
+ sys.stdout.flush()
1027
+
1028
+ for line in sys.stdin:
1029
+ line = line.strip()
1030
+ if not line:
1031
+ continue
1032
+ try:
1033
+ req = json.loads(line)
1034
+ except json.JSONDecodeError as e:
1035
+ sys.stdout.write(json.dumps({"id": "_parse", "ok": False, "error": f"bad json: {e}"}) + "\n")
1036
+ sys.stdout.flush()
1037
+ continue
1038
+
1039
+ rid = req.get("id", "?")
1040
+ method = req.get("method", "")
1041
+ params = req.get("params", {}) or {}
1042
+
1043
+ fn = METHODS.get(method)
1044
+ if fn is None:
1045
+ sys.stdout.write(json.dumps({"id": rid, "ok": False, "error": f"unknown method: {method}"}) + "\n")
1046
+ sys.stdout.flush()
1047
+ continue
1048
+
1049
+ try:
1050
+ result = fn(params)
1051
+ sys.stdout.write(json.dumps({"id": rid, "ok": True, "result": result}) + "\n")
1052
+ except Exception as e:
1053
+ tb = traceback.format_exc(limit=2)
1054
+ sys.stdout.write(json.dumps({"id": rid, "ok": False, "error": f"{e.__class__.__name__}: {e}", "trace": tb}) + "\n")
1055
+ sys.stdout.flush()
1056
+
1057
+
1058
+ if __name__ == "__main__":
1059
+ main()
1060
+ `;
1061
+ //# sourceMappingURL=bridge-source.js.map