youtube-knowledge-mcp 2.2.0 → 3.0.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 (407) hide show
  1. package/README.md +126 -36
  2. package/dist/brain-schemas.d.ts +10 -0
  3. package/dist/brain-schemas.d.ts.map +1 -1
  4. package/dist/harvest-schemas.d.ts +75 -0
  5. package/dist/harvest-schemas.d.ts.map +1 -0
  6. package/dist/harvest-schemas.js +111 -0
  7. package/dist/harvest-schemas.js.map +1 -0
  8. package/dist/registry/brain-tools.d.ts.map +1 -1
  9. package/dist/registry/brain-tools.js +16 -0
  10. package/dist/registry/brain-tools.js.map +1 -1
  11. package/dist/registry/channel-tools.d.ts.map +1 -1
  12. package/dist/registry/channel-tools.js +16 -0
  13. package/dist/registry/channel-tools.js.map +1 -1
  14. package/dist/registry/harvest-tools.d.ts +10 -0
  15. package/dist/registry/harvest-tools.d.ts.map +1 -0
  16. package/dist/registry/harvest-tools.js +109 -0
  17. package/dist/registry/harvest-tools.js.map +1 -0
  18. package/dist/registry/health-tools.d.ts.map +1 -1
  19. package/dist/registry/health-tools.js +18 -0
  20. package/dist/registry/health-tools.js.map +1 -1
  21. package/dist/registry/index.d.ts.map +1 -1
  22. package/dist/registry/index.js +6 -0
  23. package/dist/registry/index.js.map +1 -1
  24. package/dist/registry/media-tools.d.ts.map +1 -1
  25. package/dist/registry/media-tools.js +31 -0
  26. package/dist/registry/media-tools.js.map +1 -1
  27. package/dist/registry/store-tools.d.ts +9 -0
  28. package/dist/registry/store-tools.d.ts.map +1 -0
  29. package/dist/registry/store-tools.js +59 -0
  30. package/dist/registry/store-tools.js.map +1 -0
  31. package/dist/registry/transcript-tools.d.ts +4 -1
  32. package/dist/registry/transcript-tools.d.ts.map +1 -1
  33. package/dist/registry/transcript-tools.js +20 -1
  34. package/dist/registry/transcript-tools.js.map +1 -1
  35. package/dist/registry/video-tools.d.ts.map +1 -1
  36. package/dist/registry/video-tools.js +49 -1
  37. package/dist/registry/video-tools.js.map +1 -1
  38. package/dist/registry/vision-tools.d.ts +7 -0
  39. package/dist/registry/vision-tools.d.ts.map +1 -0
  40. package/dist/registry/vision-tools.js +55 -0
  41. package/dist/registry/vision-tools.js.map +1 -0
  42. package/dist/schemas.d.ts +245 -0
  43. package/dist/schemas.d.ts.map +1 -1
  44. package/dist/schemas.js +58 -0
  45. package/dist/schemas.js.map +1 -1
  46. package/dist/thumbnail-schemas.d.ts +38 -28
  47. package/dist/thumbnail-schemas.d.ts.map +1 -1
  48. package/dist/tools/ask-brain.js +1 -1
  49. package/dist/tools/ask-brain.js.map +1 -1
  50. package/dist/tools/ask-brains.d.ts +66 -0
  51. package/dist/tools/ask-brains.d.ts.map +1 -0
  52. package/dist/tools/ask-brains.js +111 -0
  53. package/dist/tools/ask-brains.js.map +1 -0
  54. package/dist/tools/brain-info.js +1 -1
  55. package/dist/tools/brain-info.js.map +1 -1
  56. package/dist/tools/check-health.d.ts +75 -6
  57. package/dist/tools/check-health.d.ts.map +1 -1
  58. package/dist/tools/check-health.js +114 -6
  59. package/dist/tools/check-health.js.map +1 -1
  60. package/dist/tools/check-new-uploads.d.ts +55 -0
  61. package/dist/tools/check-new-uploads.d.ts.map +1 -0
  62. package/dist/tools/check-new-uploads.js +74 -0
  63. package/dist/tools/check-new-uploads.js.map +1 -0
  64. package/dist/tools/clips.d.ts +15 -0
  65. package/dist/tools/clips.d.ts.map +1 -1
  66. package/dist/tools/clips.js +5 -5
  67. package/dist/tools/clips.js.map +1 -1
  68. package/dist/tools/detect-scenes.d.ts +38 -0
  69. package/dist/tools/detect-scenes.d.ts.map +1 -0
  70. package/dist/tools/detect-scenes.js +66 -0
  71. package/dist/tools/detect-scenes.js.map +1 -0
  72. package/dist/tools/export-data.d.ts +85 -0
  73. package/dist/tools/export-data.d.ts.map +1 -0
  74. package/dist/tools/export-data.js +99 -0
  75. package/dist/tools/export-data.js.map +1 -0
  76. package/dist/tools/fetch-channel-thumbnails.d.ts +8 -8
  77. package/dist/tools/fetch-videos.d.ts +15 -4
  78. package/dist/tools/fetch-videos.d.ts.map +1 -1
  79. package/dist/tools/fetch-videos.js +63 -22
  80. package/dist/tools/fetch-videos.js.map +1 -1
  81. package/dist/tools/frames-subtitles.d.ts.map +1 -1
  82. package/dist/tools/frames-subtitles.js +16 -8
  83. package/dist/tools/frames-subtitles.js.map +1 -1
  84. package/dist/tools/frames.d.ts +73 -0
  85. package/dist/tools/frames.d.ts.map +1 -0
  86. package/dist/tools/frames.js +136 -0
  87. package/dist/tools/frames.js.map +1 -0
  88. package/dist/tools/get-channel-info.d.ts +2 -0
  89. package/dist/tools/get-channel-info.d.ts.map +1 -1
  90. package/dist/tools/get-channel-info.js +4 -0
  91. package/dist/tools/get-channel-info.js.map +1 -1
  92. package/dist/tools/get-comments.d.ts +238 -6
  93. package/dist/tools/get-comments.d.ts.map +1 -1
  94. package/dist/tools/get-comments.js +85 -21
  95. package/dist/tools/get-comments.js.map +1 -1
  96. package/dist/tools/get-coverage.d.ts +122 -0
  97. package/dist/tools/get-coverage.d.ts.map +1 -0
  98. package/dist/tools/get-coverage.js +105 -0
  99. package/dist/tools/get-coverage.js.map +1 -0
  100. package/dist/tools/get-sponsor-segments.d.ts +49 -0
  101. package/dist/tools/get-sponsor-segments.d.ts.map +1 -0
  102. package/dist/tools/get-sponsor-segments.js +61 -0
  103. package/dist/tools/get-sponsor-segments.js.map +1 -0
  104. package/dist/tools/get-thumbnail.d.ts.map +1 -1
  105. package/dist/tools/get-thumbnail.js +2 -1
  106. package/dist/tools/get-thumbnail.js.map +1 -1
  107. package/dist/tools/get-transcript.d.ts +1 -0
  108. package/dist/tools/get-transcript.d.ts.map +1 -1
  109. package/dist/tools/get-transcript.js +11 -4
  110. package/dist/tools/get-transcript.js.map +1 -1
  111. package/dist/tools/get-video-details.d.ts +118 -0
  112. package/dist/tools/get-video-details.d.ts.map +1 -0
  113. package/dist/tools/get-video-details.js +147 -0
  114. package/dist/tools/get-video-details.js.map +1 -0
  115. package/dist/tools/gif-concat.d.ts +49 -0
  116. package/dist/tools/gif-concat.d.ts.map +1 -0
  117. package/dist/tools/gif-concat.js +96 -0
  118. package/dist/tools/gif-concat.js.map +1 -0
  119. package/dist/tools/harvest-channel.d.ts +92 -0
  120. package/dist/tools/harvest-channel.d.ts.map +1 -0
  121. package/dist/tools/harvest-channel.js +62 -0
  122. package/dist/tools/harvest-channel.js.map +1 -0
  123. package/dist/tools/harvest-comments.d.ts +81 -0
  124. package/dist/tools/harvest-comments.d.ts.map +1 -0
  125. package/dist/tools/harvest-comments.js +115 -0
  126. package/dist/tools/harvest-comments.js.map +1 -0
  127. package/dist/tools/harvest-details.d.ts +84 -0
  128. package/dist/tools/harvest-details.d.ts.map +1 -0
  129. package/dist/tools/harvest-details.js +71 -0
  130. package/dist/tools/harvest-details.js.map +1 -0
  131. package/dist/tools/library.js +1 -1
  132. package/dist/tools/library.js.map +1 -1
  133. package/dist/tools/list-captions.d.ts +17 -0
  134. package/dist/tools/list-captions.d.ts.map +1 -0
  135. package/dist/tools/list-captions.js +60 -0
  136. package/dist/tools/list-captions.js.map +1 -0
  137. package/dist/tools/list-channel-playlists.d.ts +30 -0
  138. package/dist/tools/list-channel-playlists.d.ts.map +1 -0
  139. package/dist/tools/list-channel-playlists.js +44 -0
  140. package/dist/tools/list-channel-playlists.js.map +1 -0
  141. package/dist/tools/list-channel-thumbnails.d.ts +10 -10
  142. package/dist/tools/list-channel-thumbnails.js +1 -1
  143. package/dist/tools/list-channel-thumbnails.js.map +1 -1
  144. package/dist/tools/list-library.js +1 -1
  145. package/dist/tools/list-library.js.map +1 -1
  146. package/dist/tools/prune-harvest.d.ts +59 -0
  147. package/dist/tools/prune-harvest.d.ts.map +1 -0
  148. package/dist/tools/prune-harvest.js +108 -0
  149. package/dist/tools/prune-harvest.js.map +1 -0
  150. package/dist/tools/query-comments.d.ts +125 -0
  151. package/dist/tools/query-comments.d.ts.map +1 -0
  152. package/dist/tools/query-comments.js +106 -0
  153. package/dist/tools/query-comments.js.map +1 -0
  154. package/dist/tools/query-videos.d.ts +118 -0
  155. package/dist/tools/query-videos.d.ts.map +1 -0
  156. package/dist/tools/query-videos.js +97 -0
  157. package/dist/tools/query-videos.js.map +1 -0
  158. package/dist/tools/repair-store.d.ts +34 -0
  159. package/dist/tools/repair-store.d.ts.map +1 -0
  160. package/dist/tools/repair-store.js +58 -0
  161. package/dist/tools/repair-store.js.map +1 -0
  162. package/dist/tools/search-channels.d.ts +6 -0
  163. package/dist/tools/search-channels.d.ts.map +1 -1
  164. package/dist/tools/search-channels.js +5 -1
  165. package/dist/tools/search-channels.js.map +1 -1
  166. package/dist/tools/search-videos.js +1 -1
  167. package/dist/tools/search-videos.js.map +1 -1
  168. package/dist/tools/transcribe-video.d.ts +28 -0
  169. package/dist/tools/transcribe-video.d.ts.map +1 -0
  170. package/dist/tools/transcribe-video.js +52 -0
  171. package/dist/tools/transcribe-video.js.map +1 -0
  172. package/dist/utils/brain-fusion.d.ts +24 -0
  173. package/dist/utils/brain-fusion.d.ts.map +1 -0
  174. package/dist/utils/brain-fusion.js +18 -0
  175. package/dist/utils/brain-fusion.js.map +1 -0
  176. package/dist/utils/channel-playlists.d.ts +21 -0
  177. package/dist/utils/channel-playlists.d.ts.map +1 -0
  178. package/dist/utils/channel-playlists.js +56 -0
  179. package/dist/utils/channel-playlists.js.map +1 -0
  180. package/dist/utils/clips.d.ts.map +1 -1
  181. package/dist/utils/clips.js +3 -17
  182. package/dist/utils/clips.js.map +1 -1
  183. package/dist/utils/comment-store.d.ts +71 -0
  184. package/dist/utils/comment-store.d.ts.map +1 -0
  185. package/dist/utils/comment-store.js +129 -0
  186. package/dist/utils/comment-store.js.map +1 -0
  187. package/dist/utils/comment-threads.d.ts +51 -0
  188. package/dist/utils/comment-threads.d.ts.map +1 -0
  189. package/dist/utils/comment-threads.js +76 -0
  190. package/dist/utils/comment-threads.js.map +1 -0
  191. package/dist/utils/concat.d.ts +19 -0
  192. package/dist/utils/concat.d.ts.map +1 -0
  193. package/dist/utils/concat.js +135 -0
  194. package/dist/utils/concat.js.map +1 -0
  195. package/dist/utils/contact-sheet.d.ts +28 -0
  196. package/dist/utils/contact-sheet.d.ts.map +1 -0
  197. package/dist/utils/contact-sheet.js +65 -0
  198. package/dist/utils/contact-sheet.js.map +1 -0
  199. package/dist/utils/coverage-text.d.ts +3 -0
  200. package/dist/utils/coverage-text.d.ts.map +1 -0
  201. package/dist/utils/coverage-text.js +62 -0
  202. package/dist/utils/coverage-text.js.map +1 -0
  203. package/dist/utils/coverage.d.ts +57 -0
  204. package/dist/utils/coverage.d.ts.map +1 -0
  205. package/dist/utils/coverage.js +142 -0
  206. package/dist/utils/coverage.js.map +1 -0
  207. package/dist/utils/detail-batch.d.ts +25 -0
  208. package/dist/utils/detail-batch.d.ts.map +1 -0
  209. package/dist/utils/detail-batch.js +58 -0
  210. package/dist/utils/detail-batch.js.map +1 -0
  211. package/dist/utils/errors.d.ts +1 -1
  212. package/dist/utils/errors.d.ts.map +1 -1
  213. package/dist/utils/errors.js +19 -1
  214. package/dist/utils/errors.js.map +1 -1
  215. package/dist/utils/export-data.d.ts +41 -0
  216. package/dist/utils/export-data.d.ts.map +1 -0
  217. package/dist/utils/export-data.js +114 -0
  218. package/dist/utils/export-data.js.map +1 -0
  219. package/dist/utils/export-format.d.ts +23 -0
  220. package/dist/utils/export-format.d.ts.map +1 -0
  221. package/dist/utils/export-format.js +59 -0
  222. package/dist/utils/export-format.js.map +1 -0
  223. package/dist/utils/export-load.d.ts +28 -0
  224. package/dist/utils/export-load.d.ts.map +1 -0
  225. package/dist/utils/export-load.js +70 -0
  226. package/dist/utils/export-load.js.map +1 -0
  227. package/dist/utils/export-rows.d.ts +35 -0
  228. package/dist/utils/export-rows.d.ts.map +1 -0
  229. package/dist/utils/export-rows.js +69 -0
  230. package/dist/utils/export-rows.js.map +1 -0
  231. package/dist/utils/ffmpeg.d.ts +26 -0
  232. package/dist/utils/ffmpeg.d.ts.map +1 -0
  233. package/dist/utils/ffmpeg.js +28 -0
  234. package/dist/utils/ffmpeg.js.map +1 -0
  235. package/dist/utils/format.d.ts +23 -1
  236. package/dist/utils/format.d.ts.map +1 -1
  237. package/dist/utils/format.js +5 -1
  238. package/dist/utils/format.js.map +1 -1
  239. package/dist/utils/frame-plan.d.ts +24 -0
  240. package/dist/utils/frame-plan.d.ts.map +1 -0
  241. package/dist/utils/frame-plan.js +58 -0
  242. package/dist/utils/frame-plan.js.map +1 -0
  243. package/dist/utils/frames.d.ts +32 -0
  244. package/dist/utils/frames.d.ts.map +1 -0
  245. package/dist/utils/frames.js +60 -0
  246. package/dist/utils/frames.js.map +1 -0
  247. package/dist/utils/gif.d.ts +31 -0
  248. package/dist/utils/gif.d.ts.map +1 -0
  249. package/dist/utils/gif.js +77 -0
  250. package/dist/utils/gif.js.map +1 -0
  251. package/dist/utils/harvest-catalog.d.ts +54 -0
  252. package/dist/utils/harvest-catalog.d.ts.map +1 -0
  253. package/dist/utils/harvest-catalog.js +173 -0
  254. package/dist/utils/harvest-catalog.js.map +1 -0
  255. package/dist/utils/harvest-details.d.ts +30 -0
  256. package/dist/utils/harvest-details.d.ts.map +1 -0
  257. package/dist/utils/harvest-details.js +98 -0
  258. package/dist/utils/harvest-details.js.map +1 -0
  259. package/dist/utils/harvest-lock.d.ts +3 -0
  260. package/dist/utils/harvest-lock.d.ts.map +1 -0
  261. package/dist/utils/harvest-lock.js +26 -0
  262. package/dist/utils/harvest-lock.js.map +1 -0
  263. package/dist/utils/harvest-receipts.d.ts +14 -0
  264. package/dist/utils/harvest-receipts.d.ts.map +1 -0
  265. package/dist/utils/harvest-receipts.js +110 -0
  266. package/dist/utils/harvest-receipts.js.map +1 -0
  267. package/dist/utils/listing-cursor.d.ts +31 -0
  268. package/dist/utils/listing-cursor.d.ts.map +1 -0
  269. package/dist/utils/listing-cursor.js +39 -0
  270. package/dist/utils/listing-cursor.js.map +1 -0
  271. package/dist/utils/local-transcription.d.ts +14 -0
  272. package/dist/utils/local-transcription.d.ts.map +1 -0
  273. package/dist/utils/local-transcription.js +85 -0
  274. package/dist/utils/local-transcription.js.map +1 -0
  275. package/dist/utils/moment.d.ts +24 -0
  276. package/dist/utils/moment.d.ts.map +1 -0
  277. package/dist/utils/moment.js +22 -0
  278. package/dist/utils/moment.js.map +1 -0
  279. package/dist/utils/most-replayed.d.ts +15 -0
  280. package/dist/utils/most-replayed.d.ts.map +1 -0
  281. package/dist/utils/most-replayed.js +25 -0
  282. package/dist/utils/most-replayed.js.map +1 -0
  283. package/dist/utils/pot-preflight.d.ts +53 -0
  284. package/dist/utils/pot-preflight.d.ts.map +1 -0
  285. package/dist/utils/pot-preflight.js +146 -0
  286. package/dist/utils/pot-preflight.js.map +1 -0
  287. package/dist/utils/scenes.d.ts +39 -0
  288. package/dist/utils/scenes.d.ts.map +1 -0
  289. package/dist/utils/scenes.js +83 -0
  290. package/dist/utils/scenes.js.map +1 -0
  291. package/dist/utils/seconds.d.ts +5 -0
  292. package/dist/utils/seconds.d.ts.map +1 -0
  293. package/dist/utils/seconds.js +7 -0
  294. package/dist/utils/seconds.js.map +1 -0
  295. package/dist/utils/sleep.d.ts +9 -0
  296. package/dist/utils/sleep.d.ts.map +1 -0
  297. package/dist/utils/sleep.js +25 -0
  298. package/dist/utils/sleep.js.map +1 -0
  299. package/dist/utils/sponsorblock.d.ts +24 -0
  300. package/dist/utils/sponsorblock.d.ts.map +1 -0
  301. package/dist/utils/sponsorblock.js +153 -0
  302. package/dist/utils/sponsorblock.js.map +1 -0
  303. package/dist/utils/store-health.d.ts +37 -0
  304. package/dist/utils/store-health.d.ts.map +1 -0
  305. package/dist/utils/store-health.js +92 -0
  306. package/dist/utils/store-health.js.map +1 -0
  307. package/dist/utils/store-migrations.d.ts +33 -0
  308. package/dist/utils/store-migrations.d.ts.map +1 -0
  309. package/dist/utils/store-migrations.js +41 -0
  310. package/dist/utils/store-migrations.js.map +1 -0
  311. package/dist/utils/store-paths.d.ts +33 -0
  312. package/dist/utils/store-paths.d.ts.map +1 -0
  313. package/dist/utils/store-paths.js +48 -0
  314. package/dist/utils/store-paths.js.map +1 -0
  315. package/dist/utils/store-rows.d.ts +22 -0
  316. package/dist/utils/store-rows.d.ts.map +1 -0
  317. package/dist/utils/store-rows.js +62 -0
  318. package/dist/utils/store-rows.js.map +1 -0
  319. package/dist/utils/store-schema.d.ts +16 -0
  320. package/dist/utils/store-schema.d.ts.map +1 -0
  321. package/dist/utils/store-schema.js +168 -0
  322. package/dist/utils/store-schema.js.map +1 -0
  323. package/dist/utils/store.d.ts +34 -0
  324. package/dist/utils/store.d.ts.map +1 -0
  325. package/dist/utils/store.js +157 -0
  326. package/dist/utils/store.js.map +1 -0
  327. package/dist/utils/transcript-cache.d.ts +5 -1
  328. package/dist/utils/transcript-cache.d.ts.map +1 -1
  329. package/dist/utils/transcript-cache.js +31 -50
  330. package/dist/utils/transcript-cache.js.map +1 -1
  331. package/dist/utils/transcript-files.d.ts +24 -0
  332. package/dist/utils/transcript-files.d.ts.map +1 -0
  333. package/dist/utils/transcript-files.js +61 -0
  334. package/dist/utils/transcript-files.js.map +1 -0
  335. package/dist/utils/transcript.d.ts +3 -0
  336. package/dist/utils/transcript.d.ts.map +1 -1
  337. package/dist/utils/transcript.js +2 -0
  338. package/dist/utils/transcript.js.map +1 -1
  339. package/dist/utils/upload-check.d.ts +38 -0
  340. package/dist/utils/upload-check.d.ts.map +1 -0
  341. package/dist/utils/upload-check.js +93 -0
  342. package/dist/utils/upload-check.js.map +1 -0
  343. package/dist/utils/validate.d.ts +2 -0
  344. package/dist/utils/validate.d.ts.map +1 -1
  345. package/dist/utils/validate.js +4 -0
  346. package/dist/utils/validate.js.map +1 -1
  347. package/dist/utils/video-detail-store.d.ts +47 -0
  348. package/dist/utils/video-detail-store.d.ts.map +1 -0
  349. package/dist/utils/video-detail-store.js +89 -0
  350. package/dist/utils/video-detail-store.js.map +1 -0
  351. package/dist/utils/video-stats-cache.d.ts +16 -0
  352. package/dist/utils/video-stats-cache.d.ts.map +1 -0
  353. package/dist/utils/video-stats-cache.js +81 -0
  354. package/dist/utils/video-stats-cache.js.map +1 -0
  355. package/dist/utils/video-stats-schema.d.ts +187 -0
  356. package/dist/utils/video-stats-schema.d.ts.map +1 -0
  357. package/dist/utils/video-stats-schema.js +50 -0
  358. package/dist/utils/video-stats-schema.js.map +1 -0
  359. package/dist/utils/video-stats-storage.d.ts +16 -0
  360. package/dist/utils/video-stats-storage.d.ts.map +1 -0
  361. package/dist/utils/video-stats-storage.js +37 -0
  362. package/dist/utils/video-stats-storage.js.map +1 -0
  363. package/dist/utils/video-stats.d.ts +82 -0
  364. package/dist/utils/video-stats.d.ts.map +1 -0
  365. package/dist/utils/video-stats.js +108 -0
  366. package/dist/utils/video-stats.js.map +1 -0
  367. package/dist/utils/video-store.d.ts +69 -0
  368. package/dist/utils/video-store.d.ts.map +1 -0
  369. package/dist/utils/video-store.js +77 -0
  370. package/dist/utils/video-store.js.map +1 -0
  371. package/dist/utils/video-stream.d.ts +21 -0
  372. package/dist/utils/video-stream.d.ts.map +1 -0
  373. package/dist/utils/video-stream.js +36 -0
  374. package/dist/utils/video-stream.js.map +1 -0
  375. package/dist/utils/whisper.d.ts +39 -0
  376. package/dist/utils/whisper.d.ts.map +1 -0
  377. package/dist/utils/whisper.js +137 -0
  378. package/dist/utils/whisper.js.map +1 -0
  379. package/dist/utils/youtube-channel.d.ts +13 -2
  380. package/dist/utils/youtube-channel.d.ts.map +1 -1
  381. package/dist/utils/youtube-channel.js +39 -3
  382. package/dist/utils/youtube-channel.js.map +1 -1
  383. package/dist/utils/youtube-schemas.d.ts +104 -0
  384. package/dist/utils/youtube-schemas.d.ts.map +1 -1
  385. package/dist/utils/youtube-schemas.js +32 -0
  386. package/dist/utils/youtube-schemas.js.map +1 -1
  387. package/dist/utils/youtube-video.d.ts +22 -1
  388. package/dist/utils/youtube-video.d.ts.map +1 -1
  389. package/dist/utils/youtube-video.js +40 -28
  390. package/dist/utils/youtube-video.js.map +1 -1
  391. package/dist/utils/ytdlp-limiter.d.ts +3 -0
  392. package/dist/utils/ytdlp-limiter.d.ts.map +1 -1
  393. package/dist/utils/ytdlp-limiter.js +19 -3
  394. package/dist/utils/ytdlp-limiter.js.map +1 -1
  395. package/dist/utils/ytdlp-pacer.d.ts +64 -0
  396. package/dist/utils/ytdlp-pacer.d.ts.map +1 -0
  397. package/dist/utils/ytdlp-pacer.js +165 -0
  398. package/dist/utils/ytdlp-pacer.js.map +1 -0
  399. package/dist/utils/ytdlp-stream.d.ts +32 -0
  400. package/dist/utils/ytdlp-stream.d.ts.map +1 -0
  401. package/dist/utils/ytdlp-stream.js +61 -0
  402. package/dist/utils/ytdlp-stream.js.map +1 -0
  403. package/dist/utils/ytdlp.d.ts +10 -0
  404. package/dist/utils/ytdlp.d.ts.map +1 -1
  405. package/dist/utils/ytdlp.js +36 -25
  406. package/dist/utils/ytdlp.js.map +1 -1
  407. package/package.json +10 -4
