@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,188 @@
1
+ /**
2
+ * @owner src::adapters::cipo::get
3
+ * @does Browser-driven CIPO single-document retrieval — Canadian Patents Database detail page extracted into a PatentRecord.
4
+ * @needs src/engine/transport/mcp-browser.ts, src/engine/normalizer/patent-envelope.ts, src/adapters/cipo/_shared.ts, src/registry.ts
5
+ * @feeds src/commands/patent.ts (capability tag patent.get)
6
+ * @breaks PATENT_INVALID_NUMBER, PATENT_NOT_FOUND, PATENT_API_DEPRECATED (MCP_BUS_MISSING)
7
+ * @invariants output row is a canonical PatentRecord
8
+ * @side-effects controls Chrome via MCP
9
+ * @perf single navigate + evaluate
10
+ * @concurrency safe
11
+ * @test tests/unit/adapters/cipo/search.test.ts (transport-error shared path)
12
+ * @stability experimental
13
+ * @since 2026-05-18
14
+ * @verification browser-only
15
+ */
16
+
17
+ import { cli, Strategy } from "../../registry.js";
18
+ import { TransportError } from "../../engine/transport/mcp-browser.js";
19
+ import { assemblePatentRecord } from "../../engine/normalizer/patent-envelope.js";
20
+ import {
21
+ cipoEnvelope,
22
+ cipoNavigateAndExtract,
23
+ transportErrorToCipoEnvelope,
24
+ } from "./_shared.js";
25
+
26
+ const ADAPTER_PATH = "src/adapters/cipo/get.ts";
27
+
28
+ interface CipoDetail {
29
+ publication_number?: string;
30
+ application_number?: string;
31
+ title?: string;
32
+ abstract?: string;
33
+ applicant?: string;
34
+ inventor?: string;
35
+ publication_date?: string;
36
+ filing_date?: string;
37
+ grant_date?: string;
38
+ source_url?: string;
39
+ }
40
+
41
+ const DETAIL_EXTRACTOR = `(() => {
42
+ const text = (sel) => {
43
+ const node = document.querySelector(sel);
44
+ return node ? (node.textContent || '').trim() : '';
45
+ };
46
+ return {
47
+ publication_number: text('.patent-number, [data-field="patentNo"]'),
48
+ application_number: text('.application-number, [data-field="appNo"]'),
49
+ title: text('.patent-title, h1.title, [data-field="title"]'),
50
+ abstract: text('.abstract, [data-field="abstract"]'),
51
+ applicant: text('.applicant-name, [data-field="applicant"]'),
52
+ inventor: text('.inventor-name, [data-field="inventor"]'),
53
+ publication_date: text('.publication-date, [data-field="pubDate"]'),
54
+ filing_date: text('.filing-date, [data-field="filingDate"]'),
55
+ grant_date: text('.grant-date, [data-field="grantDate"]'),
56
+ source_url: location.href,
57
+ };
58
+ })()`;
59
+
60
+ function detailUrlFor(pubNo: string): string {
61
+ const stripped = pubNo.replace(/^CA[-]?/, "");
62
+ return `https://cipo.ic.gc.ca/opic-cipo/cpd/eng/patent/${encodeURIComponent(stripped)}/summary.html`;
63
+ }
64
+
65
+ export async function runCipoGet(kwargs: {
66
+ publication_number: string;
67
+ }): Promise<unknown[]> {
68
+ const pubNo = String(kwargs.publication_number ?? "").trim();
69
+ if (pubNo.length === 0) {
70
+ return [
71
+ {
72
+ envelope: cipoEnvelope(
73
+ "PATENT_INVALID_NUMBER",
74
+ ADAPTER_PATH,
75
+ "validate",
76
+ "cipo get requires a non-empty publication_number",
77
+ ),
78
+ },
79
+ ];
80
+ }
81
+ const url = detailUrlFor(pubNo);
82
+ let detail: CipoDetail;
83
+ try {
84
+ const result = await cipoNavigateAndExtract<CipoDetail>(
85
+ url,
86
+ DETAIL_EXTRACTOR,
87
+ );
88
+ if (!result.data) {
89
+ return [
90
+ {
91
+ envelope: cipoEnvelope(
92
+ "PATENT_SCHEMA_DRIFT",
93
+ ADAPTER_PATH,
94
+ "evaluate",
95
+ "cipo detail evaluate returned no data",
96
+ ),
97
+ },
98
+ ];
99
+ }
100
+ detail = result.data;
101
+ } catch (err) {
102
+ if (err instanceof TransportError) {
103
+ return [
104
+ {
105
+ envelope: transportErrorToCipoEnvelope(err, ADAPTER_PATH, "navigate"),
106
+ },
107
+ ];
108
+ }
109
+ throw err;
110
+ }
111
+ if (!detail.publication_number && !detail.title) {
112
+ return [
113
+ {
114
+ envelope: cipoEnvelope(
115
+ "PATENT_NOT_FOUND",
116
+ ADAPTER_PATH,
117
+ "evaluate",
118
+ `cipo detail page for "${pubNo}" yielded no bibliographic fields`,
119
+ ["uspto", "epo"],
120
+ ),
121
+ },
122
+ ];
123
+ }
124
+ const rawPubNo = detail.publication_number || pubNo;
125
+ const canonicalPubNo = /^CA[-]?/.test(rawPubNo) ? rawPubNo : `CA${rawPubNo}`;
126
+ try {
127
+ return [
128
+ assemblePatentRecord({
129
+ publication_number: canonicalPubNo,
130
+ application_number: detail.application_number || undefined,
131
+ title: detail.title || undefined,
132
+ abstract: detail.abstract || undefined,
133
+ assignees: detail.applicant
134
+ ? [{ name: detail.applicant, country: "CA" }]
135
+ : undefined,
136
+ inventors: detail.inventor
137
+ ? [{ name: detail.inventor, country: "CA" }]
138
+ : undefined,
139
+ publication_date: detail.publication_date || undefined,
140
+ filing_date: detail.filing_date || undefined,
141
+ grant_date: detail.grant_date || undefined,
142
+ source_adapter: "cipo",
143
+ source_url: detail.source_url || url,
144
+ } as Parameters<typeof assemblePatentRecord>[0]),
145
+ ];
146
+ } catch {
147
+ return [
148
+ {
149
+ envelope: cipoEnvelope(
150
+ "PATENT_NOT_FOUND",
151
+ ADAPTER_PATH,
152
+ "normalize",
153
+ `cipo detail page for "${pubNo}" did not yield a valid publication_number`,
154
+ ["uspto"],
155
+ ),
156
+ },
157
+ ];
158
+ }
159
+ }
160
+
161
+ cli({
162
+ site: "cipo",
163
+ name: "get",
164
+ description: "Retrieve a single Canadian patent document (CIPO, browser)",
165
+ domain: "cipo.ic.gc.ca",
166
+ strategy: Strategy.PUBLIC,
167
+ adapter_path: ADAPTER_PATH,
168
+ args: [
169
+ {
170
+ name: "publication_number",
171
+ type: "str",
172
+ required: true,
173
+ positional: true,
174
+ description: "CA publication number (with or without CA prefix)",
175
+ },
176
+ ],
177
+ columns: [
178
+ "publication_number",
179
+ "title",
180
+ "publication_date",
181
+ "grant_date",
182
+ "source_url",
183
+ ],
184
+ capabilities: ["mcp-browser.navigate", "mcp-browser.evaluate", "patent.get"],
185
+ minimum_capability: "mcp-browser.evaluate",
186
+ func: async (_page, kwargs) =>
187
+ runCipoGet(kwargs as { publication_number: string }),
188
+ });
@@ -0,0 +1,148 @@
1
+ /**
2
+ * @owner src::adapters::cipo::legal-status
3
+ * @does Browser-driven CIPO legal-status / prosecution timeline lookup; emits the most recent administrative-status field from the CPD admin tab.
4
+ * @needs src/engine/transport/mcp-browser.ts, src/adapters/cipo/_shared.ts, src/registry.ts
5
+ * @feeds src/commands/patent.ts (capability tag patent.legal-status)
6
+ * @breaks PATENT_INVALID_NUMBER, PATENT_NOT_FOUND, PATENT_API_DEPRECATED (MCP_BUS_MISSING)
7
+ * @invariants output row carries legal_status verbatim as CIPO displayed it
8
+ * @side-effects controls Chrome via MCP
9
+ * @perf single navigate + evaluate
10
+ * @concurrency safe
11
+ * @test tests/unit/adapters/cipo/search.test.ts (shared transport-error path)
12
+ * @stability experimental
13
+ * @since 2026-05-18
14
+ * @verification browser-only
15
+ */
16
+
17
+ import { cli, Strategy } from "../../registry.js";
18
+ import { TransportError } from "../../engine/transport/mcp-browser.js";
19
+ import {
20
+ cipoEnvelope,
21
+ cipoNavigateAndExtract,
22
+ transportErrorToCipoEnvelope,
23
+ } from "./_shared.js";
24
+
25
+ const ADAPTER_PATH = "src/adapters/cipo/legal-status.ts";
26
+
27
+ interface CipoLegalExtract {
28
+ publication_number?: string;
29
+ legal_status?: string;
30
+ status_date?: string;
31
+ source_url?: string;
32
+ }
33
+
34
+ const EXTRACTOR = `(() => {
35
+ const text = (sel) => {
36
+ const node = document.querySelector(sel);
37
+ return node ? (node.textContent || '').trim() : '';
38
+ };
39
+ return {
40
+ publication_number: text('.patent-number, [data-field="patentNo"]'),
41
+ legal_status: text('.admin-status, [data-field="adminStatus"]'),
42
+ status_date: text('.status-date, [data-field="statusDate"]'),
43
+ source_url: location.href,
44
+ };
45
+ })()`;
46
+
47
+ function legalUrlFor(pubNo: string): string {
48
+ const stripped = pubNo.replace(/^CA[-]?/, "");
49
+ return `https://cipo.ic.gc.ca/opic-cipo/cpd/eng/patent/${encodeURIComponent(stripped)}/admin.html`;
50
+ }
51
+
52
+ export async function runCipoLegalStatus(kwargs: {
53
+ publication_number: string;
54
+ }): Promise<unknown[]> {
55
+ const pubNo = String(kwargs.publication_number ?? "").trim();
56
+ if (pubNo.length === 0) {
57
+ return [
58
+ {
59
+ envelope: cipoEnvelope(
60
+ "PATENT_INVALID_NUMBER",
61
+ ADAPTER_PATH,
62
+ "validate",
63
+ "cipo legal-status requires a non-empty publication_number",
64
+ ),
65
+ },
66
+ ];
67
+ }
68
+ const url = legalUrlFor(pubNo);
69
+ let detail: CipoLegalExtract;
70
+ try {
71
+ const result = await cipoNavigateAndExtract<CipoLegalExtract>(
72
+ url,
73
+ EXTRACTOR,
74
+ );
75
+ if (!result.data) {
76
+ return [
77
+ {
78
+ envelope: cipoEnvelope(
79
+ "PATENT_SCHEMA_DRIFT",
80
+ ADAPTER_PATH,
81
+ "evaluate",
82
+ "cipo legal-status evaluate returned no data",
83
+ ),
84
+ },
85
+ ];
86
+ }
87
+ detail = result.data;
88
+ } catch (err) {
89
+ if (err instanceof TransportError) {
90
+ return [
91
+ {
92
+ envelope: transportErrorToCipoEnvelope(err, ADAPTER_PATH, "navigate"),
93
+ },
94
+ ];
95
+ }
96
+ throw err;
97
+ }
98
+ if (!detail.legal_status) {
99
+ return [
100
+ {
101
+ envelope: cipoEnvelope(
102
+ "PATENT_NOT_FOUND",
103
+ ADAPTER_PATH,
104
+ "evaluate",
105
+ `cipo returned no admin/legal-status for "${pubNo}"`,
106
+ ["uspto", "epo"],
107
+ ),
108
+ },
109
+ ];
110
+ }
111
+ return [
112
+ {
113
+ publication_number: detail.publication_number || pubNo,
114
+ legal_status: detail.legal_status,
115
+ status_date: detail.status_date,
116
+ source_adapter: "cipo",
117
+ source_url: detail.source_url || url,
118
+ retrieved_at: new Date().toISOString(),
119
+ },
120
+ ];
121
+ }
122
+
123
+ cli({
124
+ site: "cipo",
125
+ name: "legal-status",
126
+ description: "CIPO Canadian patent administrative-status lookup (browser)",
127
+ domain: "cipo.ic.gc.ca",
128
+ strategy: Strategy.PUBLIC,
129
+ adapter_path: ADAPTER_PATH,
130
+ args: [
131
+ {
132
+ name: "publication_number",
133
+ type: "str",
134
+ required: true,
135
+ positional: true,
136
+ description: "CA publication number",
137
+ },
138
+ ],
139
+ columns: ["publication_number", "legal_status", "status_date", "source_url"],
140
+ capabilities: [
141
+ "mcp-browser.navigate",
142
+ "mcp-browser.evaluate",
143
+ "patent.legal-status",
144
+ ],
145
+ minimum_capability: "mcp-browser.evaluate",
146
+ func: async (_page, kwargs) =>
147
+ runCipoLegalStatus(kwargs as { publication_number: string }),
148
+ });
@@ -0,0 +1,195 @@
1
+ /**
2
+ * @owner src::adapters::cipo::search
3
+ * @does Browser-driven search of the Canadian Patents Database at cipo.ic.gc.ca/opic-cipo/cpd/eng/ — CIPO exposes no general open API for the patents corpus, so the browser route is the only programmatic surface.
4
+ * @needs src/engine/transport/mcp-browser.ts, src/engine/normalizer/patent-envelope.ts, src/adapters/cipo/_shared.ts, src/registry.ts
5
+ * @feeds src/commands/patent.ts (capability tag patent.search)
6
+ * @breaks PATENT_UNSUPPORTED_QUERY (empty), PATENT_NOT_FOUND (empty result), PATENT_API_DEPRECATED with MCP_BUS_MISSING (no outbound MCP transport)
7
+ * @invariants rows are canonical PatentRecord; source_adapter='cipo'
8
+ * @side-effects controls Chrome via MCP
9
+ * @perf single navigate + evaluate
10
+ * @concurrency safe
11
+ * @test tests/unit/adapters/cipo/search.test.ts
12
+ * @stability experimental
13
+ * @since 2026-05-18
14
+ * @verification browser-only
15
+ */
16
+
17
+ import { cli, Strategy } from "../../registry.js";
18
+ import { TransportError } from "../../engine/transport/mcp-browser.js";
19
+ import { assemblePatentRecord } from "../../engine/normalizer/patent-envelope.js";
20
+ import {
21
+ cipoEnvelope,
22
+ cipoNavigateAndExtract,
23
+ transportErrorToCipoEnvelope,
24
+ } from "./_shared.js";
25
+
26
+ const ADAPTER_PATH = "src/adapters/cipo/search.ts";
27
+ const CIPO_SEARCH_URL =
28
+ "https://cipo.ic.gc.ca/opic-cipo/cpd/eng/search/basic.html";
29
+
30
+ interface CipoRow {
31
+ publication_number: string;
32
+ title?: string;
33
+ applicant?: string;
34
+ publication_date?: string;
35
+ source_url?: string;
36
+ }
37
+
38
+ const EXTRACTOR = `(() => {
39
+ const rows = Array.from(
40
+ document.querySelectorAll('table.results tr.result-row, .search-results .result')
41
+ ).map((el) => {
42
+ const text = (sel) => {
43
+ const node = el.querySelector(sel);
44
+ return node ? (node.textContent || '').trim() : '';
45
+ };
46
+ const linkEl = el.querySelector('a[href*="patent/"], a[href]');
47
+ return {
48
+ publication_number: text('.patent-number, td.patent-no, [data-field="patentNo"]'),
49
+ title: text('.patent-title, td.title, [data-field="title"]'),
50
+ applicant: text('.applicant-name, td.applicant, [data-field="applicant"]'),
51
+ publication_date: text('.publication-date, td.pubDate, [data-field="pubDate"]'),
52
+ source_url: linkEl ? linkEl.href : '',
53
+ };
54
+ });
55
+ return { rows };
56
+ })()`;
57
+
58
+ function buildSearchUrl(query: string): string {
59
+ const params = new URLSearchParams({ search: query });
60
+ return `${CIPO_SEARCH_URL}?${params.toString()}`;
61
+ }
62
+
63
+ export async function runCipoSearch(kwargs: {
64
+ query: string;
65
+ limit?: number;
66
+ }): Promise<unknown[]> {
67
+ const limit =
68
+ typeof kwargs.limit === "number" && Number.isFinite(kwargs.limit)
69
+ ? Math.max(1, Math.min(100, Math.floor(kwargs.limit)))
70
+ : 25;
71
+ const query = String(kwargs.query ?? "").trim();
72
+ if (query.length === 0) {
73
+ return [
74
+ {
75
+ envelope: cipoEnvelope(
76
+ "PATENT_UNSUPPORTED_QUERY",
77
+ ADAPTER_PATH,
78
+ "validate",
79
+ "cipo search requires a non-empty query",
80
+ ),
81
+ },
82
+ ];
83
+ }
84
+ const url = buildSearchUrl(query);
85
+ let extract: { rows: CipoRow[] };
86
+ try {
87
+ const result = await cipoNavigateAndExtract<{ rows: CipoRow[] }>(
88
+ url,
89
+ EXTRACTOR,
90
+ );
91
+ if (!result.data) {
92
+ return [
93
+ {
94
+ envelope: cipoEnvelope(
95
+ "PATENT_SCHEMA_DRIFT",
96
+ ADAPTER_PATH,
97
+ "evaluate",
98
+ "cipo evaluate returned no data; selector schema likely changed",
99
+ ),
100
+ },
101
+ ];
102
+ }
103
+ extract = result.data;
104
+ } catch (err) {
105
+ if (err instanceof TransportError) {
106
+ return [
107
+ {
108
+ envelope: transportErrorToCipoEnvelope(err, ADAPTER_PATH, "navigate"),
109
+ },
110
+ ];
111
+ }
112
+ throw err;
113
+ }
114
+ if (extract.rows.length === 0) {
115
+ return [
116
+ {
117
+ envelope: cipoEnvelope(
118
+ "PATENT_NOT_FOUND",
119
+ ADAPTER_PATH,
120
+ "evaluate",
121
+ `cipo returned no rows for query "${query}"`,
122
+ ["uspto", "epo"],
123
+ ),
124
+ },
125
+ ];
126
+ }
127
+ const out: unknown[] = [];
128
+ for (const row of extract.rows.slice(0, limit)) {
129
+ if (!row.publication_number) continue;
130
+ const normalizedPub = /^CA[-]?/.test(row.publication_number)
131
+ ? row.publication_number
132
+ : `CA${row.publication_number}`;
133
+ try {
134
+ out.push(
135
+ assemblePatentRecord({
136
+ publication_number: normalizedPub,
137
+ title: row.title || undefined,
138
+ assignees: row.applicant
139
+ ? [{ name: row.applicant, country: "CA" }]
140
+ : undefined,
141
+ publication_date: row.publication_date || undefined,
142
+ source_adapter: "cipo",
143
+ source_url: row.source_url || url,
144
+ } as Parameters<typeof assemblePatentRecord>[0]),
145
+ );
146
+ } catch {
147
+ // Skip malformed rows.
148
+ }
149
+ }
150
+ if (out.length === 0) {
151
+ out.push({
152
+ envelope: cipoEnvelope(
153
+ "PATENT_NOT_FOUND",
154
+ ADAPTER_PATH,
155
+ "normalize",
156
+ "cipo returned rows but none carried a valid publication_number",
157
+ ["uspto"],
158
+ ),
159
+ });
160
+ }
161
+ return out;
162
+ }
163
+
164
+ cli({
165
+ site: "cipo",
166
+ name: "search",
167
+ description: "Search the Canadian Patents Database (CIPO, browser, no API)",
168
+ domain: "cipo.ic.gc.ca",
169
+ strategy: Strategy.PUBLIC,
170
+ adapter_path: ADAPTER_PATH,
171
+ args: [
172
+ {
173
+ name: "query",
174
+ type: "str",
175
+ required: true,
176
+ positional: true,
177
+ description: "Free-text query — matched on title/abstract/applicant",
178
+ },
179
+ {
180
+ name: "limit",
181
+ type: "int",
182
+ default: 25,
183
+ description: "Max results (1-100)",
184
+ },
185
+ ],
186
+ columns: ["publication_number", "title", "publication_date", "source_url"],
187
+ capabilities: [
188
+ "mcp-browser.navigate",
189
+ "mcp-browser.evaluate",
190
+ "patent.search",
191
+ ],
192
+ minimum_capability: "mcp-browser.evaluate",
193
+ func: async (_page, kwargs) =>
194
+ runCipoSearch(kwargs as { query: string; limit?: number }),
195
+ });
@@ -0,0 +1,138 @@
1
+ /**
2
+ * @owner src::adapters::cnipa::_shared
3
+ * @does Shared helpers for CNIPA browser-driven adapter commands — emits structured PATENT_BROWSER_CAPTCHA / MCP_BUS_MISSING / PATENT_NOT_FOUND error rows so adapters never synthesize results from a failed page.
4
+ * @needs src/engine/transport/mcp-browser.ts, src/engine/normalizer/patent-envelope.ts, src/types/patent.ts
5
+ * @feeds src/adapters/cnipa/search.ts, src/adapters/cnipa/get.ts, src/adapters/cnipa/legal-status.ts
6
+ * @breaks none — pure helpers; bubble TransportError out to the registry func contract
7
+ * @invariants every error path maps to a PatentEnvelope with adapter_path stamped; no silent fallbacks
8
+ * @side-effects none
9
+ * @perf n/a
10
+ * @concurrency safe
11
+ * @test covered transitively by src/adapters/cnipa/*.test.ts
12
+ * @stability experimental
13
+ * @since 2026-05-18
14
+ * @verification browser-only
15
+ */
16
+
17
+ import {
18
+ TransportError,
19
+ initMcpBrowserTransport,
20
+ mcpBrowserEvaluate,
21
+ mcpBrowserNavigate,
22
+ type McpBrowserResult,
23
+ } from "../../engine/transport/mcp-browser.js";
24
+ import { buildPatentEnvelope } from "../../engine/normalizer/patent-envelope.js";
25
+ import type { PatentEnvelope, PatentErrorCode } from "../../types/patent.js";
26
+
27
+ export interface CnipaErrorRow {
28
+ publication_number: string;
29
+ title: string;
30
+ envelope: PatentEnvelope;
31
+ }
32
+
33
+ export function cnipaEnvelope(
34
+ code: PatentErrorCode,
35
+ adapter_path: string,
36
+ step: string,
37
+ suggestion: string,
38
+ alternatives: string[] = [],
39
+ ): PatentEnvelope {
40
+ return buildPatentEnvelope({
41
+ code,
42
+ adapter_path,
43
+ step,
44
+ suggestion,
45
+ alternatives,
46
+ retryable: code === "PATENT_BROWSER_CAPTCHA" ? true : false,
47
+ });
48
+ }
49
+
50
+ /**
51
+ * Wrap a TransportError from mcp-browser into a PatentEnvelope row.
52
+ * MCP_BUS_MISSING is the production state today — surfaced honestly so the
53
+ * agent's repair loop knows the engine is missing the outbound MCP transport.
54
+ */
55
+ export function transportErrorToEnvelope(
56
+ err: TransportError,
57
+ adapter_path: string,
58
+ step: string,
59
+ ): PatentEnvelope {
60
+ if (err.code === "MCP_BUS_MISSING") {
61
+ return buildPatentEnvelope({
62
+ code: "PATENT_API_DEPRECATED",
63
+ adapter_path,
64
+ step,
65
+ suggestion:
66
+ "engine has no outbound MCP transport wired into the bus today; install an McpResolver via src/engine/transport/mcp-browser.installMcpResolver() before invoking this adapter, or try a non-browser source first",
67
+ alternatives: ["uspto", "epo", "lens"],
68
+ retryable: false,
69
+ });
70
+ }
71
+ return buildPatentEnvelope({
72
+ code: "PATENT_API_DEPRECATED",
73
+ adapter_path,
74
+ step,
75
+ suggestion: `mcp-browser transport error (${err.code}): ${err.message}`,
76
+ alternatives: ["uspto", "epo"],
77
+ retryable: false,
78
+ });
79
+ }
80
+
81
+ /**
82
+ * Navigate then evaluate a DOM-extraction expression. Returns the evaluate
83
+ * result on the happy path, or throws a TransportError with a structured
84
+ * code so callers map to a PatentEnvelope row.
85
+ *
86
+ * Adapters MUST treat the result as untrusted and validate shape before
87
+ * normalization — captcha pages tend to return zero-length arrays without
88
+ * throwing.
89
+ */
90
+ export async function navigateAndExtract<T>(
91
+ url: string,
92
+ expression: string,
93
+ ): Promise<McpBrowserResult<T>> {
94
+ const init = await initMcpBrowserTransport();
95
+ if (init.active_server === "none") {
96
+ const code =
97
+ init.reason === "bus-missing" ? "MCP_BUS_MISSING" : "MCP_NO_SERVER";
98
+ throw new TransportError(code, `mcp-browser unavailable (${init.reason})`);
99
+ }
100
+ const navResult = await mcpBrowserNavigate({ url });
101
+ if (!navResult.ok) {
102
+ throw new TransportError(
103
+ navResult.code ?? "MCP_NAVIGATE_FAILED",
104
+ navResult.message ?? "navigate did not succeed",
105
+ );
106
+ }
107
+ const evalResult = await mcpBrowserEvaluate<T>({
108
+ expression,
109
+ tab: navResult.tab,
110
+ });
111
+ if (!evalResult.ok) {
112
+ throw new TransportError(
113
+ evalResult.code ?? "MCP_EVALUATE_FAILED",
114
+ evalResult.message ?? "evaluate did not succeed",
115
+ );
116
+ }
117
+ return evalResult;
118
+ }
119
+
120
+ /**
121
+ * Heuristic — CNIPA public-search captcha is a 验证码 iframe. When the
122
+ * evaluator returns a zero-length result array, the safest assumption is
123
+ * captcha; emit a structured envelope rather than a "no results" message
124
+ * the agent cannot disambiguate.
125
+ */
126
+ export function looksLikeCaptcha(
127
+ rowCount: number,
128
+ htmlMarker?: string,
129
+ ): boolean {
130
+ if (rowCount > 0) return false;
131
+ if (!htmlMarker) return true; // empty result on a browser path = assume captcha
132
+ const lowered = htmlMarker.toLowerCase();
133
+ return (
134
+ lowered.includes("captcha") ||
135
+ lowered.includes("验证码") ||
136
+ lowered.includes("verifycode")
137
+ );
138
+ }