youtube-knowledge-mcp 2.1.0 → 3.0.0

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 (478) hide show
  1. package/README.md +153 -38
  2. package/dist/brain-schemas.d.ts +10 -10
  3. package/dist/brain-schemas.d.ts.map +1 -1
  4. package/dist/brain-schemas.js +0 -4
  5. package/dist/brain-schemas.js.map +1 -1
  6. package/dist/harvest-schemas.d.ts +75 -0
  7. package/dist/harvest-schemas.d.ts.map +1 -0
  8. package/dist/harvest-schemas.js +106 -0
  9. package/dist/harvest-schemas.js.map +1 -0
  10. package/dist/http/app.d.ts +16 -0
  11. package/dist/http/app.d.ts.map +1 -0
  12. package/dist/http/app.js +176 -0
  13. package/dist/http/app.js.map +1 -0
  14. package/dist/http/auth.d.ts +38 -0
  15. package/dist/http/auth.d.ts.map +1 -0
  16. package/dist/http/auth.js +79 -0
  17. package/dist/http/auth.js.map +1 -0
  18. package/dist/http/config.d.ts +41 -0
  19. package/dist/http/config.d.ts.map +1 -0
  20. package/dist/http/config.js +65 -0
  21. package/dist/http/config.js.map +1 -0
  22. package/dist/http/rate-limiter.d.ts +24 -0
  23. package/dist/http/rate-limiter.d.ts.map +1 -0
  24. package/dist/http/rate-limiter.js +55 -0
  25. package/dist/http/rate-limiter.js.map +1 -0
  26. package/dist/http/sessions.d.ts +34 -0
  27. package/dist/http/sessions.d.ts.map +1 -0
  28. package/dist/http/sessions.js +62 -0
  29. package/dist/http/sessions.js.map +1 -0
  30. package/dist/http.d.ts +6 -48
  31. package/dist/http.d.ts.map +1 -1
  32. package/dist/http.js +35 -252
  33. package/dist/http.js.map +1 -1
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +11 -517
  36. package/dist/index.js.map +1 -1
  37. package/dist/prompts-brain.d.ts +4 -0
  38. package/dist/prompts-brain.d.ts.map +1 -0
  39. package/dist/prompts-brain.js +48 -0
  40. package/dist/prompts-brain.js.map +1 -0
  41. package/dist/prompts-research.d.ts +4 -0
  42. package/dist/prompts-research.d.ts.map +1 -0
  43. package/dist/prompts-research.js +74 -0
  44. package/dist/prompts-research.js.map +1 -0
  45. package/dist/prompts-shared.d.ts +13 -0
  46. package/dist/prompts-shared.d.ts.map +1 -0
  47. package/dist/prompts-shared.js +7 -0
  48. package/dist/prompts-shared.js.map +1 -0
  49. package/dist/prompts.d.ts.map +1 -1
  50. package/dist/prompts.js +5 -100
  51. package/dist/prompts.js.map +1 -1
  52. package/dist/registry/brain-tools.d.ts +4 -0
  53. package/dist/registry/brain-tools.d.ts.map +1 -0
  54. package/dist/registry/brain-tools.js +104 -0
  55. package/dist/registry/brain-tools.js.map +1 -0
  56. package/dist/registry/channel-tools.d.ts +4 -0
  57. package/dist/registry/channel-tools.d.ts.map +1 -0
  58. package/dist/registry/channel-tools.js +53 -0
  59. package/dist/registry/channel-tools.js.map +1 -0
  60. package/dist/registry/harvest-tools.d.ts +10 -0
  61. package/dist/registry/harvest-tools.d.ts.map +1 -0
  62. package/dist/registry/harvest-tools.js +109 -0
  63. package/dist/registry/harvest-tools.js.map +1 -0
  64. package/dist/registry/health-tools.d.ts +4 -0
  65. package/dist/registry/health-tools.d.ts.map +1 -0
  66. package/dist/registry/health-tools.js +39 -0
  67. package/dist/registry/health-tools.js.map +1 -0
  68. package/dist/registry/index.d.ts +8 -0
  69. package/dist/registry/index.d.ts.map +1 -0
  70. package/dist/registry/index.js +29 -0
  71. package/dist/registry/index.js.map +1 -0
  72. package/dist/registry/library-tools.d.ts +4 -0
  73. package/dist/registry/library-tools.d.ts.map +1 -0
  74. package/dist/registry/library-tools.js +116 -0
  75. package/dist/registry/library-tools.js.map +1 -0
  76. package/dist/registry/media-tools.d.ts +4 -0
  77. package/dist/registry/media-tools.d.ts.map +1 -0
  78. package/dist/registry/media-tools.js +100 -0
  79. package/dist/registry/media-tools.js.map +1 -0
  80. package/dist/registry/thumbnail-tools.d.ts +7 -0
  81. package/dist/registry/thumbnail-tools.d.ts.map +1 -0
  82. package/dist/registry/thumbnail-tools.js +72 -0
  83. package/dist/registry/thumbnail-tools.js.map +1 -0
  84. package/dist/registry/transcript-tools.d.ts +4 -0
  85. package/dist/registry/transcript-tools.d.ts.map +1 -0
  86. package/dist/registry/transcript-tools.js +68 -0
  87. package/dist/registry/transcript-tools.js.map +1 -0
  88. package/dist/registry/types.d.ts +41 -0
  89. package/dist/registry/types.d.ts.map +1 -0
  90. package/dist/registry/types.js +17 -0
  91. package/dist/registry/types.js.map +1 -0
  92. package/dist/registry/video-tools.d.ts +4 -0
  93. package/dist/registry/video-tools.d.ts.map +1 -0
  94. package/dist/registry/video-tools.js +101 -0
  95. package/dist/registry/video-tools.js.map +1 -0
  96. package/dist/resources.d.ts.map +1 -1
  97. package/dist/resources.js +13 -10
  98. package/dist/resources.js.map +1 -1
  99. package/dist/schemas.d.ts +250 -2
  100. package/dist/schemas.d.ts.map +1 -1
  101. package/dist/schemas.js +61 -0
  102. package/dist/schemas.js.map +1 -1
  103. package/dist/thumbnail-resource.d.ts +8 -0
  104. package/dist/thumbnail-resource.d.ts.map +1 -0
  105. package/dist/thumbnail-resource.js +38 -0
  106. package/dist/thumbnail-resource.js.map +1 -0
  107. package/dist/thumbnail-schemas.d.ts +512 -0
  108. package/dist/thumbnail-schemas.d.ts.map +1 -0
  109. package/dist/thumbnail-schemas.js +95 -0
  110. package/dist/thumbnail-schemas.js.map +1 -0
  111. package/dist/tools/ask-brain.js +1 -1
  112. package/dist/tools/ask-brain.js.map +1 -1
  113. package/dist/tools/batch.js +1 -1
  114. package/dist/tools/batch.js.map +1 -1
  115. package/dist/tools/brain-info.js +1 -1
  116. package/dist/tools/brain-info.js.map +1 -1
  117. package/dist/tools/build-brain.js +1 -1
  118. package/dist/tools/build-brain.js.map +1 -1
  119. package/dist/tools/check-health.d.ts +61 -0
  120. package/dist/tools/check-health.d.ts.map +1 -1
  121. package/dist/tools/check-health.js +94 -6
  122. package/dist/tools/check-health.js.map +1 -1
  123. package/dist/tools/clips.d.ts +9 -41
  124. package/dist/tools/clips.d.ts.map +1 -1
  125. package/dist/tools/clips.js +52 -128
  126. package/dist/tools/clips.js.map +1 -1
  127. package/dist/tools/fetch-channel-thumbnails.d.ts +179 -0
  128. package/dist/tools/fetch-channel-thumbnails.d.ts.map +1 -0
  129. package/dist/tools/fetch-channel-thumbnails.js +123 -0
  130. package/dist/tools/fetch-channel-thumbnails.js.map +1 -0
  131. package/dist/tools/fetch-videos.d.ts +18 -4
  132. package/dist/tools/fetch-videos.d.ts.map +1 -1
  133. package/dist/tools/fetch-videos.js +64 -20
  134. package/dist/tools/fetch-videos.js.map +1 -1
  135. package/dist/tools/frames-subtitles.d.ts +44 -0
  136. package/dist/tools/frames-subtitles.d.ts.map +1 -0
  137. package/dist/tools/frames-subtitles.js +104 -0
  138. package/dist/tools/frames-subtitles.js.map +1 -0
  139. package/dist/tools/get-channel-info.d.ts +2 -0
  140. package/dist/tools/get-channel-info.d.ts.map +1 -1
  141. package/dist/tools/get-channel-info.js +8 -1
  142. package/dist/tools/get-channel-info.js.map +1 -1
  143. package/dist/tools/get-comments.d.ts +238 -6
  144. package/dist/tools/get-comments.d.ts.map +1 -1
  145. package/dist/tools/get-comments.js +85 -21
  146. package/dist/tools/get-comments.js.map +1 -1
  147. package/dist/tools/get-coverage.d.ts +122 -0
  148. package/dist/tools/get-coverage.d.ts.map +1 -0
  149. package/dist/tools/get-coverage.js +105 -0
  150. package/dist/tools/get-coverage.js.map +1 -0
  151. package/dist/tools/get-playlist-info.d.ts.map +1 -1
  152. package/dist/tools/get-playlist-info.js +1 -0
  153. package/dist/tools/get-playlist-info.js.map +1 -1
  154. package/dist/tools/get-thumbnail.d.ts +38 -0
  155. package/dist/tools/get-thumbnail.d.ts.map +1 -0
  156. package/dist/tools/get-thumbnail.js +152 -0
  157. package/dist/tools/get-thumbnail.js.map +1 -0
  158. package/dist/tools/get-transcript.d.ts.map +1 -1
  159. package/dist/tools/get-transcript.js +2 -14
  160. package/dist/tools/get-transcript.js.map +1 -1
  161. package/dist/tools/harvest-channel.d.ts +92 -0
  162. package/dist/tools/harvest-channel.d.ts.map +1 -0
  163. package/dist/tools/harvest-channel.js +62 -0
  164. package/dist/tools/harvest-channel.js.map +1 -0
  165. package/dist/tools/harvest-comments.d.ts +81 -0
  166. package/dist/tools/harvest-comments.d.ts.map +1 -0
  167. package/dist/tools/harvest-comments.js +115 -0
  168. package/dist/tools/harvest-comments.js.map +1 -0
  169. package/dist/tools/library.d.ts.map +1 -1
  170. package/dist/tools/library.js +14 -4
  171. package/dist/tools/library.js.map +1 -1
  172. package/dist/tools/list-channel-thumbnails.d.ts +235 -0
  173. package/dist/tools/list-channel-thumbnails.d.ts.map +1 -0
  174. package/dist/tools/list-channel-thumbnails.js +79 -0
  175. package/dist/tools/list-channel-thumbnails.js.map +1 -0
  176. package/dist/tools/list-library.js +1 -1
  177. package/dist/tools/list-library.js.map +1 -1
  178. package/dist/tools/prune-harvest.d.ts +59 -0
  179. package/dist/tools/prune-harvest.d.ts.map +1 -0
  180. package/dist/tools/prune-harvest.js +108 -0
  181. package/dist/tools/prune-harvest.js.map +1 -0
  182. package/dist/tools/query-comments.d.ts +125 -0
  183. package/dist/tools/query-comments.d.ts.map +1 -0
  184. package/dist/tools/query-comments.js +106 -0
  185. package/dist/tools/query-comments.js.map +1 -0
  186. package/dist/tools/query-videos.d.ts +118 -0
  187. package/dist/tools/query-videos.d.ts.map +1 -0
  188. package/dist/tools/query-videos.js +97 -0
  189. package/dist/tools/query-videos.js.map +1 -0
  190. package/dist/tools/repair-store.d.ts +34 -0
  191. package/dist/tools/repair-store.d.ts.map +1 -0
  192. package/dist/tools/repair-store.js +58 -0
  193. package/dist/tools/repair-store.js.map +1 -0
  194. package/dist/tools/save-to-library.d.ts.map +1 -1
  195. package/dist/tools/save-to-library.js +5 -1
  196. package/dist/tools/save-to-library.js.map +1 -1
  197. package/dist/tools/search-channels.d.ts +6 -0
  198. package/dist/tools/search-channels.d.ts.map +1 -1
  199. package/dist/tools/search-channels.js +5 -1
  200. package/dist/tools/search-channels.js.map +1 -1
  201. package/dist/tools/search-transcript.d.ts.map +1 -1
  202. package/dist/tools/search-transcript.js +6 -13
  203. package/dist/tools/search-transcript.js.map +1 -1
  204. package/dist/tools/search-videos.d.ts +3 -0
  205. package/dist/tools/search-videos.d.ts.map +1 -1
  206. package/dist/tools/search-videos.js +1 -1
  207. package/dist/tools/search-videos.js.map +1 -1
  208. package/dist/utils/batches.d.ts +15 -0
  209. package/dist/utils/batches.d.ts.map +1 -0
  210. package/dist/utils/batches.js +31 -0
  211. package/dist/utils/batches.js.map +1 -0
  212. package/dist/utils/brain-build.d.ts.map +1 -1
  213. package/dist/utils/brain-build.js +1 -12
  214. package/dist/utils/brain-build.js.map +1 -1
  215. package/dist/utils/brain-index.d.ts.map +1 -1
  216. package/dist/utils/brain-index.js +3 -2
  217. package/dist/utils/brain-index.js.map +1 -1
  218. package/dist/utils/brain-lock.d.ts +2 -18
  219. package/dist/utils/brain-lock.d.ts.map +1 -1
  220. package/dist/utils/brain-lock.js +4 -80
  221. package/dist/utils/brain-lock.js.map +1 -1
  222. package/dist/utils/brain-lookup.d.ts +8 -0
  223. package/dist/utils/brain-lookup.d.ts.map +1 -1
  224. package/dist/utils/brain-lookup.js +5 -31
  225. package/dist/utils/brain-lookup.js.map +1 -1
  226. package/dist/utils/brain-storage.d.ts.map +1 -1
  227. package/dist/utils/brain-storage.js +5 -5
  228. package/dist/utils/brain-storage.js.map +1 -1
  229. package/dist/utils/caption-probe.d.ts +7 -0
  230. package/dist/utils/caption-probe.d.ts.map +1 -0
  231. package/dist/utils/caption-probe.js +36 -0
  232. package/dist/utils/caption-probe.js.map +1 -0
  233. package/dist/utils/channel-images.d.ts +16 -0
  234. package/dist/utils/channel-images.d.ts.map +1 -0
  235. package/dist/utils/channel-images.js +35 -0
  236. package/dist/utils/channel-images.js.map +1 -0
  237. package/dist/utils/channel-lookup.d.ts +5 -0
  238. package/dist/utils/channel-lookup.d.ts.map +1 -0
  239. package/dist/utils/channel-lookup.js +37 -0
  240. package/dist/utils/channel-lookup.js.map +1 -0
  241. package/dist/utils/chapters.d.ts +11 -0
  242. package/dist/utils/chapters.d.ts.map +1 -0
  243. package/dist/utils/chapters.js +24 -0
  244. package/dist/utils/chapters.js.map +1 -0
  245. package/dist/utils/clips.d.ts.map +1 -1
  246. package/dist/utils/clips.js +18 -26
  247. package/dist/utils/clips.js.map +1 -1
  248. package/dist/utils/comment-store.d.ts +71 -0
  249. package/dist/utils/comment-store.d.ts.map +1 -0
  250. package/dist/utils/comment-store.js +129 -0
  251. package/dist/utils/comment-store.js.map +1 -0
  252. package/dist/utils/comment-threads.d.ts +51 -0
  253. package/dist/utils/comment-threads.d.ts.map +1 -0
  254. package/dist/utils/comment-threads.js +76 -0
  255. package/dist/utils/comment-threads.js.map +1 -0
  256. package/dist/utils/coverage-text.d.ts +3 -0
  257. package/dist/utils/coverage-text.d.ts.map +1 -0
  258. package/dist/utils/coverage-text.js +62 -0
  259. package/dist/utils/coverage-text.js.map +1 -0
  260. package/dist/utils/coverage.d.ts +57 -0
  261. package/dist/utils/coverage.d.ts.map +1 -0
  262. package/dist/utils/coverage.js +142 -0
  263. package/dist/utils/coverage.js.map +1 -0
  264. package/dist/utils/env.d.ts +26 -0
  265. package/dist/utils/env.d.ts.map +1 -0
  266. package/dist/utils/env.js +72 -0
  267. package/dist/utils/env.js.map +1 -0
  268. package/dist/utils/errors.d.ts +1 -1
  269. package/dist/utils/errors.d.ts.map +1 -1
  270. package/dist/utils/errors.js +28 -2
  271. package/dist/utils/errors.js.map +1 -1
  272. package/dist/utils/file-lock.d.ts +34 -0
  273. package/dist/utils/file-lock.d.ts.map +1 -0
  274. package/dist/utils/file-lock.js +91 -0
  275. package/dist/utils/file-lock.js.map +1 -0
  276. package/dist/utils/flat-listing.d.ts +89 -0
  277. package/dist/utils/flat-listing.d.ts.map +1 -0
  278. package/dist/utils/flat-listing.js +68 -0
  279. package/dist/utils/flat-listing.js.map +1 -0
  280. package/dist/utils/format.d.ts +18 -4
  281. package/dist/utils/format.d.ts.map +1 -1
  282. package/dist/utils/format.js +2 -6
  283. package/dist/utils/format.js.map +1 -1
  284. package/dist/utils/guard.d.ts +21 -0
  285. package/dist/utils/guard.d.ts.map +1 -0
  286. package/dist/utils/guard.js +105 -0
  287. package/dist/utils/guard.js.map +1 -0
  288. package/dist/utils/harvest-catalog.d.ts +44 -0
  289. package/dist/utils/harvest-catalog.d.ts.map +1 -0
  290. package/dist/utils/harvest-catalog.js +164 -0
  291. package/dist/utils/harvest-catalog.js.map +1 -0
  292. package/dist/utils/harvest-lock.d.ts +3 -0
  293. package/dist/utils/harvest-lock.d.ts.map +1 -0
  294. package/dist/utils/harvest-lock.js +26 -0
  295. package/dist/utils/harvest-lock.js.map +1 -0
  296. package/dist/utils/harvest-receipts.d.ts +14 -0
  297. package/dist/utils/harvest-receipts.d.ts.map +1 -0
  298. package/dist/utils/harvest-receipts.js +110 -0
  299. package/dist/utils/harvest-receipts.js.map +1 -0
  300. package/dist/utils/image-dimensions.d.ts +19 -0
  301. package/dist/utils/image-dimensions.d.ts.map +1 -0
  302. package/dist/utils/image-dimensions.js +93 -0
  303. package/dist/utils/image-dimensions.js.map +1 -0
  304. package/dist/utils/image-fetch.d.ts +31 -0
  305. package/dist/utils/image-fetch.d.ts.map +1 -0
  306. package/dist/utils/image-fetch.js +141 -0
  307. package/dist/utils/image-fetch.js.map +1 -0
  308. package/dist/utils/json-file.d.ts +14 -5
  309. package/dist/utils/json-file.d.ts.map +1 -1
  310. package/dist/utils/json-file.js +24 -9
  311. package/dist/utils/json-file.js.map +1 -1
  312. package/dist/utils/listing-cursor.d.ts +31 -0
  313. package/dist/utils/listing-cursor.d.ts.map +1 -0
  314. package/dist/utils/listing-cursor.js +39 -0
  315. package/dist/utils/listing-cursor.js.map +1 -0
  316. package/dist/utils/paths.d.ts +10 -0
  317. package/dist/utils/paths.d.ts.map +1 -1
  318. package/dist/utils/paths.js +14 -0
  319. package/dist/utils/paths.js.map +1 -1
  320. package/dist/utils/pattern.d.ts +30 -0
  321. package/dist/utils/pattern.d.ts.map +1 -0
  322. package/dist/utils/pattern.js +130 -0
  323. package/dist/utils/pattern.js.map +1 -0
  324. package/dist/utils/pot-preflight.d.ts +53 -0
  325. package/dist/utils/pot-preflight.d.ts.map +1 -0
  326. package/dist/utils/pot-preflight.js +146 -0
  327. package/dist/utils/pot-preflight.js.map +1 -0
  328. package/dist/utils/search-index.d.ts.map +1 -1
  329. package/dist/utils/search-index.js +9 -4
  330. package/dist/utils/search-index.js.map +1 -1
  331. package/dist/utils/sleep.d.ts +9 -0
  332. package/dist/utils/sleep.d.ts.map +1 -0
  333. package/dist/utils/sleep.js +25 -0
  334. package/dist/utils/sleep.js.map +1 -0
  335. package/dist/utils/storage.d.ts.map +1 -1
  336. package/dist/utils/storage.js +14 -8
  337. package/dist/utils/storage.js.map +1 -1
  338. package/dist/utils/store-health.d.ts +37 -0
  339. package/dist/utils/store-health.d.ts.map +1 -0
  340. package/dist/utils/store-health.js +92 -0
  341. package/dist/utils/store-health.js.map +1 -0
  342. package/dist/utils/store-migrations.d.ts +33 -0
  343. package/dist/utils/store-migrations.d.ts.map +1 -0
  344. package/dist/utils/store-migrations.js +41 -0
  345. package/dist/utils/store-migrations.js.map +1 -0
  346. package/dist/utils/store-paths.d.ts +33 -0
  347. package/dist/utils/store-paths.d.ts.map +1 -0
  348. package/dist/utils/store-paths.js +48 -0
  349. package/dist/utils/store-paths.js.map +1 -0
  350. package/dist/utils/store-rows.d.ts +22 -0
  351. package/dist/utils/store-rows.d.ts.map +1 -0
  352. package/dist/utils/store-rows.js +62 -0
  353. package/dist/utils/store-rows.js.map +1 -0
  354. package/dist/utils/store-schema.d.ts +16 -0
  355. package/dist/utils/store-schema.d.ts.map +1 -0
  356. package/dist/utils/store-schema.js +168 -0
  357. package/dist/utils/store-schema.js.map +1 -0
  358. package/dist/utils/store.d.ts +34 -0
  359. package/dist/utils/store.d.ts.map +1 -0
  360. package/dist/utils/store.js +157 -0
  361. package/dist/utils/store.js.map +1 -0
  362. package/dist/utils/subtitles.d.ts +7 -0
  363. package/dist/utils/subtitles.d.ts.map +1 -0
  364. package/dist/utils/subtitles.js +30 -0
  365. package/dist/utils/subtitles.js.map +1 -0
  366. package/dist/utils/thumbnail-entry.d.ts +19 -0
  367. package/dist/utils/thumbnail-entry.d.ts.map +1 -0
  368. package/dist/utils/thumbnail-entry.js +119 -0
  369. package/dist/utils/thumbnail-entry.js.map +1 -0
  370. package/dist/utils/thumbnail-fetch.d.ts +37 -0
  371. package/dist/utils/thumbnail-fetch.d.ts.map +1 -0
  372. package/dist/utils/thumbnail-fetch.js +89 -0
  373. package/dist/utils/thumbnail-fetch.js.map +1 -0
  374. package/dist/utils/thumbnail-ladder.d.ts +44 -0
  375. package/dist/utils/thumbnail-ladder.d.ts.map +1 -0
  376. package/dist/utils/thumbnail-ladder.js +68 -0
  377. package/dist/utils/thumbnail-ladder.js.map +1 -0
  378. package/dist/utils/thumbnail-listing.d.ts +16 -0
  379. package/dist/utils/thumbnail-listing.d.ts.map +1 -0
  380. package/dist/utils/thumbnail-listing.js +26 -0
  381. package/dist/utils/thumbnail-listing.js.map +1 -0
  382. package/dist/utils/thumbnail-paths.d.ts +20 -0
  383. package/dist/utils/thumbnail-paths.d.ts.map +1 -0
  384. package/dist/utils/thumbnail-paths.js +35 -0
  385. package/dist/utils/thumbnail-paths.js.map +1 -0
  386. package/dist/utils/thumbnail-store.d.ts +19 -0
  387. package/dist/utils/thumbnail-store.d.ts.map +1 -0
  388. package/dist/utils/thumbnail-store.js +125 -0
  389. package/dist/utils/thumbnail-store.js.map +1 -0
  390. package/dist/utils/transcript-cache.d.ts +20 -0
  391. package/dist/utils/transcript-cache.d.ts.map +1 -0
  392. package/dist/utils/transcript-cache.js +127 -0
  393. package/dist/utils/transcript-cache.js.map +1 -0
  394. package/dist/utils/transcript-search.d.ts +20 -0
  395. package/dist/utils/transcript-search.d.ts.map +1 -0
  396. package/dist/utils/transcript-search.js +35 -0
  397. package/dist/utils/transcript-search.js.map +1 -0
  398. package/dist/utils/transcript.d.ts +10 -31
  399. package/dist/utils/transcript.d.ts.map +1 -1
  400. package/dist/utils/transcript.js +2 -64
  401. package/dist/utils/transcript.js.map +1 -1
  402. package/dist/utils/validate-youtube.d.ts +35 -0
  403. package/dist/utils/validate-youtube.d.ts.map +1 -0
  404. package/dist/utils/validate-youtube.js +87 -0
  405. package/dist/utils/validate-youtube.js.map +1 -0
  406. package/dist/utils/validate.d.ts +11 -4
  407. package/dist/utils/validate.d.ts.map +1 -1
  408. package/dist/utils/validate.js +43 -36
  409. package/dist/utils/validate.js.map +1 -1
  410. package/dist/utils/version.d.ts +2 -0
  411. package/dist/utils/version.d.ts.map +1 -0
  412. package/dist/utils/version.js +19 -0
  413. package/dist/utils/version.js.map +1 -0
  414. package/dist/utils/video-stats-cache.d.ts +16 -0
  415. package/dist/utils/video-stats-cache.d.ts.map +1 -0
  416. package/dist/utils/video-stats-cache.js +81 -0
  417. package/dist/utils/video-stats-cache.js.map +1 -0
  418. package/dist/utils/video-stats.d.ts +186 -0
  419. package/dist/utils/video-stats.d.ts.map +1 -0
  420. package/dist/utils/video-stats.js +168 -0
  421. package/dist/utils/video-stats.js.map +1 -0
  422. package/dist/utils/video-store.d.ts +69 -0
  423. package/dist/utils/video-store.d.ts.map +1 -0
  424. package/dist/utils/video-store.js +77 -0
  425. package/dist/utils/video-store.js.map +1 -0
  426. package/dist/utils/youtube-channel.d.ts +51 -0
  427. package/dist/utils/youtube-channel.d.ts.map +1 -0
  428. package/dist/utils/youtube-channel.js +91 -0
  429. package/dist/utils/youtube-channel.js.map +1 -0
  430. package/dist/utils/youtube-download.d.ts +27 -0
  431. package/dist/utils/youtube-download.d.ts.map +1 -0
  432. package/dist/utils/youtube-download.js +118 -0
  433. package/dist/utils/youtube-download.js.map +1 -0
  434. package/dist/utils/youtube-schemas.d.ts +492 -0
  435. package/dist/utils/youtube-schemas.d.ts.map +1 -0
  436. package/dist/utils/youtube-schemas.js +148 -0
  437. package/dist/utils/youtube-schemas.js.map +1 -0
  438. package/dist/utils/youtube-search.d.ts +14 -0
  439. package/dist/utils/youtube-search.d.ts.map +1 -0
  440. package/dist/utils/youtube-search.js +39 -0
  441. package/dist/utils/youtube-search.js.map +1 -0
  442. package/dist/utils/youtube-url.d.ts +25 -0
  443. package/dist/utils/youtube-url.d.ts.map +1 -0
  444. package/dist/utils/youtube-url.js +75 -0
  445. package/dist/utils/youtube-url.js.map +1 -0
  446. package/dist/utils/youtube-video.d.ts +68 -0
  447. package/dist/utils/youtube-video.d.ts.map +1 -0
  448. package/dist/utils/youtube-video.js +110 -0
  449. package/dist/utils/youtube-video.js.map +1 -0
  450. package/dist/utils/youtube.d.ts +10 -122
  451. package/dist/utils/youtube.d.ts.map +1 -1
  452. package/dist/utils/youtube.js +11 -486
  453. package/dist/utils/youtube.js.map +1 -1
  454. package/dist/utils/ytdlp-env.d.ts +33 -0
  455. package/dist/utils/ytdlp-env.d.ts.map +1 -0
  456. package/dist/utils/ytdlp-env.js +121 -0
  457. package/dist/utils/ytdlp-env.js.map +1 -0
  458. package/dist/utils/ytdlp-limiter.d.ts +27 -0
  459. package/dist/utils/ytdlp-limiter.d.ts.map +1 -0
  460. package/dist/utils/ytdlp-limiter.js +85 -0
  461. package/dist/utils/ytdlp-limiter.js.map +1 -0
  462. package/dist/utils/ytdlp-pacer.d.ts +64 -0
  463. package/dist/utils/ytdlp-pacer.d.ts.map +1 -0
  464. package/dist/utils/ytdlp-pacer.js +165 -0
  465. package/dist/utils/ytdlp-pacer.js.map +1 -0
  466. package/dist/utils/ytdlp-parse.d.ts +13 -0
  467. package/dist/utils/ytdlp-parse.d.ts.map +1 -0
  468. package/dist/utils/ytdlp-parse.js +48 -0
  469. package/dist/utils/ytdlp-parse.js.map +1 -0
  470. package/dist/utils/ytdlp-stream.d.ts +32 -0
  471. package/dist/utils/ytdlp-stream.d.ts.map +1 -0
  472. package/dist/utils/ytdlp-stream.js +61 -0
  473. package/dist/utils/ytdlp-stream.js.map +1 -0
  474. package/dist/utils/ytdlp.d.ts +23 -18
  475. package/dist/utils/ytdlp.d.ts.map +1 -1
  476. package/dist/utils/ytdlp.js +56 -134
  477. package/dist/utils/ytdlp.js.map +1 -1
  478. package/package.json +3 -2
