@zenalexa/unicli 0.220.0 → 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 (626) hide show
  1. package/AGENTS.md +35 -22
  2. package/README.md +23 -17
  3. package/README.zh-CN.md +23 -17
  4. package/dist/adapters/anilist/web.d.ts +11 -0
  5. package/dist/adapters/anilist/web.d.ts.map +1 -0
  6. package/dist/adapters/anilist/web.js +284 -0
  7. package/dist/adapters/anilist/web.js.map +1 -0
  8. package/dist/adapters/bangumi/web.d.ts +14 -0
  9. package/dist/adapters/bangumi/web.d.ts.map +1 -0
  10. package/dist/adapters/bangumi/web.js +257 -0
  11. package/dist/adapters/bangumi/web.js.map +1 -0
  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/dlsite/web.d.ts +31 -0
  54. package/dist/adapters/dlsite/web.d.ts.map +1 -0
  55. package/dist/adapters/dlsite/web.js +455 -0
  56. package/dist/adapters/dlsite/web.js.map +1 -0
  57. package/dist/adapters/ehentai/web.d.ts +66 -0
  58. package/dist/adapters/ehentai/web.d.ts.map +1 -0
  59. package/dist/adapters/ehentai/web.js +608 -0
  60. package/dist/adapters/ehentai/web.js.map +1 -0
  61. package/dist/adapters/espacenet/_shared.d.ts +21 -0
  62. package/dist/adapters/espacenet/_shared.d.ts.map +1 -0
  63. package/dist/adapters/espacenet/_shared.js +67 -0
  64. package/dist/adapters/espacenet/_shared.js.map +1 -0
  65. package/dist/adapters/espacenet/family.d.ts +19 -0
  66. package/dist/adapters/espacenet/family.d.ts.map +1 -0
  67. package/dist/adapters/espacenet/family.js +118 -0
  68. package/dist/adapters/espacenet/family.js.map +1 -0
  69. package/dist/adapters/espacenet/get.d.ts +19 -0
  70. package/dist/adapters/espacenet/get.d.ts.map +1 -0
  71. package/dist/adapters/espacenet/get.js +130 -0
  72. package/dist/adapters/espacenet/get.js.map +1 -0
  73. package/dist/adapters/espacenet/legal-status.d.ts +19 -0
  74. package/dist/adapters/espacenet/legal-status.d.ts.map +1 -0
  75. package/dist/adapters/espacenet/legal-status.js +110 -0
  76. package/dist/adapters/espacenet/legal-status.js.map +1 -0
  77. package/dist/adapters/espacenet/search.d.ts +20 -0
  78. package/dist/adapters/espacenet/search.d.ts.map +1 -0
  79. package/dist/adapters/espacenet/search.js +165 -0
  80. package/dist/adapters/espacenet/search.js.map +1 -0
  81. package/dist/adapters/facebook/subtitles.d.ts +9 -0
  82. package/dist/adapters/facebook/subtitles.d.ts.map +1 -0
  83. package/dist/adapters/facebook/subtitles.js +42 -0
  84. package/dist/adapters/facebook/subtitles.js.map +1 -0
  85. package/dist/adapters/fips/_shared.d.ts +21 -0
  86. package/dist/adapters/fips/_shared.d.ts.map +1 -0
  87. package/dist/adapters/fips/_shared.js +77 -0
  88. package/dist/adapters/fips/_shared.js.map +1 -0
  89. package/dist/adapters/fips/get.d.ts +19 -0
  90. package/dist/adapters/fips/get.d.ts.map +1 -0
  91. package/dist/adapters/fips/get.js +139 -0
  92. package/dist/adapters/fips/get.js.map +1 -0
  93. package/dist/adapters/fips/search.d.ts +20 -0
  94. package/dist/adapters/fips/search.d.ts.map +1 -0
  95. package/dist/adapters/fips/search.js +148 -0
  96. package/dist/adapters/fips/search.js.map +1 -0
  97. package/dist/adapters/freepatentsonline-web/_shared.d.ts +72 -0
  98. package/dist/adapters/freepatentsonline-web/_shared.d.ts.map +1 -0
  99. package/dist/adapters/freepatentsonline-web/_shared.js +216 -0
  100. package/dist/adapters/freepatentsonline-web/_shared.js.map +1 -0
  101. package/dist/adapters/freepatentsonline-web/get.d.ts +21 -0
  102. package/dist/adapters/freepatentsonline-web/get.d.ts.map +1 -0
  103. package/dist/adapters/freepatentsonline-web/get.js +127 -0
  104. package/dist/adapters/freepatentsonline-web/get.js.map +1 -0
  105. package/dist/adapters/freepatentsonline-web/search.d.ts +22 -0
  106. package/dist/adapters/freepatentsonline-web/search.d.ts.map +1 -0
  107. package/dist/adapters/freepatentsonline-web/search.js +149 -0
  108. package/dist/adapters/freepatentsonline-web/search.js.map +1 -0
  109. package/dist/adapters/google-patents-web/_shared.d.ts +110 -0
  110. package/dist/adapters/google-patents-web/_shared.d.ts.map +1 -0
  111. package/dist/adapters/google-patents-web/_shared.js +164 -0
  112. package/dist/adapters/google-patents-web/_shared.js.map +1 -0
  113. package/dist/adapters/google-patents-web/get.d.ts +36 -0
  114. package/dist/adapters/google-patents-web/get.d.ts.map +1 -0
  115. package/dist/adapters/google-patents-web/get.js +187 -0
  116. package/dist/adapters/google-patents-web/get.js.map +1 -0
  117. package/dist/adapters/google-patents-web/search.d.ts +23 -0
  118. package/dist/adapters/google-patents-web/search.d.ts.map +1 -0
  119. package/dist/adapters/google-patents-web/search.js +169 -0
  120. package/dist/adapters/google-patents-web/search.js.map +1 -0
  121. package/dist/adapters/inpi-br/_shared.d.ts +21 -0
  122. package/dist/adapters/inpi-br/_shared.d.ts.map +1 -0
  123. package/dist/adapters/inpi-br/_shared.js +67 -0
  124. package/dist/adapters/inpi-br/_shared.js.map +1 -0
  125. package/dist/adapters/inpi-br/get.d.ts +19 -0
  126. package/dist/adapters/inpi-br/get.d.ts.map +1 -0
  127. package/dist/adapters/inpi-br/get.js +142 -0
  128. package/dist/adapters/inpi-br/get.js.map +1 -0
  129. package/dist/adapters/inpi-br/search.d.ts +20 -0
  130. package/dist/adapters/inpi-br/search.d.ts.map +1 -0
  131. package/dist/adapters/inpi-br/search.js +154 -0
  132. package/dist/adapters/inpi-br/search.js.map +1 -0
  133. package/dist/adapters/instagram/subtitles.d.ts +9 -0
  134. package/dist/adapters/instagram/subtitles.d.ts.map +1 -0
  135. package/dist/adapters/instagram/subtitles.js +42 -0
  136. package/dist/adapters/instagram/subtitles.js.map +1 -0
  137. package/dist/adapters/jikan/web.d.ts +9 -0
  138. package/dist/adapters/jikan/web.d.ts.map +1 -0
  139. package/dist/adapters/jikan/web.js +154 -0
  140. package/dist/adapters/jikan/web.js.map +1 -0
  141. package/dist/adapters/kitsu/web.d.ts +9 -0
  142. package/dist/adapters/kitsu/web.d.ts.map +1 -0
  143. package/dist/adapters/kitsu/web.js +97 -0
  144. package/dist/adapters/kitsu/web.js.map +1 -0
  145. package/dist/adapters/mangadex/web.d.ts +10 -0
  146. package/dist/adapters/mangadex/web.d.ts.map +1 -0
  147. package/dist/adapters/mangadex/web.js +188 -0
  148. package/dist/adapters/mangadex/web.js.map +1 -0
  149. package/dist/adapters/mastodon/statuses.d.ts +40 -0
  150. package/dist/adapters/mastodon/statuses.d.ts.map +1 -0
  151. package/dist/adapters/mastodon/statuses.js +153 -0
  152. package/dist/adapters/mastodon/statuses.js.map +1 -0
  153. package/dist/adapters/moegirl/web.d.ts +23 -0
  154. package/dist/adapters/moegirl/web.d.ts.map +1 -0
  155. package/dist/adapters/moegirl/web.js +269 -0
  156. package/dist/adapters/moegirl/web.js.map +1 -0
  157. package/dist/adapters/reddit/comments.d.ts +9 -0
  158. package/dist/adapters/reddit/comments.d.ts.map +1 -0
  159. package/dist/adapters/reddit/comments.js +124 -0
  160. package/dist/adapters/reddit/comments.js.map +1 -0
  161. package/dist/adapters/safebooru/web.d.ts +10 -0
  162. package/dist/adapters/safebooru/web.d.ts.map +1 -0
  163. package/dist/adapters/safebooru/web.js +120 -0
  164. package/dist/adapters/safebooru/web.js.map +1 -0
  165. package/dist/adapters/threads/post.d.ts +32 -0
  166. package/dist/adapters/threads/post.d.ts.map +1 -0
  167. package/dist/adapters/threads/post.js +287 -0
  168. package/dist/adapters/threads/post.js.map +1 -0
  169. package/dist/adapters/tiktok/subtitles.d.ts +9 -0
  170. package/dist/adapters/tiktok/subtitles.d.ts.map +1 -0
  171. package/dist/adapters/tiktok/subtitles.js +42 -0
  172. package/dist/adapters/tiktok/subtitles.js.map +1 -0
  173. package/dist/adapters/twitter/accept.js +2 -2
  174. package/dist/adapters/twitter/accept.js.map +1 -1
  175. package/dist/adapters/twitter/browser-fallback.d.ts +26 -0
  176. package/dist/adapters/twitter/browser-fallback.d.ts.map +1 -0
  177. package/dist/adapters/twitter/browser-fallback.js +93 -0
  178. package/dist/adapters/twitter/browser-fallback.js.map +1 -0
  179. package/dist/adapters/twitter/browser-state.d.ts +11 -0
  180. package/dist/adapters/twitter/browser-state.d.ts.map +1 -0
  181. package/dist/adapters/twitter/browser-state.js +46 -0
  182. package/dist/adapters/twitter/browser-state.js.map +1 -0
  183. package/dist/adapters/twitter/client.d.ts.map +1 -1
  184. package/dist/adapters/twitter/client.js +36 -13
  185. package/dist/adapters/twitter/client.js.map +1 -1
  186. package/dist/adapters/twitter/reply-dm.js +2 -2
  187. package/dist/adapters/twitter/reply-dm.js.map +1 -1
  188. package/dist/adapters/twitter/reply.js +1 -0
  189. package/dist/adapters/twitter/reply.js.map +1 -1
  190. package/dist/adapters/twitter/search.js +11 -18
  191. package/dist/adapters/twitter/search.js.map +1 -1
  192. package/dist/adapters/twitter/thread.d.ts +14 -0
  193. package/dist/adapters/twitter/thread.d.ts.map +1 -1
  194. package/dist/adapters/twitter/thread.js +28 -2
  195. package/dist/adapters/twitter/thread.js.map +1 -1
  196. package/dist/adapters/twitter/trending.js +13 -59
  197. package/dist/adapters/twitter/trending.js.map +1 -1
  198. package/dist/adapters/vndb/web.d.ts +10 -0
  199. package/dist/adapters/vndb/web.d.ts.map +1 -0
  200. package/dist/adapters/vndb/web.js +321 -0
  201. package/dist/adapters/vndb/web.js.map +1 -0
  202. package/dist/adapters/xiaohongshu/browser-state.d.ts +19 -0
  203. package/dist/adapters/xiaohongshu/browser-state.d.ts.map +1 -0
  204. package/dist/adapters/xiaohongshu/browser-state.js +67 -0
  205. package/dist/adapters/xiaohongshu/browser-state.js.map +1 -0
  206. package/dist/adapters/xiaohongshu/comments.js +28 -5
  207. package/dist/adapters/xiaohongshu/comments.js.map +1 -1
  208. package/dist/adapters/xiaohongshu/download.js +49 -11
  209. package/dist/adapters/xiaohongshu/download.js.map +1 -1
  210. package/dist/adapters/xiaohongshu/search.d.ts.map +1 -1
  211. package/dist/adapters/xiaohongshu/search.js +11 -5
  212. package/dist/adapters/xiaohongshu/search.js.map +1 -1
  213. package/dist/adapters/xiaohongshu/trending.d.ts +9 -0
  214. package/dist/adapters/xiaohongshu/trending.d.ts.map +1 -0
  215. package/dist/adapters/xiaohongshu/trending.js +94 -0
  216. package/dist/adapters/xiaohongshu/trending.js.map +1 -0
  217. package/dist/adapters/youtube/comments.d.ts +80 -0
  218. package/dist/adapters/youtube/comments.d.ts.map +1 -1
  219. package/dist/adapters/youtube/comments.js +108 -12
  220. package/dist/adapters/youtube/comments.js.map +1 -1
  221. package/dist/adapters/youtube/subtitles.d.ts +9 -0
  222. package/dist/adapters/youtube/subtitles.d.ts.map +1 -0
  223. package/dist/adapters/youtube/subtitles.js +42 -0
  224. package/dist/adapters/youtube/subtitles.js.map +1 -0
  225. package/dist/adapters/yt-dlp/subtitles.d.ts +9 -0
  226. package/dist/adapters/yt-dlp/subtitles.d.ts.map +1 -0
  227. package/dist/adapters/yt-dlp/subtitles.js +41 -0
  228. package/dist/adapters/yt-dlp/subtitles.js.map +1 -0
  229. package/dist/adapters/zhihu/answer-detail.d.ts +39 -0
  230. package/dist/adapters/zhihu/answer-detail.d.ts.map +1 -0
  231. package/dist/adapters/zhihu/answer-detail.js +204 -0
  232. package/dist/adapters/zhihu/answer-detail.js.map +1 -0
  233. package/dist/adapters/zhihu/comment.d.ts +9 -0
  234. package/dist/adapters/zhihu/comment.d.ts.map +1 -0
  235. package/dist/adapters/zhihu/comment.js +149 -0
  236. package/dist/adapters/zhihu/comment.js.map +1 -0
  237. package/dist/adapters/zhihu/recommend.d.ts +36 -0
  238. package/dist/adapters/zhihu/recommend.d.ts.map +1 -0
  239. package/dist/adapters/zhihu/recommend.js +151 -0
  240. package/dist/adapters/zhihu/recommend.js.map +1 -0
  241. package/dist/agents/codex-pack.d.ts +62 -0
  242. package/dist/agents/codex-pack.d.ts.map +1 -0
  243. package/dist/agents/codex-pack.js +163 -0
  244. package/dist/agents/codex-pack.js.map +1 -0
  245. package/dist/browser/bridge.d.ts.map +1 -1
  246. package/dist/browser/bridge.js +14 -3
  247. package/dist/browser/bridge.js.map +1 -1
  248. package/dist/browser/daemon-client.d.ts +6 -0
  249. package/dist/browser/daemon-client.d.ts.map +1 -1
  250. package/dist/browser/daemon-client.js +75 -15
  251. package/dist/browser/daemon-client.js.map +1 -1
  252. package/dist/browser/daemon.js +39 -15
  253. package/dist/browser/daemon.js.map +1 -1
  254. package/dist/browser/protocol.d.ts +1 -0
  255. package/dist/browser/protocol.d.ts.map +1 -1
  256. package/dist/browser/protocol.js +1 -0
  257. package/dist/browser/protocol.js.map +1 -1
  258. package/dist/cli.d.ts.map +1 -1
  259. package/dist/cli.js +6 -0
  260. package/dist/cli.js.map +1 -1
  261. package/dist/commands/agents.d.ts.map +1 -1
  262. package/dist/commands/agents.js +6 -43
  263. package/dist/commands/agents.js.map +1 -1
  264. package/dist/commands/approvals.d.ts.map +1 -1
  265. package/dist/commands/approvals.js +1 -37
  266. package/dist/commands/approvals.js.map +1 -1
  267. package/dist/commands/browser/adapter.d.ts.map +1 -1
  268. package/dist/commands/browser/adapter.js +17 -3
  269. package/dist/commands/browser/adapter.js.map +1 -1
  270. package/dist/commands/browser/index.d.ts.map +1 -1
  271. package/dist/commands/browser/index.js +7 -2
  272. package/dist/commands/browser/index.js.map +1 -1
  273. package/dist/commands/daemon.d.ts.map +1 -1
  274. package/dist/commands/daemon.js +7 -3
  275. package/dist/commands/daemon.js.map +1 -1
  276. package/dist/commands/describe.d.ts.map +1 -1
  277. package/dist/commands/describe.js +6 -7
  278. package/dist/commands/describe.js.map +1 -1
  279. package/dist/commands/dispatch.d.ts +1 -1
  280. package/dist/commands/dispatch.d.ts.map +1 -1
  281. package/dist/commands/dispatch.js +31 -5
  282. package/dist/commands/dispatch.js.map +1 -1
  283. package/dist/commands/mcp.d.ts +1 -1
  284. package/dist/commands/mcp.d.ts.map +1 -1
  285. package/dist/commands/mcp.js +10 -5
  286. package/dist/commands/mcp.js.map +1 -1
  287. package/dist/commands/patent-doctor.d.ts +48 -0
  288. package/dist/commands/patent-doctor.d.ts.map +1 -0
  289. package/dist/commands/patent-doctor.js +109 -0
  290. package/dist/commands/patent-doctor.js.map +1 -0
  291. package/dist/commands/patent.d.ts +78 -0
  292. package/dist/commands/patent.d.ts.map +1 -0
  293. package/dist/commands/patent.js +919 -0
  294. package/dist/commands/patent.js.map +1 -0
  295. package/dist/commands/social.d.ts +19 -0
  296. package/dist/commands/social.d.ts.map +1 -0
  297. package/dist/commands/social.js +236 -0
  298. package/dist/commands/social.js.map +1 -0
  299. package/dist/core/command-contract-lint.d.ts +10 -0
  300. package/dist/core/command-contract-lint.d.ts.map +1 -0
  301. package/dist/core/command-contract-lint.js +41 -0
  302. package/dist/core/command-contract-lint.js.map +1 -0
  303. package/dist/core/command-contract.d.ts +100 -0
  304. package/dist/core/command-contract.d.ts.map +1 -0
  305. package/dist/core/command-contract.js +174 -0
  306. package/dist/core/command-contract.js.map +1 -0
  307. package/dist/core/index.d.ts +2 -0
  308. package/dist/core/index.d.ts.map +1 -1
  309. package/dist/core/index.js +2 -0
  310. package/dist/core/index.js.map +1 -1
  311. package/dist/core/registry.d.ts +1 -1
  312. package/dist/core/registry.d.ts.map +1 -1
  313. package/dist/core/registry.js +11 -2
  314. package/dist/core/registry.js.map +1 -1
  315. package/dist/discovery/aliases.d.ts +2 -2
  316. package/dist/discovery/aliases.d.ts.map +1 -1
  317. package/dist/discovery/aliases.js +464 -6
  318. package/dist/discovery/aliases.js.map +1 -1
  319. package/dist/discovery/loader.d.ts.map +1 -1
  320. package/dist/discovery/loader.js +4 -0
  321. package/dist/discovery/loader.js.map +1 -1
  322. package/dist/discovery/search.d.ts.map +1 -1
  323. package/dist/discovery/search.js +147 -2
  324. package/dist/discovery/search.js.map +1 -1
  325. package/dist/engine/approval-presenter.d.ts +10 -0
  326. package/dist/engine/approval-presenter.d.ts.map +1 -0
  327. package/dist/engine/approval-presenter.js +45 -0
  328. package/dist/engine/approval-presenter.js.map +1 -0
  329. package/dist/engine/approval-store.d.ts +4 -0
  330. package/dist/engine/approval-store.d.ts.map +1 -1
  331. package/dist/engine/approval-store.js +85 -11
  332. package/dist/engine/approval-store.js.map +1 -1
  333. package/dist/engine/args.d.ts.map +1 -1
  334. package/dist/engine/args.js +18 -1
  335. package/dist/engine/args.js.map +1 -1
  336. package/dist/engine/artifact-validation.d.ts +29 -0
  337. package/dist/engine/artifact-validation.d.ts.map +1 -0
  338. package/dist/engine/artifact-validation.js +211 -0
  339. package/dist/engine/artifact-validation.js.map +1 -0
  340. package/dist/engine/auth/oauth2-cc.d.ts +67 -0
  341. package/dist/engine/auth/oauth2-cc.d.ts.map +1 -0
  342. package/dist/engine/auth/oauth2-cc.js +120 -0
  343. package/dist/engine/auth/oauth2-cc.js.map +1 -0
  344. package/dist/engine/browser/diagnostics.d.ts +38 -0
  345. package/dist/engine/browser/diagnostics.d.ts.map +1 -0
  346. package/dist/engine/browser/diagnostics.js +40 -0
  347. package/dist/engine/browser/diagnostics.js.map +1 -0
  348. package/dist/engine/cookies.d.ts +10 -0
  349. package/dist/engine/cookies.d.ts.map +1 -1
  350. package/dist/engine/cookies.js +64 -0
  351. package/dist/engine/cookies.js.map +1 -1
  352. package/dist/engine/download.d.ts +5 -0
  353. package/dist/engine/download.d.ts.map +1 -1
  354. package/dist/engine/download.js +11 -4
  355. package/dist/engine/download.js.map +1 -1
  356. package/dist/engine/executor.d.ts +1 -0
  357. package/dist/engine/executor.d.ts.map +1 -1
  358. package/dist/engine/executor.js +25 -0
  359. package/dist/engine/executor.js.map +1 -1
  360. package/dist/engine/framework.d.ts +5 -5
  361. package/dist/engine/framework.js +5 -5
  362. package/dist/engine/harden.d.ts +1 -1
  363. package/dist/engine/harden.js +1 -1
  364. package/dist/engine/invoke.d.ts +1 -0
  365. package/dist/engine/invoke.d.ts.map +1 -1
  366. package/dist/engine/invoke.js +1 -0
  367. package/dist/engine/invoke.js.map +1 -1
  368. package/dist/engine/kernel/errors.d.ts +11 -0
  369. package/dist/engine/kernel/errors.d.ts.map +1 -0
  370. package/dist/engine/kernel/errors.js +15 -0
  371. package/dist/engine/kernel/errors.js.map +1 -0
  372. package/dist/engine/kernel/execute.d.ts +7 -18
  373. package/dist/engine/kernel/execute.d.ts.map +1 -1
  374. package/dist/engine/kernel/execute.js +25 -410
  375. package/dist/engine/kernel/execute.js.map +1 -1
  376. package/dist/engine/kernel/stages.d.ts +44 -0
  377. package/dist/engine/kernel/stages.d.ts.map +1 -0
  378. package/dist/engine/kernel/stages.js +429 -0
  379. package/dist/engine/kernel/stages.js.map +1 -0
  380. package/dist/engine/kernel/types.d.ts +21 -1
  381. package/dist/engine/kernel/types.d.ts.map +1 -1
  382. package/dist/engine/normalizer/patent-envelope.d.ts +61 -0
  383. package/dist/engine/normalizer/patent-envelope.d.ts.map +1 -0
  384. package/dist/engine/normalizer/patent-envelope.js +132 -0
  385. package/dist/engine/normalizer/patent-envelope.js.map +1 -0
  386. package/dist/engine/research.d.ts +5 -7
  387. package/dist/engine/research.d.ts.map +1 -1
  388. package/dist/engine/research.js +6 -9
  389. package/dist/engine/research.js.map +1 -1
  390. package/dist/engine/steps/browser-helpers.d.ts +2 -2
  391. package/dist/engine/steps/browser-helpers.d.ts.map +1 -1
  392. package/dist/engine/steps/browser-helpers.js +39 -16
  393. package/dist/engine/steps/browser-helpers.js.map +1 -1
  394. package/dist/engine/steps/download.d.ts +2 -0
  395. package/dist/engine/steps/download.d.ts.map +1 -1
  396. package/dist/engine/steps/download.js +13 -7
  397. package/dist/engine/steps/download.js.map +1 -1
  398. package/dist/engine/steps/index.d.ts +2 -0
  399. package/dist/engine/steps/index.d.ts.map +1 -1
  400. package/dist/engine/steps/index.js +2 -0
  401. package/dist/engine/steps/index.js.map +1 -1
  402. package/dist/engine/steps/oauth2-token.d.ts +41 -0
  403. package/dist/engine/steps/oauth2-token.d.ts.map +1 -0
  404. package/dist/engine/steps/oauth2-token.js +115 -0
  405. package/dist/engine/steps/oauth2-token.js.map +1 -0
  406. package/dist/engine/steps/select-xml.d.ts +34 -0
  407. package/dist/engine/steps/select-xml.d.ts.map +1 -0
  408. package/dist/engine/steps/select-xml.js +222 -0
  409. package/dist/engine/steps/select-xml.js.map +1 -0
  410. package/dist/engine/template.d.ts.map +1 -1
  411. package/dist/engine/template.js +7 -0
  412. package/dist/engine/template.js.map +1 -1
  413. package/dist/engine/transport/mcp-browser.d.ts +128 -0
  414. package/dist/engine/transport/mcp-browser.d.ts.map +1 -0
  415. package/dist/engine/transport/mcp-browser.js +120 -0
  416. package/dist/engine/transport/mcp-browser.js.map +1 -0
  417. package/dist/fast-path/handlers/approvals.d.ts +11 -0
  418. package/dist/fast-path/handlers/approvals.d.ts.map +1 -0
  419. package/dist/fast-path/handlers/approvals.js +136 -0
  420. package/dist/fast-path/handlers/approvals.js.map +1 -0
  421. package/dist/fast-path/manifest.d.ts +1 -0
  422. package/dist/fast-path/manifest.d.ts.map +1 -1
  423. package/dist/fast-path/manifest.js.map +1 -1
  424. package/dist/fast-path/render.js +1 -1
  425. package/dist/fast-path/render.js.map +1 -1
  426. package/dist/fast-path.d.ts.map +1 -1
  427. package/dist/fast-path.js +3 -0
  428. package/dist/fast-path.js.map +1 -1
  429. package/dist/index.d.ts +23 -0
  430. package/dist/index.d.ts.map +1 -0
  431. package/dist/index.js +38 -0
  432. package/dist/index.js.map +1 -0
  433. package/dist/manifest-compact.txt +5 -5
  434. package/dist/manifest-search.json +1 -1
  435. package/dist/manifest.json +5189 -55
  436. package/dist/mcp/handler.d.ts.map +1 -1
  437. package/dist/mcp/handler.js +11 -1
  438. package/dist/mcp/handler.js.map +1 -1
  439. package/dist/mcp/server.d.ts +1 -1
  440. package/dist/mcp/server.js +1 -1
  441. package/dist/mcp/tools.d.ts.map +1 -1
  442. package/dist/mcp/tools.js +18 -10
  443. package/dist/mcp/tools.js.map +1 -1
  444. package/dist/output/auth-guidance.d.ts +14 -0
  445. package/dist/output/auth-guidance.d.ts.map +1 -0
  446. package/dist/output/auth-guidance.js +50 -0
  447. package/dist/output/auth-guidance.js.map +1 -0
  448. package/dist/output/error-map.d.ts +1 -1
  449. package/dist/output/error-map.d.ts.map +1 -1
  450. package/dist/output/error-map.js +29 -5
  451. package/dist/output/error-map.js.map +1 -1
  452. package/dist/output/next-actions.d.ts.map +1 -1
  453. package/dist/output/next-actions.js +19 -3
  454. package/dist/output/next-actions.js.map +1 -1
  455. package/dist/registry.d.ts +18 -1
  456. package/dist/registry.d.ts.map +1 -1
  457. package/dist/registry.js +7 -1
  458. package/dist/registry.js.map +1 -1
  459. package/dist/social/browser-errors.d.ts +13 -0
  460. package/dist/social/browser-errors.d.ts.map +1 -0
  461. package/dist/social/browser-errors.js +36 -0
  462. package/dist/social/browser-errors.js.map +1 -0
  463. package/dist/social/capabilities.d.ts +29 -0
  464. package/dist/social/capabilities.d.ts.map +1 -0
  465. package/dist/social/capabilities.js +448 -0
  466. package/dist/social/capabilities.js.map +1 -0
  467. package/dist/social/comments.d.ts +26 -0
  468. package/dist/social/comments.d.ts.map +1 -0
  469. package/dist/social/comments.js +97 -0
  470. package/dist/social/comments.js.map +1 -0
  471. package/dist/social/video-text.d.ts +27 -0
  472. package/dist/social/video-text.d.ts.map +1 -0
  473. package/dist/social/video-text.js +140 -0
  474. package/dist/social/video-text.js.map +1 -0
  475. package/dist/types/patent.d.ts +160 -0
  476. package/dist/types/patent.d.ts.map +1 -0
  477. package/dist/types/patent.js +16 -0
  478. package/dist/types/patent.js.map +1 -0
  479. package/dist/types.d.ts +12 -0
  480. package/dist/types.d.ts.map +1 -1
  481. package/dist/types.js.map +1 -1
  482. package/package.json +10 -5
  483. package/server.json +3 -3
  484. package/skills/unicli/SKILL.md +1 -1
  485. package/skills/unicli-claude-code/SKILL.md +1 -1
  486. package/skills/unicli-hermes/SKILL.md +1 -1
  487. package/src/adapters/anilist/web.test.ts +93 -0
  488. package/src/adapters/anilist/web.ts +341 -0
  489. package/src/adapters/arxiv/download.yaml +53 -0
  490. package/src/adapters/bangumi/web.test.ts +109 -0
  491. package/src/adapters/bangumi/web.ts +295 -0
  492. package/src/adapters/bilibili/comments-tree.test.ts +41 -0
  493. package/src/adapters/bilibili/comments.ts +78 -4
  494. package/src/adapters/bilibili/compat.ts +5 -2
  495. package/src/adapters/bilibili/download.ts +7 -4
  496. package/src/adapters/bilibili/wbi.ts +6 -3
  497. package/src/adapters/brave/search.yaml +53 -0
  498. package/src/adapters/cipo/_shared.ts +98 -0
  499. package/src/adapters/cipo/get.ts +188 -0
  500. package/src/adapters/cipo/legal-status.ts +148 -0
  501. package/src/adapters/cipo/search.ts +195 -0
  502. package/src/adapters/cnipa/_shared.ts +138 -0
  503. package/src/adapters/cnipa/get.ts +199 -0
  504. package/src/adapters/cnipa/legal-status.ts +162 -0
  505. package/src/adapters/cnipa/search.ts +229 -0
  506. package/src/adapters/danbooru/artists.yaml +44 -0
  507. package/src/adapters/danbooru/comments.yaml +45 -0
  508. package/src/adapters/danbooru/detail.yaml +78 -0
  509. package/src/adapters/danbooru/download.yaml +51 -0
  510. package/src/adapters/danbooru/pools.yaml +56 -0
  511. package/src/adapters/danbooru/search.yaml +69 -0
  512. package/src/adapters/danbooru/tags.yaml +42 -0
  513. package/src/adapters/danbooru/wiki.yaml +44 -0
  514. package/src/adapters/dlsite/web.test.ts +132 -0
  515. package/src/adapters/dlsite/web.ts +557 -0
  516. package/src/adapters/dpma/get.yaml +67 -0
  517. package/src/adapters/dpma/search.yaml +77 -0
  518. package/src/adapters/duckduckgo/search.yaml +54 -0
  519. package/src/adapters/duckduckgo/suggest.yaml +52 -0
  520. package/src/adapters/ehentai/web.test.ts +157 -0
  521. package/src/adapters/ehentai/web.ts +750 -0
  522. package/src/adapters/epo/family.yaml +69 -0
  523. package/src/adapters/epo/get.yaml +74 -0
  524. package/src/adapters/epo/legal-status.yaml +63 -0
  525. package/src/adapters/epo/search.yaml +84 -0
  526. package/src/adapters/espacenet/_shared.ts +98 -0
  527. package/src/adapters/espacenet/family.ts +161 -0
  528. package/src/adapters/espacenet/get.ts +185 -0
  529. package/src/adapters/espacenet/legal-status.ts +151 -0
  530. package/src/adapters/espacenet/search.ts +229 -0
  531. package/src/adapters/facebook/subtitles.ts +44 -0
  532. package/src/adapters/fips/_shared.ts +109 -0
  533. package/src/adapters/fips/get.ts +186 -0
  534. package/src/adapters/fips/search.ts +195 -0
  535. package/src/adapters/freepatentsonline-web/_shared.ts +273 -0
  536. package/src/adapters/freepatentsonline-web/get.ts +144 -0
  537. package/src/adapters/freepatentsonline-web/search.ts +170 -0
  538. package/src/adapters/google-patents-bq/prior-art.yaml +80 -0
  539. package/src/adapters/google-patents-bq/search.yaml +97 -0
  540. package/src/adapters/google-patents-web/_shared.ts +242 -0
  541. package/src/adapters/google-patents-web/get.ts +224 -0
  542. package/src/adapters/google-patents-web/search.ts +196 -0
  543. package/src/adapters/inpi-br/_shared.ts +98 -0
  544. package/src/adapters/inpi-br/get.ts +193 -0
  545. package/src/adapters/inpi-br/search.ts +206 -0
  546. package/src/adapters/inpi-fr/get.yaml +62 -0
  547. package/src/adapters/inpi-fr/search.yaml +74 -0
  548. package/src/adapters/instagram/subtitles.ts +44 -0
  549. package/src/adapters/ipaustralia/get.yaml +67 -0
  550. package/src/adapters/ipaustralia/search.yaml +74 -0
  551. package/src/adapters/jikan/web.test.ts +50 -0
  552. package/src/adapters/jikan/web.ts +177 -0
  553. package/src/adapters/jpo/get.yaml +63 -0
  554. package/src/adapters/jpo/search.yaml +76 -0
  555. package/src/adapters/kipris/get.yaml +69 -0
  556. package/src/adapters/kipris/legal-status.yaml +58 -0
  557. package/src/adapters/kipris/search.yaml +79 -0
  558. package/src/adapters/kitsu/web.test.ts +29 -0
  559. package/src/adapters/kitsu/web.ts +109 -0
  560. package/src/adapters/konachan/detail.yaml +62 -0
  561. package/src/adapters/konachan/download.yaml +55 -0
  562. package/src/adapters/konachan/search.yaml +65 -0
  563. package/src/adapters/konachan/tags.yaml +40 -0
  564. package/src/adapters/lens/get.yaml +64 -0
  565. package/src/adapters/lens/search.yaml +82 -0
  566. package/src/adapters/mangadex/web.test.ts +46 -0
  567. package/src/adapters/mangadex/web.ts +210 -0
  568. package/src/adapters/mastodon/statuses.test.ts +82 -0
  569. package/src/adapters/mastodon/statuses.ts +208 -0
  570. package/src/adapters/moegirl/web.test.ts +87 -0
  571. package/src/adapters/moegirl/web.ts +343 -0
  572. package/src/adapters/patsnap/get.yaml +65 -0
  573. package/src/adapters/patsnap/search.yaml +77 -0
  574. package/src/adapters/pdf/read.yaml +49 -0
  575. package/src/adapters/pixiv/download.yaml +15 -2
  576. package/src/adapters/pqai/prior-art.yaml +59 -0
  577. package/src/adapters/pqai/search.yaml +60 -0
  578. package/src/adapters/reddit/comments-tree.test.ts +79 -0
  579. package/src/adapters/reddit/comments.ts +159 -0
  580. package/src/adapters/safebooru/detail.yaml +63 -0
  581. package/src/adapters/safebooru/download.yaml +58 -0
  582. package/src/adapters/safebooru/search.yaml +69 -0
  583. package/src/adapters/safebooru/web.test.ts +60 -0
  584. package/src/adapters/safebooru/web.ts +130 -0
  585. package/src/adapters/threads/post.test.ts +64 -0
  586. package/src/adapters/threads/post.ts +366 -0
  587. package/src/adapters/threads/user.yaml +73 -0
  588. package/src/adapters/tiktok/subtitles.ts +44 -0
  589. package/src/adapters/twitter/accept.ts +5 -2
  590. package/src/adapters/twitter/browser-fallback.ts +138 -0
  591. package/src/adapters/twitter/browser-state.ts +74 -0
  592. package/src/adapters/twitter/client.ts +51 -21
  593. package/src/adapters/twitter/reply-dm.ts +5 -2
  594. package/src/adapters/twitter/reply.ts +1 -0
  595. package/src/adapters/twitter/search.ts +12 -38
  596. package/src/adapters/twitter/thread.test.ts +43 -0
  597. package/src/adapters/twitter/thread.ts +44 -2
  598. package/src/adapters/twitter/trending.ts +14 -95
  599. package/src/adapters/ukipo/info.yaml +43 -0
  600. package/src/adapters/uspto/get.yaml +67 -0
  601. package/src/adapters/uspto/legal-status.yaml +58 -0
  602. package/src/adapters/uspto/search.yaml +88 -0
  603. package/src/adapters/vndb/web.test.ts +86 -0
  604. package/src/adapters/vndb/web.ts +393 -0
  605. package/src/adapters/wipo-patentscope/info.yaml +43 -0
  606. package/src/adapters/xiaohongshu/browser-state.ts +95 -0
  607. package/src/adapters/xiaohongshu/comments.ts +29 -6
  608. package/src/adapters/xiaohongshu/download.ts +60 -11
  609. package/src/adapters/xiaohongshu/search.ts +18 -6
  610. package/src/adapters/xiaohongshu/trending.ts +112 -0
  611. package/src/adapters/yahoo/search.yaml +52 -0
  612. package/src/adapters/yandere/detail.yaml +61 -0
  613. package/src/adapters/yandere/download.yaml +56 -0
  614. package/src/adapters/yandere/search.yaml +67 -0
  615. package/src/adapters/yandere/tags.yaml +41 -0
  616. package/src/adapters/youtube/comments-microformat.test.ts +35 -0
  617. package/src/adapters/youtube/comments-tree.test.ts +74 -0
  618. package/src/adapters/youtube/comments.ts +166 -12
  619. package/src/adapters/youtube/subtitles.ts +44 -0
  620. package/src/adapters/yt-dlp/subtitles.ts +43 -0
  621. package/src/adapters/zhihu/answer-detail.test.ts +83 -0
  622. package/src/adapters/zhihu/answer-detail.ts +275 -0
  623. package/src/adapters/zhihu/comment-tree.test.ts +57 -0
  624. package/src/adapters/zhihu/comment.ts +186 -0
  625. package/src/adapters/zhihu/recommend.test.ts +65 -0
  626. package/src/adapters/zhihu/recommend.ts +207 -0