@@ -0,0 +1,165 @@
1
+ /**
2
+ * How this server reacts to being throttled.
3
+ *
4
+ * The old behaviour was three attempts with at most ~1.5 seconds of jitter and
5
+ * no memory between calls, which is fine for a blip and useless for an
6
+ * hour-long harvest: nothing slowed down, nothing waited, and a hard block
7
+ * produced an hour of identical failures.
8
+ *
9
+ * This adds three things that only make sense across calls — a shared
10
+ * cooldown, an adaptive concurrency ceiling, and a circuit breaker — so the
11
+ * state is deliberately process-global, the same scope as the limiter it
12
+ * cooperates with.
13
+ */
14
+ export const RATE_LIMIT_COOLDOWN_BASE_MS = 30_000;
15
+ export const RATE_LIMIT_COOLDOWN_MAX_MS = 15 * 60_000;
16
+ export const BOT_CHECK_COOLDOWN_MS = 10 * 60_000;
17
+ export const MAX_BACKOFF_MS = 120_000;
18
+ export const BASE_BACKOFF_MS = 750;
19
+ export const AIMD_MIN_CONCURRENCY = 1;
20
+ export const AIMD_INCREASE_AFTER_SUCCESSES = 20;
21
+ export const AIMD_DECREASE_FACTOR = 0.5;
22
+ /** Consecutive throttles before a global cooldown starts. */
23
+ export const COOLDOWN_AFTER_STRIKES = 2;
24
+ export const CIRCUIT_STRIKES = 5;
25
+ export const CIRCUIT_OPEN_MS = 5 * 60_000;
26
+ const TERMINAL = {
27
+ attempts: 1,
28
+ backoff: 'none',
29
+ cooldown: 'none',
30
+ concurrency: 'none',
31
+ };
32
+ /**
33
+ * What to do about each kind of failure.
34
+ *
35
+ * BOT_CHECK does not retry, and that is measured rather than assumed: from a
36
+ * datacenter address, eight player clients, a fifteen-minute cooldown, a PO
37
+ * token provider and curl_cffi TLS impersonation all returned the same answer.
38
+ * Retrying spends requests on a known-dead path; stopping and naming the cause
39
+ * is the useful response. The cooldown still applies, because whatever else is
40
+ * in flight should not keep hammering.
41
+ */
42
+ const POLICIES = {
43
+ RATE_LIMITED: {
44
+ attempts: 5,
45
+ backoff: 'exponential',
46
+ cooldown: 'rate-limit',
47
+ concurrency: 'decrease',
48
+ },
49
+ BOT_CHECK: { attempts: 1, backoff: 'none', cooldown: 'bot-check', concurrency: 'floor' },
50
+ TIMEOUT: { attempts: 3, backoff: 'exponential', cooldown: 'none', concurrency: 'decrease' },
51
+ // Deliberately absent: an unclassified yt-dlp failure carries no evidence
52
+ // that a second attempt would go differently, and `retryable` is false on it,
53
+ // so it falls through to TERMINAL. Listing it here with attempts > 1 would
54
+ // state a policy the retry loop correctly refuses to honour.
55
+ };
56
+ export function policyFor(code) {
57
+ return POLICIES[code] ?? TERMINAL;
58
+ }
59
+ let state = {
60
+ cooldownUntil: 0,
61
+ circuitOpenUntil: 0,
62
+ strikes: 0,
63
+ successes: 0,
64
+ concurrency: Number.POSITIVE_INFINITY,
65
+ };
66
+ /** ±25% so parallel callers do not come back in lockstep. */
67
+ function jitter(ms) {
68
+ return Math.round(ms * (0.75 + Math.random() * 0.5));
69
+ }
70
+ function cooldownFor(kind, strikes) {
71
+ if (kind === 'none')
72
+ return 0;
73
+ if (kind === 'bot-check')
74
+ return BOT_CHECK_COOLDOWN_MS;
75
+ const escalated = RATE_LIMIT_COOLDOWN_BASE_MS * 2 ** Math.max(0, strikes - 1);
76
+ return jitter(Math.min(escalated, RATE_LIMIT_COOLDOWN_MAX_MS));
77
+ }
78
+ export function backoffDelay(attempt, style) {
79
+ if (style === 'none')
80
+ return 0;
81
+ // Exponential with full jitter, capped so a long run cannot stall for hours.
82
+ const ceiling = Math.min(BASE_BACKOFF_MS * 2 ** (attempt - 1), MAX_BACKOFF_MS);
83
+ return Math.round(Math.random() * ceiling);
84
+ }
85
+ /** Records a failure and says whether to try again, and after how long. */
86
+ export function onFailure(code, attempt, now = Date.now()) {
87
+ const policy = policyFor(code);
88
+ const throttled = policy.cooldown !== 'none';
89
+ if (throttled) {
90
+ state.strikes += 1;
91
+ state.successes = 0;
92
+ // A first strike gets the exponential backoff and nothing more: one 429 is
93
+ // a blip, and making a single interactive call wait out a 30-second global
94
+ // cooldown would be worse than the problem. The cooldown starts once the
95
+ // client has been refused twice in a row, which is when it has stopped
96
+ // being a blip. A bot check skips the grace: it was measured not to clear
97
+ // on its own, so there is nothing to be gained by trying again sooner.
98
+ const grace = policy.cooldown === 'bot-check' ? 1 : COOLDOWN_AFTER_STRIKES;
99
+ if (state.strikes >= grace) {
100
+ state.cooldownUntil = Math.max(state.cooldownUntil, now + cooldownFor(policy.cooldown, state.strikes));
101
+ }
102
+ if (policy.concurrency === 'floor') {
103
+ state.concurrency = AIMD_MIN_CONCURRENCY;
104
+ }
105
+ else if (policy.concurrency === 'decrease') {
106
+ state.concurrency = Math.max(AIMD_MIN_CONCURRENCY, Math.floor(effectiveConcurrency(now) * AIMD_DECREASE_FACTOR));
107
+ }
108
+ if (state.strikes >= CIRCUIT_STRIKES) {
109
+ state.circuitOpenUntil = now + CIRCUIT_OPEN_MS;
110
+ }
111
+ }
112
+ return attempt >= policy.attempts
113
+ ? { giveUp: true, delayMs: 0 }
114
+ : { giveUp: false, delayMs: backoffDelay(attempt, policy.backoff) };
115
+ }
116
+ /** Records a clean spawn, easing the ceiling back up one step at a time. */
117
+ export function onSuccess() {
118
+ state.strikes = 0;
119
+ state.successes += 1;
120
+ if (state.successes >= AIMD_INCREASE_AFTER_SUCCESSES) {
121
+ state.successes = 0;
122
+ if (Number.isFinite(state.concurrency))
123
+ state.concurrency += 1;
124
+ }
125
+ }
126
+ /** How long a caller should wait before spawning, in milliseconds. */
127
+ export function waitMs(now = Date.now()) {
128
+ if (state.circuitOpenUntil > now)
129
+ return state.circuitOpenUntil - now;
130
+ return Math.max(0, state.cooldownUntil - now);
131
+ }
132
+ export function circuitOpen(now = Date.now()) {
133
+ return state.circuitOpenUntil > now;
134
+ }
135
+ /**
136
+ * The ceiling the limiter should honour right now.
137
+ *
138
+ * Infinite until something throttles us, so an untroubled server runs at
139
+ * whatever YOUTUBE_MCP_MAX_CONCURRENCY allows and the limiter stays the only
140
+ * authority on the normal case.
141
+ */
142
+ export function effectiveConcurrency(now = Date.now()) {
143
+ if (circuitOpen(now))
144
+ return AIMD_MIN_CONCURRENCY;
145
+ return state.concurrency;
146
+ }
147
+ export function pacerState(now = Date.now()) {
148
+ return {
149
+ cooldownMs: waitMs(now),
150
+ circuitOpen: circuitOpen(now),
151
+ strikes: state.strikes,
152
+ concurrency: effectiveConcurrency(now),
153
+ };
154
+ }
155
+ /** Test seam; the pacer is process-global in normal use. */
156
+ export function resetPacer() {
157
+ state = {
158
+ cooldownUntil: 0,
159
+ circuitOpenUntil: 0,
160
+ strikes: 0,
161
+ successes: 0,
162
+ concurrency: Number.POSITIVE_INFINITY,
163
+ };
164
+ }
165
+ //# sourceMappingURL=ytdlp-pacer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ytdlp-pacer.js","sourceRoot":"","sources":["../../src/utils/ytdlp-pacer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Running yt-dlp and reading its output a line at a time.
3
+ *
4
+ * `runYtDlp` buffers everything into a string, which is right for a metadata
5
+ * read and wrong for a long walk: a 40,000-entry channel listing killed at
6
+ * minute nine yields nothing at all, and the 64MB buffer is a hard ceiling.
7
+ *
8
+ * Here each line is handed over as it arrives, so a caller can checkpoint as
9
+ * it goes and keep what it already had. Paired with `--lazy-playlist`, which
10
+ * makes yt-dlp emit entries while it walks rather than after.
11
+ */
12
+ export interface StreamOptions {
13
+ label?: string;
14
+ timeoutMs?: number;
15
+ target: string;
16
+ /** Called per line, in order. A throw here aborts the walk. */
17
+ onLine: (line: string) => void;
18
+ }
19
+ export interface StreamResult {
20
+ lines: number;
21
+ /** False when the walk was cut short, so the caller knows not to claim completeness. */
22
+ completed: boolean;
23
+ }
24
+ /**
25
+ * Streams stdout line by line.
26
+ *
27
+ * A failure part-way through is not thrown away: the caller keeps every line
28
+ * delivered so far and is told the walk did not complete, which is the whole
29
+ * point of streaming rather than buffering.
30
+ */
31
+ export declare function runYtDlpLines(args: string[], options: StreamOptions): Promise<StreamResult>;
32
+ //# sourceMappingURL=ytdlp-stream.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ytdlp-stream.d.ts","sourceRoot":"","sources":["../../src/utils/ytdlp-stream.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,+DAA+D;IAC/D,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,wFAAwF;IACxF,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CA+CjG"}
@@ -0,0 +1,61 @@
1
+ import { execa } from 'execa';
2
+ import { createInterface } from 'node:readline';
3
+ import { currentContext } from './context.js';
4
+ import { acquireSlot, releaseSlot } from './ytdlp-limiter.js';
5
+ import { readYtDlpEnv } from './ytdlp-env.js';
6
+ import { YouTubeError } from './errors.js';
7
+ import { SOCKET_TIMEOUT_S } from './ytdlp.js';
8
+ /**
9
+ * Streams stdout line by line.
10
+ *
11
+ * A failure part-way through is not thrown away: the caller keeps every line
12
+ * delivered so far and is told the walk did not complete, which is the whole
13
+ * point of streaming rather than buffering.
14
+ */
15
+ export async function runYtDlpLines(args, options) {
16
+ const { timeoutMs = 0, target, onLine } = options;
17
+ const { signal } = currentContext();
18
+ if (signal?.aborted === true) {
19
+ throw new YouTubeError('CANCELLED', 'The request was cancelled.');
20
+ }
21
+ await acquireSlot(signal);
22
+ let lines = 0;
23
+ try {
24
+ const argv = [
25
+ '--socket-timeout',
26
+ SOCKET_TIMEOUT_S,
27
+ ...readYtDlpEnv().args,
28
+ ...args,
29
+ '--',
30
+ target,
31
+ ];
32
+ const child = execa('yt-dlp', argv, {
33
+ timeout: timeoutMs > 0 ? timeoutMs : undefined,
34
+ cancelSignal: signal,
35
+ buffer: false,
36
+ stdout: 'pipe',
37
+ });
38
+ // `stdout: 'pipe'` with `buffer: false` guarantees a stream here, so there
39
+ // is nothing to guard against.
40
+ const reader = createInterface({ input: child.stdout, crlfDelay: Infinity });
41
+ for await (const line of reader) {
42
+ if (line.trim() === '')
43
+ continue;
44
+ onLine(line);
45
+ lines += 1;
46
+ }
47
+ await child;
48
+ return { lines, completed: true };
49
+ }
50
+ catch (error) {
51
+ // Everything delivered so far is already the caller's. Reporting how far
52
+ // it got matters more than the reason, which the caller can classify.
53
+ if (error instanceof YouTubeError)
54
+ throw error;
55
+ return { lines, completed: false };
56
+ }
57
+ finally {
58
+ releaseSlot();
59
+ }
60
+ }
61
+ //# sourceMappingURL=ytdlp-stream.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ytdlp-stream.js","sourceRoot":"","sources":["../../src/utils/ytdlp-stream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AA4B9C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAc,EAAE,OAAsB;IACxE,MAAM,EAAE,SAAS,GAAG,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAClD,MAAM,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;IAEpC,IAAI,MAAM,EAAE,OAAO,KAAK,IAAI,EAAE,CAAC;QAC7B,MAAM,IAAI,YAAY,CAAC,WAAW,EAAE,4BAA4B,CAAC,CAAC;IACpE,CAAC;IAED,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;IAC1B,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,IAAI,CAAC;QACH,MAAM,IAAI,GAAG;YACX,kBAAkB;YAClB,gBAAgB;YAChB,GAAG,YAAY,EAAE,CAAC,IAAI;YACtB,GAAG,IAAI;YACP,IAAI;YACJ,MAAM;SACP,CAAC;QAEF,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE;YAClC,OAAO,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YAC9C,YAAY,EAAE,MAAM;YACpB,MAAM,EAAE,KAAK;YACb,MAAM,EAAE,MAAM;SACf,CAAC,CAAC;QAEH,2EAA2E;QAC3E,+BAA+B;QAC/B,MAAM,MAAM,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC7E,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;YAChC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE;gBAAE,SAAS;YACjC,MAAM,CAAC,IAAI,CAAC,CAAC;YACb,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;QAED,MAAM,KAAK,CAAC;QACZ,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,yEAAyE;QACzE,sEAAsE;QACtE,IAAI,KAAK,YAAY,YAAY;YAAE,MAAM,KAAK,CAAC;QAC/C,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACrC,CAAC;YAAS,CAAC;QACT,WAAW,EAAE,CAAC;IAChB,CAAC;AACH,CAAC"}
@@ -19,6 +19,16 @@ export declare const TIMEOUTS: {
19
19
  /** Media transfers: unbounded here; cancellation is the client's lever. */
20
20
  readonly download: 0;
21
21
  };
