@zenalexa/unicli 0.220.1 → 0.221.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 (586) hide show
  1. package/AGENTS.md +35 -13
  2. package/README.md +18 -16
  3. package/README.zh-CN.md +18 -16
  4. package/dist/adapters/acl-anthology/papers.d.ts +16 -0
  5. package/dist/adapters/acl-anthology/papers.d.ts.map +1 -0
  6. package/dist/adapters/acl-anthology/papers.js +135 -0
  7. package/dist/adapters/acl-anthology/papers.js.map +1 -0
  8. package/dist/adapters/arxiv/papers.js +2 -0
  9. package/dist/adapters/arxiv/papers.js.map +1 -1
  10. package/dist/adapters/baidu-scholar/search.js +5 -0
  11. package/dist/adapters/baidu-scholar/search.js.map +1 -1
  12. package/dist/adapters/bilibili/comments.js +66 -4
  13. package/dist/adapters/bilibili/comments.js.map +1 -1
  14. package/dist/adapters/bilibili/compat.js +2 -2
  15. package/dist/adapters/bilibili/compat.js.map +1 -1
  16. package/dist/adapters/bilibili/download.js +4 -4
  17. package/dist/adapters/bilibili/download.js.map +1 -1
  18. package/dist/adapters/bilibili/wbi.d.ts.map +1 -1
  19. package/dist/adapters/bilibili/wbi.js +3 -3
  20. package/dist/adapters/bilibili/wbi.js.map +1 -1
  21. package/dist/adapters/cipo/_shared.d.ts +21 -0
  22. package/dist/adapters/cipo/_shared.d.ts.map +1 -0
  23. package/dist/adapters/cipo/_shared.js +67 -0
  24. package/dist/adapters/cipo/_shared.js.map +1 -0
  25. package/dist/adapters/cipo/get.d.ts +19 -0
  26. package/dist/adapters/cipo/get.d.ts.map +1 -0
  27. package/dist/adapters/cipo/get.js +140 -0
  28. package/dist/adapters/cipo/get.js.map +1 -0
  29. package/dist/adapters/cipo/legal-status.d.ts +19 -0
  30. package/dist/adapters/cipo/legal-status.d.ts.map +1 -0
  31. package/dist/adapters/cipo/legal-status.js +111 -0
  32. package/dist/adapters/cipo/legal-status.js.map +1 -0
  33. package/dist/adapters/cipo/search.d.ts +20 -0
  34. package/dist/adapters/cipo/search.d.ts.map +1 -0
  35. package/dist/adapters/cipo/search.js +148 -0
  36. package/dist/adapters/cipo/search.js.map +1 -0
  37. package/dist/adapters/cnipa/_shared.d.ts +47 -0
  38. package/dist/adapters/cnipa/_shared.d.ts.map +1 -0
  39. package/dist/adapters/cnipa/_shared.js +97 -0
  40. package/dist/adapters/cnipa/_shared.js.map +1 -0
  41. package/dist/adapters/cnipa/get.d.ts +19 -0
  42. package/dist/adapters/cnipa/get.d.ts.map +1 -0
  43. package/dist/adapters/cnipa/get.js +149 -0
  44. package/dist/adapters/cnipa/get.js.map +1 -0
  45. package/dist/adapters/cnipa/legal-status.d.ts +19 -0
  46. package/dist/adapters/cnipa/legal-status.d.ts.map +1 -0
  47. package/dist/adapters/cnipa/legal-status.js +119 -0
  48. package/dist/adapters/cnipa/legal-status.js.map +1 -0
  49. package/dist/adapters/cnipa/search.d.ts +21 -0
  50. package/dist/adapters/cnipa/search.d.ts.map +1 -0
  51. package/dist/adapters/cnipa/search.js +170 -0
  52. package/dist/adapters/cnipa/search.js.map +1 -0
  53. package/dist/adapters/crossref/works.d.ts +42 -0
  54. package/dist/adapters/crossref/works.d.ts.map +1 -0
  55. package/dist/adapters/crossref/works.js +157 -0
  56. package/dist/adapters/crossref/works.js.map +1 -0
  57. package/dist/adapters/cvf/papers.d.ts +17 -0
  58. package/dist/adapters/cvf/papers.d.ts.map +1 -0
  59. package/dist/adapters/cvf/papers.js +124 -0
  60. package/dist/adapters/cvf/papers.js.map +1 -0
  61. package/dist/adapters/dblp/publications.js +4 -0
  62. package/dist/adapters/dblp/publications.js.map +1 -1
  63. package/dist/adapters/espacenet/_shared.d.ts +21 -0
  64. package/dist/adapters/espacenet/_shared.d.ts.map +1 -0
  65. package/dist/adapters/espacenet/_shared.js +67 -0
  66. package/dist/adapters/espacenet/_shared.js.map +1 -0
  67. package/dist/adapters/espacenet/family.d.ts +19 -0
  68. package/dist/adapters/espacenet/family.d.ts.map +1 -0
  69. package/dist/adapters/espacenet/family.js +118 -0
  70. package/dist/adapters/espacenet/family.js.map +1 -0
  71. package/dist/adapters/espacenet/get.d.ts +19 -0
  72. package/dist/adapters/espacenet/get.d.ts.map +1 -0
  73. package/dist/adapters/espacenet/get.js +130 -0
  74. package/dist/adapters/espacenet/get.js.map +1 -0
  75. package/dist/adapters/espacenet/legal-status.d.ts +19 -0
  76. package/dist/adapters/espacenet/legal-status.d.ts.map +1 -0
  77. package/dist/adapters/espacenet/legal-status.js +110 -0
  78. package/dist/adapters/espacenet/legal-status.js.map +1 -0
  79. package/dist/adapters/espacenet/search.d.ts +20 -0
  80. package/dist/adapters/espacenet/search.d.ts.map +1 -0
  81. package/dist/adapters/espacenet/search.js +165 -0
  82. package/dist/adapters/espacenet/search.js.map +1 -0
  83. package/dist/adapters/facebook/subtitles.d.ts +9 -0
  84. package/dist/adapters/facebook/subtitles.d.ts.map +1 -0
  85. package/dist/adapters/facebook/subtitles.js +42 -0
  86. package/dist/adapters/facebook/subtitles.js.map +1 -0
  87. package/dist/adapters/fips/_shared.d.ts +21 -0
  88. package/dist/adapters/fips/_shared.d.ts.map +1 -0
  89. package/dist/adapters/fips/_shared.js +77 -0
  90. package/dist/adapters/fips/_shared.js.map +1 -0
  91. package/dist/adapters/fips/get.d.ts +19 -0
  92. package/dist/adapters/fips/get.d.ts.map +1 -0
  93. package/dist/adapters/fips/get.js +139 -0
  94. package/dist/adapters/fips/get.js.map +1 -0
  95. package/dist/adapters/fips/search.d.ts +20 -0
  96. package/dist/adapters/fips/search.d.ts.map +1 -0
  97. package/dist/adapters/fips/search.js +148 -0
  98. package/dist/adapters/fips/search.js.map +1 -0
  99. package/dist/adapters/freepatentsonline-web/_shared.d.ts +72 -0
  100. package/dist/adapters/freepatentsonline-web/_shared.d.ts.map +1 -0
  101. package/dist/adapters/freepatentsonline-web/_shared.js +216 -0
  102. package/dist/adapters/freepatentsonline-web/_shared.js.map +1 -0
  103. package/dist/adapters/freepatentsonline-web/get.d.ts +21 -0
  104. package/dist/adapters/freepatentsonline-web/get.d.ts.map +1 -0
  105. package/dist/adapters/freepatentsonline-web/get.js +127 -0
  106. package/dist/adapters/freepatentsonline-web/get.js.map +1 -0
  107. package/dist/adapters/freepatentsonline-web/search.d.ts +22 -0
  108. package/dist/adapters/freepatentsonline-web/search.d.ts.map +1 -0
  109. package/dist/adapters/freepatentsonline-web/search.js +149 -0
  110. package/dist/adapters/freepatentsonline-web/search.js.map +1 -0
  111. package/dist/adapters/google-patents-web/_shared.d.ts +110 -0
  112. package/dist/adapters/google-patents-web/_shared.d.ts.map +1 -0
  113. package/dist/adapters/google-patents-web/_shared.js +164 -0
  114. package/dist/adapters/google-patents-web/_shared.js.map +1 -0
  115. package/dist/adapters/google-patents-web/get.d.ts +36 -0
  116. package/dist/adapters/google-patents-web/get.d.ts.map +1 -0
  117. package/dist/adapters/google-patents-web/get.js +187 -0
  118. package/dist/adapters/google-patents-web/get.js.map +1 -0
  119. package/dist/adapters/google-patents-web/search.d.ts +23 -0
  120. package/dist/adapters/google-patents-web/search.d.ts.map +1 -0
  121. package/dist/adapters/google-patents-web/search.js +169 -0
  122. package/dist/adapters/google-patents-web/search.js.map +1 -0
  123. package/dist/adapters/google-scholar/cite.js +1 -0
  124. package/dist/adapters/google-scholar/cite.js.map +1 -1
  125. package/dist/adapters/google-scholar/profile.js +5 -0
  126. package/dist/adapters/google-scholar/profile.js.map +1 -1
  127. package/dist/adapters/google-scholar/search.js +5 -0
  128. package/dist/adapters/google-scholar/search.js.map +1 -1
  129. package/dist/adapters/hf/paper.js +1 -0
  130. package/dist/adapters/hf/paper.js.map +1 -1
  131. package/dist/adapters/inpi-br/_shared.d.ts +21 -0
  132. package/dist/adapters/inpi-br/_shared.d.ts.map +1 -0
  133. package/dist/adapters/inpi-br/_shared.js +67 -0
  134. package/dist/adapters/inpi-br/_shared.js.map +1 -0
  135. package/dist/adapters/inpi-br/get.d.ts +19 -0
  136. package/dist/adapters/inpi-br/get.d.ts.map +1 -0
  137. package/dist/adapters/inpi-br/get.js +142 -0
  138. package/dist/adapters/inpi-br/get.js.map +1 -0
  139. package/dist/adapters/inpi-br/search.d.ts +20 -0
  140. package/dist/adapters/inpi-br/search.d.ts.map +1 -0
  141. package/dist/adapters/inpi-br/search.js +154 -0
  142. package/dist/adapters/inpi-br/search.js.map +1 -0
  143. package/dist/adapters/instagram/subtitles.d.ts +9 -0
  144. package/dist/adapters/instagram/subtitles.d.ts.map +1 -0
  145. package/dist/adapters/instagram/subtitles.js +42 -0
  146. package/dist/adapters/instagram/subtitles.js.map +1 -0
  147. package/dist/adapters/mastodon/statuses.d.ts +40 -0
  148. package/dist/adapters/mastodon/statuses.d.ts.map +1 -0
  149. package/dist/adapters/mastodon/statuses.js +153 -0
  150. package/dist/adapters/mastodon/statuses.js.map +1 -0
  151. package/dist/adapters/neurips/proceedings.d.ts +17 -0
  152. package/dist/adapters/neurips/proceedings.d.ts.map +1 -0
  153. package/dist/adapters/neurips/proceedings.js +112 -0
  154. package/dist/adapters/neurips/proceedings.js.map +1 -0
  155. package/dist/adapters/openalex/works.d.ts.map +1 -1
  156. package/dist/adapters/openalex/works.js +32 -0
  157. package/dist/adapters/openalex/works.js.map +1 -1
  158. package/dist/adapters/openreview/papers.js +5 -0
  159. package/dist/adapters/openreview/papers.js.map +1 -1
  160. package/dist/adapters/pmlr/proceedings.d.ts +35 -0
  161. package/dist/adapters/pmlr/proceedings.d.ts.map +1 -0
  162. package/dist/adapters/pmlr/proceedings.js +139 -0
  163. package/dist/adapters/pmlr/proceedings.js.map +1 -0
  164. package/dist/adapters/pubmed/articles.js +5 -0
  165. package/dist/adapters/pubmed/articles.js.map +1 -1
  166. package/dist/adapters/reddit/comments.d.ts +9 -0
  167. package/dist/adapters/reddit/comments.d.ts.map +1 -0
  168. package/dist/adapters/reddit/comments.js +124 -0
  169. package/dist/adapters/reddit/comments.js.map +1 -0
  170. package/dist/adapters/semantic-scholar/papers.d.ts +36 -0
  171. package/dist/adapters/semantic-scholar/papers.d.ts.map +1 -0
  172. package/dist/adapters/semantic-scholar/papers.js +214 -0
  173. package/dist/adapters/semantic-scholar/papers.js.map +1 -0
  174. package/dist/adapters/threads/post.d.ts +32 -0
  175. package/dist/adapters/threads/post.d.ts.map +1 -0
  176. package/dist/adapters/threads/post.js +287 -0
  177. package/dist/adapters/threads/post.js.map +1 -0
  178. package/dist/adapters/tiktok/subtitles.d.ts +9 -0
  179. package/dist/adapters/tiktok/subtitles.d.ts.map +1 -0
  180. package/dist/adapters/tiktok/subtitles.js +42 -0
  181. package/dist/adapters/tiktok/subtitles.js.map +1 -0
  182. package/dist/adapters/twitter/accept.js +2 -2
  183. package/dist/adapters/twitter/accept.js.map +1 -1
  184. package/dist/adapters/twitter/browser-fallback.d.ts +26 -0
  185. package/dist/adapters/twitter/browser-fallback.d.ts.map +1 -0
  186. package/dist/adapters/twitter/browser-fallback.js +93 -0
  187. package/dist/adapters/twitter/browser-fallback.js.map +1 -0
  188. package/dist/adapters/twitter/browser-state.d.ts +11 -0
  189. package/dist/adapters/twitter/browser-state.d.ts.map +1 -0
  190. package/dist/adapters/twitter/browser-state.js +46 -0
  191. package/dist/adapters/twitter/browser-state.js.map +1 -0
  192. package/dist/adapters/twitter/client.d.ts.map +1 -1
  193. package/dist/adapters/twitter/client.js +36 -13
  194. package/dist/adapters/twitter/client.js.map +1 -1
  195. package/dist/adapters/twitter/reply-dm.js +2 -2
  196. package/dist/adapters/twitter/reply-dm.js.map +1 -1
  197. package/dist/adapters/twitter/reply.js +1 -0
  198. package/dist/adapters/twitter/reply.js.map +1 -1
  199. package/dist/adapters/twitter/search.js +11 -18
  200. package/dist/adapters/twitter/search.js.map +1 -1
  201. package/dist/adapters/twitter/thread.d.ts +14 -0
  202. package/dist/adapters/twitter/thread.d.ts.map +1 -1
  203. package/dist/adapters/twitter/thread.js +28 -2
  204. package/dist/adapters/twitter/thread.js.map +1 -1
  205. package/dist/adapters/twitter/trending.js +13 -59
  206. package/dist/adapters/twitter/trending.js.map +1 -1
  207. package/dist/adapters/unpaywall/works.d.ts +33 -0
  208. package/dist/adapters/unpaywall/works.d.ts.map +1 -0
  209. package/dist/adapters/unpaywall/works.js +101 -0
  210. package/dist/adapters/unpaywall/works.js.map +1 -0
  211. package/dist/adapters/xiaohongshu/browser-state.d.ts +19 -0
  212. package/dist/adapters/xiaohongshu/browser-state.d.ts.map +1 -0
  213. package/dist/adapters/xiaohongshu/browser-state.js +67 -0
  214. package/dist/adapters/xiaohongshu/browser-state.js.map +1 -0
  215. package/dist/adapters/xiaohongshu/comments.js +28 -5
  216. package/dist/adapters/xiaohongshu/comments.js.map +1 -1
  217. package/dist/adapters/xiaohongshu/download.js +49 -11
  218. package/dist/adapters/xiaohongshu/download.js.map +1 -1
  219. package/dist/adapters/xiaohongshu/search.d.ts.map +1 -1
  220. package/dist/adapters/xiaohongshu/search.js +11 -5
  221. package/dist/adapters/xiaohongshu/search.js.map +1 -1
  222. package/dist/adapters/xiaohongshu/trending.d.ts +9 -0
  223. package/dist/adapters/xiaohongshu/trending.d.ts.map +1 -0
  224. package/dist/adapters/xiaohongshu/trending.js +94 -0
  225. package/dist/adapters/xiaohongshu/trending.js.map +1 -0
  226. package/dist/adapters/youtube/comments.d.ts +80 -0
  227. package/dist/adapters/youtube/comments.d.ts.map +1 -1
  228. package/dist/adapters/youtube/comments.js +108 -12
  229. package/dist/adapters/youtube/comments.js.map +1 -1
  230. package/dist/adapters/youtube/subtitles.d.ts +9 -0
  231. package/dist/adapters/youtube/subtitles.d.ts.map +1 -0
  232. package/dist/adapters/youtube/subtitles.js +42 -0
  233. package/dist/adapters/youtube/subtitles.js.map +1 -0
  234. package/dist/adapters/yt-dlp/subtitles.d.ts +9 -0
  235. package/dist/adapters/yt-dlp/subtitles.d.ts.map +1 -0
  236. package/dist/adapters/yt-dlp/subtitles.js +41 -0
  237. package/dist/adapters/yt-dlp/subtitles.js.map +1 -0
  238. package/dist/adapters/zhihu/answer-detail.d.ts +39 -0
  239. package/dist/adapters/zhihu/answer-detail.d.ts.map +1 -0
  240. package/dist/adapters/zhihu/answer-detail.js +204 -0
  241. package/dist/adapters/zhihu/answer-detail.js.map +1 -0
  242. package/dist/adapters/zhihu/comment.d.ts +9 -0
  243. package/dist/adapters/zhihu/comment.d.ts.map +1 -0
  244. package/dist/adapters/zhihu/comment.js +149 -0
  245. package/dist/adapters/zhihu/comment.js.map +1 -0
  246. package/dist/adapters/zhihu/recommend.d.ts +36 -0
  247. package/dist/adapters/zhihu/recommend.d.ts.map +1 -0
  248. package/dist/adapters/zhihu/recommend.js +151 -0
  249. package/dist/adapters/zhihu/recommend.js.map +1 -0
  250. package/dist/browser/bridge.d.ts.map +1 -1
  251. package/dist/browser/bridge.js +14 -3
  252. package/dist/browser/bridge.js.map +1 -1
  253. package/dist/browser/daemon-client.d.ts +6 -0
  254. package/dist/browser/daemon-client.d.ts.map +1 -1
  255. package/dist/browser/daemon-client.js +75 -15
  256. package/dist/browser/daemon-client.js.map +1 -1
  257. package/dist/browser/daemon.js +39 -15
  258. package/dist/browser/daemon.js.map +1 -1
  259. package/dist/browser/protocol.d.ts +1 -0
  260. package/dist/browser/protocol.d.ts.map +1 -1
  261. package/dist/browser/protocol.js +1 -0
  262. package/dist/browser/protocol.js.map +1 -1
  263. package/dist/cli.d.ts.map +1 -1
  264. package/dist/cli.js +21 -1
  265. package/dist/cli.js.map +1 -1
  266. package/dist/commands/approvals.d.ts.map +1 -1
  267. package/dist/commands/approvals.js +1 -37
  268. package/dist/commands/approvals.js.map +1 -1
  269. package/dist/commands/browser/index.d.ts.map +1 -1
  270. package/dist/commands/browser/index.js +7 -2
  271. package/dist/commands/browser/index.js.map +1 -1
  272. package/dist/commands/daemon.d.ts.map +1 -1
  273. package/dist/commands/daemon.js +7 -3
  274. package/dist/commands/daemon.js.map +1 -1
  275. package/dist/commands/dispatch.d.ts.map +1 -1
  276. package/dist/commands/dispatch.js +27 -3
  277. package/dist/commands/dispatch.js.map +1 -1
  278. package/dist/commands/do.d.ts +30 -0
  279. package/dist/commands/do.d.ts.map +1 -0
  280. package/dist/commands/do.js +248 -0
  281. package/dist/commands/do.js.map +1 -0
  282. package/dist/commands/extract.d.ts +34 -0
  283. package/dist/commands/extract.d.ts.map +1 -0
  284. package/dist/commands/extract.js +316 -0
  285. package/dist/commands/extract.js.map +1 -0
  286. package/dist/commands/patent-doctor.d.ts +48 -0
  287. package/dist/commands/patent-doctor.d.ts.map +1 -0
  288. package/dist/commands/patent-doctor.js +109 -0
  289. package/dist/commands/patent-doctor.js.map +1 -0
  290. package/dist/commands/patent.d.ts +78 -0
  291. package/dist/commands/patent.d.ts.map +1 -0
  292. package/dist/commands/patent.js +919 -0
  293. package/dist/commands/patent.js.map +1 -0
  294. package/dist/commands/scholar.d.ts +33 -0
  295. package/dist/commands/scholar.d.ts.map +1 -0
  296. package/dist/commands/scholar.js +494 -0
  297. package/dist/commands/scholar.js.map +1 -0
  298. package/dist/commands/search.d.ts.map +1 -1
  299. package/dist/commands/search.js +2 -5
  300. package/dist/commands/search.js.map +1 -1
  301. package/dist/commands/social.d.ts +19 -0
  302. package/dist/commands/social.d.ts.map +1 -0
  303. package/dist/commands/social.js +236 -0
  304. package/dist/commands/social.js.map +1 -0
  305. package/dist/core/registry.d.ts +1 -1
  306. package/dist/core/registry.d.ts.map +1 -1
  307. package/dist/core/registry.js +11 -2
  308. package/dist/core/registry.js.map +1 -1
  309. package/dist/discovery/aliases.d.ts +2 -2
  310. package/dist/discovery/aliases.d.ts.map +1 -1
  311. package/dist/discovery/aliases.js +182 -11
  312. package/dist/discovery/aliases.js.map +1 -1
  313. package/dist/discovery/intents.d.ts +10 -0
  314. package/dist/discovery/intents.d.ts.map +1 -0
  315. package/dist/discovery/intents.js +255 -0
  316. package/dist/discovery/intents.js.map +1 -0
  317. package/dist/discovery/loader.d.ts.map +1 -1
  318. package/dist/discovery/loader.js +4 -0
  319. package/dist/discovery/loader.js.map +1 -1
  320. package/dist/discovery/search.d.ts +4 -1
  321. package/dist/discovery/search.d.ts.map +1 -1
  322. package/dist/discovery/search.js +28 -140
  323. package/dist/discovery/search.js.map +1 -1
  324. package/dist/engine/approval-presenter.d.ts +10 -0
  325. package/dist/engine/approval-presenter.d.ts.map +1 -0
  326. package/dist/engine/approval-presenter.js +45 -0
  327. package/dist/engine/approval-presenter.js.map +1 -0
  328. package/dist/engine/approval-store.d.ts +4 -0
  329. package/dist/engine/approval-store.d.ts.map +1 -1
  330. package/dist/engine/approval-store.js +85 -11
  331. package/dist/engine/approval-store.js.map +1 -1
  332. package/dist/engine/auth/oauth2-cc.d.ts +67 -0
  333. package/dist/engine/auth/oauth2-cc.d.ts.map +1 -0
  334. package/dist/engine/auth/oauth2-cc.js +120 -0
  335. package/dist/engine/auth/oauth2-cc.js.map +1 -0
  336. package/dist/engine/cookies.d.ts +10 -0
  337. package/dist/engine/cookies.d.ts.map +1 -1
  338. package/dist/engine/cookies.js +64 -0
  339. package/dist/engine/cookies.js.map +1 -1
  340. package/dist/engine/download.d.ts +5 -0
  341. package/dist/engine/download.d.ts.map +1 -1
  342. package/dist/engine/download.js +11 -4
  343. package/dist/engine/download.js.map +1 -1
  344. package/dist/engine/executor.d.ts +1 -0
  345. package/dist/engine/executor.d.ts.map +1 -1
  346. package/dist/engine/executor.js +25 -0
  347. package/dist/engine/executor.js.map +1 -1
  348. package/dist/engine/framework.d.ts +5 -5
  349. package/dist/engine/framework.js +5 -5
  350. package/dist/engine/harden.d.ts +1 -1
  351. package/dist/engine/harden.js +1 -1
  352. package/dist/engine/kernel/stages.d.ts.map +1 -1
  353. package/dist/engine/kernel/stages.js +2 -1
  354. package/dist/engine/kernel/stages.js.map +1 -1
  355. package/dist/engine/normalizer/patent-envelope.d.ts +61 -0
  356. package/dist/engine/normalizer/patent-envelope.d.ts.map +1 -0
  357. package/dist/engine/normalizer/patent-envelope.js +132 -0
  358. package/dist/engine/normalizer/patent-envelope.js.map +1 -0
  359. package/dist/engine/research.d.ts +5 -7
  360. package/dist/engine/research.d.ts.map +1 -1
  361. package/dist/engine/research.js +6 -9
  362. package/dist/engine/research.js.map +1 -1
  363. package/dist/engine/steps/browser-helpers.d.ts +2 -2
  364. package/dist/engine/steps/browser-helpers.d.ts.map +1 -1
  365. package/dist/engine/steps/browser-helpers.js +39 -16
  366. package/dist/engine/steps/browser-helpers.js.map +1 -1
  367. package/dist/engine/steps/download.d.ts +1 -0
  368. package/dist/engine/steps/download.d.ts.map +1 -1
  369. package/dist/engine/steps/download.js +3 -1
  370. package/dist/engine/steps/download.js.map +1 -1
  371. package/dist/engine/steps/index.d.ts +2 -0
  372. package/dist/engine/steps/index.d.ts.map +1 -1
  373. package/dist/engine/steps/index.js +2 -0
  374. package/dist/engine/steps/index.js.map +1 -1
  375. package/dist/engine/steps/oauth2-token.d.ts +41 -0
  376. package/dist/engine/steps/oauth2-token.d.ts.map +1 -0
  377. package/dist/engine/steps/oauth2-token.js +115 -0
  378. package/dist/engine/steps/oauth2-token.js.map +1 -0
  379. package/dist/engine/steps/select-xml.d.ts +34 -0
  380. package/dist/engine/steps/select-xml.d.ts.map +1 -0
  381. package/dist/engine/steps/select-xml.js +222 -0
  382. package/dist/engine/steps/select-xml.js.map +1 -0
  383. package/dist/engine/template.d.ts.map +1 -1
  384. package/dist/engine/template.js +7 -0
  385. package/dist/engine/template.js.map +1 -1
  386. package/dist/engine/transport/mcp-browser.d.ts +128 -0
  387. package/dist/engine/transport/mcp-browser.d.ts.map +1 -0
  388. package/dist/engine/transport/mcp-browser.js +120 -0
  389. package/dist/engine/transport/mcp-browser.js.map +1 -0
  390. package/dist/fast-path/handlers/approvals.d.ts +11 -0
  391. package/dist/fast-path/handlers/approvals.d.ts.map +1 -0
  392. package/dist/fast-path/handlers/approvals.js +136 -0
  393. package/dist/fast-path/handlers/approvals.js.map +1 -0
  394. package/dist/fast-path/handlers/discovery.d.ts.map +1 -1
  395. package/dist/fast-path/handlers/discovery.js +17 -3
  396. package/dist/fast-path/handlers/discovery.js.map +1 -1
  397. package/dist/fast-path/manifest.d.ts +1 -0
  398. package/dist/fast-path/manifest.d.ts.map +1 -1
  399. package/dist/fast-path/manifest.js.map +1 -1
  400. package/dist/fast-path.d.ts.map +1 -1
  401. package/dist/fast-path.js +3 -0
  402. package/dist/fast-path.js.map +1 -1
  403. package/dist/index.d.ts +23 -0
  404. package/dist/index.d.ts.map +1 -0
  405. package/dist/index.js +38 -0
  406. package/dist/index.js.map +1 -0
  407. package/dist/manifest-compact.txt +13 -11
  408. package/dist/manifest-search.json +1 -1
  409. package/dist/manifest.json +2560 -103
  410. package/dist/mcp/handler.d.ts.map +1 -1
  411. package/dist/mcp/handler.js +14 -2
  412. package/dist/mcp/handler.js.map +1 -1
  413. package/dist/mcp/tools.d.ts.map +1 -1
  414. package/dist/mcp/tools.js +11 -3
  415. package/dist/mcp/tools.js.map +1 -1
  416. package/dist/output/auth-guidance.d.ts +14 -0
  417. package/dist/output/auth-guidance.d.ts.map +1 -0
  418. package/dist/output/auth-guidance.js +50 -0
  419. package/dist/output/auth-guidance.js.map +1 -0
  420. package/dist/output/error-map.d.ts +1 -1
  421. package/dist/output/error-map.d.ts.map +1 -1
  422. package/dist/output/error-map.js +28 -4
  423. package/dist/output/error-map.js.map +1 -1
  424. package/dist/output/next-actions.d.ts.map +1 -1
  425. package/dist/output/next-actions.js +19 -3
  426. package/dist/output/next-actions.js.map +1 -1
  427. package/dist/registry.d.ts +19 -1
  428. package/dist/registry.d.ts.map +1 -1
  429. package/dist/registry.js +10 -0
  430. package/dist/registry.js.map +1 -1
  431. package/dist/social/browser-errors.d.ts +13 -0
  432. package/dist/social/browser-errors.d.ts.map +1 -0
  433. package/dist/social/browser-errors.js +36 -0
  434. package/dist/social/browser-errors.js.map +1 -0
  435. package/dist/social/capabilities.d.ts +29 -0
  436. package/dist/social/capabilities.d.ts.map +1 -0
  437. package/dist/social/capabilities.js +448 -0
  438. package/dist/social/capabilities.js.map +1 -0
  439. package/dist/social/comments.d.ts +26 -0
  440. package/dist/social/comments.d.ts.map +1 -0
  441. package/dist/social/comments.js +97 -0
  442. package/dist/social/comments.js.map +1 -0
  443. package/dist/social/video-text.d.ts +27 -0
  444. package/dist/social/video-text.d.ts.map +1 -0
  445. package/dist/social/video-text.js +140 -0
  446. package/dist/social/video-text.js.map +1 -0
  447. package/dist/types/patent.d.ts +160 -0
  448. package/dist/types/patent.d.ts.map +1 -0
  449. package/dist/types/patent.js +16 -0
  450. package/dist/types/patent.js.map +1 -0
  451. package/dist/types/scholarly.d.ts +49 -0
  452. package/dist/types/scholarly.d.ts.map +1 -0
  453. package/dist/types/scholarly.js +16 -0
  454. package/dist/types/scholarly.js.map +1 -0
  455. package/dist/types.d.ts +12 -0
  456. package/dist/types.d.ts.map +1 -1
  457. package/dist/types.js.map +1 -1
  458. package/package.json +9 -4
  459. package/server.json +3 -3
  460. package/skills/unicli/SKILL.md +1 -1
  461. package/skills/unicli-claude-code/SKILL.md +1 -1
  462. package/skills/unicli-hermes/SKILL.md +1 -1
  463. package/src/adapters/acl-anthology/papers.ts +157 -0
  464. package/src/adapters/arxiv/download.yaml +1 -1
  465. package/src/adapters/arxiv/paper.yaml +1 -1
  466. package/src/adapters/arxiv/papers.ts +2 -0
  467. package/src/adapters/arxiv/search.yaml +1 -1
  468. package/src/adapters/arxiv/trending.yaml +1 -1
  469. package/src/adapters/baidu-scholar/search.ts +5 -0
  470. package/src/adapters/bilibili/comments-tree.test.ts +41 -0
  471. package/src/adapters/bilibili/comments.ts +78 -4
  472. package/src/adapters/bilibili/compat.ts +5 -2
  473. package/src/adapters/bilibili/download.ts +7 -4
  474. package/src/adapters/bilibili/wbi.ts +6 -3
  475. package/src/adapters/brave/search.yaml +53 -0
  476. package/src/adapters/cipo/_shared.ts +98 -0
  477. package/src/adapters/cipo/get.ts +188 -0
  478. package/src/adapters/cipo/legal-status.ts +148 -0
  479. package/src/adapters/cipo/search.ts +195 -0
  480. package/src/adapters/cnipa/_shared.ts +138 -0
  481. package/src/adapters/cnipa/get.ts +199 -0
  482. package/src/adapters/cnipa/legal-status.ts +162 -0
  483. package/src/adapters/cnipa/search.ts +229 -0
  484. package/src/adapters/crossref/works.ts +209 -0
  485. package/src/adapters/cvf/papers.ts +136 -0
  486. package/src/adapters/dblp/publications.ts +4 -0
  487. package/src/adapters/dpma/get.yaml +67 -0
  488. package/src/adapters/dpma/search.yaml +77 -0
  489. package/src/adapters/duckduckgo/search.yaml +54 -0
  490. package/src/adapters/duckduckgo/suggest.yaml +52 -0
  491. package/src/adapters/epo/family.yaml +69 -0
  492. package/src/adapters/epo/get.yaml +74 -0
  493. package/src/adapters/epo/legal-status.yaml +63 -0
  494. package/src/adapters/epo/search.yaml +84 -0
  495. package/src/adapters/espacenet/_shared.ts +98 -0
  496. package/src/adapters/espacenet/family.ts +161 -0
  497. package/src/adapters/espacenet/get.ts +185 -0
  498. package/src/adapters/espacenet/legal-status.ts +151 -0
  499. package/src/adapters/espacenet/search.ts +229 -0
  500. package/src/adapters/facebook/subtitles.ts +44 -0
  501. package/src/adapters/fips/_shared.ts +109 -0
  502. package/src/adapters/fips/get.ts +186 -0
  503. package/src/adapters/fips/search.ts +195 -0
  504. package/src/adapters/freepatentsonline-web/_shared.ts +273 -0
  505. package/src/adapters/freepatentsonline-web/get.ts +144 -0
  506. package/src/adapters/freepatentsonline-web/search.ts +170 -0
  507. package/src/adapters/google-patents-bq/prior-art.yaml +80 -0
  508. package/src/adapters/google-patents-bq/search.yaml +97 -0
  509. package/src/adapters/google-patents-web/_shared.ts +242 -0
  510. package/src/adapters/google-patents-web/get.ts +224 -0
  511. package/src/adapters/google-patents-web/search.ts +196 -0
  512. package/src/adapters/google-scholar/cite.ts +1 -0
  513. package/src/adapters/google-scholar/profile.ts +5 -0
  514. package/src/adapters/google-scholar/search.ts +5 -0
  515. package/src/adapters/hf/paper.test.ts +10 -0
  516. package/src/adapters/hf/paper.ts +1 -0
  517. package/src/adapters/hf/top.yaml +1 -1
  518. package/src/adapters/huggingface-papers/daily.yaml +1 -1
  519. package/src/adapters/huggingface-papers/search.yaml +1 -1
  520. package/src/adapters/inpi-br/_shared.ts +98 -0
  521. package/src/adapters/inpi-br/get.ts +193 -0
  522. package/src/adapters/inpi-br/search.ts +206 -0
  523. package/src/adapters/inpi-fr/get.yaml +62 -0
  524. package/src/adapters/inpi-fr/search.yaml +74 -0
  525. package/src/adapters/instagram/subtitles.ts +44 -0
  526. package/src/adapters/ipaustralia/get.yaml +67 -0
  527. package/src/adapters/ipaustralia/search.yaml +74 -0
  528. package/src/adapters/jpo/get.yaml +63 -0
  529. package/src/adapters/jpo/search.yaml +76 -0
  530. package/src/adapters/kipris/get.yaml +69 -0
  531. package/src/adapters/kipris/legal-status.yaml +58 -0
  532. package/src/adapters/kipris/search.yaml +79 -0
  533. package/src/adapters/lens/get.yaml +64 -0
  534. package/src/adapters/lens/search.yaml +82 -0
  535. package/src/adapters/mastodon/statuses.test.ts +82 -0
  536. package/src/adapters/mastodon/statuses.ts +208 -0
  537. package/src/adapters/neurips/proceedings.ts +126 -0
  538. package/src/adapters/openalex/works.ts +33 -0
  539. package/src/adapters/openreview/papers.ts +5 -0
  540. package/src/adapters/patsnap/get.yaml +65 -0
  541. package/src/adapters/patsnap/search.yaml +77 -0
  542. package/src/adapters/pmlr/proceedings.ts +167 -0
  543. package/src/adapters/pqai/prior-art.yaml +59 -0
  544. package/src/adapters/pqai/search.yaml +60 -0
  545. package/src/adapters/pubmed/articles.ts +5 -0
  546. package/src/adapters/reddit/comments-tree.test.ts +79 -0
  547. package/src/adapters/reddit/comments.ts +159 -0
  548. package/src/adapters/semantic-scholar/papers.ts +268 -0
  549. package/src/adapters/threads/post.test.ts +64 -0
  550. package/src/adapters/threads/post.ts +366 -0
  551. package/src/adapters/threads/user.yaml +73 -0
  552. package/src/adapters/tiktok/subtitles.ts +44 -0
  553. package/src/adapters/twitter/accept.ts +5 -2
  554. package/src/adapters/twitter/browser-fallback.ts +138 -0
  555. package/src/adapters/twitter/browser-state.ts +74 -0
  556. package/src/adapters/twitter/client.ts +51 -21
  557. package/src/adapters/twitter/reply-dm.ts +5 -2
  558. package/src/adapters/twitter/reply.ts +1 -0
  559. package/src/adapters/twitter/search.ts +12 -38
  560. package/src/adapters/twitter/thread.test.ts +43 -0
  561. package/src/adapters/twitter/thread.ts +44 -2
  562. package/src/adapters/twitter/trending.ts +14 -95
  563. package/src/adapters/ukipo/info.yaml +43 -0
  564. package/src/adapters/unpaywall/works.ts +138 -0
  565. package/src/adapters/uspto/get.yaml +67 -0
  566. package/src/adapters/uspto/legal-status.yaml +58 -0
  567. package/src/adapters/uspto/search.yaml +88 -0
  568. package/src/adapters/wipo-patentscope/info.yaml +43 -0
  569. package/src/adapters/xiaohongshu/browser-state.ts +95 -0
  570. package/src/adapters/xiaohongshu/comments.ts +29 -6
  571. package/src/adapters/xiaohongshu/download.ts +60 -11
  572. package/src/adapters/xiaohongshu/search.ts +18 -6
  573. package/src/adapters/xiaohongshu/trending.ts +112 -0
  574. package/src/adapters/yahoo/search.yaml +52 -0
  575. package/src/adapters/youtube/comments-microformat.test.ts +35 -0
  576. package/src/adapters/youtube/comments-tree.test.ts +74 -0
  577. package/src/adapters/youtube/comments.ts +166 -12
  578. package/src/adapters/youtube/subtitles.ts +44 -0
  579. package/src/adapters/yt-dlp/subtitles.ts +43 -0
  580. package/src/adapters/zhihu/answer-detail.test.ts +83 -0
  581. package/src/adapters/zhihu/answer-detail.ts +275 -0
  582. package/src/adapters/zhihu/comment-tree.test.ts +57 -0
  583. package/src/adapters/zhihu/comment.ts +186 -0
  584. package/src/adapters/zhihu/recommend.test.ts +65 -0
  585. package/src/adapters/zhihu/recommend.ts +207 -0
  586. package/src/adapters/zotero/search.yaml +1 -1
