@zenalexa/unicli 0.220.1 → 0.221.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (471) hide show
  1. package/AGENTS.md +28 -6
  2. package/README.md +8 -8
  3. package/README.zh-CN.md +8 -8
  4. package/dist/adapters/bilibili/comments.js +66 -4
  5. package/dist/adapters/bilibili/comments.js.map +1 -1
  6. package/dist/adapters/bilibili/compat.js +2 -2
  7. package/dist/adapters/bilibili/compat.js.map +1 -1
  8. package/dist/adapters/bilibili/download.js +4 -4
  9. package/dist/adapters/bilibili/download.js.map +1 -1
  10. package/dist/adapters/bilibili/wbi.d.ts.map +1 -1
  11. package/dist/adapters/bilibili/wbi.js +3 -3
  12. package/dist/adapters/bilibili/wbi.js.map +1 -1
  13. package/dist/adapters/cipo/_shared.d.ts +21 -0
  14. package/dist/adapters/cipo/_shared.d.ts.map +1 -0
  15. package/dist/adapters/cipo/_shared.js +67 -0
  16. package/dist/adapters/cipo/_shared.js.map +1 -0
  17. package/dist/adapters/cipo/get.d.ts +19 -0
  18. package/dist/adapters/cipo/get.d.ts.map +1 -0
  19. package/dist/adapters/cipo/get.js +140 -0
  20. package/dist/adapters/cipo/get.js.map +1 -0
  21. package/dist/adapters/cipo/legal-status.d.ts +19 -0
  22. package/dist/adapters/cipo/legal-status.d.ts.map +1 -0
  23. package/dist/adapters/cipo/legal-status.js +111 -0
  24. package/dist/adapters/cipo/legal-status.js.map +1 -0
  25. package/dist/adapters/cipo/search.d.ts +20 -0
  26. package/dist/adapters/cipo/search.d.ts.map +1 -0
  27. package/dist/adapters/cipo/search.js +148 -0
  28. package/dist/adapters/cipo/search.js.map +1 -0
  29. package/dist/adapters/cnipa/_shared.d.ts +47 -0
  30. package/dist/adapters/cnipa/_shared.d.ts.map +1 -0
  31. package/dist/adapters/cnipa/_shared.js +97 -0
  32. package/dist/adapters/cnipa/_shared.js.map +1 -0
  33. package/dist/adapters/cnipa/get.d.ts +19 -0
  34. package/dist/adapters/cnipa/get.d.ts.map +1 -0
  35. package/dist/adapters/cnipa/get.js +149 -0
  36. package/dist/adapters/cnipa/get.js.map +1 -0
  37. package/dist/adapters/cnipa/legal-status.d.ts +19 -0
  38. package/dist/adapters/cnipa/legal-status.d.ts.map +1 -0
  39. package/dist/adapters/cnipa/legal-status.js +119 -0
  40. package/dist/adapters/cnipa/legal-status.js.map +1 -0
  41. package/dist/adapters/cnipa/search.d.ts +21 -0
  42. package/dist/adapters/cnipa/search.d.ts.map +1 -0
  43. package/dist/adapters/cnipa/search.js +170 -0
  44. package/dist/adapters/cnipa/search.js.map +1 -0
  45. package/dist/adapters/espacenet/_shared.d.ts +21 -0
  46. package/dist/adapters/espacenet/_shared.d.ts.map +1 -0
  47. package/dist/adapters/espacenet/_shared.js +67 -0
  48. package/dist/adapters/espacenet/_shared.js.map +1 -0
  49. package/dist/adapters/espacenet/family.d.ts +19 -0
  50. package/dist/adapters/espacenet/family.d.ts.map +1 -0
  51. package/dist/adapters/espacenet/family.js +118 -0
  52. package/dist/adapters/espacenet/family.js.map +1 -0
  53. package/dist/adapters/espacenet/get.d.ts +19 -0
  54. package/dist/adapters/espacenet/get.d.ts.map +1 -0
  55. package/dist/adapters/espacenet/get.js +130 -0
  56. package/dist/adapters/espacenet/get.js.map +1 -0
  57. package/dist/adapters/espacenet/legal-status.d.ts +19 -0
  58. package/dist/adapters/espacenet/legal-status.d.ts.map +1 -0
  59. package/dist/adapters/espacenet/legal-status.js +110 -0
  60. package/dist/adapters/espacenet/legal-status.js.map +1 -0
  61. package/dist/adapters/espacenet/search.d.ts +20 -0
  62. package/dist/adapters/espacenet/search.d.ts.map +1 -0
  63. package/dist/adapters/espacenet/search.js +165 -0
  64. package/dist/adapters/espacenet/search.js.map +1 -0
  65. package/dist/adapters/facebook/subtitles.d.ts +9 -0
  66. package/dist/adapters/facebook/subtitles.d.ts.map +1 -0
  67. package/dist/adapters/facebook/subtitles.js +42 -0
  68. package/dist/adapters/facebook/subtitles.js.map +1 -0
  69. package/dist/adapters/fips/_shared.d.ts +21 -0
  70. package/dist/adapters/fips/_shared.d.ts.map +1 -0
  71. package/dist/adapters/fips/_shared.js +77 -0
  72. package/dist/adapters/fips/_shared.js.map +1 -0
  73. package/dist/adapters/fips/get.d.ts +19 -0
  74. package/dist/adapters/fips/get.d.ts.map +1 -0
  75. package/dist/adapters/fips/get.js +139 -0
  76. package/dist/adapters/fips/get.js.map +1 -0
  77. package/dist/adapters/fips/search.d.ts +20 -0
  78. package/dist/adapters/fips/search.d.ts.map +1 -0
  79. package/dist/adapters/fips/search.js +148 -0
  80. package/dist/adapters/fips/search.js.map +1 -0
  81. package/dist/adapters/freepatentsonline-web/_shared.d.ts +72 -0
  82. package/dist/adapters/freepatentsonline-web/_shared.d.ts.map +1 -0
  83. package/dist/adapters/freepatentsonline-web/_shared.js +216 -0
  84. package/dist/adapters/freepatentsonline-web/_shared.js.map +1 -0
  85. package/dist/adapters/freepatentsonline-web/get.d.ts +21 -0
  86. package/dist/adapters/freepatentsonline-web/get.d.ts.map +1 -0
  87. package/dist/adapters/freepatentsonline-web/get.js +127 -0
  88. package/dist/adapters/freepatentsonline-web/get.js.map +1 -0
  89. package/dist/adapters/freepatentsonline-web/search.d.ts +22 -0
  90. package/dist/adapters/freepatentsonline-web/search.d.ts.map +1 -0
  91. package/dist/adapters/freepatentsonline-web/search.js +149 -0
  92. package/dist/adapters/freepatentsonline-web/search.js.map +1 -0
  93. package/dist/adapters/google-patents-web/_shared.d.ts +110 -0
  94. package/dist/adapters/google-patents-web/_shared.d.ts.map +1 -0
  95. package/dist/adapters/google-patents-web/_shared.js +164 -0
  96. package/dist/adapters/google-patents-web/_shared.js.map +1 -0
  97. package/dist/adapters/google-patents-web/get.d.ts +36 -0
  98. package/dist/adapters/google-patents-web/get.d.ts.map +1 -0
  99. package/dist/adapters/google-patents-web/get.js +187 -0
  100. package/dist/adapters/google-patents-web/get.js.map +1 -0
  101. package/dist/adapters/google-patents-web/search.d.ts +23 -0
  102. package/dist/adapters/google-patents-web/search.d.ts.map +1 -0
  103. package/dist/adapters/google-patents-web/search.js +169 -0
  104. package/dist/adapters/google-patents-web/search.js.map +1 -0
  105. package/dist/adapters/inpi-br/_shared.d.ts +21 -0
  106. package/dist/adapters/inpi-br/_shared.d.ts.map +1 -0
  107. package/dist/adapters/inpi-br/_shared.js +67 -0
  108. package/dist/adapters/inpi-br/_shared.js.map +1 -0
  109. package/dist/adapters/inpi-br/get.d.ts +19 -0
  110. package/dist/adapters/inpi-br/get.d.ts.map +1 -0
  111. package/dist/adapters/inpi-br/get.js +142 -0
  112. package/dist/adapters/inpi-br/get.js.map +1 -0
  113. package/dist/adapters/inpi-br/search.d.ts +20 -0
  114. package/dist/adapters/inpi-br/search.d.ts.map +1 -0
  115. package/dist/adapters/inpi-br/search.js +154 -0
  116. package/dist/adapters/inpi-br/search.js.map +1 -0
  117. package/dist/adapters/instagram/subtitles.d.ts +9 -0
  118. package/dist/adapters/instagram/subtitles.d.ts.map +1 -0
  119. package/dist/adapters/instagram/subtitles.js +42 -0
  120. package/dist/adapters/instagram/subtitles.js.map +1 -0
  121. package/dist/adapters/mastodon/statuses.d.ts +40 -0
  122. package/dist/adapters/mastodon/statuses.d.ts.map +1 -0
  123. package/dist/adapters/mastodon/statuses.js +153 -0
  124. package/dist/adapters/mastodon/statuses.js.map +1 -0
  125. package/dist/adapters/reddit/comments.d.ts +9 -0
  126. package/dist/adapters/reddit/comments.d.ts.map +1 -0
  127. package/dist/adapters/reddit/comments.js +124 -0
  128. package/dist/adapters/reddit/comments.js.map +1 -0
  129. package/dist/adapters/threads/post.d.ts +32 -0
  130. package/dist/adapters/threads/post.d.ts.map +1 -0
  131. package/dist/adapters/threads/post.js +287 -0
  132. package/dist/adapters/threads/post.js.map +1 -0
  133. package/dist/adapters/tiktok/subtitles.d.ts +9 -0
  134. package/dist/adapters/tiktok/subtitles.d.ts.map +1 -0
  135. package/dist/adapters/tiktok/subtitles.js +42 -0
  136. package/dist/adapters/tiktok/subtitles.js.map +1 -0
  137. package/dist/adapters/twitter/accept.js +2 -2
  138. package/dist/adapters/twitter/accept.js.map +1 -1
  139. package/dist/adapters/twitter/browser-fallback.d.ts +26 -0
  140. package/dist/adapters/twitter/browser-fallback.d.ts.map +1 -0
  141. package/dist/adapters/twitter/browser-fallback.js +93 -0
  142. package/dist/adapters/twitter/browser-fallback.js.map +1 -0
  143. package/dist/adapters/twitter/browser-state.d.ts +11 -0
  144. package/dist/adapters/twitter/browser-state.d.ts.map +1 -0
  145. package/dist/adapters/twitter/browser-state.js +46 -0
  146. package/dist/adapters/twitter/browser-state.js.map +1 -0
  147. package/dist/adapters/twitter/client.d.ts.map +1 -1
  148. package/dist/adapters/twitter/client.js +36 -13
  149. package/dist/adapters/twitter/client.js.map +1 -1
  150. package/dist/adapters/twitter/reply-dm.js +2 -2
  151. package/dist/adapters/twitter/reply-dm.js.map +1 -1
  152. package/dist/adapters/twitter/reply.js +1 -0
  153. package/dist/adapters/twitter/reply.js.map +1 -1
  154. package/dist/adapters/twitter/search.js +11 -18
  155. package/dist/adapters/twitter/search.js.map +1 -1
  156. package/dist/adapters/twitter/thread.d.ts +14 -0
  157. package/dist/adapters/twitter/thread.d.ts.map +1 -1
  158. package/dist/adapters/twitter/thread.js +28 -2
  159. package/dist/adapters/twitter/thread.js.map +1 -1
  160. package/dist/adapters/twitter/trending.js +13 -59
  161. package/dist/adapters/twitter/trending.js.map +1 -1
  162. package/dist/adapters/xiaohongshu/browser-state.d.ts +19 -0
  163. package/dist/adapters/xiaohongshu/browser-state.d.ts.map +1 -0
  164. package/dist/adapters/xiaohongshu/browser-state.js +67 -0
  165. package/dist/adapters/xiaohongshu/browser-state.js.map +1 -0
  166. package/dist/adapters/xiaohongshu/comments.js +28 -5
  167. package/dist/adapters/xiaohongshu/comments.js.map +1 -1
  168. package/dist/adapters/xiaohongshu/download.js +49 -11
  169. package/dist/adapters/xiaohongshu/download.js.map +1 -1
  170. package/dist/adapters/xiaohongshu/search.d.ts.map +1 -1
  171. package/dist/adapters/xiaohongshu/search.js +11 -5
  172. package/dist/adapters/xiaohongshu/search.js.map +1 -1
  173. package/dist/adapters/xiaohongshu/trending.d.ts +9 -0
  174. package/dist/adapters/xiaohongshu/trending.d.ts.map +1 -0
  175. package/dist/adapters/xiaohongshu/trending.js +94 -0
  176. package/dist/adapters/xiaohongshu/trending.js.map +1 -0
  177. package/dist/adapters/youtube/comments.d.ts +80 -0
  178. package/dist/adapters/youtube/comments.d.ts.map +1 -1
  179. package/dist/adapters/youtube/comments.js +108 -12
  180. package/dist/adapters/youtube/comments.js.map +1 -1
  181. package/dist/adapters/youtube/subtitles.d.ts +9 -0
  182. package/dist/adapters/youtube/subtitles.d.ts.map +1 -0
  183. package/dist/adapters/youtube/subtitles.js +42 -0
  184. package/dist/adapters/youtube/subtitles.js.map +1 -0
  185. package/dist/adapters/yt-dlp/subtitles.d.ts +9 -0
  186. package/dist/adapters/yt-dlp/subtitles.d.ts.map +1 -0
  187. package/dist/adapters/yt-dlp/subtitles.js +41 -0
  188. package/dist/adapters/yt-dlp/subtitles.js.map +1 -0
  189. package/dist/adapters/zhihu/answer-detail.d.ts +39 -0
  190. package/dist/adapters/zhihu/answer-detail.d.ts.map +1 -0
  191. package/dist/adapters/zhihu/answer-detail.js +204 -0
  192. package/dist/adapters/zhihu/answer-detail.js.map +1 -0
  193. package/dist/adapters/zhihu/comment.d.ts +9 -0
  194. package/dist/adapters/zhihu/comment.d.ts.map +1 -0
  195. package/dist/adapters/zhihu/comment.js +149 -0
  196. package/dist/adapters/zhihu/comment.js.map +1 -0
  197. package/dist/adapters/zhihu/recommend.d.ts +36 -0
  198. package/dist/adapters/zhihu/recommend.d.ts.map +1 -0
  199. package/dist/adapters/zhihu/recommend.js +151 -0
  200. package/dist/adapters/zhihu/recommend.js.map +1 -0
  201. package/dist/browser/bridge.d.ts.map +1 -1
  202. package/dist/browser/bridge.js +14 -3
  203. package/dist/browser/bridge.js.map +1 -1
  204. package/dist/browser/daemon-client.d.ts +6 -0
  205. package/dist/browser/daemon-client.d.ts.map +1 -1
  206. package/dist/browser/daemon-client.js +75 -15
  207. package/dist/browser/daemon-client.js.map +1 -1
  208. package/dist/browser/daemon.js +39 -15
  209. package/dist/browser/daemon.js.map +1 -1
  210. package/dist/browser/protocol.d.ts +1 -0
  211. package/dist/browser/protocol.d.ts.map +1 -1
  212. package/dist/browser/protocol.js +1 -0
  213. package/dist/browser/protocol.js.map +1 -1
  214. package/dist/cli.d.ts.map +1 -1
  215. package/dist/cli.js +6 -0
  216. package/dist/cli.js.map +1 -1
  217. package/dist/commands/approvals.d.ts.map +1 -1
  218. package/dist/commands/approvals.js +1 -37
  219. package/dist/commands/approvals.js.map +1 -1
  220. package/dist/commands/browser/index.d.ts.map +1 -1
  221. package/dist/commands/browser/index.js +7 -2
  222. package/dist/commands/browser/index.js.map +1 -1
  223. package/dist/commands/daemon.d.ts.map +1 -1
  224. package/dist/commands/daemon.js +7 -3
  225. package/dist/commands/daemon.js.map +1 -1
  226. package/dist/commands/dispatch.d.ts.map +1 -1
  227. package/dist/commands/dispatch.js +27 -3
  228. package/dist/commands/dispatch.js.map +1 -1
  229. package/dist/commands/patent-doctor.d.ts +48 -0
  230. package/dist/commands/patent-doctor.d.ts.map +1 -0
  231. package/dist/commands/patent-doctor.js +109 -0
  232. package/dist/commands/patent-doctor.js.map +1 -0
  233. package/dist/commands/patent.d.ts +78 -0
  234. package/dist/commands/patent.d.ts.map +1 -0
  235. package/dist/commands/patent.js +919 -0
  236. package/dist/commands/patent.js.map +1 -0
  237. package/dist/commands/social.d.ts +19 -0
  238. package/dist/commands/social.d.ts.map +1 -0
  239. package/dist/commands/social.js +236 -0
  240. package/dist/commands/social.js.map +1 -0
  241. package/dist/core/registry.d.ts +1 -1
  242. package/dist/core/registry.d.ts.map +1 -1
  243. package/dist/core/registry.js +11 -2
  244. package/dist/core/registry.js.map +1 -1
  245. package/dist/discovery/loader.d.ts.map +1 -1
  246. package/dist/discovery/loader.js +4 -0
  247. package/dist/discovery/loader.js.map +1 -1
  248. package/dist/engine/approval-presenter.d.ts +10 -0
  249. package/dist/engine/approval-presenter.d.ts.map +1 -0
  250. package/dist/engine/approval-presenter.js +45 -0
  251. package/dist/engine/approval-presenter.js.map +1 -0
  252. package/dist/engine/approval-store.d.ts +4 -0
  253. package/dist/engine/approval-store.d.ts.map +1 -1
  254. package/dist/engine/approval-store.js +85 -11
  255. package/dist/engine/approval-store.js.map +1 -1
  256. package/dist/engine/auth/oauth2-cc.d.ts +67 -0
  257. package/dist/engine/auth/oauth2-cc.d.ts.map +1 -0
  258. package/dist/engine/auth/oauth2-cc.js +120 -0
  259. package/dist/engine/auth/oauth2-cc.js.map +1 -0
  260. package/dist/engine/cookies.d.ts +10 -0
  261. package/dist/engine/cookies.d.ts.map +1 -1
  262. package/dist/engine/cookies.js +64 -0
  263. package/dist/engine/cookies.js.map +1 -1
  264. package/dist/engine/download.d.ts +5 -0
  265. package/dist/engine/download.d.ts.map +1 -1
  266. package/dist/engine/download.js +11 -4
  267. package/dist/engine/download.js.map +1 -1
  268. package/dist/engine/executor.d.ts +1 -0
  269. package/dist/engine/executor.d.ts.map +1 -1
  270. package/dist/engine/executor.js +25 -0
  271. package/dist/engine/executor.js.map +1 -1
  272. package/dist/engine/framework.d.ts +5 -5
  273. package/dist/engine/framework.js +5 -5
  274. package/dist/engine/harden.d.ts +1 -1
  275. package/dist/engine/harden.js +1 -1
  276. package/dist/engine/kernel/stages.d.ts.map +1 -1
  277. package/dist/engine/kernel/stages.js +2 -1
  278. package/dist/engine/kernel/stages.js.map +1 -1
  279. package/dist/engine/normalizer/patent-envelope.d.ts +61 -0
  280. package/dist/engine/normalizer/patent-envelope.d.ts.map +1 -0
  281. package/dist/engine/normalizer/patent-envelope.js +132 -0
  282. package/dist/engine/normalizer/patent-envelope.js.map +1 -0
  283. package/dist/engine/research.d.ts +5 -7
  284. package/dist/engine/research.d.ts.map +1 -1
  285. package/dist/engine/research.js +6 -9
  286. package/dist/engine/research.js.map +1 -1
  287. package/dist/engine/steps/browser-helpers.d.ts +2 -2
  288. package/dist/engine/steps/browser-helpers.d.ts.map +1 -1
  289. package/dist/engine/steps/browser-helpers.js +39 -16
  290. package/dist/engine/steps/browser-helpers.js.map +1 -1
  291. package/dist/engine/steps/download.d.ts +1 -0
  292. package/dist/engine/steps/download.d.ts.map +1 -1
  293. package/dist/engine/steps/download.js +3 -1
  294. package/dist/engine/steps/download.js.map +1 -1
  295. package/dist/engine/steps/index.d.ts +2 -0
  296. package/dist/engine/steps/index.d.ts.map +1 -1
  297. package/dist/engine/steps/index.js +2 -0
  298. package/dist/engine/steps/index.js.map +1 -1
  299. package/dist/engine/steps/oauth2-token.d.ts +41 -0
  300. package/dist/engine/steps/oauth2-token.d.ts.map +1 -0
  301. package/dist/engine/steps/oauth2-token.js +115 -0
  302. package/dist/engine/steps/oauth2-token.js.map +1 -0
  303. package/dist/engine/steps/select-xml.d.ts +34 -0
  304. package/dist/engine/steps/select-xml.d.ts.map +1 -0
  305. package/dist/engine/steps/select-xml.js +222 -0
  306. package/dist/engine/steps/select-xml.js.map +1 -0
  307. package/dist/engine/template.d.ts.map +1 -1
  308. package/dist/engine/template.js +7 -0
  309. package/dist/engine/template.js.map +1 -1
  310. package/dist/engine/transport/mcp-browser.d.ts +128 -0
  311. package/dist/engine/transport/mcp-browser.d.ts.map +1 -0
  312. package/dist/engine/transport/mcp-browser.js +120 -0
  313. package/dist/engine/transport/mcp-browser.js.map +1 -0
  314. package/dist/fast-path/handlers/approvals.d.ts +11 -0
  315. package/dist/fast-path/handlers/approvals.d.ts.map +1 -0
  316. package/dist/fast-path/handlers/approvals.js +136 -0
  317. package/dist/fast-path/handlers/approvals.js.map +1 -0
  318. package/dist/fast-path/manifest.d.ts +1 -0
  319. package/dist/fast-path/manifest.d.ts.map +1 -1
  320. package/dist/fast-path/manifest.js.map +1 -1
  321. package/dist/fast-path.d.ts.map +1 -1
  322. package/dist/fast-path.js +3 -0
  323. package/dist/fast-path.js.map +1 -1
  324. package/dist/index.d.ts +23 -0
  325. package/dist/index.d.ts.map +1 -0
  326. package/dist/index.js +38 -0
  327. package/dist/index.js.map +1 -0
  328. package/dist/manifest-compact.txt +3 -3
  329. package/dist/manifest-search.json +1 -1
  330. package/dist/manifest.json +2239 -176
  331. package/dist/output/auth-guidance.d.ts +14 -0
  332. package/dist/output/auth-guidance.d.ts.map +1 -0
  333. package/dist/output/auth-guidance.js +50 -0
  334. package/dist/output/auth-guidance.js.map +1 -0
  335. package/dist/output/error-map.d.ts +1 -1
  336. package/dist/output/error-map.d.ts.map +1 -1
  337. package/dist/output/error-map.js +28 -4
  338. package/dist/output/error-map.js.map +1 -1
  339. package/dist/output/next-actions.d.ts.map +1 -1
  340. package/dist/output/next-actions.js +19 -3
  341. package/dist/output/next-actions.js.map +1 -1
  342. package/dist/registry.d.ts +18 -1
  343. package/dist/registry.d.ts.map +1 -1
  344. package/dist/registry.js +5 -0
  345. package/dist/registry.js.map +1 -1
  346. package/dist/social/browser-errors.d.ts +13 -0
  347. package/dist/social/browser-errors.d.ts.map +1 -0
  348. package/dist/social/browser-errors.js +36 -0
  349. package/dist/social/browser-errors.js.map +1 -0
  350. package/dist/social/capabilities.d.ts +29 -0
  351. package/dist/social/capabilities.d.ts.map +1 -0
  352. package/dist/social/capabilities.js +448 -0
  353. package/dist/social/capabilities.js.map +1 -0
  354. package/dist/social/comments.d.ts +26 -0
  355. package/dist/social/comments.d.ts.map +1 -0
  356. package/dist/social/comments.js +97 -0
  357. package/dist/social/comments.js.map +1 -0
  358. package/dist/social/video-text.d.ts +27 -0
  359. package/dist/social/video-text.d.ts.map +1 -0
  360. package/dist/social/video-text.js +140 -0
  361. package/dist/social/video-text.js.map +1 -0
  362. package/dist/types/patent.d.ts +160 -0
  363. package/dist/types/patent.d.ts.map +1 -0
  364. package/dist/types/patent.js +16 -0
  365. package/dist/types/patent.js.map +1 -0
  366. package/dist/types.d.ts +12 -0
  367. package/dist/types.d.ts.map +1 -1
  368. package/dist/types.js.map +1 -1
  369. package/package.json +9 -4
  370. package/server.json +3 -3
  371. package/skills/unicli/SKILL.md +1 -1
  372. package/skills/unicli-claude-code/SKILL.md +1 -1
  373. package/skills/unicli-hermes/SKILL.md +1 -1
  374. package/src/adapters/bilibili/comments-tree.test.ts +41 -0
  375. package/src/adapters/bilibili/comments.ts +78 -4
  376. package/src/adapters/bilibili/compat.ts +5 -2
  377. package/src/adapters/bilibili/download.ts +7 -4
  378. package/src/adapters/bilibili/wbi.ts +6 -3
  379. package/src/adapters/brave/search.yaml +53 -0
  380. package/src/adapters/cipo/_shared.ts +98 -0
  381. package/src/adapters/cipo/get.ts +188 -0
  382. package/src/adapters/cipo/legal-status.ts +148 -0
  383. package/src/adapters/cipo/search.ts +195 -0
  384. package/src/adapters/cnipa/_shared.ts +138 -0
  385. package/src/adapters/cnipa/get.ts +199 -0
  386. package/src/adapters/cnipa/legal-status.ts +162 -0
  387. package/src/adapters/cnipa/search.ts +229 -0
  388. package/src/adapters/dpma/get.yaml +67 -0
  389. package/src/adapters/dpma/search.yaml +77 -0
  390. package/src/adapters/duckduckgo/search.yaml +54 -0
  391. package/src/adapters/duckduckgo/suggest.yaml +52 -0
  392. package/src/adapters/epo/family.yaml +69 -0
  393. package/src/adapters/epo/get.yaml +74 -0
  394. package/src/adapters/epo/legal-status.yaml +63 -0
  395. package/src/adapters/epo/search.yaml +84 -0
  396. package/src/adapters/espacenet/_shared.ts +98 -0
  397. package/src/adapters/espacenet/family.ts +161 -0
  398. package/src/adapters/espacenet/get.ts +185 -0
  399. package/src/adapters/espacenet/legal-status.ts +151 -0
  400. package/src/adapters/espacenet/search.ts +229 -0
  401. package/src/adapters/facebook/subtitles.ts +44 -0
  402. package/src/adapters/fips/_shared.ts +109 -0
  403. package/src/adapters/fips/get.ts +186 -0
  404. package/src/adapters/fips/search.ts +195 -0
  405. package/src/adapters/freepatentsonline-web/_shared.ts +273 -0
  406. package/src/adapters/freepatentsonline-web/get.ts +144 -0
  407. package/src/adapters/freepatentsonline-web/search.ts +170 -0
  408. package/src/adapters/google-patents-bq/prior-art.yaml +80 -0
  409. package/src/adapters/google-patents-bq/search.yaml +97 -0
  410. package/src/adapters/google-patents-web/_shared.ts +242 -0
  411. package/src/adapters/google-patents-web/get.ts +224 -0
  412. package/src/adapters/google-patents-web/search.ts +196 -0
  413. package/src/adapters/inpi-br/_shared.ts +98 -0
  414. package/src/adapters/inpi-br/get.ts +193 -0
  415. package/src/adapters/inpi-br/search.ts +206 -0
  416. package/src/adapters/inpi-fr/get.yaml +62 -0
  417. package/src/adapters/inpi-fr/search.yaml +74 -0
  418. package/src/adapters/instagram/subtitles.ts +44 -0
  419. package/src/adapters/ipaustralia/get.yaml +67 -0
  420. package/src/adapters/ipaustralia/search.yaml +74 -0
  421. package/src/adapters/jpo/get.yaml +63 -0
  422. package/src/adapters/jpo/search.yaml +76 -0
  423. package/src/adapters/kipris/get.yaml +69 -0
  424. package/src/adapters/kipris/legal-status.yaml +58 -0
  425. package/src/adapters/kipris/search.yaml +79 -0
  426. package/src/adapters/lens/get.yaml +64 -0
  427. package/src/adapters/lens/search.yaml +82 -0
  428. package/src/adapters/mastodon/statuses.test.ts +82 -0
  429. package/src/adapters/mastodon/statuses.ts +208 -0
  430. package/src/adapters/patsnap/get.yaml +65 -0
  431. package/src/adapters/patsnap/search.yaml +77 -0
  432. package/src/adapters/pqai/prior-art.yaml +59 -0
  433. package/src/adapters/pqai/search.yaml +60 -0
  434. package/src/adapters/reddit/comments-tree.test.ts +79 -0
  435. package/src/adapters/reddit/comments.ts +159 -0
  436. package/src/adapters/threads/post.test.ts +64 -0
  437. package/src/adapters/threads/post.ts +366 -0
  438. package/src/adapters/threads/user.yaml +73 -0
  439. package/src/adapters/tiktok/subtitles.ts +44 -0
  440. package/src/adapters/twitter/accept.ts +5 -2
  441. package/src/adapters/twitter/browser-fallback.ts +138 -0
  442. package/src/adapters/twitter/browser-state.ts +74 -0
  443. package/src/adapters/twitter/client.ts +51 -21
  444. package/src/adapters/twitter/reply-dm.ts +5 -2
  445. package/src/adapters/twitter/reply.ts +1 -0
  446. package/src/adapters/twitter/search.ts +12 -38
  447. package/src/adapters/twitter/thread.test.ts +43 -0
  448. package/src/adapters/twitter/thread.ts +44 -2
  449. package/src/adapters/twitter/trending.ts +14 -95
  450. package/src/adapters/ukipo/info.yaml +43 -0
  451. package/src/adapters/uspto/get.yaml +67 -0
  452. package/src/adapters/uspto/legal-status.yaml +58 -0
  453. package/src/adapters/uspto/search.yaml +88 -0
  454. package/src/adapters/wipo-patentscope/info.yaml +43 -0
  455. package/src/adapters/xiaohongshu/browser-state.ts +95 -0
  456. package/src/adapters/xiaohongshu/comments.ts +29 -6
  457. package/src/adapters/xiaohongshu/download.ts +60 -11
  458. package/src/adapters/xiaohongshu/search.ts +18 -6
  459. package/src/adapters/xiaohongshu/trending.ts +112 -0
  460. package/src/adapters/yahoo/search.yaml +52 -0
  461. package/src/adapters/youtube/comments-microformat.test.ts +35 -0
  462. package/src/adapters/youtube/comments-tree.test.ts +74 -0
  463. package/src/adapters/youtube/comments.ts +166 -12
  464. package/src/adapters/youtube/subtitles.ts +44 -0
  465. package/src/adapters/yt-dlp/subtitles.ts +43 -0
  466. package/src/adapters/zhihu/answer-detail.test.ts +83 -0
  467. package/src/adapters/zhihu/answer-detail.ts +275 -0
  468. package/src/adapters/zhihu/comment-tree.test.ts +57 -0
  469. package/src/adapters/zhihu/comment.ts +186 -0
  470. package/src/adapters/zhihu/recommend.test.ts +65 -0
  471. package/src/adapters/zhihu/recommend.ts +207 -0