22
+ /**
23
+ * Seconds of socket inactivity before yt-dlp gives up on a connection.
24
+ *
25
+ * Media transfers deliberately run without a wall-clock timeout — a long clip
26
+ * is allowed to take as long as it honestly takes — which left a dead
27
+ * connection indistinguishable from a slow one, holding its concurrency slot
28
+ * forever. This bounds the silence, not the work: a transfer still making
29
+ * progress is never interrupted.
30
+ */
31
+ export declare const SOCKET_TIMEOUT_S = "30";
22
32
  export interface RunOptions {
23
33
  /** Milliseconds before the child is killed. 0 disables the timeout. */
24
34
  timeoutMs?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"ytdlp.d.ts","sourceRoot":"","sources":["../../src/utils/ytdlp.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvE;;;;;;;GAOG;AAEH,kFAAkF;AAClF,eAAO,MAAM,QAAQ;IACnB,wDAAwD;;IAExD,gDAAgD;;IAEhD,iEAAiE;;IAEjE,2EAA2E;;CAEnE,CAAC;AAkBX,MAAM,WAAW,UAAU;IACzB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAsBD;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBnF"}
1
+ {"version":3,"file":"ytdlp.d.ts","sourceRoot":"","sources":["../../src/utils/ytdlp.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvE;;;;;;;GAOG;AAEH,kFAAkF;AAClF,eAAO,MAAM,QAAQ;IACnB,wDAAwD;;IAExD,gDAAgD;;IAEhD,iEAAiE;;IAEjE,2EAA2E;;CAEnE,CAAC;AAMX;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAErC,MAAM,WAAW,UAAU;IACzB,uEAAuE;IACvE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,iFAAiF;IACjF,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wDAAwD;IACxD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA8DnF"}
@@ -1,5 +1,7 @@
1
1
  import { execa, ExecaError } from 'execa';
2
2
  import { currentContext, log } from './context.js';
3
+ import { sleep } from './sleep.js';
4
+ import { circuitOpen, onFailure, onSuccess, waitMs } from './ytdlp-pacer.js';
3
5
  import { YouTubeError, classifyYtDlpFailure } from './errors.js';
4
6
  import { acquireSlot, releaseSlot } from './ytdlp-limiter.js';
5
7
  import { readYtDlpEnv } from './ytdlp-env.js';
@@ -25,7 +27,6 @@ export const TIMEOUTS = {
25
27
  download: 0,
26
28
  };
27
29
  const MAX_ATTEMPTS = 3;
28
- const BASE_BACKOFF_MS = 750;
29
30
  /** Guards against a pathological video description blowing up memory. */
30
31
  const MAX_OUTPUT_BYTES = 64 * 1024 * 1024;
31
32
  /**
@@ -37,25 +38,7 @@ const MAX_OUTPUT_BYTES = 64 * 1024 * 1024;
37
38
  * forever. This bounds the silence, not the work: a transfer still making
38
39
  * progress is never interrupted.
39
40
  */
40
- const SOCKET_TIMEOUT_S = '30';
41
- function backoffDelay(attempt) {
42
- // Exponential with full jitter, so parallel callers do not retry in lockstep.
43
- const ceiling = BASE_BACKOFF_MS * 2 ** (attempt - 1);
44
- return Math.round(Math.random() * ceiling);
45
- }
46
- async function sleep(ms, signal) {
47
- await new Promise((resolve, reject) => {
48
- const timer = setTimeout(() => {
49
- signal?.removeEventListener('abort', onAbort);
50
- resolve();
51
- }, ms);
52
- const onAbort = () => {
53
- clearTimeout(timer);
54
- reject(new YouTubeError('CANCELLED', 'The request was cancelled.'));
55
- };
56
- signal?.addEventListener('abort', onAbort, { once: true });
57
- });
58
- }
41
+ export const SOCKET_TIMEOUT_S = '30';
59
42
  /**
60
43
  * Run yt-dlp and return its stdout.
61
44
  *
@@ -74,17 +57,45 @@ export async function runYtDlp(args, options) {
74
57
  if (signal?.aborted === true) {
75
58
  throw new YouTubeError('CANCELLED', 'The request was cancelled.');
76
59
  }
60
+ // The cooldown gates NEW work, not this call's own retries: it applies on
61
+ // the first attempt only. Mixing the two would make a single call's latency
62
+ // unbounded — its retry would wait out a global cooldown that exists to
63
+ // slow the *next* caller down. Retries use the backoff.
64
+ //
65
+ // Deliberately outside the try: an open circuit is this server's own
66
+ // decision, not a spawn failure, and letting the catch below translate and
67
+ // retry it would spawn the very request the circuit exists to prevent.
68
+ // Waiting also happens before a slot is taken, so a cooling-down server
69
+ // does not sit on the concurrency queue while it waits.
70
+ const wait = attempt === 1 ? waitMs() : 0;
71
+ if (wait > 0) {
72
+ if (circuitOpen()) {
73
+ throw new YouTubeError('RATE_LIMITED', 'YouTube has refused this client repeatedly, so requests are paused.', {
74
+ nextStep: `Wait about ${String(Math.ceil(wait / 60_000))} minutes. If it persists this address is likely being gated: check check_health for the cookie and PO token provider settings.`,
75
+ retryable: true,
76
+ });
77
+ }
78
+ log('info', `${label} waiting ${String(wait)}ms before spawning`);
79
+ await sleep(wait, signal);
80
+ }
77
81
  try {
78
- return await spawnOnce(args, target, timeoutMs, signal);
82
+ const stdout = await spawnOnce(args, target, timeoutMs, signal);
83
+ onSuccess();
84
+ return stdout;
79
85
  }
80
86
  catch (error) {
81
87
  const failure = translateExecaFailure(error, timeoutMs);
82
- if (!failure.retryable || attempt >= maxAttempts)
88
+ const decision = onFailure(failure.code, attempt);
89
+ // The error's own `retryable` wins over the pacer's policy. The
90
+ // classifier read the stderr and knows whether a retry can help; the
91
+ // pacer only knows the code. Dropping this gate made every unclassified
92
+ // YTDLP_FAILED retry, doubling requests on exactly the failures we cannot
93
+ // diagnose — the opposite of the point.
94
+ if (!failure.retryable || decision.giveUp || attempt >= maxAttempts)
83
95
  throw failure;
84
- const delay = backoffDelay(attempt);
85
- log('warning', `${label} failed (${failure.code}), retrying in ${delay}ms`);
96
+ log('warning', `${label} failed (${failure.code}), retrying in ${String(decision.delayMs)}ms`);
86
97
  // The slot is already released, so the backoff does not hold the queue.
87
- await sleep(delay, signal);
98
+ await sleep(decision.delayMs, signal);
88
99
  }
89
100
  }
90
101
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ytdlp.js","sourceRoot":"","sources":["../../src/utils/ytdlp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ytdlp.js","sourceRoot":"","sources":["../../src/utils/ytdlp.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "youtube-knowledge-mcp",
3
- "version": "2.2.0",
3
+ "version": "3.0.1",
4
4
  "description": "MCP Server for extracting and managing YouTube video knowledge",
5
5
  "author": "teobouancheau",
6
6
  "repository": {
@@ -42,9 +42,13 @@
42
42
  "test:coverage": "vitest run --coverage",
43
43
  "test:e2e": "npm run build && vitest run -c vitest.e2e.config.ts",
44
44
  "typecheck": "tsc --noEmit",
45
- "validate": "npm run typecheck && npm run lint && npm run format:check && npm run test:coverage",
45
+ "validate": "npm run secrets && npm run typecheck && npm run lint && npm run format:check && npm run test:coverage",
46
46
  "prepare": "husky",
47
- "prepublishOnly": "npm run rebuild && npm run validate"
47
+ "prepublishOnly": "npm run rebuild && npm run validate",
48
+ "render:icon": "node scripts/render-icon.mjs",
49
+ "secrets": "sh scripts/secret-scan.sh tree",
50
+ "audit": "npm audit --audit-level=moderate",
51
+ "smoke": "npm run build && node scripts/smoke.mjs"
48
52
  },
49
53
  "files": [
50
54
  "dist"
@@ -66,6 +70,8 @@
66
70
  "zod": "^3.25.0"
67
71
  },
68
72
  "devDependencies": {
73
+ "@commitlint/cli": "^21.2.3",
74
+ "@commitlint/config-conventional": "^21.2.3",
69
75
  "@eslint/js": "^10.0.1",
70
76
  "@types/express": "^5.0.6",
71
77
  "@types/node": "^22.20.1",
@@ -83,6 +89,6 @@
83
89
  "vitest": "^4.1.10"
84
90
  },
85
91
  "engines": {
86
- "node": ">=22.0.0"
92
+ "node": ">=22.13.0"
87
93
  }
88
94
  }