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
@@ -92,9 +92,16 @@ export declare const videoDetailsRowSchema: z.ZodObject<{
92
92
  }>, "many">>>;
93
93
  upload_date: z.ZodOptional<z.ZodNullable<z.ZodString>>;
94
94
  duration: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
95
+ /**
96
+ * The video's real comment count — trustworthy ONLY here, because this read
97
+ * does not pass --write-comments. With that flag yt-dlp replaces the value
98
+ * with the number it extracted (measured: 300 against a video with 2.4M).
99
+ */
100
+ comment_count: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
95
101
  }, "strip", z.ZodTypeAny, {
96
102
  duration?: number | null | undefined;
97
103
  upload_date?: string | null | undefined;
104
+ comment_count?: number | null | undefined;
98
105
  chapters?: {
99
106
  title: string;
100
107
  start_time: number;
@@ -103,66 +110,157 @@ export declare const videoDetailsRowSchema: z.ZodObject<{
103
110
  }, {
104
111
  duration?: number | null | undefined;
105
112
  upload_date?: string | null | undefined;
113
+ comment_count?: number | null | undefined;
106
114
  chapters?: {
107
115
  title: string;
108
116
  start_time: number;
109
117
  end_time: number;
110
118
  }[] | null | undefined;
111
119
  }>;
120
+ /**
121
+ * Every field yt-dlp returns for a comment, verified against 2026.08.19.
122
+ *
123
+ * Nine of these were previously dropped on the floor after being paid for:
124
+ * the extraction fetches them either way, so discarding `id` and `parent`
125
+ * meant a thread could not be rebuilt from what we already had.
126
+ */
112
127
  export declare const commentRowSchema: z.ZodObject<{
128
+ id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
113
129
  author: z.ZodOptional<z.ZodNullable<z.ZodString>>;
130
+ author_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
131
+ author_url: z.ZodOptional<z.ZodNullable<z.ZodString>>;
132
+ author_thumbnail: z.ZodOptional<z.ZodNullable<z.ZodString>>;
133
+ author_is_uploader: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
134
+ author_is_verified: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
114
135
  text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
115
136
  like_count: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
116
137
  is_pinned: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
138
+ is_favorited: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
139
+ timestamp: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
140
+ _time_text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
141
+ /** 'root' for a top-level comment; the parent's id for a reply. */
117
142
  parent: z.ZodOptional<z.ZodNullable<z.ZodString>>;
118
143
  }, "strip", z.ZodTypeAny, {
144
+ id?: string | null | undefined;
119
145
  author?: string | null | undefined;
120
146
  text?: string | null | undefined;
147
+ timestamp?: number | null | undefined;
121
148
  parent?: string | null | undefined;
122
149
  like_count?: number | null | undefined;
150
+ author_id?: string | null | undefined;
151
+ author_url?: string | null | undefined;
152
+ author_thumbnail?: string | null | undefined;
153
+ author_is_uploader?: boolean | null | undefined;
154
+ author_is_verified?: boolean | null | undefined;
123
155
  is_pinned?: boolean | null | undefined;
156
+ is_favorited?: boolean | null | undefined;
157
+ _time_text?: string | null | undefined;
124
158
  }, {
159
+ id?: string | null | undefined;
125
160
  author?: string | null | undefined;
126
161
  text?: string | null | undefined;
162
+ timestamp?: number | null | undefined;
127
163
  parent?: string | null | undefined;
128
164
  like_count?: number | null | undefined;
165
+ author_id?: string | null | undefined;
166
+ author_url?: string | null | undefined;
167
+ author_thumbnail?: string | null | undefined;
168
+ author_is_uploader?: boolean | null | undefined;
169
+ author_is_verified?: boolean | null | undefined;
129
170
  is_pinned?: boolean | null | undefined;
171
+ is_favorited?: boolean | null | undefined;
172
+ _time_text?: string | null | undefined;
130
173
  }>;
131
174
  export declare const commentsRowSchema: z.ZodObject<{
132
175
  comments: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodObject<{
176
+ id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
133
177
  author: z.ZodOptional<z.ZodNullable<z.ZodString>>;
178
+ author_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
179
+ author_url: z.ZodOptional<z.ZodNullable<z.ZodString>>;
180
+ author_thumbnail: z.ZodOptional<z.ZodNullable<z.ZodString>>;
181
+ author_is_uploader: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
182
+ author_is_verified: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
134
183
  text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
135
184
  like_count: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
136
185
  is_pinned: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
186
+ is_favorited: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
187
+ timestamp: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
188
+ _time_text: z.ZodOptional<z.ZodNullable<z.ZodString>>;
189
+ /** 'root' for a top-level comment; the parent's id for a reply. */
137
190
  parent: z.ZodOptional<z.ZodNullable<z.ZodString>>;
138
191
  }, "strip", z.ZodTypeAny, {
192
+ id?: string | null | undefined;
139
193
  author?: string | null | undefined;
140
194
  text?: string | null | undefined;
195
+ timestamp?: number | null | undefined;
141
196
  parent?: string | null | undefined;
142
197
  like_count?: number | null | undefined;
198
+ author_id?: string | null | undefined;
199
+ author_url?: string | null | undefined;
200
+ author_thumbnail?: string | null | undefined;
201
+ author_is_uploader?: boolean | null | undefined;
202
+ author_is_verified?: boolean | null | undefined;
143
203
  is_pinned?: boolean | null | undefined;
204
+ is_favorited?: boolean | null | undefined;
205
+ _time_text?: string | null | undefined;
144
206
  }, {
207
+ id?: string | null | undefined;
145
208
  author?: string | null | undefined;
146
209
  text?: string | null | undefined;
210
+ timestamp?: number | null | undefined;
147
211
  parent?: string | null | undefined;
148
212
  like_count?: number | null | undefined;
213
+ author_id?: string | null | undefined;
214
+ author_url?: string | null | undefined;
215
+ author_thumbnail?: string | null | undefined;
216
+ author_is_uploader?: boolean | null | undefined;
217
+ author_is_verified?: boolean | null | undefined;
149
218
  is_pinned?: boolean | null | undefined;
219
+ is_favorited?: boolean | null | undefined;
220
+ _time_text?: string | null | undefined;
150
221
  }>, "many">>>;
222
+ /**
223
+ * With --write-comments yt-dlp OVERWRITES this with the number extracted,
224
+ * and sets it to null when the extraction was interrupted. So it is a
225
+ * three-state signal about this run, never the video's real total, which
226
+ * only a separate metadata pass can report.
227
+ */
228
+ comment_count: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
151
229
  }, "strip", z.ZodTypeAny, {
230
+ comment_count?: number | null | undefined;
152
231
  comments?: {
232
+ id?: string | null | undefined;
153
233
  author?: string | null | undefined;
154
234
  text?: string | null | undefined;
235
+ timestamp?: number | null | undefined;
155
236
  parent?: string | null | undefined;
156
237
  like_count?: number | null | undefined;
238
+ author_id?: string | null | undefined;
239
+ author_url?: string | null | undefined;
240
+ author_thumbnail?: string | null | undefined;
241
+ author_is_uploader?: boolean | null | undefined;
242
+ author_is_verified?: boolean | null | undefined;
157
243
  is_pinned?: boolean | null | undefined;
244
+ is_favorited?: boolean | null | undefined;
245
+ _time_text?: string | null | undefined;
158
246
  }[] | null | undefined;
159
247
  }, {
248
+ comment_count?: number | null | undefined;
160
249
  comments?: {
250
+ id?: string | null | undefined;
161
251
  author?: string | null | undefined;
162
252
  text?: string | null | undefined;
253
+ timestamp?: number | null | undefined;
163
254
  parent?: string | null | undefined;
164
255
  like_count?: number | null | undefined;
256
+ author_id?: string | null | undefined;
257
+ author_url?: string | null | undefined;
258
+ author_thumbnail?: string | null | undefined;
259
+ author_is_uploader?: boolean | null | undefined;
260
+ author_is_verified?: boolean | null | undefined;
165
261
  is_pinned?: boolean | null | undefined;
262
+ is_favorited?: boolean | null | undefined;
263
+ _time_text?: string | null | undefined;
166
264
  }[] | null | undefined;
167
265
  }>;
168
266
  export declare const formatRowSchema: z.ZodObject<{
@@ -340,24 +438,30 @@ export declare const channelMetaSchema: z.ZodObject<{
340
438
  channel_url: z.ZodOptional<z.ZodNullable<z.ZodString>>;
341
439
  uploader_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
342
440
  channel_follower_count: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
441
+ channel_is_verified: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
442
+ tags: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString, "many">>>;
343
443
  description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
344
444
  /** Checked by `selectChannelImages`, which tolerates any shape. */
345
445
  thumbnails: z.ZodUnknown;
346
446
  }, "strip", z.ZodTypeAny, {
347
447
  channel?: string | null | undefined;
348
448
  description?: string | null | undefined;
449
+ tags?: string[] | null | undefined;
349
450
  channel_id?: string | null | undefined;
350
451
  channel_url?: string | null | undefined;
351
452
  uploader_id?: string | null | undefined;
352
453
  channel_follower_count?: number | null | undefined;
454
+ channel_is_verified?: boolean | null | undefined;
353
455
  thumbnails?: unknown;
354
456
  }, {
355
457
  channel?: string | null | undefined;
356
458
  description?: string | null | undefined;
459
+ tags?: string[] | null | undefined;
357
460
  channel_id?: string | null | undefined;
358
461
  channel_url?: string | null | undefined;
359
462
  uploader_id?: string | null | undefined;
360
463
  channel_follower_count?: number | null | undefined;
464
+ channel_is_verified?: boolean | null | undefined;
361
465
  thumbnails?: unknown;
362
466
  }>;
363
467
  export declare const playlistMetaSchema: z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"youtube-schemas.d.ts","sourceRoot":"","sources":["../../src/utils/youtube-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;GAQG;AAEH,2FAA2F;AAC3F,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgB7B,CAAC;AAEH,wFAAwF;AACxF,eAAO,MAAM,kBAAkB;;;;;;;;;EAG7B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;EAI3B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAIhC,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;EAM3B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE5B,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAY1B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE3B,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;EAG9B,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;EAO7B,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;EASjC,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;IAO5B,mEAAmE;;;;;;;;;;;;;;;;;;EAEnE,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAU7B,CAAC"}
1
+ {"version":3,"file":"youtube-schemas.d.ts","sourceRoot":"","sources":["../../src/utils/youtube-schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;GAQG;AAEH,2FAA2F;AAC3F,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgB7B,CAAC;AAEH,wFAAwF;AACxF,eAAO,MAAM,kBAAkB;;;;;;;;;EAG7B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;EAI3B,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;IAIhC;;;;OAIG;;;;;;;;;;;;;;;;;;;;EAEH,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;IAc3B,mEAAmE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEnE,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;QAJ5B,mEAAmE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAMnE;;;;;OAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEH,CAAC;AAEH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAY1B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE3B,CAAC;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;EAG9B,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;EAO7B,CAAC;AAEH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;EASjC,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;IAS5B,mEAAmE;;;;;;;;;;;;;;;;;;;;;;EAEnE,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAU7B,CAAC"}
@@ -40,16 +40,46 @@ export const videoDetailsRowSchema = z.object({
40
40
  chapters: z.array(chapterRowSchema).nullish(),
41
41
  upload_date: z.string().nullish(),
42
42
  duration: z.number().nullish(),
43
+ /**
44
+ * The video's real comment count — trustworthy ONLY here, because this read
45
+ * does not pass --write-comments. With that flag yt-dlp replaces the value
46
+ * with the number it extracted (measured: 300 against a video with 2.4M).
47
+ */
48
+ comment_count: z.number().nullish(),
43
49
  });
50
+ /**
51
+ * Every field yt-dlp returns for a comment, verified against 2026.08.19.
52
+ *
53
+ * Nine of these were previously dropped on the floor after being paid for:
54
+ * the extraction fetches them either way, so discarding `id` and `parent`
55
+ * meant a thread could not be rebuilt from what we already had.
56
+ */
44
57
  export const commentRowSchema = z.object({
58
+ id: z.string().nullish(),
45
59
  author: z.string().nullish(),
60
+ author_id: z.string().nullish(),
61
+ author_url: z.string().nullish(),
62
+ author_thumbnail: z.string().nullish(),
63
+ author_is_uploader: z.boolean().nullish(),
64
+ author_is_verified: z.boolean().nullish(),
46
65
  text: z.string().nullish(),
47
66
  like_count: z.number().nullish(),
48
67
  is_pinned: z.boolean().nullish(),
68
+ is_favorited: z.boolean().nullish(),
69
+ timestamp: z.number().nullish(),
70
+ _time_text: z.string().nullish(),
71
+ /** 'root' for a top-level comment; the parent's id for a reply. */
49
72
  parent: z.string().nullish(),
50
73
  });
51
74
  export const commentsRowSchema = z.object({
52
75
  comments: z.array(commentRowSchema).nullish(),
76
+ /**
77
+ * With --write-comments yt-dlp OVERWRITES this with the number extracted,
78
+ * and sets it to null when the extraction was interrupted. So it is a
79
+ * three-state signal about this run, never the video's real total, which
80
+ * only a separate metadata pass can report.
81
+ */
82
+ comment_count: z.number().nullish(),
53
83
  });
54
84
  export const formatRowSchema = z.object({
55
85
  format_id: z.string(),
@@ -100,6 +130,8 @@ export const channelMetaSchema = z.object({
100
130
  channel_url: z.string().nullish(),
101
131
  uploader_id: z.string().nullish(),
102
132
  channel_follower_count: z.number().nullish(),
133
+ channel_is_verified: z.boolean().nullish(),
134
+ tags: z.array(z.string()).nullish(),
103
135
  description: z.string().nullish(),
104
136
  /** Checked by `selectChannelImages`, which tolerates any shape. */
105
137
  thumbnails: z.unknown(),
@@ -1 +1 @@
1
- {"version":3,"file":"youtube-schemas.js","sourceRoot":"","sources":["../../src/utils/youtube-schemas.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"youtube-schemas.js","sourceRoot":"","sources":["../../src/utils/youtube-schemas.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { type ThreadedComments } from './comment-threads.js';
1
2
  /** Everything read about one video: metadata, chapters and comments. */
2
3
  export interface VideoInfo {
3
4
  id: string;
@@ -41,7 +42,27 @@ export interface VideoDetails {
41
42
  uploadDate: string;
42
43
  durationSeconds: number;
43
44
  chapters: Chapter[];
45
+ /** YouTube's own count, from a read without --write-comments. Approximate and lagging. */
46
+ commentCount?: number;
44
47
  }
45
48
  export declare function getVideoDetails(urlOrId: string): Promise<VideoDetails>;
46
- export declare function getComments(urlOrId: string, limit?: number): Promise<VideoComment[]>;
49
+ export interface CommentsResult extends ThreadedComments {
50
+ /**
51
+ * Whether yt-dlp's own iteration finished rather than being cut off.
52
+ *
53
+ * From common.py:3882-3908: `comment_count` is overwritten with the number
54
+ * extracted, and set to null when the walk was interrupted. Necessary for
55
+ * completeness but NOT sufficient — `itertools.islice` also ends iteration
56
+ * at a cap, so a capped run reports that it finished too.
57
+ */
58
+ ranToExhaustion: boolean;
59
+ /** True when the video has comments turned off, where zero is the real total. */
60
+ commentsDisabled: boolean;
61
+ extractedTotal: number;
62
+ }
63
+ export declare function getComments(urlOrId: string, options?: {
64
+ limit?: number;
65
+ sort?: 'top' | 'new';
66
+ maxRepliesPerThread?: number;
67
+ }): Promise<CommentsResult>;
47
68
  //# sourceMappingURL=youtube-video.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"youtube-video.d.ts","sourceRoot":"","sources":["../../src/utils/youtube-video.ts"],"names":[],"mappings":"AAMA,wEAAwE;AAExE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAKD,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAoDtE;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAErE;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAqB5E;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,SAAK,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA2BtF"}
1
+ {"version":3,"file":"youtube-video.d.ts","sourceRoot":"","sources":["../../src/utils/youtube-video.ts"],"names":[],"mappings":"AAKA,OAAO,EAAa,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGxE,wEAAwE;AAExE,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAKD,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAoDtE;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAErE;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,0FAA0F;IAC1F,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAkB5E;AAED,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD;;;;;;;OAOG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB,iFAAiF;IACjF,gBAAgB,EAAE,OAAO,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAsB,WAAW,CAC/B,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IAAC,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAAO,GACnF,OAAO,CAAC,cAAc,CAAC,CAgCzB"}
@@ -1,8 +1,10 @@
1
1
  import { formatYouTubeDate } from './format.js';
2
2
  import { classifyPlayability } from './errors.js';
3
3
  import { TIMEOUTS, parseYtDlpJson, runYtDlp } from './ytdlp.js';
4
- import { commentsRowSchema, videoDetailsRowSchema, videoInfoRowSchema } from './youtube-schemas.js';
4
+ import { commentsRowSchema, videoInfoRowSchema } from './youtube-schemas.js';
5
5
  import { extractVideoId, formatDuration, watchUrl } from './youtube-url.js';
6
+ import { toThreads } from './comment-threads.js';
7
+ import { readVideoStats } from './video-stats-cache.js';
6
8
  const VIDEO_INFO_TEMPLATE = '%(.{id,title,channel,duration,upload_date,description,tags,thumbnail,view_count,like_count,comment_count,availability,live_status})j';
7
9
  export async function getVideoInfo(urlOrId) {
8
10
  const videoId = extractVideoId(urlOrId);
@@ -54,26 +56,26 @@ export async function getChapters(urlOrId) {
54
56
  return (await getVideoDetails(urlOrId)).chapters;
55
57
  }
56
58
  export async function getVideoDetails(urlOrId) {
57
- const videoId = extractVideoId(urlOrId);
58
- const url = watchUrl(videoId);
59
- const stdout = await runYtDlp(['-j', '--skip-download'], {
60
- label: 'get_video_details',
61
- target: url,
62
- });
63
- const data = parseYtDlpJson(stdout, videoDetailsRowSchema, 'video details');
59
+ // A projection of the one full read, not a second spawn. This used to run
60
+ // its own `-j` and discard everything but three fields, so a caller wanting
61
+ // a title and a chapter list paid for two extractions of the same video.
62
+ const { stats } = await readVideoStats(urlOrId);
64
63
  return {
65
- uploadDate: formatYouTubeDate(data.upload_date ?? ''),
66
- durationSeconds: typeof data.duration === 'number' ? data.duration : 0,
67
- chapters: (data.chapters ?? []).map((ch) => ({
68
- title: ch.title,
69
- startTime: ch.start_time,
70
- startTimeFormatted: formatDuration(Math.floor(ch.start_time)),
71
- endTime: ch.end_time,
72
- endTimeFormatted: formatDuration(Math.floor(ch.end_time)),
64
+ uploadDate: stats.uploadDate,
65
+ durationSeconds: stats.durationSeconds,
66
+ chapters: stats.chapters.map((chapter) => ({
67
+ title: chapter.title,
68
+ startTime: chapter.startTime,
69
+ startTimeFormatted: formatDuration(Math.floor(chapter.startTime)),
70
+ endTime: chapter.endTime,
71
+ endTimeFormatted: formatDuration(Math.floor(chapter.endTime)),
73
72
  })),
73
+ ...(stats.commentCount === undefined ? {} : { commentCount: stats.commentCount }),
74
74
  };
75
75
  }
76
- export async function getComments(urlOrId, limit = 20) {
76
+ export async function getComments(urlOrId, options = {}) {
77
+ const limit = options.limit ?? 20;
78
+ const sort = options.sort ?? 'top';
77
79
  const videoId = extractVideoId(urlOrId);
78
80
  const url = watchUrl(videoId);
79
81
  const stdout = await runYtDlp([
@@ -81,18 +83,28 @@ export async function getComments(urlOrId, limit = 20) {
81
83
  '--skip-download',
82
84
  '--write-comments',
83
85
  '--extractor-args',
84
- `youtube:comment_sort=top;max_comments=${limit}`,
86
+ // Five positions, per _video.py:2578: total, parents, replies, per
87
+ // thread, depth. An omitted position means unbounded, not a default, so
88
+ // every one is stated. Depth is 2 because YouTube's tree is two levels
89
+ // and a deeper cap would spend requests on nothing.
90
+ youtubeCommentArgs({ limit, sort, maxRepliesPerThread: options.maxRepliesPerThread ?? 100 }),
85
91
  ], { label: 'get_comments', timeoutMs: TIMEOUTS.comments, target: url });
86
92
  const data = parseYtDlpJson(stdout, commentsRowSchema, 'video comments');
87
- const comments = data.comments ?? [];
88
- return comments
89
- .filter((c) => c.parent === 'root')
90
- .slice(0, limit)
91
- .map((c) => ({
92
- author: c.author ?? 'Unknown',
93
- text: c.text ?? '',
94
- likeCount: c.like_count ?? 0,
95
- isPinned: c.is_pinned ?? false,
96
- }));
93
+ const rows = data.comments ?? [];
94
+ return {
95
+ ...toThreads(rows),
96
+ ranToExhaustion: data.comment_count !== null && data.comment_count !== undefined,
97
+ commentsDisabled: (data.comments === null || data.comments === undefined) &&
98
+ (data.comment_count === null || data.comment_count === undefined),
99
+ extractedTotal: rows.length,
100
+ };
101
+ }
102
+ function youtubeCommentArgs(options) {
103
+ const parents = Math.max(1, Math.ceil(options.limit / 2));
104
+ const replies = Math.max(0, options.limit - parents);
105
+ return [
106
+ `youtube:comment_sort=${options.sort}`,
107
+ `max_comments=${String(options.limit)},${String(parents)},${String(replies)},${String(options.maxRepliesPerThread)},2`,
108
+ ].join(';');
97
109
  }
98
110
  //# sourceMappingURL=youtube-video.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"youtube-video.js","sourceRoot":"","sources":["../../src/utils/youtube-video.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AACpG,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAmC5E,MAAM,mBAAmB,GACvB,sIAAsI,CAAC;AAEzI,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAe;IAChD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAE9B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAC3B;QACE,iBAAiB;QACjB,2EAA2E;QAC3E,wEAAwE;QACxE,mEAAmE;QACnE,uEAAuE;QACvE,kDAAkD;QAClD,2BAA2B;QAC3B,0EAA0E;QAC1E,yEAAyE;QACzE,wEAAwE;QACxE,wBAAwB;QACxB,SAAS;QACT,mBAAmB;KACpB,EACD,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,GAAG,EAAE,CACzC,CAAC;IAEF,MAAM,GAAG,GAAG,cAAc,CAAC,MAAM,EAAE,kBAAkB,EAAE,gBAAgB,CAAC,CAAC;IAEzE,6EAA6E;IAC7E,4CAA4C;IAC5C,MAAM,OAAO,GAAG,mBAAmB,CAAC;QAClC,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,SAAS;QAC3C,UAAU,EAAE,GAAG,CAAC,WAAW,IAAI,SAAS;KACzC,CAAC,CAAC;IACH,IAAI,OAAO;QAAE,MAAM,OAAO,CAAC;IAE3B,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,IAAI,CAAC,CAAC;IAEnC,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE,IAAI,OAAO;QACrB,KAAK,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE;QACtB,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE;QAC1B,QAAQ;QACR,iBAAiB,EAAE,cAAc,CAAC,QAAQ,CAAC;QAC3C,UAAU,EAAE,iBAAiB,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;QACpD,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,EAAE;QAClC,IAAI,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAC3B,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAiB,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC;YAClE,CAAC,CAAC,EAAE;QACN,GAAG;QACH,YAAY,EAAE,GAAG,CAAC,SAAS,IAAI,EAAE;QACjC,SAAS,EAAE,GAAG,CAAC,UAAU,IAAI,CAAC;QAC9B,SAAS,EAAE,GAAG,CAAC,UAAU,IAAI,CAAC;QAC9B,YAAY,EAAE,GAAG,CAAC,aAAa,IAAI,CAAC;KACrC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe;IAC/C,OAAO,CAAC,MAAM,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;AACnD,CAAC;AAgBD,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAAe;IACnD,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAE9B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,CAAC,IAAI,EAAE,iBAAiB,CAAC,EAAE;QACvD,KAAK,EAAE,mBAAmB;QAC1B,MAAM,EAAE,GAAG;KACZ,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,EAAE,qBAAqB,EAAE,eAAe,CAAC,CAAC;IAE5E,OAAO;QACL,UAAU,EAAE,iBAAiB,CAAC,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;QACrD,eAAe,EAAE,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACtE,QAAQ,EAAE,CAAC,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;YAC3C,KAAK,EAAE,EAAE,CAAC,KAAK;YACf,SAAS,EAAE,EAAE,CAAC,UAAU;YACxB,kBAAkB,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC;YAC7D,OAAO,EAAE,EAAE,CAAC,QAAQ;YACpB,gBAAgB,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC;SAC1D,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAe,EAAE,KAAK,GAAG,EAAE;IAC3D,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IAE9B,MAAM,MAAM,GAAG,MAAM,QAAQ,CAC3B;QACE,IAAI;QACJ,iBAAiB;QACjB,kBAAkB;QAClB,kBAAkB;QAClB,yCAAyC,KAAK,EAAE;KACjD,EACD,EAAE,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,CACrE,CAAC;IAEF,MAAM,IAAI,GAAG,cAAc,CAAC,MAAM,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;IAErC,OAAO,QAAQ;SACZ,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC;SAClC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACX,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,SAAS;QAC7B,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE;QAClB,SAAS,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC;QAC5B,QAAQ,EAAE,CAAC,CAAC,SAAS,IAAI,KAAK;KAC/B,CAAC,CAAC,CAAC;AACR,CAAC"}
1
+ {"version":3,"file":"youtube-video.js","sourceRoot":"","sources":["../../src/utils/youtube-video.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,9 @@ export declare function releaseSlot(): void;
19
19
  export declare function concurrencyState(): {
20
20
  active: number;
21
21
  queued: number;
22
+ /** The level in force now, which throttling can lower. */
22
23
  limit: number;
24
+ /** The configured maximum the level never exceeds. */
25
+ ceiling: number;
23
26
  };
24
27
  //# sourceMappingURL=ytdlp-limiter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ytdlp-limiter.d.ts","sourceRoot":"","sources":["../../src/utils/ytdlp-limiter.ts"],"names":[],"mappings":"AAqBA;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BhF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAOlC;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAEpF"}
1
+ {"version":3,"file":"ytdlp-limiter.d.ts","sourceRoot":"","sources":["../../src/utils/ytdlp-limiter.ts"],"names":[],"mappings":"AAiCA;;;;;;;;GAQG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BhF;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAOlC;AAED,+EAA+E;AAC/E,wBAAgB,gBAAgB,IAAI;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,sDAAsD;IACtD,OAAO,EAAE,MAAM,CAAC;CACjB,CAOA"}
@@ -1,13 +1,24 @@
1
1
  import { envInt } from './env.js';
2
2
  import { YouTubeError } from './errors.js';
3
+ import { effectiveConcurrency } from './ytdlp-pacer.js';
3
4
  /**
4
5
  * The concurrency limiter every yt-dlp spawn passes through.
5
6
  *
6
7
  * A cap so batch operations do not look like a scraper to YouTube, with a queue
7
8
  * that honours cancellation so an abandoned request never holds a place in it.
8
9
  */
9
- /** A limit of 0 (or NaN) would queue every call forever, so the floor is 1. */
10
+ /**
11
+ * The ceiling this server will never exceed.
12
+ *
13
+ * A limit of 0 (or NaN) would queue every call forever, so the floor is 1.
14
+ * Under throttling the pacer lowers the level below this; the setting is the
15
+ * maximum, not the level.
16
+ */
10
17
  const MAX_CONCURRENT = envInt('YOUTUBE_MCP_MAX_CONCURRENCY', 3, { min: 1, max: 32 });
18
+ /** The level in force right now: the configured ceiling, or less if throttled. */
19
+ function currentLimit() {
20
+ return Math.max(1, Math.min(MAX_CONCURRENT, effectiveConcurrency()));
21
+ }
11
22
  let active = 0;
12
23
  const waiting = [];
13
24
  /**
@@ -23,7 +34,7 @@ export async function acquireSlot(signal) {
23
34
  // No already-aborted check here: `runYtDlp` makes it before every attempt and
24
35
  // nothing awaits in between, so a second one could never fire — an
25
36
  // unreachable guard that reads like a reachable one.
26
- if (active < MAX_CONCURRENT) {
37
+ if (active < currentLimit()) {
27
38
  active++;
28
39
  return;
29
40
  }
@@ -64,6 +75,11 @@ export function releaseSlot() {
64
75
  }
65
76
  /** Test seam: lets the suite assert the limiter without spawning processes. */
66
77
  export function concurrencyState() {
67
- return { active, queued: waiting.length, limit: MAX_CONCURRENT };
78
+ return {
79
+ active,
80
+ queued: waiting.length,
81
+ limit: currentLimit(),
82
+ ceiling: MAX_CONCURRENT,
83
+ };
68
84
  }
69
85
  //# sourceMappingURL=ytdlp-limiter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ytdlp-limiter.js","sourceRoot":"","sources":["../../src/utils/ytdlp-limiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C;;;;;GAKG;AAEH,+EAA+E;AAC/E,MAAM,cAAc,GAAG,MAAM,CAAC,6BAA6B,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;AAOrF,IAAI,MAAM,GAAG,CAAC,CAAC;AACf,MAAM,OAAO,GAAa,EAAE,CAAC;AAE7B;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAA+B;IAC/D,8EAA8E;IAC9E,mEAAmE;IACnE,qDAAqD;IACrD,IAAI,MAAM,GAAG,cAAc,EAAE,CAAC;QAC5B,MAAM,EAAE,CAAC;QACT,OAAO;IACT,CAAC;IAED,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,MAAM,GAAW;YACrB,KAAK,EAAE,GAAG,EAAE;gBACV,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC9C,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBAChB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC9C,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC;SACF,CAAC;QAEF,SAAS,OAAO;YACd,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACtC,IAAI,KAAK,KAAK,CAAC,CAAC;gBAAE,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAC3C,MAAM,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,WAAW,EAAE,4BAA4B,CAAC,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAC7B,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IACD,MAAM,EAAE,CAAC;AACX,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,gBAAgB;IAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;AACnE,CAAC"}
1
+ {"version":3,"file":"ytdlp-limiter.js","sourceRoot":"","sources":["../../src/utils/ytdlp-limiter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAExD;;;;;GAKG;AAEH;;;;;;GAMG;AACH,MAAM,cAAc,GAAG,MAAM,CAAC,6BAA6B,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;AAErF,kFAAkF;AAClF,SAAS,YAAY;IACnB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,oBAAoB,EAAE,CAAC,CAAC,CAAC;AACvE,CAAC;AAOD,IAAI,MAAM,GAAG,CAAC,CAAC;AACf,MAAM,OAAO,GAAa,EAAE,CAAC;AAE7B;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAA+B;IAC/D,8EAA8E;IAC9E,mEAAmE;IACnE,qDAAqD;IACrD,IAAI,MAAM,GAAG,YAAY,EAAE,EAAE,CAAC;QAC5B,MAAM,EAAE,CAAC;QACT,OAAO;IACT,CAAC;IAED,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,MAAM,GAAW;YACrB,KAAK,EAAE,GAAG,EAAE;gBACV,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC9C,OAAO,EAAE,CAAC;YACZ,CAAC;YACD,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;gBAChB,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC9C,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC;SACF,CAAC;QAEF,SAAS,OAAO;YACd,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YACtC,IAAI,KAAK,KAAK,CAAC,CAAC;gBAAE,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAC3C,MAAM,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,WAAW,EAAE,4BAA4B,CAAC,CAAC,CAAC;QAC7E,CAAC;QAED,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAC7B,IAAI,IAAI,EAAE,CAAC;QACT,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,OAAO;IACT,CAAC;IACD,MAAM,EAAE,CAAC;AACX,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,gBAAgB;IAQ9B,OAAO;QACL,MAAM;QACN,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK,EAAE,YAAY,EAAE;QACrB,OAAO,EAAE,cAAc;KACxB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,64 @@
1
+ import type { YouTubeErrorCode } from './errors.js';
2
+ /**
3
+ * How this server reacts to being throttled.
4
+ *
5
+ * The old behaviour was three attempts with at most ~1.5 seconds of jitter and
6
+ * no memory between calls, which is fine for a blip and useless for an
7
+ * hour-long harvest: nothing slowed down, nothing waited, and a hard block
8
+ * produced an hour of identical failures.
9
+ *
10
+ * This adds three things that only make sense across calls — a shared
11
+ * cooldown, an adaptive concurrency ceiling, and a circuit breaker — so the
12
+ * state is deliberately process-global, the same scope as the limiter it
13
+ * cooperates with.
14
+ */
15
+ export declare const RATE_LIMIT_COOLDOWN_BASE_MS = 30000;
16
+ export declare const RATE_LIMIT_COOLDOWN_MAX_MS: number;
17
+ export declare const BOT_CHECK_COOLDOWN_MS: number;
18
+ export declare const MAX_BACKOFF_MS = 120000;
19
+ export declare const BASE_BACKOFF_MS = 750;
20
+ export declare const AIMD_MIN_CONCURRENCY = 1;
21
+ export declare const AIMD_INCREASE_AFTER_SUCCESSES = 20;
22
+ export declare const AIMD_DECREASE_FACTOR = 0.5;
23
+ /** Consecutive throttles before a global cooldown starts. */
24
+ export declare const COOLDOWN_AFTER_STRIKES = 2;
25
+ export declare const CIRCUIT_STRIKES = 5;
26
+ export declare const CIRCUIT_OPEN_MS: number;
27
+ interface RetryPolicy {
28
+ /** Total spawns, including the first. */
29
+ attempts: number;
30
+ backoff: 'none' | 'exponential';
31
+ cooldown: 'none' | 'rate-limit' | 'bot-check';
32
+ concurrency: 'none' | 'decrease' | 'floor';
33
+ }
34
+ export declare function policyFor(code: YouTubeErrorCode): RetryPolicy;
35
+ export declare function backoffDelay(attempt: number, style: RetryPolicy['backoff']): number;
36
+ export interface PacerDecision {
37
+ giveUp: boolean;
38
+ delayMs: number;
39
+ }
40
+ /** Records a failure and says whether to try again, and after how long. */
41
+ export declare function onFailure(code: YouTubeErrorCode, attempt: number, now?: number): PacerDecision;
42
+ /** Records a clean spawn, easing the ceiling back up one step at a time. */
43
+ export declare function onSuccess(): void;
44
+ /** How long a caller should wait before spawning, in milliseconds. */
45
+ export declare function waitMs(now?: number): number;
46
+ export declare function circuitOpen(now?: number): boolean;
47
+ /**
48
+ * The ceiling the limiter should honour right now.
49
+ *
50
+ * Infinite until something throttles us, so an untroubled server runs at
51
+ * whatever YOUTUBE_MCP_MAX_CONCURRENCY allows and the limiter stays the only
52
+ * authority on the normal case.
53
+ */
54
+ export declare function effectiveConcurrency(now?: number): number;
55
+ export declare function pacerState(now?: number): {
56
+ cooldownMs: number;
57
+ circuitOpen: boolean;
58
+ strikes: number;
59
+ concurrency: number;
60
+ };
61
+ /** Test seam; the pacer is process-global in normal use. */
62
+ export declare function resetPacer(): void;
63
+ export {};
64
+ //# sourceMappingURL=ytdlp-pacer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ytdlp-pacer.d.ts","sourceRoot":"","sources":["../../src/utils/ytdlp-pacer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD;;;;;;;;;;;;GAYG;AAEH,eAAO,MAAM,2BAA2B,QAAS,CAAC;AAClD,eAAO,MAAM,0BAA0B,QAAc,CAAC;AACtD,eAAO,MAAM,qBAAqB,QAAc,CAAC;AACjD,eAAO,MAAM,cAAc,SAAU,CAAC;AACtC,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,eAAO,MAAM,oBAAoB,IAAI,CAAC;AACtC,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAExC,6DAA6D;AAC7D,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,eAAO,MAAM,eAAe,IAAI,CAAC;AACjC,eAAO,MAAM,eAAe,QAAa,CAAC;AAE1C,UAAU,WAAW;IACnB,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC;IAChC,QAAQ,EAAE,MAAM,GAAG,YAAY,GAAG,WAAW,CAAC;IAC9C,WAAW,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC;CAC5C;AAkCD,wBAAgB,SAAS,CAAC,IAAI,EAAE,gBAAgB,GAAG,WAAW,CAE7D;AA+BD,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,CAAC,SAAS,CAAC,GAAG,MAAM,CAMnF;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CACvB,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,MAAM,EACf,GAAG,SAAa,GACf,aAAa,CAuCf;AAED,4EAA4E;AAC5E,wBAAgB,SAAS,IAAI,IAAI,CAQhC;AAED,sEAAsE;AACtE,wBAAgB,MAAM,CAAC,GAAG,SAAa,GAAG,MAAM,CAG/C;AAED,wBAAgB,WAAW,CAAC,GAAG,SAAa,GAAG,OAAO,CAErD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,SAAa,GAAG,MAAM,CAG7D;AAED,wBAAgB,UAAU,CAAC,GAAG,SAAa,GAAG;IAC5C,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB,CAOA;AAED,4DAA4D;AAC5D,wBAAgB,UAAU,IAAI,IAAI,CAQjC"}