@@ -0,0 +1,126 @@
1
+ /**
2
+ * @owner src::adapters::neurips::proceedings
3
+ * @does Registers NeurIPS proceedings search over the official yearly paper list.
4
+ * @needs proceedings.neurips.cc static HTML, src/registry.ts
5
+ * @feeds src/commands/scholar.ts via scholar.search, scholar.pdf, and scholar.venue
6
+ * @breaks NeurIPS markup drift surfaces as empty parse output; no unrelated source fallback is used.
7
+ * @invariants Year is explicit; paper URLs are absolutized against proceedings.neurips.cc.
8
+ * @side-effects HTTPS egress to proceedings.neurips.cc only
9
+ * @perf O(N) over one proceedings HTML page
10
+ * @concurrency safe
11
+ * @test tests/unit/adapters/scholar-sources.test.ts
12
+ * @stability experimental
13
+ * @since 2026-05-19
14
+ */
15
+
16
+ import { cli, Strategy } from "../../registry.js";
17
+ import type { ScholarlyWorkRecord } from "../../types/scholarly.js";
18
+
19
+ const ORIGIN = "https://proceedings.neurips.cc";
20
+
21
+ function decode(value: string): string {
22
+ return value
23
+ .replace(/&/g, "&")
24
+ .replace(/&lt;/g, "<")
25
+ .replace(/&gt;/g, ">")
26
+ .replace(/&quot;/g, '"')
27
+ .replace(/&#39;/g, "'")
28
+ .replace(/\s+/g, " ")
29
+ .trim();
30
+ }
31
+
32
+ function absolute(path: string): string {
33
+ return /^https?:\/\//i.test(path)
34
+ ? path
35
+ : `${ORIGIN}${path.startsWith("/") ? "" : "/"}${path}`;
36
+ }
37
+
38
+ function requireYear(value: unknown): string {
39
+ const year = String(value ?? "").trim();
40
+ if (!/^\d{4}$/.test(year))
41
+ throw new Error(`neurips year "${year}" is not valid.`);
42
+ return year;
43
+ }
44
+
45
+ export function parseNeuripsRows(
46
+ html: string,
47
+ year = "2024",
48
+ ): ScholarlyWorkRecord[] {
49
+ const out: ScholarlyWorkRecord[] = [];
50
+ const re =
51
+ /<div class="paper-content">[\s\S]*?<a title="paper title" href="([^"]+)">([\s\S]*?)<\/a>[\s\S]*?<span class="paper-authors">([\s\S]*?)<\/span>/g;
52
+ let match: RegExpExecArray | null;
53
+ while ((match = re.exec(html)) !== null) {
54
+ const sourceUrl = absolute(match[1]);
55
+ out.push({
56
+ id:
57
+ sourceUrl
58
+ .split("/")
59
+ .pop()
60
+ ?.replace(/\.html$/, "") ?? decode(match[2]),
61
+ title: decode(match[2].replace(/<[^>]+>/g, " ")),
62
+ authors: decode(match[3])
63
+ .split(",")
64
+ .map((author) => author.trim())
65
+ .filter(Boolean),
66
+ year: Number(year),
67
+ venue: "NeurIPS",
68
+ pdf_url: sourceUrl
69
+ .replace("-Abstract-", "-Paper-")
70
+ .replace(/\.html$/, ".pdf"),
71
+ source_adapter: "neurips",
72
+ source_url: sourceUrl,
73
+ retrieved_at: new Date().toISOString(),
74
+ });
75
+ }
76
+ return out;
77
+ }
78
+
79
+ cli({
80
+ site: "neurips",
81
+ name: "search",
82
+ description: "Search NeurIPS proceedings by year",
83
+ domain: "proceedings.neurips.cc",
84
+ strategy: Strategy.PUBLIC,
85
+ args: [
86
+ { name: "query", type: "str", required: true, positional: true },
87
+ { name: "year", type: "str", default: "2024" },
88
+ { name: "limit", type: "int", default: 20 },
89
+ ],
90
+ columns: ["id", "title", "authors", "year", "venue", "pdf_url", "source_url"],
91
+ capabilities: [
92
+ "http.fetch",
93
+ "scholar.search",
94
+ "scholar.venue",
95
+ "scholar.pdf",
96
+ ],
97
+ func: async (_page, kwargs) => {
98
+ const query = String(kwargs.query ?? "")
99
+ .trim()
100
+ .toLowerCase();
101
+ if (!query) throw new Error("neurips search query cannot be empty.");
102
+ const year = requireYear(kwargs.year);
103
+ const response = await fetch(`${ORIGIN}/paper_files/paper/${year}`, {
104
+ headers: {
105
+ Accept: "text/html",
106
+ "User-Agent":
107
+ "unicli-neurips/1.0 (https://github.com/olo-dot-io/Uni-CLI)",
108
+ },
109
+ });
110
+ if (response.status === 404)
111
+ throw new Error(`NeurIPS ${year} returned no proceedings page.`);
112
+ if (!response.ok)
113
+ throw new Error(`NeurIPS ${year} returned HTTP ${response.status}.`);
114
+ const limit = Math.min(Math.max(Number(kwargs.limit ?? 20), 1), 200);
115
+ const rows = parseNeuripsRows(await response.text(), year)
116
+ .filter((row) =>
117
+ `${row.title} ${row.authors?.join(" ") ?? ""}`
118
+ .toLowerCase()
119
+ .includes(query),
120
+ )
121
+ .slice(0, limit);
122
+ if (rows.length === 0)
123
+ throw new Error(`No NeurIPS ${year} papers matched "${query}".`);
124
+ return rows;
125
+ },
126
+ });
@@ -164,6 +164,14 @@ function authors(work: OpenAlexWork): string {
164
164
  : "";
165
165
  }