@@ -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"}
@@ -1,3 +1,5 @@
1
+ export { concurrencyState } from './ytdlp-limiter.js';
2
+ export { parseYtDlpJson, parseYtDlpJsonLines } from './ytdlp-parse.js';
1
3
  /**
2
4
  * The single place this server spawns yt-dlp.
3
5
  *
@@ -17,12 +19,16 @@ export declare const TIMEOUTS: {
17
19
  /** Media transfers: unbounded here; cancellation is the client's lever. */
18
20
  readonly download: 0;
19
21
  };
20
- /** Test seam: lets the suite assert the limiter without spawning processes. */
21
- export declare function concurrencyState(): {
22
- active: number;
23
- queued: number;
24
- limit: number;
25
- };
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";
26
32
  export interface RunOptions {
27
33
  /** Milliseconds before the child is killed. 0 disables the timeout. */
28
34
  timeoutMs?: number;
@@ -30,22 +36,21 @@ export interface RunOptions {
30
36
  retry?: boolean;
31
37
  /** Human-readable operation name, used in log lines. */
32
38
  label?: string;
39
+ /**
40
+ * The URL, search expression or id yt-dlp operates on.
41
+ *
42
+ * Always the last argument and always preceded by a literal `--`, so a value
43
+ * that begins with a dash is a target yt-dlp fails to fetch, never an option
44
+ * it obeys. Required rather than defaulted: a call site cannot forget it.
45
+ */
46
+ target: string;
33
47
  }
34
48
  /**
35
49
  * Run yt-dlp and return its stdout.
36
50
  *
37
51
  * Arguments are always passed as an array — never a shell string — so video
38
- * titles and user-supplied queries cannot become shell metacharacters.
39
- */
40
- export declare function runYtDlp(args: string[], options?: RunOptions): Promise<string>;
41
- /**
42
- * Parse yt-dlp JSON output behind a type guard.
43
- *
44
- * Every JSON.parse in this codebase used to be unguarded, so a truncated or
45
- * non-JSON response surfaced as a raw SyntaxError.
52
+ * titles and user-supplied queries cannot become shell metacharacters. The
53
+ * target follows a `--` terminator, so it cannot become a yt-dlp option either.
46
54
  */
47
- export declare function parseYtDlpJson<T>(stdout: string, guard: (value: unknown) => value is T, what: string): T;
48
- /** Parse newline-delimited JSON, skipping unparseable lines rather than failing the call. */
49
- export declare function parseYtDlpJsonLines<T>(stdout: string, guard: (value: unknown) => value is T): T[];
50
- export declare function isRecord(value: unknown): value is Record<string, unknown>;
55
+ export declare function runYtDlp(args: string[], options: RunOptions): Promise<string>;
51
56
  //# sourceMappingURL=ytdlp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ytdlp.d.ts","sourceRoot":"","sources":["../../src/utils/ytdlp.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,kFAAkF;AAClF,eAAO,MAAM,QAAQ;IACnB,wDAAwD;;IAExD,gDAAgD;;IAEhD,iEAAiE;;IAEjE,2EAA2E;;CAEnE,CAAC;AAmFX,+EAA+E;AAC/E,wBAAgB,gBAAgB,IAAI;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAEpF;AAED,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;CAChB;AAsBD;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAyBxF;AAoED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,IAAI,CAAC,EACrC,IAAI,EAAE,MAAM,GACX,CAAC,CAuBH;AAED,6FAA6F;AAC7F,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAcjG;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE"}
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,6 +1,12 @@
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';
6
+ import { acquireSlot, releaseSlot } from './ytdlp-limiter.js';
7
+ import { readYtDlpEnv } from './ytdlp-env.js';
8
+ export { concurrencyState } from './ytdlp-limiter.js';
9
+ export { parseYtDlpJson, parseYtDlpJsonLines } from './ytdlp-parse.js';
4
10
  /**
5
11
  * The single place this server spawns yt-dlp.
6
12
  *
@@ -20,9 +26,7 @@ export const TIMEOUTS = {
20
26
  /** Media transfers: unbounded here; cancellation is the client's lever. */
21
27
  download: 0,
22
28
  };