@@ -0,0 +1,199 @@
1
+ /**
2
+ * @owner src::adapters::cnipa::get
3
+ * @does Browser-driven retrieval of a single CNIPA patent document by publication number; loads the detail page through the mcp-browser transport and extracts the bibliographic fields into a PatentRecord.
4
+ * @needs src/engine/transport/mcp-browser.ts, src/engine/normalizer/patent-envelope.ts, src/adapters/cnipa/_shared.ts, src/registry.ts
5
+ * @feeds src/commands/patent.ts (capability tag patent.get)
6
+ * @breaks emits PATENT_INVALID_NUMBER when input is empty or fails canonicalization; emits PATENT_NOT_FOUND when the detail page returns no fields; PATENT_BROWSER_CAPTCHA when the page is captcha-gated; PATENT_API_DEPRECATED with MCP_BUS_MISSING context when no outbound MCP transport is registered
7
+ * @invariants output is a single PatentRecord row when the upstream answers; never falls back to a stub record
8
+ * @side-effects controls the user's Chrome via MCP
9
+ * @perf single navigate + one evaluate
10
+ * @concurrency safe
11
+ * @test tests/unit/adapters/cnipa/search.test.ts (transport-error path) — get-specific tests deferred to integration
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
+ cnipaEnvelope,
22
+ looksLikeCaptcha,
23
+ navigateAndExtract,
24
+ transportErrorToEnvelope,
25
+ } from "./_shared.js";
26
+
27
+ const ADAPTER_PATH = "src/adapters/cnipa/get.ts";
28
+ const CNIPA_DETAIL_URL =
29
+ "https://pss-system.cponline.cnipa.gov.cn/conventionalDetail";
30
+
31
+ interface CnipaDetail {
32
+ publication_number?: string;
33
+ application_number?: string;
34
+ title?: string;
35
+ abstract?: string;
36
+ applicant?: string;
37
+ inventor?: string;
38
+ publication_date?: string;
39
+ filing_date?: string;
40
+ grant_date?: string;
41
+ legal_status?: string;
42
+ source_url?: string;
43
+ html_marker?: string;
44
+ }
45
+
46
+ const DETAIL_EXTRACTOR = `(() => {
47
+ const text = (sel) => {
48
+ const node = document.querySelector(sel);
49
+ return node ? (node.textContent || '').trim() : '';
50
+ };
51
+ return {
52
+ publication_number: text('[data-field="pubNo"], .publication-number'),
53
+ application_number: text('[data-field="appNo"], .application-number'),
54
+ title: text('[data-field="title"], h1.title, .invention-title'),
55
+ abstract: text('[data-field="abstract"], .abstract'),
56
+ applicant: text('[data-field="applicant"], .applicant'),
57
+ inventor: text('[data-field="inventor"], .inventor'),
58
+ publication_date: text('[data-field="pubDate"], .publication-date'),
59
+ filing_date: text('[data-field="appDate"], .filing-date'),
60
+ grant_date: text('[data-field="grantDate"], .grant-date'),
61
+ legal_status: text('[data-field="legalStatus"], .legal-status'),
62
+ source_url: location.href,
63
+ html_marker: document.body && document.body.innerText
64
+ ? document.body.innerText.slice(0, 200)
65
+ : '',
66
+ };
67
+ })()`;
68
+
69
+ export async function runCnipaGet(kwargs: {
70
+ publication_number: string;
71
+ }): Promise<unknown[]> {
72
+ const pubNo = String(kwargs.publication_number ?? "").trim();
73
+ if (pubNo.length === 0) {
74
+ return [
75
+ {
76
+ envelope: cnipaEnvelope(
77
+ "PATENT_INVALID_NUMBER",
78
+ ADAPTER_PATH,
79
+ "validate",
80
+ "cnipa get requires a non-empty publication_number",
81
+ ),
82
+ },
83
+ ];
84
+ }
85
+ const url = `${CNIPA_DETAIL_URL}?pubNo=${encodeURIComponent(pubNo)}`;
86
+ let detail: CnipaDetail;
87
+ try {
88
+ const result = await navigateAndExtract<CnipaDetail>(url, DETAIL_EXTRACTOR);
89
+ if (!result.data) {
90
+ return [
91
+ {
92
+ envelope: cnipaEnvelope(
93
+ "PATENT_SCHEMA_DRIFT",
94
+ ADAPTER_PATH,
95
+ "evaluate",
96
+ "mcp-browser evaluate returned no data; check selector schema in src/adapters/cnipa/get.ts",
97
+ ),
98
+ },
99
+ ];
100
+ }
101
+ detail = result.data;
102
+ } catch (err) {
103
+ if (err instanceof TransportError) {
104
+ return [
105
+ {
106
+ envelope: transportErrorToEnvelope(err, ADAPTER_PATH, "navigate"),
107
+ },
108
+ ];
109
+ }
110
+ throw err;
111
+ }
112
+
113
+ // Captcha heuristic: detail page returned without any of the expected
114
+ // bibliographic fields → almost certainly captcha-gated.
115
+ const fieldCount = [
116
+ detail.publication_number,
117
+ detail.title,
118
+ detail.application_number,
119
+ detail.publication_date,
120
+ ].filter(Boolean).length;
121
+ if (looksLikeCaptcha(fieldCount, detail.html_marker)) {
122
+ return [
123
+ {
124
+ envelope: cnipaEnvelope(
125
+ "PATENT_BROWSER_CAPTCHA",
126
+ ADAPTER_PATH,
127
+ "evaluate",
128
+ "CNIPA detail page returned no bibliographic fields; solve the 验证码 in the open browser tab and re-run",
129
+ ["espacenet"],
130
+ ),
131
+ },
132
+ ];
133
+ }
134
+
135
+ const canonicalPubNo = detail.publication_number || pubNo;
136
+ try {
137
+ return [
138
+ assemblePatentRecord({
139
+ publication_number: canonicalPubNo,
140
+ application_number: detail.application_number || undefined,
141
+ title: detail.title || undefined,
142
+ abstract: detail.abstract || undefined,
143
+ assignees: detail.applicant
144
+ ? [{ name: detail.applicant, country: "CN" }]
145
+ : undefined,
146
+ inventors: detail.inventor
147
+ ? [{ name: detail.inventor, country: "CN" }]
148
+ : undefined,
149
+ publication_date: detail.publication_date || undefined,
150
+ filing_date: detail.filing_date || undefined,
151
+ grant_date: detail.grant_date || undefined,
152
+ legal_status: detail.legal_status || undefined,
153
+ source_adapter: "cnipa",
154
+ source_url: detail.source_url || url,
155
+ } as Parameters<typeof assemblePatentRecord>[0]),
156
+ ];
157
+ } catch {
158
+ return [
159
+ {
160
+ envelope: cnipaEnvelope(
161
+ "PATENT_NOT_FOUND",
162
+ ADAPTER_PATH,
163
+ "normalize",
164
+ `cnipa detail page did not yield a valid publication_number for "${pubNo}"`,
165
+ ["espacenet"],
166
+ ),
167
+ },
168
+ ];
169
+ }
170
+ }
171
+
172
+ cli({
173
+ site: "cnipa",
174
+ name: "get",
175
+ description: "Retrieve a single CNIPA patent document by publication number",
176
+ domain: "pss-system.cponline.cnipa.gov.cn",
177
+ strategy: Strategy.PUBLIC,
178
+ adapter_path: ADAPTER_PATH,
179
+ args: [
180
+ {
181
+ name: "publication_number",
182
+ type: "str",
183
+ required: true,
184
+ positional: true,
185
+ description: "ST.16 publication number (e.g. CN114123456A)",
186
+ },
187
+ ],
188
+ columns: [
189
+ "publication_number",
190
+ "title",
191
+ "publication_date",
192
+ "legal_status",
193
+ "source_url",
194
+ ],
195
+ capabilities: ["mcp-browser.navigate", "mcp-browser.evaluate", "patent.get"],
196
+ minimum_capability: "mcp-browser.evaluate",
197
+ func: async (_page, kwargs) =>
198
+ runCnipaGet(kwargs as { publication_number: string }),
199
+ });
@@ -0,0 +1,162 @@
1
+ /**
2
+ * @owner src::adapters::cnipa::legal-status
3
+ * @does Browser-driven CNIPA legal-status lookup — scrapes the prosecution timeline + grant status from the 公众查询 detail page; emits structured envelopes for captcha / not-found / MCP-bus gaps.
4
+ * @needs src/engine/transport/mcp-browser.ts, src/engine/normalizer/patent-envelope.ts, src/adapters/cnipa/_shared.ts, src/registry.ts
5
+ * @feeds src/commands/patent.ts (capability tag patent.legal-status)
6
+ * @breaks emits PATENT_INVALID_NUMBER, PATENT_BROWSER_CAPTCHA, PATENT_API_DEPRECATED (with MCP_BUS_MISSING context); never synthesizes a status
7
+ * @invariants output row carries `legal_status` exactly as scraped; no normalization beyond trim
8
+ * @side-effects controls Chrome via MCP
9
+ * @perf single navigate + evaluate
10
+ * @concurrency safe
11
+ * @test tests/unit/adapters/cnipa/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
+ cnipaEnvelope,
21
+ looksLikeCaptcha,
22
+ navigateAndExtract,
23
+ transportErrorToEnvelope,
24
+ } from "./_shared.js";
25
+
26
+ const ADAPTER_PATH = "src/adapters/cnipa/legal-status.ts";
27
+ const CNIPA_LEGAL_URL = "https://pss-system.cponline.cnipa.gov.cn/legalStatus";
28
+
29
+ interface CnipaLegalRow {
30
+ publication_number: string;
31
+ legal_status?: string;
32
+ status_date?: string;
33
+ source_url?: string;
34
+ html_marker?: string;
35
+ }
36
+
37
+ const EXTRACTOR = `(() => {
38
+ const text = (sel) => {
39
+ const node = document.querySelector(sel);
40
+ return node ? (node.textContent || '').trim() : '';
41
+ };
42
+ return {
43
+ publication_number: text('[data-field="pubNo"], .publication-number'),
44
+ legal_status: text('[data-field="legalStatus"], .legal-status'),
45
+ status_date: text('[data-field="statusDate"], .status-date'),
46
+ source_url: location.href,
47
+ html_marker: document.body && document.body.innerText
48
+ ? document.body.innerText.slice(0, 200)
49
+ : '',
50
+ };
51
+ })()`;
52
+
53
+ export async function runCnipaLegalStatus(kwargs: {
54
+ publication_number: string;
55
+ }): Promise<unknown[]> {
56
+ const pubNo = String(kwargs.publication_number ?? "").trim();
57
+ if (pubNo.length === 0) {
58
+ return [
59
+ {
60
+ envelope: cnipaEnvelope(
61
+ "PATENT_INVALID_NUMBER",
62
+ ADAPTER_PATH,
63
+ "validate",
64
+ "cnipa legal-status requires a non-empty publication_number",
65
+ ),
66
+ },
67
+ ];
68
+ }
69
+ const url = `${CNIPA_LEGAL_URL}?pubNo=${encodeURIComponent(pubNo)}`;
70
+ let detail: CnipaLegalRow;
71
+ try {
72
+ const result = await navigateAndExtract<CnipaLegalRow>(url, EXTRACTOR);
73
+ if (!result.data) {
74
+ return [
75
+ {
76
+ envelope: cnipaEnvelope(
77
+ "PATENT_SCHEMA_DRIFT",
78
+ ADAPTER_PATH,
79
+ "evaluate",
80
+ "mcp-browser evaluate returned no data",
81
+ ),
82
+ },
83
+ ];
84
+ }
85
+ detail = result.data;
86
+ } catch (err) {
87
+ if (err instanceof TransportError) {
88
+ return [
89
+ {
90
+ envelope: transportErrorToEnvelope(err, ADAPTER_PATH, "navigate"),
91
+ },
92
+ ];
93
+ }
94
+ throw err;
95
+ }
96
+ const fieldCount = [detail.publication_number, detail.legal_status].filter(
97
+ Boolean,
98
+ ).length;
99
+ if (looksLikeCaptcha(fieldCount, detail.html_marker)) {
100
+ return [
101
+ {
102
+ envelope: cnipaEnvelope(
103
+ "PATENT_BROWSER_CAPTCHA",
104
+ ADAPTER_PATH,
105
+ "evaluate",
106
+ "CNIPA legal-status page returned no fields; solve the 验证码 and re-run",
107
+ ["espacenet"],
108
+ ),
109
+ },
110
+ ];
111
+ }
112
+ if (!detail.legal_status) {
113
+ return [
114
+ {
115
+ envelope: cnipaEnvelope(
116
+ "PATENT_NOT_FOUND",
117
+ ADAPTER_PATH,
118
+ "normalize",
119
+ `cnipa returned no legal_status for "${pubNo}"`,
120
+ ["espacenet"],
121
+ ),
122
+ },
123
+ ];
124
+ }
125
+ return [
126
+ {
127
+ publication_number: detail.publication_number || pubNo,
128
+ legal_status: detail.legal_status,
129
+ status_date: detail.status_date,
130
+ source_adapter: "cnipa",
131
+ source_url: detail.source_url || url,
132
+ retrieved_at: new Date().toISOString(),
133
+ },
134
+ ];
135
+ }
136
+
137
+ cli({
138
+ site: "cnipa",
139
+ name: "legal-status",
140
+ description: "CNIPA legal-status / prosecution timeline lookup (browser)",
141
+ domain: "pss-system.cponline.cnipa.gov.cn",
142
+ strategy: Strategy.PUBLIC,
143
+ adapter_path: ADAPTER_PATH,
144
+ args: [
145
+ {
146
+ name: "publication_number",
147
+ type: "str",
148
+ required: true,
149
+ positional: true,
150
+ description: "ST.16 publication number",
151
+ },
152
+ ],
153
+ columns: ["publication_number", "legal_status", "status_date", "source_url"],
154
+ capabilities: [
155
+ "mcp-browser.navigate",
156
+ "mcp-browser.evaluate",
157
+ "patent.legal-status",
158
+ ],
159
+ minimum_capability: "mcp-browser.evaluate",
160
+ func: async (_page, kwargs) =>
161
+ runCnipaLegalStatus(kwargs as { publication_number: string }),
162
+ });
@@ -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,44 @@
1
+ site: danbooru
2
+ name: artists
3
+ description: Search Danbooru artist records
4
+ domain: danbooru.donmai.us
5
+ type: web-api
6
+ strategy: public
7
+
8
+ args:
9
+ query:
10
+ type: str
11
+ required: true
12
+ positional: true
13
+ description: Artist name
14
+ limit:
15
+ type: int
16
+ default: 20
17
+ description: Number of artists to return
18
+
19
+ pipeline:
20
+ - fetch:
21
+ url: "https://danbooru.donmai.us/artists.json"
22
+ params:
23
+ "search[name]": "${{ args.query }}"
24
+ limit: "${{ args.limit }}"
25
+
26
+ - map:
27
+ rank: "${{ index + 1 }}"
28
+ id: "${{ item.id }}"
29
+ name: "${{ item.name }}"
30
+ group_name: "${{ item.group_name }}"
31
+ other_names: "${{ Array.isArray(item.other_names) ? item.other_names.join(', ') : '' }}"
32
+ is_banned: "${{ item.is_banned }}"
33
+ is_deleted: "${{ item.is_deleted }}"
34
+ url: "${{ 'https://danbooru.donmai.us/artists/' + item.id }}"
35
+
36
+ columns: [rank, id, name, group_name, other_names, is_banned, is_deleted, url]
37
+
38
+ # schema-v2 metadata — injected by `unicli migrate schema-v2`
39
+ capabilities: ["http.fetch"]
40
+ minimum_capability: http.fetch
41
+ trust: public
42
+ confidentiality: public
43
+ quarantine: false
44
+ schema_version: v2
@@ -0,0 +1,45 @@
1
+ site: danbooru
2
+ name: comments
3
+ description: List Danbooru comments for a post
4
+ domain: danbooru.donmai.us
5
+ type: web-api
6
+ strategy: public
7
+
8
+ args:
9
+ post_id:
10
+ type: str
11
+ required: true
12
+ positional: true
13
+ description: Danbooru post ID
14
+ x-unicli-kind: id
15
+ limit:
16
+ type: int
17
+ default: 20
18
+ description: Number of comments to return
19
+
20
+ pipeline:
21
+ - fetch:
22
+ url: "https://danbooru.donmai.us/comments.json"
23
+ params:
24
+ "search[post_id]": "${{ args.post_id }}"
25
+ limit: "${{ args.limit }}"
26
+
27
+ - map:
28
+ rank: "${{ index + 1 }}"
29
+ id: "${{ item.id }}"
30
+ post_id: "${{ item.post_id }}"
31
+ creator_id: "${{ item.creator_id }}"
32
+ score: "${{ item.score }}"
33
+ body: "${{ String(item.body || '').replace(/\\s+/g, ' ').trim() }}"
34
+ created_at: "${{ item.created_at }}"
35
+ is_deleted: "${{ item.is_deleted }}"
36
+
37
+ columns: [rank, id, post_id, creator_id, score, body, created_at, is_deleted]
38
+
39
+ # schema-v2 metadata — injected by `unicli migrate schema-v2`
40
+ capabilities: ["http.fetch"]
41
+ minimum_capability: http.fetch
42
+ trust: public
43
+ confidentiality: public
44
+ quarantine: false
45
+ schema_version: v2