166
166
 
167
+ function authorList(work: OpenAlexWork): string[] {
168
+ return Array.isArray(work.authorships)
169
+ ? work.authorships
170
+ .map((item) => stringField(item.author?.display_name).trim())
171
+ .filter(Boolean)
172
+ : [];
173
+ }
174
+
167
175
  function venue(work: OpenAlexWork): string {
168
176
  return stringField(work.primary_location?.source?.display_name).trim();
169
177
  }
@@ -181,10 +189,17 @@ export function mapOpenAlexSearchRows(
181
189
  year: numberField(work.publication_year),
182
190
  citations: numberField(work.cited_by_count),
183
191
  firstAuthor: firstAuthor(work),
192
+ authors: authorList(work),
184
193
  venue: venue(work),
185
194
  openAccess: Boolean(work.open_access?.is_oa),
195
+ is_open_access: Boolean(work.open_access?.is_oa),
186
196
  type: stringField(work.type).trim(),
187
197
  doi: bareDoi(work.doi),
198
+ pdf_url: stringField(work.open_access?.oa_url).trim(),
199
+ openalex_id: id,
200
+ source_adapter: "openalex",
201
+ source_url: id ? `https://openalex.org/${id}` : "",
202
+ retrieved_at: new Date().toISOString(),
188
203
  url: id ? `https://openalex.org/${id}` : "",
189
204
  };