23
- const MAX_CONCURRENT = Number(process.env.YOUTUBE_MCP_MAX_CONCURRENCY ?? '3');
24
29
  const MAX_ATTEMPTS = 3;
25
- const BASE_BACKOFF_MS = 750;
26
30
  /** Guards against a pathological video description blowing up memory. */
27
31
  const MAX_OUTPUT_BYTES = 64 * 1024 * 1024;
28
32
  /**
@@ -34,91 +38,16 @@ const MAX_OUTPUT_BYTES = 64 * 1024 * 1024;
34
38
  * forever. This bounds the silence, not the work: a transfer still making
35
39
  * progress is never interrupted.
36
40
  */
37
- const SOCKET_TIMEOUT_S = '30';
38
- let active = 0;
39
- const waiting = [];
40
- /**
41
- * Takes a concurrency slot, waiting for one when the limiter is full.
42
- *
43
- * The wait honours the request's abort signal. It used to be a bare promise
44
- * with no way out, so a client that gave up stayed queued forever — and since a
45
- * media transfer runs without a wall-clock timeout, three stalled downloads
46
- * held every slot and every later call queued behind them, uncancellable. The
47
- * server was not slow, it was wedged, and no tool could run again.
48
- */
49
- async function acquireSlot(signal) {
50
- // No already-aborted check here: `runYtDlp` makes it before every attempt and
51
- // nothing awaits in between, so a second one could never fire — an
52
- // unreachable guard that reads like a reachable one.
53
- if (active < MAX_CONCURRENT) {
54
- active++;
55
- return;
56
- }
57
- await new Promise((resolve, reject) => {
58
- const waiter = {
59
- grant: () => {
60
- signal?.removeEventListener('abort', onAbort);
61
- resolve();
62
- },
63
- cancel: (error) => {
64
- signal?.removeEventListener('abort', onAbort);
65
- reject(error);
66
- },
67
- };
68
- function onAbort() {
69
- const index = waiting.indexOf(waiter);
70
- if (index !== -1)
71
- waiting.splice(index, 1);
72
- waiter.cancel(new YouTubeError('CANCELLED', 'The request was cancelled.'));
73
- }
74
- signal?.addEventListener('abort', onAbort, { once: true });
75
- waiting.push(waiter);
76
- });
77
- }
78
- /**
79
- * Hands the slot to the next waiter rather than freeing it and letting them
80
- * race for it: decrementing first left `active` below the limit for a tick, so
81
- * a fresh caller could take the slot the queue was already promised and the
82
- * limiter would run over its own ceiling.
83
- */
84
- function releaseSlot() {
85
- const next = waiting.shift();
86
- if (next) {
87
- next.grant();
88
- return;
89
- }
90
- active--;
91
- }
92
- /** Test seam: lets the suite assert the limiter without spawning processes. */
93
- export function concurrencyState() {
94
- return { active, queued: waiting.length, limit: MAX_CONCURRENT };
95
- }
96
- function backoffDelay(attempt) {
97
- // Exponential with full jitter, so parallel callers do not retry in lockstep.
98
- const ceiling = BASE_BACKOFF_MS * 2 ** (attempt - 1);
99
- return Math.round(Math.random() * ceiling);
100
- }
101
- async function sleep(ms, signal) {
102
- await new Promise((resolve, reject) => {
103
- const timer = setTimeout(() => {
104
- signal?.removeEventListener('abort', onAbort);
105
- resolve();
106
- }, ms);
107
- const onAbort = () => {
108
- clearTimeout(timer);
109
- reject(new YouTubeError('CANCELLED', 'The request was cancelled.'));
110
- };
111
- signal?.addEventListener('abort', onAbort, { once: true });
112
- });
113
- }
41
+ export const SOCKET_TIMEOUT_S = '30';
114
42
  /**
115
43
  * Run yt-dlp and return its stdout.
116
44
  *
117
45
  * Arguments are always passed as an array — never a shell string — so video
118
- * titles and user-supplied queries cannot become shell metacharacters.
46
+ * titles and user-supplied queries cannot become shell metacharacters. The
47
+ * target follows a `--` terminator, so it cannot become a yt-dlp option either.
119
48
  */