@@ -0,0 +1,229 @@
1
+ /**
2
+ * @owner src::adapters::cnipa::search
3
+ * @does Browser-driven search of CNIPA 公众查询 system at pss-system.cponline.cnipa.gov.cn — the only programmatic route for CN patents (CNIPA has no open API today). Drives a real Chrome session via the mcp-browser transport, extracts result rows, normalizes through assemblePatentRecord.
4
+ * @needs src/engine/transport/mcp-browser.ts, src/engine/normalizer/patent-envelope.ts, src/types/patent.ts, src/adapters/cnipa/_shared.ts, src/registry.ts
5
+ * @feeds src/commands/patent.ts (meta-command discovers via patent.search capability tag)
6
+ * @breaks emits PATENT_BROWSER_CAPTCHA envelope when zero rows return from a navigation that did not error (CNIPA almost always shows a captcha gate); emits PATENT_API_DEPRECATED with MCP_BUS_MISSING context when no outbound MCP transport is registered
7
+ * @invariants result rows always include source_adapter='cnipa'; publication_number canonicalized via assemblePatentRecord; never returns a synthetic row when extraction fails
8
+ * @side-effects controls the user's Chrome browser via MCP; reads no env vars
9
+ * @perf single navigation + one evaluate; ~2-5 s wall-clock when active
10
+ * @concurrency safe — every call opens a fresh tab via mcpBrowserNavigate
11
+ * @test tests/unit/adapters/cnipa/search.test.ts
12
+ * @stability experimental
13
+ * @since 2026-05-18
14
+ * @verification browser-only — no upstream API; gated on a live mcp-browser transport
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
+ cnipaEnvelope,
22
+ looksLikeCaptcha,
23
+ navigateAndExtract,
24
+ transportErrorToEnvelope,
25
+ } from "./_shared.js";
26
+
27
+ const ADAPTER_PATH = "src/adapters/cnipa/search.ts";
28
+ const CNIPA_SEARCH_URL =
29
+ "https://pss-system.cponline.cnipa.gov.cn/conventionalSearch";
30
+
31
+ interface CnipaRow {
32
+ publication_number: string;
33
+ application_number?: string;
34
+ title?: string;
35
+ applicant?: string;
36
+ publication_date?: string;
37
+ filing_date?: string;
38
+ source_url?: string;
39
+ }
40
+
41
+ interface CnipaExtractResult {
42
+ rows: CnipaRow[];
43
+ html_marker?: string;
44
+ }
45
+
46
+ /**
47
+ * DOM extractor executed inside the page via mcp-browser. The selectors are
48
+ * the documented ones for the CNIPA 公众查询 result table; when CNIPA
49
+ * changes the markup an agent reads the failure envelope and updates the
50
+ * selector here (rule 02 self-repair).
51
+ */
52
+ const EXTRACTOR = `(() => {
53
+ const rows = Array.from(
54
+ document.querySelectorAll('table.result-table tbody tr, .result-list .result-item')
55
+ ).map((el) => {
56
+ const text = (sel) => {
57
+ const node = el.querySelector(sel);
58
+ return node ? (node.textContent || '').trim() : '';
59
+ };
60
+ return {
61
+ publication_number: text('.publication-number, [data-field="pubNo"]'),
62
+ application_number: text('.application-number, [data-field="appNo"]'),
63
+ title: text('.title, [data-field="title"]'),
64
+ applicant: text('.applicant, [data-field="applicant"]'),
65
+ publication_date: text('.publication-date, [data-field="pubDate"]'),
66
+ filing_date: text('.filing-date, [data-field="appDate"]'),
67
+ source_url: (el.querySelector('a[href]') || {}).href || '',
68
+ };
69
+ });
70
+ const html_marker = (document.body && document.body.innerText
71
+ ? document.body.innerText.slice(0, 200)
72
+ : '');
73
+ return { rows, html_marker };
74
+ })()`;
75
+
76
+ function buildSearchUrl(query: string, limit: number, offset: number): string {
77
+ const params = new URLSearchParams({
78
+ q: query,
79
+ pageSize: String(limit),
80
+ pageNo: String(Math.floor(offset / Math.max(1, limit)) + 1),
81
+ });
82
+ return `${CNIPA_SEARCH_URL}?${params.toString()}`;
83
+ }
84
+
85
+ export async function runCnipaSearch(kwargs: {
86
+ query: string;
87
+ limit?: number;
88
+ offset?: number;
89
+ }): Promise<unknown[]> {
90
+ const limit =
91
+ typeof kwargs.limit === "number" && Number.isFinite(kwargs.limit)
92
+ ? Math.max(1, Math.min(100, Math.floor(kwargs.limit)))
93
+ : 25;
94
+ const offset =
95
+ typeof kwargs.offset === "number" && Number.isFinite(kwargs.offset)
96
+ ? Math.max(0, Math.floor(kwargs.offset))
97
+ : 0;
98
+ const query = String(kwargs.query ?? "").trim();
99
+ if (query.length === 0) {
100
+ return [
101
+ {
102
+ envelope: cnipaEnvelope(
103
+ "PATENT_UNSUPPORTED_QUERY",
104
+ ADAPTER_PATH,
105
+ "validate",
106
+ "cnipa search requires a non-empty query string",
107
+ ),
108
+ },
109
+ ];
110
+ }
111
+ const url = buildSearchUrl(query, limit, offset);
112
+ let extract: CnipaExtractResult;
113
+ try {
114
+ const result = await navigateAndExtract<CnipaExtractResult>(url, EXTRACTOR);
115
+ if (!result.data) {
116
+ return [
117
+ {
118
+ envelope: cnipaEnvelope(
119
+ "PATENT_SCHEMA_DRIFT",
120
+ ADAPTER_PATH,
121
+ "evaluate",
122
+ "mcp-browser evaluate returned no data; check selector schema in src/adapters/cnipa/search.ts",
123
+ ),
124
+ },
125
+ ];
126
+ }
127
+ extract = result.data;
128
+ } catch (err) {
129
+ if (err instanceof TransportError) {
130
+ return [
131
+ {
132
+ envelope: transportErrorToEnvelope(err, ADAPTER_PATH, "navigate"),
133
+ },
134
+ ];
135
+ }
136
+ throw err;
137
+ }
138
+
139
+ if (looksLikeCaptcha(extract.rows.length, extract.html_marker)) {
140
+ return [
141
+ {
142
+ envelope: cnipaEnvelope(
143
+ "PATENT_BROWSER_CAPTCHA",
144
+ ADAPTER_PATH,
145
+ "evaluate",
146
+ "CNIPA returned no rows for a non-empty query; solve the 验证码 in the open browser tab and re-run",
147
+ ["espacenet", "lens"],
148
+ ),
149
+ },
150
+ ];
151
+ }
152
+
153
+ const out: unknown[] = [];
154
+ for (const row of extract.rows.slice(0, limit)) {
155
+ if (!row.publication_number) continue;
156
+ try {
157
+ out.push(
158
+ assemblePatentRecord({
159
+ publication_number: row.publication_number,
160
+ application_number: row.application_number || undefined,
161
+ title: row.title || undefined,
162
+ assignees: row.applicant
163
+ ? [{ name: row.applicant, country: "CN" }]
164
+ : undefined,
165
+ publication_date: row.publication_date || undefined,
166
+ filing_date: row.filing_date || undefined,
167
+ source_adapter: "cnipa",
168
+ source_url: row.source_url || url,
169
+ } as Parameters<typeof assemblePatentRecord>[0]),
170
+ );
171
+ } catch {
172
+ // Skip malformed row rather than synthesize — rule 02.
173
+ }
174
+ }
175
+ if (out.length === 0) {
176
+ out.push({
177
+ envelope: cnipaEnvelope(
178
+ "PATENT_NOT_FOUND",
179
+ ADAPTER_PATH,
180
+ "normalize",
181
+ "cnipa returned rows but none carried a publication_number; report as schema drift",
182
+ ["espacenet"],
183
+ ),
184
+ });
185
+ }
186
+ return out;
187
+ }
188
+
189
+ cli({
190
+ site: "cnipa",
191
+ name: "search",
192
+ description:
193
+ "Search CNIPA via the public 公众查询 browser interface (no API)",
194
+ domain: "pss-system.cponline.cnipa.gov.cn",
195
+ strategy: Strategy.PUBLIC,
196
+ adapter_path: ADAPTER_PATH,
197
+ args: [
198
+ {
199
+ name: "query",
200
+ type: "str",
201
+ required: true,
202
+ positional: true,
203
+ description: "Free-text query — matched against title/abstract/claims",
204
+ },
205
+ {
206
+ name: "limit",
207
+ type: "int",
208
+ default: 25,
209
+ description: "Maximum results to return (1-100)",
210
+ },
211
+ {
212
+ name: "offset",
213
+ type: "int",
214
+ default: 0,
215
+ description: "Result offset for pagination",
216
+ },
217
+ ],
218
+ columns: ["publication_number", "title", "publication_date", "source_url"],
219
+ capabilities: [
220
+ "mcp-browser.navigate",
221
+ "mcp-browser.evaluate",
222
+ "patent.search",
223
+ ],
224
+ minimum_capability: "mcp-browser.evaluate",
225
+ func: async (_page, kwargs) =>
226
+ runCnipaSearch(
227
+ kwargs as { query: string; limit?: number; offset?: number },
228
+ ),
229
+ });
@@ -0,0 +1,67 @@
1
+ # @owner src::adapters::dpma::get
2
+ # @does Fetch a German patent record by publication number via DPMAconnectPlus REST.
3
+ # @needs src/engine/steps/fetch.ts, src/engine/steps/select-xml.ts, src/engine/steps/map.ts
4
+ # @feeds src/commands/patent.ts
5
+ # @breaks throws PipelineError on 401/403, 404, 5xx
6
+ # @invariants output row conforms to PatentRecord
7
+ # @side-effects reads env DPMA_AUTHORIZATION; HTTPS egress to dpmaconnect.dpma.de
8
+ # @perf single request
9
+ # @concurrency safe
10
+ # @test none yet
11
+ # @stability stable
12
+ # @since 2026-05-18
13
+ # @verification blocked-by-subscription
14
+ site: dpma
15
+ name: get
16
+ description: Fetch a German patent record by publication number (subscription)
17
+ domain: dpmaconnect.dpma.de
18
+ type: web-api
19
+ strategy: public
20
+ lint_listing_detail: skip
21
+
22
+ args:
23
+ publication_number:
24
+ type: str
25
+ required: true
26
+ positional: true
27
+ description: German publication number (e.g. DE102023012345)
28
+
29
+ pipeline:
30
+ - fetch:
31
+ url: "https://dpmaconnect.dpma.de/dpmaconnectplus/rest/document/${{ args.publication_number | urlencode }}"
32
+ method: GET
33
+ headers:
34
+ Accept: application/xml
35
+ Authorization: "${{ env.DPMA_AUTHORIZATION || '' }}"
36
+
37
+ - select-xml:
38
+ xpath: "//record"
39
+ unwrap_single: true
40
+
41
+ - map:
42
+ publication_number: "${{ 'DE-' + (item.publicationNumber || args.publication_number || '') + '-' + (item.kindCode || '') }}"
43
+ application_number: "${{ item.applicationNumber || '' }}"
44
+ title: "${{ item.title || item.titleDe || item.titleEn || '' }}"
45
+ abstract: "${{ item.abstract || item.abstractDe || item.abstractEn || '' }}"
46
+ kind_code: "${{ item.kindCode || '' }}"
47
+ filing_date: "${{ item.filingDate || '' }}"
48
+ publication_date: "${{ item.publicationDate || '' }}"
49
+ grant_date: "${{ item.grantDate || '' }}"
50
+ priority_date: "${{ item.priorityDate || '' }}"
51
+ legal_status: "${{ item.legalStatus || item.status || '' }}"
52
+ inventors: "${{ JSON.stringify((function(){ var i=item.inventor || item.inventors; if(!i) return []; var arr = Array.isArray(i) ? i : [i]; return arr.map(n => ({ name: typeof n === 'string' ? n : (n.name || n.fullName || ''), country: 'DE' })).filter(x => x.name); })()) }}"
53
+ assignees: "${{ JSON.stringify((function(){ var a=item.applicant || item.applicants; if(!a) return []; var arr = Array.isArray(a) ? a : [a]; return arr.map(n => ({ name: typeof n === 'string' ? n : (n.name || n.fullName || ''), country: 'DE' })).filter(x => x.name); })()) }}"
54
+ classifications: "${{ JSON.stringify((function(){ var c=item.ipc || item.classifications; if(!c) return []; var arr = Array.isArray(c) ? c : [c]; return arr.map(x => ({ scheme: 'ipc', code: typeof x === 'string' ? x : (x.code || '') })).filter(x => x.code); })()) }}"
55
+ source_adapter: dpma
56
+ source_url: "${{ 'https://register.dpma.de/DPMAregister/pat/register?AKZ=' + (item.applicationNumber || '') }}"
57
+ retrieved_at: ""
58
+
59
+ columns: [publication_number, title, filing_date, publication_date]
60
+
61
+ # schema-v2 metadata
62
+ capabilities: ["http.fetch", "patent.get"]
63
+ minimum_capability: http.fetch
64
+ trust: public
65
+ confidentiality: public
66
+ quarantine: false
67
+ schema_version: v2
@@ -0,0 +1,77 @@
1
+ # @owner src::adapters::dpma::search
2
+ # @does Search German patents via the DPMAconnectPlus REST API (XML / OAI-PMH-style envelope).
3
+ # @needs src/engine/steps/fetch.ts, src/engine/steps/select-xml.ts, src/engine/steps/map.ts, src/engine/steps/limit.ts
4
+ # @feeds src/commands/patent.ts
5
+ # @breaks throws PipelineError on 401/403 (missing DPMA_AUTHORIZATION precomputed `Basic <base64>` header), 4xx, 5xx
6
+ # @invariants output rows conform to PatentRecord; publication_number is `DE-<doc>-<kind>`
7
+ # @side-effects reads env DPMA_AUTHORIZATION (precomputed `Basic <base64(user:pass)>`); HTTPS egress to dpmaconnect.dpma.de
8
+ # @perf single request
9
+ # @concurrency safe
10
+ # @test none yet
11
+ # @stability stable
12
+ # @since 2026-05-18
13
+ # @verification blocked-by-subscription — DPMAconnectPlus requires a paid connection contract (~200 EUR setup). Adapter ships so contracted users can run it; precompute `DPMA_AUTHORIZATION="Basic $(printf '%s:%s' "$USER" "$PASS" | base64)"` before invocation.
14
+ site: dpma
15
+ name: search
16
+ description: Search German patents via DPMAconnectPlus REST (subscription)
17
+ domain: dpmaconnect.dpma.de
18
+ type: web-api
19
+ strategy: public
20
+ lint_listing_detail: skip
21
+
22
+ args:
23
+ query:
24
+ type: str
25
+ required: true
26
+ positional: true
27
+ description: DPMA query (free-text, mapped to title/abstract)
28
+ limit:
29
+ type: int
30
+ default: 25
31
+ description: Maximum results
32
+
33
+ pipeline:
34
+ - fetch:
35
+ url: "https://dpmaconnect.dpma.de/dpmaconnectplus/rest/search/published"
36
+ method: GET
37
+ headers:
38
+ Accept: application/xml
39
+ Authorization: "${{ env.DPMA_AUTHORIZATION || '' }}"
40
+ params:
41
+ query: "${{ args.query }}"
42
+ maximumRecords: "${{ args.limit }}"
43
+ startRecord: "1"
44
+
45
+ - select-xml:
46
+ xpath: "//record"
47
+
48
+ # DPMAconnectPlus XML mirrors INPI / EPO field naming; preserve German
49
+ # script in title / abstract.
50
+ - map:
51
+ publication_number: "${{ 'DE-' + (item.publicationNumber || '') + '-' + (item.kindCode || '') }}"
52
+ application_number: "${{ item.applicationNumber || '' }}"
53
+ title: "${{ item.title || item.titleDe || item.titleEn || '' }}"
54
+ abstract: "${{ item.abstract || item.abstractDe || item.abstractEn || '' }}"
55
+ kind_code: "${{ item.kindCode || '' }}"
56
+ filing_date: "${{ item.filingDate || '' }}"
57
+ publication_date: "${{ item.publicationDate || '' }}"
58
+ grant_date: "${{ item.grantDate || '' }}"
59
+ priority_date: "${{ item.priorityDate || '' }}"
60
+ inventors: "${{ JSON.stringify((function(){ var i=item.inventor || item.inventors; if(!i) return []; var arr = Array.isArray(i) ? i : [i]; return arr.map(n => ({ name: typeof n === 'string' ? n : (n.name || n.fullName || ''), country: 'DE' })).filter(x => x.name); })()) }}"
61
+ assignees: "${{ JSON.stringify((function(){ var a=item.applicant || item.applicants; if(!a) return []; var arr = Array.isArray(a) ? a : [a]; return arr.map(n => ({ name: typeof n === 'string' ? n : (n.name || n.fullName || ''), country: 'DE' })).filter(x => x.name); })()) }}"
62
+ classifications: "${{ JSON.stringify((function(){ var c=item.ipc || item.classifications; if(!c) return []; var arr = Array.isArray(c) ? c : [c]; return arr.map(x => ({ scheme: 'ipc', code: typeof x === 'string' ? x : (x.code || '') })).filter(x => x.code); })()) }}"
63
+ source_adapter: dpma
64
+ source_url: "${{ 'https://register.dpma.de/DPMAregister/pat/register?AKZ=' + (item.applicationNumber || '') }}"
65
+ retrieved_at: ""
66
+
67
+ - limit: "${{ args.limit }}"
68
+
69
+ columns: [publication_number, title, filing_date, publication_date]
70
+
71
+ # schema-v2 metadata
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,54 @@
1
+ # DuckDuckGo Search — keyless HTML lite endpoint.
2
+ #
3
+ # verification_status: keyless-best-effort
4
+ #
5
+ # DuckDuckGo runs an Instant-Answer JSON API at api.duckduckgo.com that
6
+ # returns disambiguation pages and zero web results, plus a lite HTML
7
+ # search at https://html.duckduckgo.com/html that returns SSR result rows
8
+ # without JS. We use the lite HTML path so a fresh user gets web results
9
+ # with no token of any kind. DDG rate-limits aggressive scraping; the
10
+ # adapter is for human-scale interactive use.
11
+ site: duckduckgo
12
+ name: search
13
+ description: Search the public web via DuckDuckGo (no API key needed)
14
+ type: web-api
15
+ domain: html.duckduckgo.com
16
+ strategy: public
17
+ lint_listing_detail: skip
18
+
19
+ args:
20
+ query:
21
+ type: str
22
+ required: true
23
+ positional: true
24
+ description: Free-text web search query
25
+ limit:
26
+ type: int
27
+ default: 10
28
+ description: Maximum results returned (DDG lite caps at ~30 per page)
29
+
30
+ pipeline:
31
+ - fetch_text:
32
+ url: "https://html.duckduckgo.com/html/?q=${{ args.query | url_encode }}"
33
+ headers:
34
+ User-Agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
35
+ Accept: "text/html,application/xhtml+xml"
36
+
37
+ - extract:
38
+ selector: "div.result"
39
+ fields:
40
+ title: "h2.result__title a"
41
+ url: "h2.result__title a@href"
42
+ snippet: "a.result__snippet"
43
+
44
+ - limit: ${{ args.limit }}
45
+
46
+ columns: [title, url, snippet]
47
+
48
+ # schema-v2 metadata
49
+ capabilities: ["http.fetch"]
50
+ minimum_capability: http.fetch
51
+ trust: public
52
+ confidentiality: public
53
+ quarantine: false
54
+ schema_version: v2
@@ -0,0 +1,52 @@
1
+ # DuckDuckGo Autocomplete — keyless JSON endpoint.
2
+ #
3
+ # verification_status: keyless-best-effort
4
+ #
5
+ # The autocomplete endpoint at https://duckduckgo.com/ac is the JSON used
6
+ # by the DDG search box. No auth, no rate-limit gate at low volumes, and
7
+ # returns a flat list of suggested completions for a prefix.
8
+ site: duckduckgo
9
+ name: suggest
10
+ description: Get query autocompletion suggestions from DuckDuckGo
11
+ type: web-api
12
+ domain: duckduckgo.com
13
+ strategy: public
14
+ lint_listing_detail: skip
15
+
16
+ args:
17
+ query:
18
+ type: str
19
+ required: true
20
+ positional: true
21
+ description: Partial query prefix to autocomplete
22
+ limit:
23
+ type: int
24
+ default: 10
25
+ description: Maximum suggestions returned
26
+
27
+ pipeline:
28
+ - fetch:
29
+ url: "https://duckduckgo.com/ac/"
30
+ params:
31
+ q: "${{ args.query }}"
32
+ type: list
33
+ headers:
34
+ User-Agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36"
35
+ Accept: "application/json"
36
+
37
+ - select: "1"
38
+
39
+ - map:
40
+ phrase: "${{ item }}"
41
+
42
+ - limit: ${{ args.limit }}
43
+
44
+ columns: [phrase]
45
+
46
+ # schema-v2 metadata
47
+ capabilities: ["http.fetch"]
48
+ minimum_capability: http.fetch
49
+ trust: public
50
+ confidentiality: public
51
+ quarantine: false
52
+ schema_version: v2
@@ -0,0 +1,69 @@
1
+ # @owner src::adapters::epo::family
2
+ # @does Fetch INPADOC simple family for a publication via EPO Open Patent Services v3.2.
3
+ # @needs src/engine/steps/oauth2-token.ts, src/engine/steps/fetch.ts, src/engine/steps/select-xml.ts, src/engine/steps/map.ts
4
+ # @feeds src/commands/patent.ts
5
+ # @breaks throws PipelineError on token failure, 404, 401/403, 5xx
6
+ # @invariants output rows are family members in PatentRecord shape with `family_id` populated
7
+ # @side-effects reads EPO OAuth2 credentials; HTTPS to ops.epo.org
8
+ # @perf two HTTPS requests
9
+ # @concurrency safe
10
+ # @test none yet
11
+ # @stability stable
12
+ # @since 2026-05-18
13
+ # @verification blocked-by-key
14
+ site: epo
15
+ name: family
16
+ description: INPADOC simple family for an EPO publication
17
+ domain: ops.epo.org
18
+ type: web-api
19
+ strategy: public
20
+ lint_listing_detail: skip
21
+
22
+ args:
23
+ publication_number:
24
+ type: str
25
+ required: true
26
+ positional: true
27
+ description: Publication number in epodoc format
28
+
29
+ pipeline:
30
+ - oauth2-token:
31
+ site: epo
32
+ token_url: https://ops.epo.org/3.2/auth/accesstoken
33
+ client_id_env: EPO_OPS_CLIENT_ID
34
+ client_secret_env: EPO_OPS_CLIENT_SECRET
35
+
36
+ - fetch:
37
+ url: "https://ops.epo.org/3.2/rest-services/family/publication/epodoc/${{ args.publication_number | urlencode }}"
38
+ method: GET
39
+ headers:
40
+ Authorization: "Bearer ${{ auth.bearer || '' }}"
41
+ Accept: application/xml
42
+
43
+ - select-xml:
44
+ xpath: "//ops:family-member"
45
+ namespaces:
46
+ ops: "http://ops.epo.org"
47
+
48
+ # Family endpoint returns ops:family-member nodes with publication-reference,
49
+ # application-reference, and a `@family-id` attribute on each.
50
+ - map:
51
+ publication_number: "${{ ((item['publication-reference'] && item['publication-reference']['document-id']) ? (item['publication-reference']['document-id'].country + '-' + item['publication-reference']['document-id']['doc-number'] + '-' + (item['publication-reference']['document-id'].kind || '')) : '') }}"
52
+ application_number: "${{ ((item['application-reference'] && item['application-reference']['document-id']) ? (item['application-reference']['document-id'].country + '-' + item['application-reference']['document-id']['doc-number'] + '-' + (item['application-reference']['document-id'].kind || '')) : '') }}"
53
+ kind_code: "${{ (item['publication-reference'] && item['publication-reference']['document-id']) ? (item['publication-reference']['document-id'].kind || '') : '' }}"
54
+ publication_date: "${{ (function(d){ if(!d) return ''; var s=String(d); return s.length===8 ? (s.slice(0,4)+'-'+s.slice(4,6)+'-'+s.slice(6,8)) : s; })((item['publication-reference'] && item['publication-reference']['document-id']) ? item['publication-reference']['document-id'].date : '') }}"
55
+ filing_date: "${{ (function(d){ if(!d) return ''; var s=String(d); return s.length===8 ? (s.slice(0,4)+'-'+s.slice(4,6)+'-'+s.slice(6,8)) : s; })((item['application-reference'] && item['application-reference']['document-id']) ? item['application-reference']['document-id'].date : '') }}"
56
+ family_id: "${{ item['@_family-id'] || '' }}"
57
+ source_adapter: epo
58
+ source_url: "${{ 'https://worldwide.espacenet.com/patent/search/family/' + (item['@_family-id'] || '') }}"
59
+ retrieved_at: ""
60
+
61
+ columns: [publication_number, family_id]
62
+
63
+ # schema-v2 metadata
64
+ capabilities: ["http.fetch", "patent.family"]
65
+ minimum_capability: http.fetch
66
+ trust: public
67
+ confidentiality: public
68
+ quarantine: false
69
+ schema_version: v2
@@ -0,0 +1,74 @@
1
+ # @owner src::adapters::epo::get
2
+ # @does Fetch DOCDB biblio for a single EPO publication number via Open Patent Services v3.2.
3
+ # @needs src/engine/steps/oauth2-token.ts, src/engine/steps/fetch.ts, src/engine/steps/select-xml.ts, src/engine/steps/map.ts
4
+ # @feeds src/commands/patent.ts
5
+ # @breaks throws PipelineError on token failure, 404 (unknown publication), 401/403, 5xx
6
+ # @invariants output row conforms to PatentRecord
7
+ # @side-effects reads EPO OAuth2 credentials; HTTPS to ops.epo.org
8
+ # @perf two HTTPS requests (token + data); cached token
9
+ # @concurrency safe
10
+ # @test none yet
11
+ # @stability stable
12
+ # @since 2026-05-18
13
+ # @verification blocked-by-key
14
+ site: epo
15
+ name: get
16
+ description: Fetch EPO DOCDB biblio for a single publication number
17
+ domain: ops.epo.org
18
+ type: web-api
19
+ strategy: public
20
+ lint_listing_detail: skip
21
+
22
+ args:
23
+ publication_number:
24
+ type: str
25
+ required: true
26
+ positional: true
27
+ description: Publication number in epodoc format (e.g. EP.4123456.A1 or US.20240123456.A1)
28
+
29
+ pipeline:
30
+ - oauth2-token:
31
+ site: epo
32
+ token_url: https://ops.epo.org/3.2/auth/accesstoken
33
+ client_id_env: EPO_OPS_CLIENT_ID
34
+ client_secret_env: EPO_OPS_CLIENT_SECRET
35
+
36
+ - fetch:
37
+ url: "https://ops.epo.org/3.2/rest-services/published-data/publication/epodoc/${{ args.publication_number | urlencode }}/biblio"
38
+ method: GET
39
+ headers:
40
+ Authorization: "Bearer ${{ auth.bearer || '' }}"
41
+ Accept: application/xml
42
+
43
+ - select-xml:
44
+ xpath: "//ops:exchange-document"
45
+ namespaces:
46
+ ops: "http://ops.epo.org"
47
+
48
+ # Same DOCDB envelope as search; richer biblio fields are present.
49
+ - map:
50
+ publication_number: "${{ ((item['bibliographic-data'] && item['bibliographic-data']['publication-reference'] && item['bibliographic-data']['publication-reference']['document-id']) ? (item['bibliographic-data']['publication-reference']['document-id'].country + '-' + item['bibliographic-data']['publication-reference']['document-id']['doc-number'] + '-' + (item['bibliographic-data']['publication-reference']['document-id'].kind || '')) : (args.publication_number || '')) }}"
51
+ application_number: "${{ ((item['bibliographic-data'] && item['bibliographic-data']['application-reference'] && item['bibliographic-data']['application-reference']['document-id']) ? (item['bibliographic-data']['application-reference']['document-id'].country + '-' + item['bibliographic-data']['application-reference']['document-id']['doc-number'] + '-' + (item['bibliographic-data']['application-reference']['document-id'].kind || '')) : '') }}"
52
+ title: "${{ (function(t){ if(!t) return ''; if(Array.isArray(t)){ var en=t.find(x=>x['@_lang']==='en'); return en ? (en['#text']||en) : (t[0]['#text']||t[0]); } return t['#text']||t; })(item['bibliographic-data'] ? item['bibliographic-data']['invention-title'] : null) }}"
53
+ abstract: "${{ (function(a){ if(!a) return ''; if(Array.isArray(a)){ var en=a.find(x=>x['@_lang']==='en'); return en ? ((en.p ? (en.p['#text']||en.p) : (en['#text']||en))) : ''; } return a.p ? (a.p['#text']||a.p) : (a['#text']||a); })(item.abstract) }}"
54
+ kind_code: "${{ (item['bibliographic-data'] && item['bibliographic-data']['publication-reference'] && item['bibliographic-data']['publication-reference']['document-id']) ? (item['bibliographic-data']['publication-reference']['document-id'].kind || '') : '' }}"
55
+ publication_date: "${{ (function(d){ if(!d) return ''; var s=String(d); return s.length===8 ? (s.slice(0,4)+'-'+s.slice(4,6)+'-'+s.slice(6,8)) : s; })((item['bibliographic-data'] && item['bibliographic-data']['publication-reference'] && item['bibliographic-data']['publication-reference']['document-id']) ? item['bibliographic-data']['publication-reference']['document-id'].date : '') }}"
56
+ filing_date: "${{ (function(d){ if(!d) return ''; var s=String(d); return s.length===8 ? (s.slice(0,4)+'-'+s.slice(4,6)+'-'+s.slice(6,8)) : s; })((item['bibliographic-data'] && item['bibliographic-data']['application-reference'] && item['bibliographic-data']['application-reference']['document-id']) ? item['bibliographic-data']['application-reference']['document-id'].date : '') }}"
57
+ priority_date: "${{ (function(){ var pc = item['bibliographic-data'] && item['bibliographic-data']['priority-claims']; if(!pc || !pc['priority-claim']) return ''; var arr = Array.isArray(pc['priority-claim']) ? pc['priority-claim'] : [pc['priority-claim']]; for (var i=0;i<arr.length;i++){ var did = arr[i]['document-id']; if(Array.isArray(did)){ for (var j=0;j<did.length;j++){ if(did[j].date){ var s=String(did[j].date); return s.length===8 ? (s.slice(0,4)+'-'+s.slice(4,6)+'-'+s.slice(6,8)) : s; } } } else if(did && did.date){ var s=String(did.date); return s.length===8 ? (s.slice(0,4)+'-'+s.slice(4,6)+'-'+s.slice(6,8)) : s; } } return ''; })() }}"
58
+ inventors: "${{ JSON.stringify((function(){ var p=item['bibliographic-data'] && item['bibliographic-data'].parties; if(!p || !p.inventors || !p.inventors.inventor) return []; var arr = Array.isArray(p.inventors.inventor) ? p.inventors.inventor : [p.inventors.inventor]; return arr.map(i => ({ name: (i['inventor-name'] && (i['inventor-name'].name || i['inventor-name']['#text'])) || '' })).filter(x => x.name); })()) }}"
59
+ assignees: "${{ JSON.stringify((function(){ var p=item['bibliographic-data'] && item['bibliographic-data'].parties; if(!p || !p.applicants || !p.applicants.applicant) return []; var arr = Array.isArray(p.applicants.applicant) ? p.applicants.applicant : [p.applicants.applicant]; return arr.map(i => ({ name: (i['applicant-name'] && (i['applicant-name'].name || i['applicant-name']['#text'])) || '' })).filter(x => x.name); })()) }}"
60
+ classifications: "${{ JSON.stringify((function(){ var bd = item['bibliographic-data']; if(!bd) return []; var out = []; var ipcr = bd['classifications-ipcr'] && bd['classifications-ipcr']['classification-ipcr']; if(ipcr){ var arr = Array.isArray(ipcr) ? ipcr : [ipcr]; for (var i=0;i<arr.length;i++) out.push({ scheme: 'ipc', code: arr[i].text || arr[i]['#text'] || '' }); } var pc = bd['patent-classifications'] && bd['patent-classifications']['patent-classification']; if(pc){ var arr2 = Array.isArray(pc) ? pc : [pc]; for (var i=0;i<arr2.length;i++){ var c=arr2[i]; var scheme=(c['classification-scheme'] && (c['classification-scheme']['@_scheme']||'')).toLowerCase()||'cpc'; var section=(c.section||'')+(c.class||'')+(c.subclass||''); var main=(c['main-group']||'')+(c['subgroup']?'/'+c.subgroup:''); out.push({ scheme: scheme, code: (section+main) }); } } return out.filter(x => x.code); })()) }}"
61
+ family_id: "${{ item['@_family-id'] || '' }}"
62
+ source_adapter: epo
63
+ source_url: "${{ 'https://worldwide.espacenet.com/patent/search/publication/' + (args.publication_number || '') }}"
64
+ retrieved_at: ""
65
+
66
+ columns: [publication_number, title]
67
+
68
+ # schema-v2 metadata
69
+ capabilities: ["http.fetch", "patent.get"]
70
+ minimum_capability: http.fetch
71
+ trust: public
72
+ confidentiality: public
73
+ quarantine: false
74
+ schema_version: v2