190
205
  });
@@ -203,15 +218,26 @@ export function mapOpenAlexWorkRow(
203
218
  date: stringField(work.publication_date).trim(),
204
219
  language: stringField(work.language).trim(),
205
220
  authors: authors(work),
221
+ author_list: authorList(work),
206
222
  venue: venue(work),
207
223
  citations: numberField(work.cited_by_count),
224
+ cited_by_count: numberField(work.cited_by_count),
208
225
  openAccess: Boolean(work.open_access?.is_oa),
226
+ is_open_access: Boolean(work.open_access?.is_oa),
209
227
  openAccessUrl: stringField(work.open_access?.oa_url).trim(),
228
+ pdf_url: stringField(work.open_access?.oa_url).trim(),
210
229
  referencedCount: Array.isArray(work.referenced_works)
211
230
  ? work.referenced_works.length
212
231
  : null,
232
+ references_count: Array.isArray(work.referenced_works)
233
+ ? work.referenced_works.length
234
+ : null,
213
235
  doi: bareDoi(work.doi),
214
236
  abstract: reconstructOpenAlexAbstract(work.abstract_inverted_index),
237
+ openalex_id: id,
238
+ source_adapter: "openalex",
239
+ source_url: `https://openalex.org/${id}`,
240
+ retrieved_at: new Date().toISOString(),
215
241
  url: `https://openalex.org/${id}`,
216
242
  };