120
- export async function runYtDlp(args, options = {}) {
121
- const { timeoutMs = TIMEOUTS.metadata, retry = true, label = 'yt-dlp' } = options;
49
+ export async function runYtDlp(args, options) {
50
+ const { timeoutMs = TIMEOUTS.metadata, retry = true, label = 'yt-dlp', target } = options;
122
51
  const { signal } = currentContext();
123
52
  const maxAttempts = retry ? MAX_ATTEMPTS : 1;
124
53
  for (let attempt = 1;; attempt++) {
@@ -128,25 +57,63 @@ export async function runYtDlp(args, options = {}) {
128
57
  if (signal?.aborted === true) {
129
58
  throw new YouTubeError('CANCELLED', 'The request was cancelled.');
130
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
+ }
131
81
  try {
132
- return await spawnOnce(args, timeoutMs, signal);
82
+ const stdout = await spawnOnce(args, target, timeoutMs, signal);
83
+ onSuccess();
84
+ return stdout;
133
85
  }
134
86
  catch (error) {
135
87
  const failure = translateExecaFailure(error, timeoutMs);
136
- 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)
137
95
  throw failure;
138
- const delay = backoffDelay(attempt);
139
- log('warning', `${label} failed (${failure.code}), retrying in ${delay}ms`);
96
+ log('warning', `${label} failed (${failure.code}), retrying in ${String(decision.delayMs)}ms`);
140
97
  // The slot is already released, so the backoff does not hold the queue.
141
- await sleep(delay, signal);
98
+ await sleep(decision.delayMs, signal);
142
99
  }
143
100
  }
144
101
  }
145
102
  /** One attempt, holding a concurrency slot for exactly its duration. */
146
- async function spawnOnce(args, timeoutMs, signal) {
103
+ async function spawnOnce(args, target, timeoutMs, signal) {
147
104
  await acquireSlot(signal);
148
105
  try {
149
- const { stdout } = await execa('yt-dlp', ['--socket-timeout', SOCKET_TIMEOUT_S, ...args], {
106
+ // Session flags (cookies, proxy, pacing) go first so a caller's argument can
107
+ // never be read as their value; the target goes last, behind `--`.
108
+ const argv = [
109
+ '--socket-timeout',
110
+ SOCKET_TIMEOUT_S,
111
+ ...readYtDlpEnv().args,
112
+ ...args,
113
+ '--',
114
+ target,
115
+ ];
116
+ const { stdout } = await execa('yt-dlp', argv, {
150
117
  timeout: timeoutMs > 0 ? timeoutMs : undefined,
151
118
  cancelSignal: signal,
152
119
  maxBuffer: MAX_OUTPUT_BYTES,
@@ -193,49 +160,4 @@ function asText(value) {
193
160
  }
194
161
  return '';
195
162
  }
196
- /**
197
- * Parse yt-dlp JSON output behind a type guard.
198
- *
199
- * Every JSON.parse in this codebase used to be unguarded, so a truncated or
200
- * non-JSON response surfaced as a raw SyntaxError.
201
- */
202
- export function parseYtDlpJson(stdout, guard, what) {
203
- let parsed;
204
- try {
205
- parsed = JSON.parse(stdout);
206
- }
207
- catch (error) {
208
- throw new YouTubeError('MALFORMED_RESPONSE', `yt-dlp returned unreadable output for ${what}.`, {
209
- nextStep: 'This usually means yt-dlp is out of date. Run `yt-dlp -U` and try again.',
210
- retryable: true,
211
- cause: error,
212
- });
213
- }
214
- if (!guard(parsed)) {
215
- throw new YouTubeError('MALFORMED_RESPONSE', `yt-dlp returned an unexpected shape for ${what}.`, {
216
- nextStep: 'This usually means yt-dlp is out of date. Run `yt-dlp -U` and try again.',
217
- });
218
- }
219
- return parsed;
220
- }
221
- /** Parse newline-delimited JSON, skipping unparseable lines rather than failing the call. */
222
- export function parseYtDlpJsonLines(stdout, guard) {
223
- const results = [];
224
- for (const line of stdout.trim().split('\n')) {
225
- if (!line.trim())
226
- continue;
227
- try {
228
- const parsed = JSON.parse(line);
229
- if (guard(parsed))
230
- results.push(parsed);
231
- }
232
- catch {
233
- // A single malformed row should not lose the whole result set.
234
- }
235
- }
236
- return results;
237
- }
238
- export function isRecord(value) {
239
- return typeof value === 'object' && value !== null && !Array.isArray(value);
240
- }
241
163
  //# sourceMappingURL=ytdlp.js.map
@@ -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.1.0",
3
+ "version": "3.0.0",
4
4
  "description": "MCP Server for extracting and managing YouTube video knowledge",
5
5
  "author": "teobouancheau",
6
6
  "repository": {
@@ -40,6 +40,7 @@
40
40
  "test": "vitest run",
41
41
  "test:watch": "vitest",
42
42
  "test:coverage": "vitest run --coverage",
43
+ "test:e2e": "npm run build && vitest run -c vitest.e2e.config.ts",
43
44
  "typecheck": "tsc --noEmit",
44
45
  "validate": "npm run typecheck && npm run lint && npm run format:check && npm run test:coverage",
45
46
  "prepare": "husky",
@@ -82,6 +83,6 @@
82
83
  "vitest": "^4.1.10"
83
84
  },
84
85
  "engines": {
85
- "node": ">=22.0.0"
86
+ "node": ">=22.13.0"
86
87
  }
87
88
  }