@kenkaiiii/gg-editor 0.6.7 → 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 (455) hide show
  1. package/dist/cli.js +64 -1
  2. package/dist/cli.js.map +1 -1
  3. package/dist/core/audio-mix.d.ts.map +1 -1
  4. package/dist/core/audio-mix.js +8 -1
  5. package/dist/core/audio-mix.js.map +1 -1
  6. package/dist/core/audio-mix.test.js +1 -1
  7. package/dist/core/audio-mix.test.js.map +1 -1
  8. package/dist/core/auth/api-keys.d.ts +1 -1
  9. package/dist/core/auth/api-keys.d.ts.map +1 -1
  10. package/dist/core/auth/api-keys.js +2 -1
  11. package/dist/core/auth/api-keys.js.map +1 -1
  12. package/dist/core/auth/index.d.ts +18 -5
  13. package/dist/core/auth/index.d.ts.map +1 -1
  14. package/dist/core/auth/index.js +16 -4
  15. package/dist/core/auth/index.js.map +1 -1
  16. package/dist/core/auth/login.d.ts.map +1 -1
  17. package/dist/core/auth/login.js +4 -31
  18. package/dist/core/auth/login.js.map +1 -1
  19. package/dist/core/beats.d.ts +59 -0
  20. package/dist/core/beats.d.ts.map +1 -0
  21. package/dist/core/beats.js +122 -0
  22. package/dist/core/beats.js.map +1 -0
  23. package/dist/core/beats.test.d.ts +2 -0
  24. package/dist/core/beats.test.d.ts.map +1 -0
  25. package/dist/core/beats.test.js +86 -0
  26. package/dist/core/beats.test.js.map +1 -0
  27. package/dist/core/brand-kit.d.ts +80 -0
  28. package/dist/core/brand-kit.d.ts.map +1 -0
  29. package/dist/core/brand-kit.js +96 -0
  30. package/dist/core/brand-kit.js.map +1 -0
  31. package/dist/core/brand-kit.test.d.ts +2 -0
  32. package/dist/core/brand-kit.test.d.ts.map +1 -0
  33. package/dist/core/brand-kit.test.js +76 -0
  34. package/dist/core/brand-kit.test.js.map +1 -0
  35. package/dist/core/bundled-sfx.d.ts +64 -0
  36. package/dist/core/bundled-sfx.d.ts.map +1 -0
  37. package/dist/core/bundled-sfx.js +218 -0
  38. package/dist/core/bundled-sfx.js.map +1 -0
  39. package/dist/core/bundled-sfx.test.d.ts +2 -0
  40. package/dist/core/bundled-sfx.test.d.ts.map +1 -0
  41. package/dist/core/bundled-sfx.test.js +81 -0
  42. package/dist/core/bundled-sfx.test.js.map +1 -0
  43. package/dist/core/child-abort.d.ts +57 -0
  44. package/dist/core/child-abort.d.ts.map +1 -0
  45. package/dist/core/child-abort.js +95 -0
  46. package/dist/core/child-abort.js.map +1 -0
  47. package/dist/core/child-abort.test.d.ts +2 -0
  48. package/dist/core/child-abort.test.d.ts.map +1 -0
  49. package/dist/core/child-abort.test.js +88 -0
  50. package/dist/core/child-abort.test.js.map +1 -0
  51. package/dist/core/clip-scoring.d.ts +44 -0
  52. package/dist/core/clip-scoring.d.ts.map +1 -0
  53. package/dist/core/clip-scoring.js +165 -0
  54. package/dist/core/clip-scoring.js.map +1 -0
  55. package/dist/core/clip-scoring.test.d.ts +2 -0
  56. package/dist/core/clip-scoring.test.d.ts.map +1 -0
  57. package/dist/core/clip-scoring.test.js +113 -0
  58. package/dist/core/clip-scoring.test.js.map +1 -0
  59. package/dist/core/emoji-captions.d.ts +45 -0
  60. package/dist/core/emoji-captions.d.ts.map +1 -0
  61. package/dist/core/emoji-captions.js +121 -0
  62. package/dist/core/emoji-captions.js.map +1 -0
  63. package/dist/core/face-reframe.d.ts +91 -0
  64. package/dist/core/face-reframe.d.ts.map +1 -0
  65. package/dist/core/face-reframe.js +141 -0
  66. package/dist/core/face-reframe.js.map +1 -0
  67. package/dist/core/face-reframe.test.d.ts +2 -0
  68. package/dist/core/face-reframe.test.d.ts.map +1 -0
  69. package/dist/core/face-reframe.test.js +171 -0
  70. package/dist/core/face-reframe.test.js.map +1 -0
  71. package/dist/core/filler-words.d.ts +57 -9
  72. package/dist/core/filler-words.d.ts.map +1 -1
  73. package/dist/core/filler-words.js +61 -9
  74. package/dist/core/filler-words.js.map +1 -1
  75. package/dist/core/filler-words.test.js +91 -17
  76. package/dist/core/filler-words.test.js.map +1 -1
  77. package/dist/core/hook-rewrite.d.ts +48 -0
  78. package/dist/core/hook-rewrite.d.ts.map +1 -0
  79. package/dist/core/hook-rewrite.js +151 -0
  80. package/dist/core/hook-rewrite.js.map +1 -0
  81. package/dist/core/hook-rewrite.test.d.ts +2 -0
  82. package/dist/core/hook-rewrite.test.d.ts.map +1 -0
  83. package/dist/core/hook-rewrite.test.js +58 -0
  84. package/dist/core/hook-rewrite.test.js.map +1 -0
  85. package/dist/core/hosts/lazy.d.ts.map +1 -1
  86. package/dist/core/hosts/lazy.js +2 -0
  87. package/dist/core/hosts/lazy.js.map +1 -1
  88. package/dist/core/hosts/premiere/adapter.d.ts +1 -0
  89. package/dist/core/hosts/premiere/adapter.d.ts.map +1 -1
  90. package/dist/core/hosts/premiere/adapter.js.map +1 -1
  91. package/dist/core/hosts/premiere/bridge-source.d.ts.map +1 -1
  92. package/dist/core/hosts/premiere/bridge-source.js +6 -3
  93. package/dist/core/hosts/premiere/bridge-source.js.map +1 -1
  94. package/dist/core/hosts/resolve/adapter.d.ts +1 -0
  95. package/dist/core/hosts/resolve/adapter.d.ts.map +1 -1
  96. package/dist/core/hosts/resolve/adapter.js.map +1 -1
  97. package/dist/core/hosts/resolve/bridge-source.d.ts.map +1 -1
  98. package/dist/core/hosts/resolve/bridge-source.js +31 -4
  99. package/dist/core/hosts/resolve/bridge-source.js.map +1 -1
  100. package/dist/core/hosts/resolve/bridge.d.ts +2 -19
  101. package/dist/core/hosts/resolve/bridge.d.ts.map +1 -1
  102. package/dist/core/hosts/resolve/bridge.js +70 -41
  103. package/dist/core/hosts/resolve/bridge.js.map +1 -1
  104. package/dist/core/hosts/resolve/bridge.test.js +130 -0
  105. package/dist/core/hosts/resolve/bridge.test.js.map +1 -1
  106. package/dist/core/hosts/types.d.ts +6 -0
  107. package/dist/core/hosts/types.d.ts.map +1 -1
  108. package/dist/core/hosts/types.js.map +1 -1
  109. package/dist/core/logger.d.ts +32 -0
  110. package/dist/core/logger.d.ts.map +1 -0
  111. package/dist/core/logger.js +188 -0
  112. package/dist/core/logger.js.map +1 -0
  113. package/dist/core/loop-match.d.ts +57 -0
  114. package/dist/core/loop-match.d.ts.map +1 -0
  115. package/dist/core/loop-match.js +91 -0
  116. package/dist/core/loop-match.js.map +1 -0
  117. package/dist/core/media/ffmpeg.d.ts.map +1 -1
  118. package/dist/core/media/ffmpeg.js +14 -3
  119. package/dist/core/media/ffmpeg.js.map +1 -1
  120. package/dist/core/multi-format.d.ts +67 -0
  121. package/dist/core/multi-format.d.ts.map +1 -0
  122. package/dist/core/multi-format.js +127 -0
  123. package/dist/core/multi-format.js.map +1 -0
  124. package/dist/core/multi-format.test.d.ts +2 -0
  125. package/dist/core/multi-format.test.d.ts.map +1 -0
  126. package/dist/core/multi-format.test.js +151 -0
  127. package/dist/core/multi-format.test.js.map +1 -0
  128. package/dist/core/python/beats.py +61 -0
  129. package/dist/core/python/face_reframe.py +163 -0
  130. package/dist/core/python/sidecar-path.d.ts +13 -0
  131. package/dist/core/python/sidecar-path.d.ts.map +1 -0
  132. package/dist/core/python/sidecar-path.js +24 -0
  133. package/dist/core/python/sidecar-path.js.map +1 -0
  134. package/dist/core/python.d.ts +57 -0
  135. package/dist/core/python.d.ts.map +1 -0
  136. package/dist/core/python.js +107 -0
  137. package/dist/core/python.js.map +1 -0
  138. package/dist/core/python.test.d.ts +2 -0
  139. package/dist/core/python.test.d.ts.map +1 -0
  140. package/dist/core/python.test.js +129 -0
  141. package/dist/core/python.test.js.map +1 -0
  142. package/dist/core/retention-structure.d.ts +81 -0
  143. package/dist/core/retention-structure.d.ts.map +1 -0
  144. package/dist/core/retention-structure.js +206 -0
  145. package/dist/core/retention-structure.js.map +1 -0
  146. package/dist/core/retention-structure.test.d.ts +2 -0
  147. package/dist/core/retention-structure.test.d.ts.map +1 -0
  148. package/dist/core/retention-structure.test.js +88 -0
  149. package/dist/core/retention-structure.test.js.map +1 -0
  150. package/dist/core/review.d.ts +17 -0
  151. package/dist/core/review.d.ts.map +1 -1
  152. package/dist/core/review.js +20 -24
  153. package/dist/core/review.js.map +1 -1
  154. package/dist/core/safe-paths.d.ts +11 -0
  155. package/dist/core/safe-paths.d.ts.map +1 -1
  156. package/dist/core/safe-paths.js +26 -10
  157. package/dist/core/safe-paths.js.map +1 -1
  158. package/dist/core/safe-paths.test.js +16 -0
  159. package/dist/core/safe-paths.test.js.map +1 -1
  160. package/dist/core/skills-loader.d.ts +48 -2
  161. package/dist/core/skills-loader.d.ts.map +1 -1
  162. package/dist/core/skills-loader.js +97 -19
  163. package/dist/core/skills-loader.js.map +1 -1
  164. package/dist/core/skills-loader.test.js +63 -1
  165. package/dist/core/skills-loader.test.js.map +1 -1
  166. package/dist/core/srt.d.ts +42 -7
  167. package/dist/core/srt.d.ts.map +1 -1
  168. package/dist/core/srt.js +101 -32
  169. package/dist/core/srt.js.map +1 -1
  170. package/dist/core/srt.test.js +54 -1
  171. package/dist/core/srt.test.js.map +1 -1
  172. package/dist/core/thumbnail-compose.d.ts +58 -0
  173. package/dist/core/thumbnail-compose.d.ts.map +1 -0
  174. package/dist/core/thumbnail-compose.js +101 -0
  175. package/dist/core/thumbnail-compose.js.map +1 -0
  176. package/dist/core/thumbnail-promise.d.ts +46 -0
  177. package/dist/core/thumbnail-promise.d.ts.map +1 -0
  178. package/dist/core/thumbnail-promise.js +133 -0
  179. package/dist/core/thumbnail-promise.js.map +1 -0
  180. package/dist/core/thumbnail-promise.test.d.ts +2 -0
  181. package/dist/core/thumbnail-promise.test.d.ts.map +1 -0
  182. package/dist/core/thumbnail-promise.test.js +52 -0
  183. package/dist/core/thumbnail-promise.test.js.map +1 -0
  184. package/dist/core/viral-moments.d.ts +70 -0
  185. package/dist/core/viral-moments.d.ts.map +1 -0
  186. package/dist/core/viral-moments.js +192 -0
  187. package/dist/core/viral-moments.js.map +1 -0
  188. package/dist/core/viral-moments.test.d.ts +2 -0
  189. package/dist/core/viral-moments.test.d.ts.map +1 -0
  190. package/dist/core/viral-moments.test.js +153 -0
  191. package/dist/core/viral-moments.test.js.map +1 -0
  192. package/dist/core/whisper.d.ts +16 -0
  193. package/dist/core/whisper.d.ts.map +1 -1
  194. package/dist/core/whisper.js +72 -5
  195. package/dist/core/whisper.js.map +1 -1
  196. package/dist/core/whisper.test.js +111 -1
  197. package/dist/core/whisper.test.js.map +1 -1
  198. package/dist/core/youtube-metadata.d.ts +44 -0
  199. package/dist/core/youtube-metadata.d.ts.map +1 -0
  200. package/dist/core/youtube-metadata.js +168 -0
  201. package/dist/core/youtube-metadata.js.map +1 -0
  202. package/dist/core/youtube-metadata.test.d.ts +2 -0
  203. package/dist/core/youtube-metadata.test.d.ts.map +1 -0
  204. package/dist/core/youtube-metadata.test.js +132 -0
  205. package/dist/core/youtube-metadata.test.js.map +1 -0
  206. package/dist/index.d.ts +1 -1
  207. package/dist/index.d.ts.map +1 -1
  208. package/dist/index.js +3 -2
  209. package/dist/index.js.map +1 -1
  210. package/dist/prompt-commands.d.ts +24 -0
  211. package/dist/prompt-commands.d.ts.map +1 -0
  212. package/dist/prompt-commands.js +243 -0
  213. package/dist/prompt-commands.js.map +1 -0
  214. package/dist/prompt-commands.test.d.ts +2 -0
  215. package/dist/prompt-commands.test.d.ts.map +1 -0
  216. package/dist/prompt-commands.test.js +46 -0
  217. package/dist/prompt-commands.test.js.map +1 -0
  218. package/dist/skills.d.ts +6 -6
  219. package/dist/skills.d.ts.map +1 -1
  220. package/dist/skills.js +1426 -445
  221. package/dist/skills.js.map +1 -1
  222. package/dist/system-prompt.d.ts.map +1 -1
  223. package/dist/system-prompt.js +108 -0
  224. package/dist/system-prompt.js.map +1 -1
  225. package/dist/tools/add-fades.d.ts.map +1 -1
  226. package/dist/tools/add-fades.js +2 -1
  227. package/dist/tools/add-fades.js.map +1 -1
  228. package/dist/tools/add-sfx-at-cuts.d.ts.map +1 -1
  229. package/dist/tools/add-sfx-at-cuts.js +36 -11
  230. package/dist/tools/add-sfx-at-cuts.js.map +1 -1
  231. package/dist/tools/add-sfx-to-timeline.d.ts +34 -0
  232. package/dist/tools/add-sfx-to-timeline.d.ts.map +1 -0
  233. package/dist/tools/add-sfx-to-timeline.js +169 -0
  234. package/dist/tools/add-sfx-to-timeline.js.map +1 -0
  235. package/dist/tools/add-sfx-to-timeline.test.d.ts +2 -0
  236. package/dist/tools/add-sfx-to-timeline.test.d.ts.map +1 -0
  237. package/dist/tools/add-sfx-to-timeline.test.js +181 -0
  238. package/dist/tools/add-sfx-to-timeline.test.js.map +1 -0
  239. package/dist/tools/audit-first-frame.d.ts +36 -0
  240. package/dist/tools/audit-first-frame.d.ts.map +1 -0
  241. package/dist/tools/audit-first-frame.js +181 -0
  242. package/dist/tools/audit-first-frame.js.map +1 -0
  243. package/dist/tools/audit-retention-structure.d.ts +20 -0
  244. package/dist/tools/audit-retention-structure.d.ts.map +1 -0
  245. package/dist/tools/audit-retention-structure.js +95 -0
  246. package/dist/tools/audit-retention-structure.js.map +1 -0
  247. package/dist/tools/audit-retention-structure.test.d.ts +2 -0
  248. package/dist/tools/audit-retention-structure.test.d.ts.map +1 -0
  249. package/dist/tools/audit-retention-structure.test.js +93 -0
  250. package/dist/tools/audit-retention-structure.test.js.map +1 -0
  251. package/dist/tools/bleep-words.d.ts +59 -0
  252. package/dist/tools/bleep-words.d.ts.map +1 -0
  253. package/dist/tools/bleep-words.js +211 -0
  254. package/dist/tools/bleep-words.js.map +1 -0
  255. package/dist/tools/bleep-words.test.d.ts +2 -0
  256. package/dist/tools/bleep-words.test.d.ts.map +1 -0
  257. package/dist/tools/bleep-words.test.js +96 -0
  258. package/dist/tools/bleep-words.test.js.map +1 -0
  259. package/dist/tools/burn-subtitles.d.ts.map +1 -1
  260. package/dist/tools/burn-subtitles.js +10 -5
  261. package/dist/tools/burn-subtitles.js.map +1 -1
  262. package/dist/tools/clean-audio.d.ts.map +1 -1
  263. package/dist/tools/clean-audio.js +2 -1
  264. package/dist/tools/clean-audio.js.map +1 -1
  265. package/dist/tools/cluster-takes.js +2 -1
  266. package/dist/tools/cluster-takes.js.map +1 -1
  267. package/dist/tools/compose-thumbnail-variants.d.ts +70 -0
  268. package/dist/tools/compose-thumbnail-variants.d.ts.map +1 -0
  269. package/dist/tools/compose-thumbnail-variants.js +274 -0
  270. package/dist/tools/compose-thumbnail-variants.js.map +1 -0
  271. package/dist/tools/compose-thumbnail.d.ts +6 -13
  272. package/dist/tools/compose-thumbnail.d.ts.map +1 -1
  273. package/dist/tools/compose-thumbnail.js +44 -81
  274. package/dist/tools/compose-thumbnail.js.map +1 -1
  275. package/dist/tools/concat-videos.d.ts.map +1 -1
  276. package/dist/tools/concat-videos.js +12 -5
  277. package/dist/tools/concat-videos.js.map +1 -1
  278. package/dist/tools/concat-videos.test.d.ts +2 -0
  279. package/dist/tools/concat-videos.test.d.ts.map +1 -0
  280. package/dist/tools/concat-videos.test.js +103 -0
  281. package/dist/tools/concat-videos.test.js.map +1 -0
  282. package/dist/tools/crossfade-videos.d.ts.map +1 -1
  283. package/dist/tools/crossfade-videos.js +2 -1
  284. package/dist/tools/crossfade-videos.js.map +1 -1
  285. package/dist/tools/cut-filler-words.d.ts.map +1 -1
  286. package/dist/tools/cut-filler-words.js +24 -8
  287. package/dist/tools/cut-filler-words.js.map +1 -1
  288. package/dist/tools/detect-speaker-changes.js +2 -1
  289. package/dist/tools/detect-speaker-changes.js.map +1 -1
  290. package/dist/tools/extract-audio.d.ts.map +1 -1
  291. package/dist/tools/extract-audio.js +13 -7
  292. package/dist/tools/extract-audio.js.map +1 -1
  293. package/dist/tools/face-reframe.d.ts +30 -0
  294. package/dist/tools/face-reframe.d.ts.map +1 -0
  295. package/dist/tools/face-reframe.js +143 -0
  296. package/dist/tools/face-reframe.js.map +1 -0
  297. package/dist/tools/face-reframe.test.d.ts +2 -0
  298. package/dist/tools/face-reframe.test.d.ts.map +1 -0
  299. package/dist/tools/face-reframe.test.js +139 -0
  300. package/dist/tools/face-reframe.test.js.map +1 -0
  301. package/dist/tools/find-viral-moments.d.ts +23 -0
  302. package/dist/tools/find-viral-moments.d.ts.map +1 -0
  303. package/dist/tools/find-viral-moments.js +176 -0
  304. package/dist/tools/find-viral-moments.js.map +1 -0
  305. package/dist/tools/find-viral-moments.test.d.ts +2 -0
  306. package/dist/tools/find-viral-moments.test.d.ts.map +1 -0
  307. package/dist/tools/find-viral-moments.test.js +144 -0
  308. package/dist/tools/find-viral-moments.test.js.map +1 -0
  309. package/dist/tools/generate-gif.d.ts.map +1 -1
  310. package/dist/tools/generate-gif.js +47 -40
  311. package/dist/tools/generate-gif.js.map +1 -1
  312. package/dist/tools/generate-gif.test.d.ts +2 -0
  313. package/dist/tools/generate-gif.test.d.ts.map +1 -0
  314. package/dist/tools/generate-gif.test.js +115 -0
  315. package/dist/tools/generate-gif.test.js.map +1 -0
  316. package/dist/tools/generate-outro.d.ts +18 -0
  317. package/dist/tools/generate-outro.d.ts.map +1 -0
  318. package/dist/tools/generate-outro.js +175 -0
  319. package/dist/tools/generate-outro.js.map +1 -0
  320. package/dist/tools/generate-youtube-metadata.d.ts +23 -0
  321. package/dist/tools/generate-youtube-metadata.d.ts.map +1 -0
  322. package/dist/tools/generate-youtube-metadata.js +103 -0
  323. package/dist/tools/generate-youtube-metadata.js.map +1 -0
  324. package/dist/tools/generate-youtube-metadata.test.d.ts +2 -0
  325. package/dist/tools/generate-youtube-metadata.test.d.ts.map +1 -0
  326. package/dist/tools/generate-youtube-metadata.test.js +118 -0
  327. package/dist/tools/generate-youtube-metadata.test.js.map +1 -0
  328. package/dist/tools/index.d.ts +14 -0
  329. package/dist/tools/index.d.ts.map +1 -1
  330. package/dist/tools/index.js +130 -1
  331. package/dist/tools/index.js.map +1 -1
  332. package/dist/tools/index.test.js +27 -1
  333. package/dist/tools/index.test.js.map +1 -1
  334. package/dist/tools/ken-burns.d.ts.map +1 -1
  335. package/dist/tools/ken-burns.js +2 -1
  336. package/dist/tools/ken-burns.js.map +1 -1
  337. package/dist/tools/loop-match-short.d.ts +22 -0
  338. package/dist/tools/loop-match-short.d.ts.map +1 -0
  339. package/dist/tools/loop-match-short.js +107 -0
  340. package/dist/tools/loop-match-short.js.map +1 -0
  341. package/dist/tools/mix-audio.d.ts.map +1 -1
  342. package/dist/tools/mix-audio.js +2 -1
  343. package/dist/tools/mix-audio.js.map +1 -1
  344. package/dist/tools/normalize-loudness.d.ts.map +1 -1
  345. package/dist/tools/normalize-loudness.js +2 -1
  346. package/dist/tools/normalize-loudness.js.map +1 -1
  347. package/dist/tools/path-traversal.test.d.ts +15 -0
  348. package/dist/tools/path-traversal.test.d.ts.map +1 -0
  349. package/dist/tools/path-traversal.test.js +223 -0
  350. package/dist/tools/path-traversal.test.js.map +1 -0
  351. package/dist/tools/pick-best-takes.js +2 -1
  352. package/dist/tools/pick-best-takes.js.map +1 -1
  353. package/dist/tools/punch-in.d.ts.map +1 -1
  354. package/dist/tools/punch-in.js +2 -1
  355. package/dist/tools/punch-in.js.map +1 -1
  356. package/dist/tools/read-transcript.js +2 -1
  357. package/dist/tools/read-transcript.js.map +1 -1
  358. package/dist/tools/render-multi-format.d.ts +35 -0
  359. package/dist/tools/render-multi-format.d.ts.map +1 -0
  360. package/dist/tools/render-multi-format.js +206 -0
  361. package/dist/tools/render-multi-format.js.map +1 -0
  362. package/dist/tools/render-multi-format.test.d.ts +2 -0
  363. package/dist/tools/render-multi-format.test.d.ts.map +1 -0
  364. package/dist/tools/render-multi-format.test.js +312 -0
  365. package/dist/tools/render-multi-format.test.js.map +1 -0
  366. package/dist/tools/render.d.ts.map +1 -1
  367. package/dist/tools/render.js +2 -2
  368. package/dist/tools/render.js.map +1 -1
  369. package/dist/tools/rewrite-hook.d.ts +32 -0
  370. package/dist/tools/rewrite-hook.d.ts.map +1 -0
  371. package/dist/tools/rewrite-hook.js +65 -0
  372. package/dist/tools/rewrite-hook.js.map +1 -0
  373. package/dist/tools/score-clip.d.ts +30 -0
  374. package/dist/tools/score-clip.d.ts.map +1 -0
  375. package/dist/tools/score-clip.js +109 -0
  376. package/dist/tools/score-clip.js.map +1 -0
  377. package/dist/tools/score-clip.test.d.ts +2 -0
  378. package/dist/tools/score-clip.test.d.ts.map +1 -0
  379. package/dist/tools/score-clip.test.js +110 -0
  380. package/dist/tools/score-clip.test.js.map +1 -0
  381. package/dist/tools/search-tools.d.ts +34 -0
  382. package/dist/tools/search-tools.d.ts.map +1 -0
  383. package/dist/tools/search-tools.js +86 -0
  384. package/dist/tools/search-tools.js.map +1 -0
  385. package/dist/tools/search-tools.test.d.ts +2 -0
  386. package/dist/tools/search-tools.test.d.ts.map +1 -0
  387. package/dist/tools/search-tools.test.js +60 -0
  388. package/dist/tools/search-tools.test.js.map +1 -0
  389. package/dist/tools/snap-cuts-to-beats.d.ts +18 -0
  390. package/dist/tools/snap-cuts-to-beats.d.ts.map +1 -0
  391. package/dist/tools/snap-cuts-to-beats.js +110 -0
  392. package/dist/tools/snap-cuts-to-beats.js.map +1 -0
  393. package/dist/tools/snap-cuts-to-beats.test.d.ts +2 -0
  394. package/dist/tools/snap-cuts-to-beats.test.d.ts.map +1 -0
  395. package/dist/tools/snap-cuts-to-beats.test.js +99 -0
  396. package/dist/tools/snap-cuts-to-beats.test.js.map +1 -0
  397. package/dist/tools/speed-ramp.d.ts.map +1 -1
  398. package/dist/tools/speed-ramp.js +2 -1
  399. package/dist/tools/speed-ramp.js.map +1 -1
  400. package/dist/tools/stabilize-video.d.ts.map +1 -1
  401. package/dist/tools/stabilize-video.js +2 -1
  402. package/dist/tools/stabilize-video.js.map +1 -1
  403. package/dist/tools/suggest-broll.d.ts +34 -0
  404. package/dist/tools/suggest-broll.d.ts.map +1 -0
  405. package/dist/tools/suggest-broll.js +367 -0
  406. package/dist/tools/suggest-broll.js.map +1 -0
  407. package/dist/tools/suggest-broll.test.d.ts +2 -0
  408. package/dist/tools/suggest-broll.test.d.ts.map +1 -0
  409. package/dist/tools/suggest-broll.test.js +217 -0
  410. package/dist/tools/suggest-broll.test.js.map +1 -0
  411. package/dist/tools/text-based-cut.d.ts +33 -0
  412. package/dist/tools/text-based-cut.d.ts.map +1 -0
  413. package/dist/tools/text-based-cut.js +172 -0
  414. package/dist/tools/text-based-cut.js.map +1 -0
  415. package/dist/tools/text-based-cut.test.d.ts +2 -0
  416. package/dist/tools/text-based-cut.test.d.ts.map +1 -0
  417. package/dist/tools/text-based-cut.test.js +32 -0
  418. package/dist/tools/text-based-cut.test.js.map +1 -0
  419. package/dist/tools/transcribe.d.ts +1 -1
  420. package/dist/tools/transition-videos.d.ts +1 -1
  421. package/dist/tools/transition-videos.d.ts.map +1 -1
  422. package/dist/tools/transition-videos.js +2 -1
  423. package/dist/tools/transition-videos.js.map +1 -1
  424. package/dist/tools/trim-dead-air.d.ts +59 -0
  425. package/dist/tools/trim-dead-air.d.ts.map +1 -0
  426. package/dist/tools/trim-dead-air.js +215 -0
  427. package/dist/tools/trim-dead-air.js.map +1 -0
  428. package/dist/tools/trim-dead-air.test.d.ts +2 -0
  429. package/dist/tools/trim-dead-air.test.d.ts.map +1 -0
  430. package/dist/tools/trim-dead-air.test.js +75 -0
  431. package/dist/tools/trim-dead-air.test.js.map +1 -0
  432. package/dist/tools/verify-thumbnail-promise.d.ts +33 -0
  433. package/dist/tools/verify-thumbnail-promise.d.ts.map +1 -0
  434. package/dist/tools/verify-thumbnail-promise.js +112 -0
  435. package/dist/tools/verify-thumbnail-promise.js.map +1 -0
  436. package/dist/tools/verify-thumbnail-promise.test.d.ts +2 -0
  437. package/dist/tools/verify-thumbnail-promise.test.d.ts.map +1 -0
  438. package/dist/tools/verify-thumbnail-promise.test.js +38 -0
  439. package/dist/tools/verify-thumbnail-promise.test.js.map +1 -0
  440. package/dist/tools/write-keyword-captions.d.ts +7 -0
  441. package/dist/tools/write-keyword-captions.d.ts.map +1 -1
  442. package/dist/tools/write-keyword-captions.js +35 -4
  443. package/dist/tools/write-keyword-captions.js.map +1 -1
  444. package/dist/ui/App.d.ts.map +1 -1
  445. package/dist/ui/App.js +75 -11
  446. package/dist/ui/App.js.map +1 -1
  447. package/dist/ui/tool-formatters.d.ts +30 -0
  448. package/dist/ui/tool-formatters.d.ts.map +1 -0
  449. package/dist/ui/tool-formatters.js +461 -0
  450. package/dist/ui/tool-formatters.js.map +1 -0
  451. package/dist/ui/tool-formatters.test.d.ts +2 -0
  452. package/dist/ui/tool-formatters.test.d.ts.map +1 -0
  453. package/dist/ui/tool-formatters.test.js +143 -0
  454. package/dist/ui/tool-formatters.test.js.map +1 -0
  455. package/package.json +10 -9
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=youtube-metadata.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"youtube-metadata.test.d.ts","sourceRoot":"","sources":["../../src/core/youtube-metadata.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,132 @@
1
+ import { afterEach, describe, expect, it, vi } from "vitest";
2
+ import { enforceMetadataConstraints, generateMetadata, parseMetadataResponse, } from "./youtube-metadata.js";
3
+ describe("parseMetadataResponse", () => {
4
+ it("parses a well-formed response", () => {
5
+ const r = parseMetadataResponse(JSON.stringify({
6
+ titles: ["A", "B", "C"],
7
+ description: "intro\n\n00:00 Intro",
8
+ tags: ["one", "two"],
9
+ chapters: [{ atSec: 0, title: "Intro" }],
10
+ hashtags: ["#tag1", "tag2"],
11
+ }));
12
+ expect(r.titles).toHaveLength(3);
13
+ expect(r.tags).toEqual(["one", "two"]);
14
+ expect(r.chapters[0].atSec).toBe(0);
15
+ // hashtag without # gets one prepended
16
+ expect(r.hashtags).toContain("#tag2");
17
+ });
18
+ it("strips leading # from tags", () => {
19
+ const r = parseMetadataResponse(JSON.stringify({ tags: ["#foo", "bar"] }));
20
+ expect(r.tags).toEqual(["foo", "bar"]);
21
+ });
22
+ it("drops chapter entries with bad atSec or empty title", () => {
23
+ const r = parseMetadataResponse(JSON.stringify({
24
+ chapters: [
25
+ { atSec: 0, title: "ok" },
26
+ { atSec: -5, title: "neg" },
27
+ { atSec: "x", title: "bad" },
28
+ { atSec: 30, title: "" },
29
+ ],
30
+ }));
31
+ expect(r.chapters).toHaveLength(1);
32
+ });
33
+ it("throws on absent JSON", () => {
34
+ expect(() => parseMetadataResponse("just prose")).toThrow(/no JSON/);
35
+ });
36
+ });
37
+ describe("enforceMetadataConstraints", () => {
38
+ const base = {
39
+ titles: ["t1", "t2", "t3"],
40
+ description: "desc",
41
+ tags: Array.from({ length: 20 }, (_, i) => `tag${i}`),
42
+ chapters: [
43
+ { atSec: 0, title: "Intro" },
44
+ { atSec: 60, title: "Topic A" },
45
+ { atSec: 120, title: "Topic B" },
46
+ { atSec: 200, title: "Topic C" },
47
+ { atSec: 280, title: "Topic D" },
48
+ ],
49
+ hashtags: ["#a", "#b", "#c", "#d", "#e", "#f"],
50
+ };
51
+ it("drops chapters when duration < 5 minutes", () => {
52
+ const r = enforceMetadataConstraints(base, 200);
53
+ expect(r.chapters).toEqual([]);
54
+ });
55
+ it("preserves chapters when duration >= 5 minutes and there are 5-15", () => {
56
+ const r = enforceMetadataConstraints(base, 600);
57
+ expect(r.chapters.length).toBeGreaterThanOrEqual(5);
58
+ expect(r.chapters[0].atSec).toBe(0);
59
+ });
60
+ it("forces first chapter to atSec=0 even if LLM returned a different time", () => {
61
+ const r = enforceMetadataConstraints({ ...base, chapters: [{ atSec: 5, title: "Late Intro" }, ...base.chapters.slice(1)] }, 600);
62
+ expect(r.chapters[0].atSec).toBe(0);
63
+ });
64
+ it("drops chapters with <30s gap", () => {
65
+ const r = enforceMetadataConstraints({
66
+ ...base,
67
+ chapters: [
68
+ { atSec: 0, title: "A" },
69
+ { atSec: 10, title: "B" }, // too close
70
+ { atSec: 60, title: "C" },
71
+ { atSec: 120, title: "D" },
72
+ { atSec: 180, title: "E" },
73
+ ],
74
+ }, 600);
75
+ // Must have ≥ 5 entries to keep — if pruning kills it below 5 we get [].
76
+ // After pruning B: A, C, D, E = 4 → []
77
+ expect(r.chapters).toEqual([]);
78
+ });
79
+ it("caps tags at 15 and dedupes", () => {
80
+ const r = enforceMetadataConstraints({ ...base, tags: ["a", "A", "b", ...base.tags] }, 200);
81
+ expect(r.tags.length).toBeLessThanOrEqual(15);
82
+ // case-insensitive dedupe
83
+ expect(r.tags.filter((t) => t.toLowerCase() === "a")).toHaveLength(1);
84
+ });
85
+ it("caps hashtags at 5", () => {
86
+ const r = enforceMetadataConstraints(base, 200);
87
+ expect(r.hashtags.length).toBeLessThanOrEqual(5);
88
+ });
89
+ it("truncates each title to 70 chars", () => {
90
+ const long = "x".repeat(100);
91
+ const r = enforceMetadataConstraints({ ...base, titles: [long, long, long] }, 200);
92
+ for (const t of r.titles)
93
+ expect(t.length).toBeLessThanOrEqual(70);
94
+ });
95
+ });
96
+ describe("generateMetadata", () => {
97
+ afterEach(() => {
98
+ vi.unstubAllGlobals();
99
+ delete process.env.OPENAI_API_KEY;
100
+ });
101
+ it("throws without API key", async () => {
102
+ delete process.env.OPENAI_API_KEY;
103
+ await expect(generateMetadata({ language: "en", durationSec: 60, segments: [] })).rejects.toThrow(/OPENAI_API_KEY/);
104
+ });
105
+ it("returns enforced metadata on success", async () => {
106
+ process.env.OPENAI_API_KEY = "k";
107
+ const json = {
108
+ titles: ["A title", "B title", "C title"],
109
+ description: "Some description",
110
+ tags: ["tech", "ai", "shorts"],
111
+ chapters: [{ atSec: 0, title: "Intro" }],
112
+ hashtags: ["#ai", "#tech"],
113
+ };
114
+ vi.stubGlobal("fetch", vi.fn(async () => ({
115
+ ok: true,
116
+ status: 200,
117
+ json: async () => ({
118
+ choices: [{ message: { content: JSON.stringify(json) } }],
119
+ }),
120
+ text: async () => "",
121
+ })));
122
+ const r = await generateMetadata({
123
+ language: "en",
124
+ durationSec: 200,
125
+ segments: [{ start: 0, end: 200, text: "intro" }],
126
+ });
127
+ expect(r.titles).toHaveLength(3);
128
+ // <5 min → chapters dropped
129
+ expect(r.chapters).toEqual([]);
130
+ });
131
+ });
132
+ //# sourceMappingURL=youtube-metadata.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"youtube-metadata.test.js","sourceRoot":"","sources":["../../src/core/youtube-metadata.test.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -13,7 +13,7 @@ export { runDoctorInteractive } from "./core/doctor-runner.js";
13
13
  export type { DoctorRunOptions } from "./core/doctor-runner.js";
14
14
  export { buildEditorSystemPrompt, buildEditorStaticBody, buildEditorHostBlock, spliceHostBlock, } from "./system-prompt.js";
15
15
  export type { StaticPromptOptions } from "./system-prompt.js";
16
- export { AuthStorage, AUTH_FILE, NotLoggedInError, generatePKCE, loginAnthropic, loginOpenAI, refreshAnthropicToken, refreshOpenAIToken, runLogin, runLogout, runStatus, } from "./core/auth/index.js";
16
+ export { AuthStorage, NotLoggedInError, loginAnthropic, loginOpenAI, refreshAnthropicToken, refreshOpenAIToken, runLogin, runLogout, runStatus, } from "./core/auth/index.js";
17
17
  export type { OAuthCredentials, OAuthLoginCallbacks, SupportedAuthProvider, } from "./core/auth/index.js";
18
18
  export type { ClipInfo, EditorConfig, Frame, FrameRange, HostCapabilities, HostName, MarkerInfo, TimelineState, } from "./types.js";
19
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAGjE,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGtE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC1F,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGvE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC/E,YAAY,EACV,aAAa,EACb,WAAW,EACX,WAAW,EACX,YAAY,EACZ,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAG9D,OAAO,EACL,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,SAAS,GACV,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAG9B,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,KAAK,EACL,UAAU,EACV,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,aAAa,GACd,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,YAAY,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAGjE,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGtE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC1F,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAGvE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC/E,YAAY,EACV,aAAa,EACb,WAAW,EACX,WAAW,EACX,YAAY,EACZ,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,YAAY,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAGhE,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAI9D,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,SAAS,GACV,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EACV,gBAAgB,EAChB,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAG9B,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,KAAK,EACL,UAAU,EACV,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,aAAa,GACd,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ export { renderDoctorReport } from "./core/doctor-render.js";
11
11
  export { runDoctorInteractive } from "./core/doctor-runner.js";
12
12
  // System prompt
13
13
  export { buildEditorSystemPrompt, buildEditorStaticBody, buildEditorHostBlock, spliceHostBlock, } from "./system-prompt.js";
14
- // Auth (shared with ggcoder via ~/.gg/auth.json)
15
- export { AuthStorage, AUTH_FILE, NotLoggedInError, generatePKCE, loginAnthropic, loginOpenAI, refreshAnthropicToken, refreshOpenAIToken, runLogin, runLogout, runStatus, } from "./core/auth/index.js";
14
+ // Auth (shared with ggcoder via ~/.gg/auth.json — implementations live in
15
+ // @kenkaiiii/ggcoder/auth and are re-exported through ./core/auth/index.js)
16
+ export { AuthStorage, NotLoggedInError, loginAnthropic, loginOpenAI, refreshAnthropicToken, refreshOpenAIToken, runLogin, runLogout, runStatus, } from "./core/auth/index.js";
16
17
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,QAAQ;AACR,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,QAAQ;AACR,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAG1F,gCAAgC;AAChC,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAQ/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,gBAAgB;AAChB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAG5B,iDAAiD;AACjD,OAAO,EACL,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,SAAS,GACV,MAAM,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,QAAQ;AACR,OAAO,EACL,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGtD,QAAQ;AACR,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAG1F,gCAAgC;AAChC,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAQ/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAG/D,gBAAgB;AAChB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,EACpB,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAG5B,0EAA0E;AAC1E,4EAA4E;AAC5E,OAAO,EACL,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,qBAAqB,EACrB,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,SAAS,GACV,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Bundled slash-command prompt templates for gg-editor.
3
+ *
4
+ * Mirrors ggcoder's `core/prompt-commands.ts` pattern: each command name maps
5
+ * to a full prompt that the agent loop executes. When the user types `/X`,
6
+ * the App.tsx slash dispatcher looks up the command, optionally appends any
7
+ * args, and runs the prompt as if it were a normal user message.
8
+ *
9
+ * Why bundled (not custom): these are core gg-editor workflows tied to our
10
+ * tool surface (`brand_kit`, `audit_*`, `verify_thumbnail_promise`, etc.).
11
+ * Per-project custom commands could still live in `<cwd>/.gg/commands/*.md`
12
+ * if we wire that loader in later — bundled commands take priority either
13
+ * way.
14
+ */
15
+ export interface PromptCommand {
16
+ name: string;
17
+ aliases: string[];
18
+ description: string;
19
+ prompt: string;
20
+ }
21
+ export declare const EDITOR_PROMPT_COMMANDS: PromptCommand[];
22
+ /** Look up a prompt command by name or alias. Returns undefined when not found. */
23
+ export declare function getEditorPromptCommand(name: string): PromptCommand | undefined;
24
+ //# sourceMappingURL=prompt-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-commands.d.ts","sourceRoot":"","sources":["../src/prompt-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,eAAO,MAAM,sBAAsB,EAAE,aAAa,EA+NjD,CAAC;AAEF,mFAAmF;AACnF,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CAE9E"}
@@ -0,0 +1,243 @@
1
+ /**
2
+ * Bundled slash-command prompt templates for gg-editor.
3
+ *
4
+ * Mirrors ggcoder's `core/prompt-commands.ts` pattern: each command name maps
5
+ * to a full prompt that the agent loop executes. When the user types `/X`,
6
+ * the App.tsx slash dispatcher looks up the command, optionally appends any
7
+ * args, and runs the prompt as if it were a normal user message.
8
+ *
9
+ * Why bundled (not custom): these are core gg-editor workflows tied to our
10
+ * tool surface (`brand_kit`, `audit_*`, `verify_thumbnail_promise`, etc.).
11
+ * Per-project custom commands could still live in `<cwd>/.gg/commands/*.md`
12
+ * if we wire that loader in later — bundled commands take priority either
13
+ * way.
14
+ */
15
+ export const EDITOR_PROMPT_COMMANDS = [
16
+ {
17
+ name: "setup-channel",
18
+ aliases: ["brand-kit"],
19
+ description: "Walk through brand-kit setup, write .gg/brand.json",
20
+ prompt: `# Brand kit setup
21
+
22
+ Walk the user through configuring their channel's brand kit. The output is a single JSON file at \`<cwd>/.gg/brand.json\` that every render-time tool inherits from.
23
+
24
+ ## Why this matters
25
+
26
+ Once the brand kit is set up, the user never has to re-specify channel name, logo, fonts, colours, intro/outro, or CTA on any future video. Tools like \`generate_outro\`, \`compose_thumbnail_variants\`, \`compose_thumbnail\`, and \`generate_youtube_metadata\` automatically inherit the kit's defaults.
27
+
28
+ ## How to run this
29
+
30
+ ASK the user the questions below ONE AT A TIME (or in small grouped batches). DO NOT ask them all at once — that's overwhelming. Skip optional fields cleanly when the user says "skip" or "n/a". Show your work as you go.
31
+
32
+ After each answer, validate quickly:
33
+ - Path fields → confirm the file exists at the given path (use \`probe_media\` for video files, just check existence for fonts/images via your read tool's error behaviour).
34
+ - Hex colours → must be 6 hex chars, no leading \`#\`. If the user provides \`#FF6B35\`, strip the \`#\` automatically.
35
+ - URLs → no validation needed, just record.
36
+
37
+ If validation fails, tell the user clearly and ask once more.
38
+
39
+ ## The questions, in order
40
+
41
+ ### Required
42
+ 1. **Channel name** — display name surfaced in outros / lower-thirds / metadata. Free text.
43
+ 2. **Channel niche / topic** — one-sentence description. Used to give \`generate_youtube_metadata\` topical context for descriptions.
44
+
45
+ ### Visual identity (recommended, but skippable)
46
+ 3. **Logo** — relative path to a PNG with alpha (used by \`overlay_watermark\` and \`generate_outro\`). Skip if none.
47
+ 4. **Watermark** — separate path if they have a positioned/sized variant (otherwise the agent uses logo). Optional.
48
+ 5. **Intro video** — pre-rendered intro mp4 to splice via \`concat_videos\`. Optional.
49
+ 6. **Outro video** — pre-rendered outro mp4. Optional. (\`generate_outro\` can produce one on-the-fly if they don't have one.)
50
+
51
+ ### Typography (one-time pain, lifelong save)
52
+ 7. **Heading font** — path to a .ttf/.otf used for thumbnail text + outro headline. Bebas Neue, Inter Black, Anton, Impact are common choices. If they don't have one, suggest downloading Bebas Neue (free, https://fonts.google.com/specimen/Bebas+Neue) and recommend a path like \`assets/Bebas-Bold.ttf\`.
53
+ 8. **Body font** — for lower-thirds / captions. Optional; skip is fine.
54
+
55
+ ### Colours (6-char hex, no #)
56
+ 9. **Primary colour** — used for thumbnail text outline, accent. e.g. \`FF6B35\`.
57
+ 10. **Secondary colour** — optional accent.
58
+ 11. **Accent colour** — optional third.
59
+
60
+ ### Voice
61
+ 12. **CTA text** — what the outro card says. Default suggestion: "Subscribe for more". Free text.
62
+ 13. **Subscribe URL** — full URL of their channel (e.g. \`youtube.com/@kenkaidoesai\`). Optional but useful for description templates.
63
+
64
+ ## Writing the file
65
+
66
+ Use the file-write tool path you have access to (the agent's general write tool — not a video tool). The file must be valid JSON with at minimum the fields the user provided. Skip fields they declined; do NOT write empty strings or null values.
67
+
68
+ Schema (only include keys the user actually answered):
69
+
70
+ \`\`\`json
71
+ {
72
+ "channelName": "string",
73
+ "logo": "string (relative path)",
74
+ "watermark": "string",
75
+ "intro": "string",
76
+ "outro": "string",
77
+ "fonts": { "heading": "string", "body": "string" },
78
+ "colors": { "primary": "RRGGBB", "secondary": "RRGGBB", "accent": "RRGGBB" },
79
+ "ctaText": "string",
80
+ "subscribeUrl": "string"
81
+ }
82
+ \`\`\`
83
+
84
+ \`channelStyle\` (the niche from question 2) is NOT a brand-kit field — it goes into a separate \`<cwd>/.gg/editor-styles/channel.md\` if the user wants the LLM to consistently match their voice. Offer this as a follow-up after the kit is saved.
85
+
86
+ After writing \`<cwd>/.gg/brand.json\`:
87
+ 1. Show the user the final saved JSON (pretty-printed) so they can sanity-check.
88
+ 2. Tell them what's next:
89
+
90
+ > Brand kit saved to \`.gg/brand.json\`. From now on, every render automatically uses these defaults. Drop your footage in this directory and try:
91
+ >
92
+ > \`Make me a YouTube video from <filename>\`
93
+ >
94
+ > The agent will pick up the brand kit silently and produce a long-form cut + Shorts + thumbnails + metadata in one prompt.
95
+
96
+ 3. If they skipped colours / fonts, gently note what they're missing — the kit still works without them, but thumbnail consistency takes a hit.
97
+
98
+ ## Idempotency
99
+
100
+ If \`<cwd>/.gg/brand.json\` ALREADY exists, read it first. Tell the user what's currently set and ask whether they want to (a) update specific fields, (b) start over, or (c) cancel. Default to update-specific-fields and only ask the relevant questions.
101
+
102
+ ## Constraints
103
+
104
+ - Don't fabricate paths. If the user says "I have a logo at \`assets/logo.png\`" — verify the file actually exists before writing it into the JSON. If it doesn't, say so and ask if they want to fix the path or skip the field.
105
+ - Don't over-engineer. The brand kit is small. Don't ask about lower-third templates, end-screen positioning, or other advanced stuff in this command.
106
+ - Keep tone friendly and quick. This should take the user under 3 minutes.
107
+ `,
108
+ },
109
+ {
110
+ name: "audit",
111
+ aliases: ["pre-render"],
112
+ description: "Run the canonical pre-render audit chain on a video",
113
+ prompt: `# Pre-render audit
114
+
115
+ Run the canonical audit chain before declaring a video ready to ship. The user will provide the video path (or thumbnail + video) as args; if not provided, ASK them which file to audit and whether it's a Short or long-form.
116
+
117
+ ## For Shorts (short-form)
118
+
119
+ \`\`\`
120
+ audit_first_frame(input) # is t=0 thumbnail-quality?
121
+ analyze_hook(input) # does the spoken line earn the watch in the first 3s?
122
+ verify_thumbnail_promise(thumbnail, input, windowSec=15)
123
+ \`\`\`
124
+
125
+ If any score is below the gate (\`audit_first_frame.score < 60\`, \`analyze_hook.score < 60\`, \`verify_thumbnail_promise.matches < 0.6\`), surface the failing check + the tool's suggestion. **Don't say it passes when it doesn't.**
126
+
127
+ If the hook fails specifically, run \`rewrite_hook(currentHook=..., pattern="auto")\` to produce 3 candidate rewrites and surface them to the user. Be explicit: the agent can't re-record the line — the user has to either pick an alternative opener from existing source or re-shoot.
128
+
129
+ ## For long-form
130
+
131
+ \`\`\`
132
+ analyze_hook(input) # first 3s
133
+ audit_retention_structure(transcript, checkpoints=...) # 3min, 6min, 9min
134
+ verify_thumbnail_promise(thumbnail, input, windowSec=60) # MrBeast: match clickbait promise in first minute
135
+ pre_render_check(timelineEmpty=false, expectCaptions=true,
136
+ loudnessSource=..., loudnessTarget="youtube")
137
+ \`\`\`
138
+
139
+ For each weak retention checkpoint, propose ONE concrete fix (\`cut_filler_words\`, \`text_based_cut\`, \`punch_in\`, or \`add_sfx_at_cuts\`) on the surrounding window. Don't dump the whole menu.
140
+
141
+ ## Reporting
142
+
143
+ End with a structured pass/fail summary:
144
+
145
+ \`\`\`
146
+ ✅ first_frame: 82 — strong subject, clear contrast
147
+ ⚠️ hook: 54 — silent open, no on-screen text
148
+ ✅ thumbnail_promise: 0.78
149
+ ❌ retention[3min]: 0.42 — flat 2:30–3:30; suggested: punch_in + add_sfx_at_cuts
150
+ ✅ retention[6min]: 0.71
151
+ ✅ pre_render: pass
152
+ \`\`\`
153
+
154
+ The user reads the table and decides what to fix. Don't auto-fix without asking.
155
+ `,
156
+ },
157
+ {
158
+ name: "diagnose",
159
+ aliases: ["why-no-views"],
160
+ description: "Diagnose an underperforming video from Studio metrics",
161
+ prompt: `# Diagnose underperformance
162
+
163
+ The user's video isn't getting views and they want to know why. The agent does NOT have access to YouTube Studio. Don't fabricate diagnoses.
164
+
165
+ ## Step 1 — Get the numbers
166
+
167
+ ASK the user to paste from YouTube Studio:
168
+
169
+ - **Impressions** (total)
170
+ - **Click-through rate (CTR)** as a %
171
+ - **Average view duration (AVD)** as M:SS
172
+ - **Average percentage viewed (AVP%)** as a %
173
+ - **Total video length** in seconds or M:SS
174
+
175
+ If they have the retention CSV exported, accept that too — it gives much more diagnostic power. Otherwise the four numbers above are enough.
176
+
177
+ ## Step 2 — Diagnose in order, surface the FIRST failing metric
178
+
179
+ Use the order from the \`youtube-algorithm-primer\` skill (read it via \`read_skill\` if you haven't this session):
180
+
181
+ 1. **CTR < 4% vs the channel's typical baseline?**
182
+ → The package (thumbnail + title) isn't earning the click.
183
+ → Recommend running \`compose_thumbnail_variants(input=..., strategy="expression", count=3)\` plus \`generate_youtube_metadata\` for 3 fresh title candidates.
184
+ → Tell the user to upload the resulting variants to YouTube Studio's **Test & Compare** (which the agent CANNOT trigger directly — it lives only in Studio). YouTube picks the winner by Watch Time Share over 1–14 days.
185
+
186
+ 2. **CTR ok but AVP% < 30%?**
187
+ → Hook problem.
188
+ → Run \`analyze_hook\` on the video. If Shorts, also \`audit_first_frame\`.
189
+ → If hook scores low, run \`rewrite_hook(pattern="auto")\` and surface 3 candidates.
190
+ → Be explicit: the agent CAN'T re-record. Options: pick a different opener from existing source via \`text_based_cut\`, or re-shoot.
191
+
192
+ 3. **AVP% ok but AVD low (in absolute time)?**
193
+ → Pacing.
194
+ → Run \`audit_retention_structure(transcript)\` to find the flat stretches.
195
+ → For each weak checkpoint propose ONE fix (\`cut_filler_words\` / \`text_based_cut\` / \`punch_in\` / \`add_sfx_at_cuts\`).
196
+
197
+ 4. **AVD ok but no growth past initial views?** (Session contribution.)
198
+ → Outro / next-video pointer missing. Use \`generate_outro\` with the brand kit's outro chain.
199
+
200
+ 5. **Engagement velocity zero in first 24h?**
201
+ → Either no question in description (run \`generate_youtube_metadata\` to add one) OR small-channel reality (no algorithmic fix; tell the user honestly).
202
+
203
+ ## Step 3 — Surface ONE concrete fix
204
+
205
+ Don't dump the menu. Pick the FIRST failing metric and propose one tool call. After the user runs that fix and re-uploads / re-tests, they can come back and \`/diagnose\` again on the new numbers.
206
+
207
+ ## Constraints
208
+
209
+ - If the user gives one number and asks for a full diagnosis, ask for the others first. CTR alone isn't enough; CTR plus AVP% is.
210
+ - If the channel is genuinely small (< 1k subs) and CTR is fine but views are low, tell them: this is community-size, not an algorithmic problem. No tool fix.
211
+ - Cite the source from the \`youtube-algorithm-primer\` skill when the user asks "why does that metric matter?" — don't paraphrase from memory.
212
+ `,
213
+ },
214
+ {
215
+ name: "youtube",
216
+ aliases: ["yt"],
217
+ description: "Make a YouTube video (long-form + Shorts) from footage",
218
+ prompt: `# Canonical YouTube delivery
219
+
220
+ Run the \`youtube-end-to-end\` skill on the footage the user provides. If they didn't specify a file, ASK once for the path; otherwise just go.
221
+
222
+ ## Steps (the skill is authoritative — read it if you haven't this session)
223
+
224
+ 1. \`read_skill(name="youtube-end-to-end")\` if not already in your context.
225
+ 2. \`probe_media(input)\` — duration determines whether to produce long-form, Shorts, or both. Default per the skill: > 5min source → both.
226
+ 3. Read \`<cwd>/.gg/brand.json\` if it exists. Mention which fields you'll inherit. If it DOESN'T exist, mention that running \`/setup-channel\` first would mean every future video uses the channel's defaults automatically — but don't block on it.
227
+ 4. Run the canonical pipeline.
228
+ 5. Run the pre-render audit chain (\`audit_first_frame\` on Shorts, \`analyze_hook\`, \`verify_thumbnail_promise\`, \`audit_retention_structure\` for long-form).
229
+ 6. End with the structured deliverable summary the skill prescribes (long-form path, Shorts paths, 3 candidate titles, 3 thumbnail variants, description, dropped candidates with reasons).
230
+
231
+ ## Reminders
232
+
233
+ - Don't paraphrase the skill's pipeline — call it out and follow it.
234
+ - The agent CANNOT generate footage. If a hook fails after \`rewrite_hook\`, surface the candidates and let the user choose between recutting and re-shooting.
235
+ - The agent CANNOT trigger Test & Compare. Tell the user to upload the 3 thumbnails to Studio manually.
236
+ `,
237
+ },
238
+ ];
239
+ /** Look up a prompt command by name or alias. Returns undefined when not found. */
240
+ export function getEditorPromptCommand(name) {
241
+ return EDITOR_PROMPT_COMMANDS.find((cmd) => cmd.name === name || cmd.aliases.includes(name));
242
+ }
243
+ //# sourceMappingURL=prompt-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-commands.js","sourceRoot":"","sources":["../src/prompt-commands.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AASH,MAAM,CAAC,MAAM,sBAAsB,GAAoB;IACrD;QACE,IAAI,EAAE,eAAe;QACrB,OAAO,EAAE,CAAC,WAAW,CAAC;QACtB,WAAW,EAAE,oDAAoD;QACjE,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuFX;KACE;IACD;QACE,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,CAAC,YAAY,CAAC;QACvB,WAAW,EAAE,qDAAqD;QAClE,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0CX;KACE;IACD;QACE,IAAI,EAAE,UAAU;QAChB,OAAO,EAAE,CAAC,cAAc,CAAC;QACzB,WAAW,EAAE,uDAAuD;QACpE,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDX;KACE;IACD;QACE,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,CAAC,IAAI,CAAC;QACf,WAAW,EAAE,wDAAwD;QACrE,MAAM,EAAE;;;;;;;;;;;;;;;;;;CAkBX;KACE;CACF,CAAC;AAEF,mFAAmF;AACnF,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,OAAO,sBAAsB,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/F,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=prompt-commands.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-commands.test.d.ts","sourceRoot":"","sources":["../src/prompt-commands.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import { EDITOR_PROMPT_COMMANDS, getEditorPromptCommand } from "./prompt-commands.js";
3
+ describe("EDITOR_PROMPT_COMMANDS", () => {
4
+ it("registers the four bundled commands", () => {
5
+ expect(EDITOR_PROMPT_COMMANDS.map((c) => c.name).sort()).toEqual([
6
+ "audit",
7
+ "diagnose",
8
+ "setup-channel",
9
+ "youtube",
10
+ ]);
11
+ });
12
+ it("every command has a non-empty prompt and description", () => {
13
+ for (const cmd of EDITOR_PROMPT_COMMANDS) {
14
+ expect(cmd.prompt.length).toBeGreaterThan(50);
15
+ expect(cmd.description.length).toBeGreaterThan(0);
16
+ }
17
+ });
18
+ it("aliases are unique across commands", () => {
19
+ const seen = new Set();
20
+ for (const cmd of EDITOR_PROMPT_COMMANDS) {
21
+ expect(seen.has(cmd.name)).toBe(false);
22
+ seen.add(cmd.name);
23
+ for (const a of cmd.aliases) {
24
+ expect(seen.has(a)).toBe(false);
25
+ seen.add(a);
26
+ }
27
+ }
28
+ });
29
+ });
30
+ describe("getEditorPromptCommand", () => {
31
+ it("resolves by primary name", () => {
32
+ expect(getEditorPromptCommand("setup-channel")?.name).toBe("setup-channel");
33
+ expect(getEditorPromptCommand("youtube")?.name).toBe("youtube");
34
+ });
35
+ it("resolves by alias", () => {
36
+ expect(getEditorPromptCommand("brand-kit")?.name).toBe("setup-channel");
37
+ expect(getEditorPromptCommand("yt")?.name).toBe("youtube");
38
+ expect(getEditorPromptCommand("pre-render")?.name).toBe("audit");
39
+ expect(getEditorPromptCommand("why-no-views")?.name).toBe("diagnose");
40
+ });
41
+ it("returns undefined for unknown names", () => {
42
+ expect(getEditorPromptCommand("nope")).toBeUndefined();
43
+ expect(getEditorPromptCommand("")).toBeUndefined();
44
+ });
45
+ });
46
+ //# sourceMappingURL=prompt-commands.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-commands.test.js","sourceRoot":"","sources":["../src/prompt-commands.test.ts"],"names":[],"mappings":"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"}
package/dist/skills.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /**
2
- * Bundled skill markdowns. Embedded as TS string constants so they ship in the
3
- * compiled package without depending on disk layout. Authored in
4
- * src/skills/*.md regenerate this file by running `node build-skills.mjs`
5
- * from the package root if you edit the source markdowns.
2
+ * Bundled skill markdowns. Auto-generated from src/skills/*.md by
3
+ * scripts/build-skills.mjs DO NOT EDIT BY HAND. Add a new skill by
4
+ * dropping a .md file in src/skills/ (with optional YAML frontmatter)
5
+ * and re-running `node scripts/build-skills.mjs`.
6
6
  *
7
- * Skills are exposed through the read_skill tool; their descriptions live in
8
- * the system prompt. Pattern follows the Anthropic skills convention:
7
+ * Skills are exposed through the read_skill tool; their descriptions live
8
+ * in the system prompt. Pattern follows the Anthropic skill convention:
9
9
  * description in the prompt, full content on demand.
10
10
  */
11
11
  export interface BundledSkill {
@@ -1 +1 @@
1
- {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AA2vBD,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAqC/C,CAAC;AAEF,eAAO,MAAM,WAAW,UAAsB,CAAC"}
1
+ {"version":3,"file":"skills.d.ts","sourceRoot":"","sources":["../src/skills.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAgsDD,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAmD/C,CAAC;AAEF,eAAO,MAAM,WAAW,UAAsB,CAAC"}