217
243
  }
@@ -259,6 +285,7 @@ cli({
259
285
  "doi",
260
286
  "url",
261
287
  ],
288
+ capabilities: ["http.fetch", "scholar.search"],
262
289
  func: async (_page, kwargs) => {
263
290
  const query = requireOpenAlexString(kwargs.query, "query");
264
291
  const limit = requireOpenAlexLimit(kwargs.limit);
@@ -308,6 +335,12 @@ cli({
308
335
  "abstract",
309
336
  "url",
310
337
  ],
338
+ capabilities: [
339
+ "http.fetch",
340
+ "scholar.get",
341
+ "scholar.pdf",
342
+ "scholar.references",
343
+ ],
311
344
  func: async (_page, kwargs) => {
312
345
  const ref = requireOpenAlexWorkRef(kwargs.id);
313
346
  const work = (await fetchOpenAlex(
@@ -303,6 +303,7 @@ cli({
303
303
  { name: "limit", type: "int", default: 25, description: "Max results" },
304
304
  ],
305
305
  columns: ["rank", "id", "title", "authors", "venue", "pdate", "url"],
306
+ capabilities: ["http.fetch", "scholar.search", "scholar.review"],
306
307
  func: async (_page, kwargs) => {
307
308
  const query = String(kwargs.query ?? "").trim();
308
309
  if (!query) throw new Error("openreview search query cannot be empty.");
@@ -363,6 +364,7 @@ cli({
363
364
  "pdf",
364
365
  "url",
365
366
  ],
367
+ capabilities: ["http.fetch", "scholar.get", "scholar.pdf", "scholar.review"],
366
368
  func: async (_page, kwargs) => {
367
369
  const id = requireForumId(kwargs.id);
368
370
  const notes = notesFromEnvelope(
@@ -409,6 +411,7 @@ cli({
409
411
  { name: "limit", type: "int", default: 50, description: "Max submissions" },
410
412
  ],
411
413
  columns: ["rank", "id", "title", "authors", "venue", "pdate", "url"],
414
+ capabilities: ["http.fetch", "scholar.author", "scholar.search"],
412
415
  func: async (_page, kwargs) => {
413
416
  const profile = requireProfileId(kwargs.profile);
414
417
  const limit = requireOpenReviewLimit(kwargs.limit, 50, 1000);
@@ -473,6 +476,7 @@ cli({
473
476
  "pdf",
474
477
  "url",
475
478
  ],
479
+ capabilities: ["http.fetch", "scholar.venue", "scholar.search"],
476
480
  func: async (_page, kwargs) => {
477
481
  const venue = String(kwargs.venue ?? "").trim();
478
482
  if (!venue) throw new Error("openreview venue cannot be empty.");
@@ -531,6 +535,7 @@ cli({
531
535
  },
532
536
  ],
533
537
  columns: ["type", "author", "rating", "confidence", "text"],
538
+ capabilities: ["http.fetch", "scholar.review"],
534
539
  func: async (_page, kwargs) => {
535
540
  const forum = requireForumId(kwargs.forum, "forum");
536
541
  const maxLength = coerceOpenReviewInt(
@@ -0,0 +1,65 @@
1
+ # PatSnap Eureka — single-record fetch.
2
+ #
3
+ # verification_status: blocked-by-subscription
4
+ #
5
+ # Maps to PatSnap's /patent/biblio/{publication_number} endpoint. The same
6
+ # OAuth2 token resolution pattern as `patsnap/search.yaml`.
7
+ site: patsnap
8
+ name: get
9
+ description: Retrieve one PatSnap patent record by publication number
10
+ domain: connect.zhihuiya.com
11
+ type: web-api
12
+ strategy: header
13
+
14
+ args:
15
+ publication_number:
16
+ type: str
17
+ required: true
18
+ positional: true
19
+
20
+ pipeline:
21
+ - oauth2-token:
22
+ token_url: https://connect.zhihuiya.com/oauth/token
23
+ client_id_env: PATSNAP_CLIENT_ID
24
+ client_secret_env: PATSNAP_CLIENT_SECRET
25
+ site: patsnap
26
+ destination: auth.bearer
27
+
28
+ - fetch:
29
+ url: "https://connect.zhihuiya.com/patent/biblio"
30
+ params:
31
+ patent_number: "${{ args.publication_number }}"
32
+ headers:
33
+ Authorization: "Bearer ${{ auth.bearer }}"
34
+
35
+ - select: data
36
+
37
+ - map:
38
+ publication_number: "${{ item.pn }}"
39
+ title: "${{ item.title }}"
40
+ abstract: "${{ item.abstract }}"
41
+ kind_code: "${{ item.kind_code || item.kindcode || '' }}"
42
+ filing_date: "${{ item.apdt || '' }}"
43
+ publication_date: "${{ item.pbdt || '' }}"
44
+ grant_date: "${{ item.grant_date || item.granted || '' }}"
45
+ priority_date: "${{ item.priority_date || item.prdate || '' }}"
46
+ application_number: "${{ item.application_number || item.an || '' }}"
47
+ family_id: "${{ item.simple_family_id || '' }}"
48
+ legal_status: "${{ item.legal_status || '' }}"
49
+ inventors: "${{ JSON.stringify((function(){ var i=item.inventor || item.inventors; if(!i) return []; if(typeof i === 'string') return i.split(/\\s*[\\|;,]\\s*/).filter(s => s).map(name => ({ name: name })); return Array.isArray(i) ? i.map(n => ({ name: typeof n === 'string' ? n : (n.name || ''), country: n.country || undefined })) : []; })()) }}"
50
+ assignees: "${{ JSON.stringify((function(){ var a=item.current_assignee || item.assignee || item.assignees; if(!a) return []; if(typeof a === 'string') return a.split(/\\s*[\\|;,]\\s*/).filter(s => s).map(name => ({ name: name })); return Array.isArray(a) ? a.map(n => ({ name: typeof n === 'string' ? n : (n.name || ''), country: n.country || undefined })) : []; })()) }}"
51
+ classifications: "${{ JSON.stringify((function(){ var out=[]; var ipc=item.ipc; if(ipc){ var arr = Array.isArray(ipc) ? ipc : String(ipc).split(/[\\|;,]/); for (var i=0;i<arr.length;i++){ var c = arr[i]; var code = typeof c === 'string' ? c.trim() : (c.code || ''); if(code) out.push({ scheme: 'ipc', code: code }); } } var cpc=item.cpc; if(cpc){ var arr2 = Array.isArray(cpc) ? cpc : String(cpc).split(/[\\|;,]/); for (var j=0;j<arr2.length;j++){ var c2 = arr2[j]; var code2 = typeof c2 === 'string' ? c2.trim() : (c2.code || ''); if(code2) out.push({ scheme: 'cpc', code: code2 }); } } return out; })()) }}"
52
+ cited_by_count: "${{ item.cited_by !== undefined ? item.cited_by : (item.citation_count !== undefined ? item.citation_count : '') }}"
53
+ cites_count: "${{ item.cites !== undefined ? item.cites : '' }}"
54
+ source_adapter: patsnap
55
+ source_url: "${{ 'https://analytics.zhihuiya.com/patent/' + (item.pn || '') }}"
56
+ retrieved_at: "${{ now }}"
57
+
58
+ columns: [publication_number, title, legal_status, source_adapter]
59
+
60
+ capabilities: ["http.fetch", "patent.get"]
61
+ minimum_capability: http.fetch
62
+ trust: public
63
+ confidentiality: public
64
+ quarantine: false
65
+ schema_version: v2
@@ -0,0 +1,77 @@
1
+ # PatSnap Eureka — OAuth2 client_credentials search.
2
+ #
3
+ # verification_status: blocked-by-subscription
4
+ #
5
+ # PatSnap is a commercial patent intelligence platform. API access requires a
6
+ # Connect / Eureka subscription with two static credentials (CLIENT_ID /
7
+ # CLIENT_SECRET) the buyer pastes into env vars. The `oauth2-token` step
8
+ # resolves the bearer once and caches it; downstream fetch reuses it.
9
+ site: patsnap
10
+ name: search
11
+ description: PatSnap Eureka patent search via OAuth2 client_credentials
12
+ domain: connect.zhihuiya.com
13
+ type: web-api
14
+ strategy: header
15
+
16
+ args:
17
+ query:
18
+ type: str
19
+ required: true
20
+ positional: true
21
+ limit:
22
+ type: int
23
+ default: 20
24
+
25
+ pipeline:
26
+ - oauth2-token:
27
+ token_url: https://connect.zhihuiya.com/oauth/token
28
+ client_id_env: PATSNAP_CLIENT_ID
29
+ client_secret_env: PATSNAP_CLIENT_SECRET
30
+ site: patsnap
31
+ destination: auth.bearer
32
+
33
+ - fetch:
34
+ url: https://connect.zhihuiya.com/search/patent/query-search-patent/v2
35
+ method: POST
36
+ headers:
37
+ Authorization: "Bearer ${{ auth.bearer }}"
38
+ Content-Type: application/json
39
+ body:
40
+ text: "${{ args.query }}"
41
+ offset: 0
42
+ limit: "${{ args.limit }}"
43
+
44
+ - select: data.results
45
+
46
+ # PatSnap Eureka response carries inventors / assignees / classifications
47
+ # under documented field names.
48
+ - map:
49
+ publication_number: "${{ item.pn || item.pbd_number }}"
50
+ title: "${{ item.title }}"
51
+ abstract: "${{ item.abstract }}"
52
+ kind_code: "${{ item.kind_code || item.kindcode || '' }}"
53
+ filing_date: "${{ item.apdt || '' }}"
54
+ publication_date: "${{ item.pbdt || '' }}"
55
+ grant_date: "${{ item.grant_date || item.granted || '' }}"
56
+ priority_date: "${{ item.priority_date || item.prdate || '' }}"
57
+ application_number: "${{ item.application_number || item.an || '' }}"
58
+ family_id: "${{ item.simple_family_id || '' }}"
59
+ inventors: "${{ JSON.stringify((function(){ var i=item.inventor || item.inventors; if(!i) return []; if(typeof i === 'string') return i.split(/\\s*[\\|;,]\\s*/).filter(s => s).map(name => ({ name: name })); return Array.isArray(i) ? i.map(n => ({ name: typeof n === 'string' ? n : (n.name || ''), country: n.country || undefined })) : []; })()) }}"
60
+ assignees: "${{ JSON.stringify((function(){ var a=item.current_assignee || item.assignee || item.assignees; if(!a) return []; if(typeof a === 'string') return a.split(/\\s*[\\|;,]\\s*/).filter(s => s).map(name => ({ name: name })); return Array.isArray(a) ? a.map(n => ({ name: typeof n === 'string' ? n : (n.name || ''), country: n.country || undefined })) : []; })()) }}"
61
+ classifications: "${{ JSON.stringify((function(){ var out=[]; var ipc=item.ipc; if(ipc){ var arr = Array.isArray(ipc) ? ipc : String(ipc).split(/[\\|;,]/); for (var i=0;i<arr.length;i++){ var c = arr[i]; var code = typeof c === 'string' ? c.trim() : (c.code || ''); if(code) out.push({ scheme: 'ipc', code: code }); } } var cpc=item.cpc; if(cpc){ var arr2 = Array.isArray(cpc) ? cpc : String(cpc).split(/[\\|;,]/); for (var j=0;j<arr2.length;j++){ var c2 = arr2[j]; var code2 = typeof c2 === 'string' ? c2.trim() : (c2.code || ''); if(code2) out.push({ scheme: 'cpc', code: code2 }); } } return out; })()) }}"
62
+ cited_by_count: "${{ item.cited_by !== undefined ? item.cited_by : (item.citation_count !== undefined ? item.citation_count : '') }}"
63
+ cites_count: "${{ item.cites !== undefined ? item.cites : '' }}"
64
+ source_adapter: patsnap
65
+ source_url: "${{ 'https://analytics.zhihuiya.com/patent/' + (item.pn || item.pbd_number || '') }}"
66
+ retrieved_at: "${{ now }}"
67
+
68
+ - limit: ${{ args.limit }}
69
+
70
+ columns: [publication_number, title, publication_date, source_adapter]
71
+
72
+ capabilities: ["http.fetch", "patent.search"]
73
+ minimum_capability: http.fetch
74
+ trust: public
75
+ confidentiality: public
76
+ quarantine: false
77
+ schema_version: v2
@@ -0,0 +1,167 @@
1
+ /**
2
+ * @owner src::adapters::pmlr::proceedings
3
+ * @does Registers Proceedings of Machine Learning Research volume search using official citeproc.yaml metadata.
4
+ * @needs proceedings.mlr.press citeproc.yaml files, js-yaml, src/registry.ts
5
+ * @feeds src/commands/scholar.ts via scholar.search, scholar.get, scholar.pdf, and scholar.venue
6
+ * @breaks Missing volume metadata or citeproc drift surfaces as explicit adapter errors.
7
+ * @invariants Volume is explicit; rows are filtered locally from official YAML metadata, not scraped from rendered cards.
8
+ * @side-effects HTTPS egress to proceedings.mlr.press only
9
+ * @perf O(N) over one proceedings volume
10
+ * @concurrency safe
11
+ * @test tests/unit/adapters/scholar-sources.test.ts
12
+ * @stability experimental
13
+ * @since 2026-05-19
14
+ */
15
+
16
+ import yaml from "js-yaml";
17
+ import { cli, Strategy } from "../../registry.js";
18
+ import type { ScholarlyWorkRecord } from "../../types/scholarly.js";
19
+
20
+ interface PmlrEntry {
21
+ title?: unknown;
22
+ abstract?: unknown;
23
+ URL?: unknown;
24
+ PDF?: unknown;
25
+ "container-title"?: unknown;
26
+ author?: Array<{ given?: unknown; family?: unknown }>;
27
+ id?: unknown;
28
+ issued?: { "date-parts"?: unknown[] };
29
+ volume?: unknown;
30
+ }
31
+
32
+ function str(value: unknown): string {
33
+ return typeof value === "string" ? value.trim() : "";
34
+ }
35
+
36
+ function authors(value: PmlrEntry["author"]): string[] | undefined {
37
+ if (!Array.isArray(value)) return undefined;
38
+ const out = value
39
+ .map((person) =>
40
+ [person.given, person.family].map(str).filter(Boolean).join(" "),
41
+ )
42
+ .filter(Boolean);
43
+ return out.length > 0 ? out : undefined;
44
+ }
45
+
46
+ function issuedYear(entry: PmlrEntry): number | undefined {
47
+ const first = entry.issued?.["date-parts"]?.[0];
48
+ return typeof first === "number" && Number.isFinite(first)
49
+ ? first
50
+ : undefined;
51
+ }
52
+
53
+ export function parsePmlrCiteproc(text: string): PmlrEntry[] {
54
+ const parsed = yaml.load(text);
55
+ return Array.isArray(parsed) ? (parsed as PmlrEntry[]) : [];
56
+ }
57
+
58
+ export function mapPmlrEntry(
59
+ entry: PmlrEntry,
60
+ source: string,
61
+ ): ScholarlyWorkRecord {
62
+ const id = str(entry.id);
63
+ if (!id) throw new Error("PMLR entry did not include id.");
64
+ return {
65
+ id,
66
+ title: str(entry.title),
67
+ abstract: str(entry.abstract) || undefined,
68
+ authors: authors(entry.author),
69
+ year: issuedYear(entry),
70
+ venue: str(entry["container-title"]) || undefined,
71
+ type: entry.volume ? `pmlr:${String(entry.volume)}` : "pmlr",
72
+ pdf_url: str(entry.PDF) || undefined,
73
+ source_adapter: source,
74
+ source_url: str(entry.URL) || undefined,
75
+ retrieved_at: new Date().toISOString(),
76
+ };
77
+ }
78
+
79
+ function requireVolume(value: unknown): string {
80
+ const raw = String(value ?? "")
81
+ .trim()
82
+ .replace(/^v/i, "");
83
+ if (!/^\d+$/.test(raw))
84
+ throw new Error(`pmlr volume "${String(value)}" is not valid.`);
85
+ return raw;
86
+ }
87
+
88
+ async function fetchVolume(volume: string): Promise<PmlrEntry[]> {
89
+ const response = await fetch(
90
+ `https://proceedings.mlr.press/v${volume}/assets/bib/citeproc.yaml`,
91
+ {
92
+ headers: {
93
+ Accept: "application/x-yaml,text/yaml,text/plain",
94
+ "User-Agent": "unicli-pmlr/1.0 (https://github.com/olo-dot-io/Uni-CLI)",
95
+ },
96
+ },
97
+ );
98
+ if (response.status === 404)
99
+ throw new Error(`PMLR volume v${volume} returned no metadata.`);
100
+ if (!response.ok)
101
+ throw new Error(`PMLR volume v${volume} returned HTTP ${response.status}.`);
102
+ return parsePmlrCiteproc(await response.text());
103
+ }
104
+
105
+ cli({
106
+ site: "pmlr",
107
+ name: "search",
108
+ description: "Search a PMLR proceedings volume (e.g. v235 for ICML 2024)",
109
+ domain: "proceedings.mlr.press",
110
+ strategy: Strategy.PUBLIC,
111
+ args: [
112
+ { name: "query", type: "str", required: true, positional: true },
113
+ { name: "volume", type: "str", default: "235" },
114
+ { name: "limit", type: "int", default: 20 },
115
+ ],
116
+ columns: ["id", "title", "authors", "year", "venue", "pdf_url", "source_url"],
117
+ capabilities: [
118
+ "http.fetch",
119
+ "scholar.search",
120
+ "scholar.venue",
121
+ "scholar.pdf",
122
+ ],
123
+ func: async (_page, kwargs) => {
124
+ const query = String(kwargs.query ?? "")
125
+ .trim()
126
+ .toLowerCase();
127
+ if (!query) throw new Error("pmlr search query cannot be empty.");
128
+ const volume = requireVolume(kwargs.volume);
129
+ const limit = Math.min(Math.max(Number(kwargs.limit ?? 20), 1), 200);
130
+ const rows = (await fetchVolume(volume))
131
+ .map((entry) => mapPmlrEntry(entry, "pmlr"))
132
+ .filter((row) =>
133
+ `${row.title} ${row.abstract ?? ""} ${row.authors?.join(" ") ?? ""}`
134
+ .toLowerCase()
135
+ .includes(query),
136
+ )
137
+ .slice(0, limit);
138
+ if (rows.length === 0)
139
+ throw new Error(`No PMLR v${volume} papers matched "${query}".`);
140
+ return rows;
141
+ },
142
+ });
143
+
144
+ cli({
145
+ site: "pmlr",
146
+ name: "paper",
147
+ description: "Fetch a PMLR paper by id inside a proceedings volume",
148
+ domain: "proceedings.mlr.press",
149
+ strategy: Strategy.PUBLIC,
150
+ args: [
151
+ { name: "id", type: "str", required: true, positional: true },
152
+ { name: "volume", type: "str", default: "235" },
153
+ ],
154
+ columns: ["id", "title", "authors", "year", "venue", "pdf_url", "source_url"],
155
+ capabilities: ["http.fetch", "scholar.get", "scholar.pdf"],
156
+ func: async (_page, kwargs) => {
157
+ const id = String(kwargs.id ?? kwargs.ref ?? "").trim();
158
+ if (!id) throw new Error("pmlr paper id is required.");
159
+ const volume = requireVolume(kwargs.volume);
160
+ const row = (await fetchVolume(volume))
161
+ .map((entry) => mapPmlrEntry(entry, "pmlr"))
162
+ .find((entry) => entry.id === id);
163
+ if (!row)
164
+ throw new Error(`No PMLR v${volume} paper found with id "${id}".`);
165
+ return [row];
166
+ },
167
+ });
@@ -0,0 +1,59 @@
1
+ # Project PQAI — semantic prior-art retrieval.
2
+ #
3
+ # verification_status: blocked-by-key
4
+ #
5
+ # PQAI publishes a permanent free tier for non-commercial use, but rate limits
6
+ # beyond ~100 queries / day require their USD 20 / month plan. The token is a
7
+ # single string passed as a `token=` query param (the only auth scheme PQAI
8
+ # offers today). Set $PQAI_API_TOKEN.
9
+ site: pqai
10
+ name: prior-art
11
+ description: Semantic prior-art retrieval via PQAI's embedding-based ranker
12
+ domain: api.projectpq.ai
13
+ type: web-api
14
+ strategy: public
15
+
16
+ args:
17
+ abstract:
18
+ type: str
19
+ required: true
20
+ description: Candidate abstract or claim text
21
+ limit:
22
+ type: int
23
+ default: 20
24
+
25
+ pipeline:
26
+ - fetch:
27
+ url: https://api.projectpq.ai/search/102
28
+ params:
29
+ q: "${{ args.abstract }}"
30
+ n: "${{ args.limit }}"
31
+ type: patent
32
+ token: "${{ env.PQAI_API_TOKEN || '' }}"
33
+
34
+ - select: results
35
+
36
+ # PQAI ships per-result `score` (semantic embedding cosine, ∈ [0, 1]).
37
+ # Forward as relevance_score so the meta-command's RRF stage can fuse it.
38
+ - map:
39
+ publication_number: "${{ item.id }}"
40
+ title: "${{ item.title }}"
41
+ abstract: "${{ item.abstract }}"
42
+ publication_date: "${{ item.publication_date || '' }}"
43
+ filing_date: "${{ item.filing_date || '' }}"
44
+ kind_code: "${{ item.kind_code || '' }}"
45
+ relevance_score: "${{ item.score !== undefined ? item.score : '' }}"
46
+ source_adapter: pqai
47
+ source_url: "https://search.projectpq.ai/patent/${{ item.id }}"
48
+ retrieved_at: "${{ now }}"
49
+
50
+ - limit: ${{ args.limit }}
51
+
52
+ columns: [publication_number, title, abstract]
53
+
54
+ capabilities: ["http.fetch", "patent.prior-art"]
55
+ minimum_capability: http.fetch
56
+ trust: public
57
+ confidentiality: public
58
+ quarantine: false
59
+ schema_version: v2
@@ -0,0 +1,60 @@
1
+ # Project PQAI — free-text keyword search.
2
+ #
3
+ # verification_status: blocked-by-key
4
+ #
5
+ # PQAI ships a `/search/102` endpoint that accepts both natural-language and
6
+ # Boolean queries. This adapter exposes it as the standard patent.search
7
+ # capability; the prior-art-specific tuning lives in pqai/prior-art.yaml.
8
+ site: pqai
9
+ name: search
10
+ description: Keyword + semantic patent search through PQAI's hybrid index
11
+ domain: api.projectpq.ai
12
+ type: web-api
13
+ strategy: public
14
+ lint_listing_detail: skip
15
+
16
+ args:
17
+ query:
18
+ type: str
19
+ required: true
20
+ positional: true
21
+ limit:
22
+ type: int
23
+ default: 20
24
+
25
+ pipeline:
26
+ - fetch:
27
+ url: https://api.projectpq.ai/search/102
28
+ params:
29
+ q: "${{ args.query }}"
30
+ n: "${{ args.limit }}"
31
+ type: patent
32
+ token: "${{ env.PQAI_API_TOKEN || '' }}"
33
+
34
+ - select: results
35
+
36
+ # PQAI returns `score` (∈ [0, 1] semantic relevance) alongside the patent
37
+ # record. Surface it as relevance_score so the downstream RRF stage can
38
+ # consult the per-engine ranking.
39
+ - map:
40
+ publication_number: "${{ item.id }}"
41
+ title: "${{ item.title }}"
42
+ abstract: "${{ item.abstract }}"
43
+ publication_date: "${{ item.publication_date || '' }}"
44
+ filing_date: "${{ item.filing_date || '' }}"
45
+ kind_code: "${{ item.kind_code || '' }}"
46
+ relevance_score: "${{ item.score !== undefined ? item.score : '' }}"
47
+ source_adapter: pqai
48
+ source_url: "https://search.projectpq.ai/patent/${{ item.id }}"
49
+ retrieved_at: "${{ now }}"
50
+
51
+ - limit: ${{ args.limit }}
52
+
53
+ columns: [publication_number, title, publication_date]
54
+
55
+ capabilities: ["http.fetch", "patent.search"]
56
+ minimum_capability: http.fetch
57
+ trust: public
58
+ confidentiality: public
59
+ quarantine: false
60
+ schema_version: v2