@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
@@ -4,9 +4,8 @@
4
4
 
5
5
  import { cli } from "../../registry.js";
6
6
  import { Strategy } from "../../types.js";
7
- import { twitterGuideFetch } from "./client.js";
8
-
9
- const GUIDE_URL = "https://x.com/i/api/2/guide.json";
7
+ import { browserTrendingTopics } from "./browser-fallback.js";
8
+ import type { IPage } from "../../types.js";
10
9
 
11
10
  cli({
12
11
  site: "twitter",
@@ -14,99 +13,19 @@ cli({
14
13
  description: "Get trending topics",
15
14
  domain: "x.com",
16
15
  strategy: Strategy.COOKIE,
16
+ browser: true,
17
+ browserSession: "user",
18
+ args: [
19
+ {
20
+ name: "limit",
21
+ type: "int",
22
+ default: 20,
23
+ description: "Number of trends",
24
+ },
25
+ ],
17
26
  columns: ["name", "tweet_count", "description", "url"],
18
- func: async (_page, kwargs) => {
27
+ func: async (page, kwargs) => {
19
28
  const count = (kwargs.limit as number) ?? 20;
20
-
21
- const data = (await twitterGuideFetch(GUIDE_URL, {
22
- count: String(count),
23
- include_page_configuration: "false",
24
- })) as Record<string, unknown>;
25
-
26
- // Navigate: data.timeline.instructions[0].addEntries.entries
27
- const timeline = data.timeline as Record<string, unknown> | undefined;
28
- const instructions = (timeline?.instructions as unknown[]) ?? [];
29
-
30
- const trends: Array<{
31
- name: string;
32
- tweet_count: string;
33
- description: string;
34
- url: string;
35
- }> = [];
36
-
37
- for (const instruction of instructions) {
38
- const inst = instruction as Record<string, unknown>;
39
- const addEntries = inst.addEntries as Record<string, unknown> | undefined;
40
- if (!addEntries) continue;
41
-
42
- const entries = (addEntries.entries as unknown[]) ?? [];
43
-
44
- for (const entry of entries) {
45
- const e = entry as Record<string, unknown>;
46
- const content = e.content as Record<string, unknown> | undefined;
47
- if (!content) continue;
48
-
49
- // Trend items are nested in timelineModule or timelineItem
50
- const items =
51
- (content.items as unknown[]) ??
52
- (content.item ? [{ item: content.item }] : []);
53
-
54
- for (const item of items) {
55
- const i = item as Record<string, unknown>;
56
- const itemObj = (i.item ?? i) as Record<string, unknown>;
57
- const clientEventInfo = itemObj.clientEventInfo as
58
- | Record<string, unknown>
59
- | undefined;
60
- const details = clientEventInfo?.details as
61
- | Record<string, unknown>
62
- | undefined;
63
- const guideDetails = details?.guideDetails as
64
- | Record<string, unknown>
65
- | undefined;
66
- const transparentGuideDetails =
67
- guideDetails?.transparentGuideDetails as
68
- | Record<string, unknown>
69
- | undefined;
70
- const trendMetadata = transparentGuideDetails?.trendMetadata as
71
- | Record<string, unknown>
72
- | undefined;
73
-
74
- // Also try direct content path
75
- const itemContent = (
76
- itemObj as Record<string, Record<string, unknown>>
77
- ).content;
78
- const trend = itemContent?.trend as
79
- | Record<string, unknown>
80
- | undefined;
81
-
82
- const name =
83
- (trendMetadata?.trendName as string) ??
84
- (trend?.name as string) ??
85
- "";
86
- if (!name) continue;
87
-
88
- const tweetCount =
89
- (trendMetadata?.metaDescription as string) ??
90
- (trend?.tweetCount as string) ??
91
- "";
92
- const desc =
93
- (trend?.description as string) ??
94
- (trendMetadata?.metaDescription as string) ??
95
- "";
96
- const trendUrl = trend?.url as Record<string, unknown> | undefined;
97
-
98
- trends.push({
99
- name,
100
- tweet_count: tweetCount,
101
- description: desc,
102
- url:
103
- (trendUrl?.url as string) ??
104
- `https://x.com/search?q=${encodeURIComponent(name)}`,
105
- });
106
- }
107
- }
108
- }
109
-
110
- return trends.slice(0, count);
29
+ return browserTrendingTopics(page as IPage, count);
111
30
  },
112
31
  });
@@ -0,0 +1,43 @@
1
+ # @owner src::adapters::ukipo::info
2
+ # @does Registry placeholder for the UK Intellectual Property Office — surfaces a structured PATENT_API_DEPRECATED envelope until UK IPO ships the OneIPO programmatic API listed on its 2026 roadmap.
3
+ # @needs src/engine/steps/assert.ts
4
+ # @feeds src/commands/patent.ts (meta-command discovery via `patent.*` capability)
5
+ # @breaks always throws PipelineError carrying a PATENT_API_DEPRECATED message; never silently returns rows
6
+ # @invariants no HTTPS egress; no env reads; no caller-visible state beyond the error envelope
7
+ # @side-effects none
8
+ # @perf n/a — fails before any I/O
9
+ # @concurrency safe (pure local assertion)
10
+ # @test none yet
11
+ # @stability experimental — replace with a real adapter when UK IPO publishes the OneIPO API spec
12
+ # @since 2026-05-18
13
+ # @verification waiting-for-api — UK IPO retired Ipsum on 2025-01; the OneIPOSearch web UI is live at https://www.search-for-intellectual-property.service.gov.uk/patent and a programmatic OneIPO API is listed on the 2026 roadmap with no fixed launch date. Until the API ships, callers can run searches manually through the OneIPOSearch UI.
14
+ site: ukipo
15
+ name: info
16
+ description: UK IPO registry placeholder — Ipsum retired 2025-01; OneIPO API on 2026 roadmap
17
+ domain: search-for-intellectual-property.service.gov.uk
18
+ type: web-api
19
+ strategy: public
20
+ lint_listing_detail: skip
21
+
22
+ args: {}
23
+
24
+ pipeline:
25
+ # Fail closed with a structured envelope. The message points at the
26
+ # OneIPOSearch web UI so a caller has a concrete next step today, and
27
+ # names the OneIPO API roadmap so future repair loops know where the
28
+ # gap is going to close.
29
+ - assert:
30
+ condition: "false"
31
+ message: "PATENT_API_DEPRECATED: UK IPO retired Ipsum on 2025-01. Use the OneIPOSearch web UI at https://www.search-for-intellectual-property.service.gov.uk/patent for now; the OneIPO programmatic API is listed on the UK IPO 2026 roadmap (https://www.gov.uk/government/organisations/intellectual-property-office) but has not shipped."
32
+
33
+ columns: []
34
+
35
+ # schema-v2 metadata
36
+ # The patent.* capability lets `unicli patent doctor` discover this adapter
37
+ # so the gap surfaces in the doctor table; the runtime step is `assert`.
38
+ capabilities: ["assert", "patent.search", "patent.get"]
39
+ minimum_capability: assert
40
+ trust: public
41
+ confidentiality: public
42
+ quarantine: false
43
+ schema_version: v2
@@ -0,0 +1,67 @@
1
+ # @owner src::adapters::uspto::get
2
+ # @does Fetch a single USPTO patent/application by application number via the ODP detail endpoint.
3
+ # @needs src/engine/steps/fetch.ts, src/engine/steps/map.ts
4
+ # @feeds src/commands/patent.ts
5
+ # @breaks throws PipelineError on 401/403 (missing/invalid X-API-KEY), 404 (number not found) or 5xx
6
+ # @invariants output row conforms to PatentRecord; publication_number is canonicalized to ST.16 form
7
+ # @side-effects reads env USPTO_ODP_API_KEY; HTTPS egress to api.uspto.gov
8
+ # @perf single request
9
+ # @concurrency safe
10
+ # @test none yet
11
+ # @stability stable
12
+ # @since 2026-05-18
13
+ # @verification blocked-by-key — needs USPTO_ODP_API_KEY
14
+ site: uspto
15
+ name: get
16
+ description: Fetch a USPTO patent/application by application number
17
+ domain: api.uspto.gov
18
+ type: web-api
19
+ strategy: public
20
+ lint_listing_detail: skip
21
+
22
+ args:
23
+ application_number:
24
+ type: str
25
+ required: true
26
+ positional: true
27
+ description: USPTO application number (e.g. 16/123,456 with or without slash)
28
+
29
+ pipeline:
30
+ - fetch:
31
+ url: "https://api.uspto.gov/api/v1/patent/applications/${{ args.application_number | replace('/', '') | replace(',', '') }}"
32
+ method: GET
33
+ headers:
34
+ Accept: application/json
35
+ X-API-KEY: "${{ env.USPTO_ODP_API_KEY || '' }}"
36
+
37
+ # ODP single-record detail endpoint returns the same `applicationMetaData`
38
+ # envelope as search, plus a richer `patentTermAdjustment` / `inventor` /
39
+ # `applicant` set on the detail path. Every field reference below maps to a
40
+ # documented ODP path; adapters do not synthesise.
41
+ - map:
42
+ publication_number: "${{ item.applicationMetaData && item.applicationMetaData.earliestPublicationNumber ? ('US-' + item.applicationMetaData.earliestPublicationNumber) : ('US-' + (item.applicationNumberText || '')) }}"
43
+ application_number: "${{ item.applicationNumberText || '' }}"
44
+ title: "${{ item.applicationMetaData ? (item.applicationMetaData.inventionTitle || '') : '' }}"
45
+ abstract: "${{ item.applicationMetaData ? (item.applicationMetaData.abstractText || '') : '' }}"
46
+ filing_date: "${{ item.applicationMetaData ? (item.applicationMetaData.filingDate || '') : '' }}"
47
+ publication_date: "${{ item.applicationMetaData ? (item.applicationMetaData.earliestPublicationDate || '') : '' }}"
48
+ grant_date: "${{ item.applicationMetaData ? (item.applicationMetaData.grantDate || '') : '' }}"
49
+ priority_date: "${{ item.applicationMetaData ? (item.applicationMetaData.firstInventorToFileIndicator ? item.applicationMetaData.filingDate : (item.applicationMetaData.earliestPriorityDate || '')) : '' }}"
50
+ kind_code: "${{ (item.applicationMetaData && item.applicationMetaData.earliestPublicationNumber) ? (item.applicationMetaData.earliestPublicationNumber.match(/[A-Z]\\d?$/) || [''])[0] : '' }}"
51
+ inventors: "${{ JSON.stringify((item.applicationMetaData && item.applicationMetaData.inventorBag) ? item.applicationMetaData.inventorBag.map(p => ({ name: p.inventorNameText || ((p.firstName || '') + ' ' + (p.lastName || '')).trim(), country: p.countryCode || undefined })) : []) }}"
52
+ assignees: "${{ JSON.stringify((item.applicationMetaData && item.applicationMetaData.applicantBag) ? item.applicationMetaData.applicantBag.map(p => ({ name: p.applicantNameText || p.organizationNameText || '', country: p.countryCode || undefined })) : []) }}"
53
+ classifications: "${{ JSON.stringify((item.applicationMetaData && item.applicationMetaData.cpcClassificationBag) ? item.applicationMetaData.cpcClassificationBag.map(c => ({ scheme: 'cpc', code: c.cpcSymbol || c })) : []) }}"
54
+ legal_status: "${{ item.applicationMetaData ? (item.applicationMetaData.applicationStatusDescriptionText || '') : '' }}"
55
+ source_adapter: uspto
56
+ source_url: "${{ 'https://ppubs.uspto.gov/dirsearch-public/patents/' + (item.applicationNumberText || '') }}"
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,58 @@
1
+ # @owner src::adapters::uspto::legal-status
2
+ # @does Fetch USPTO transaction history (PAIR) for an application — used to derive legal-status (issued, abandoned, pending, etc.).
3
+ # @needs src/engine/steps/fetch.ts, src/engine/steps/select.ts, src/engine/steps/map.ts
4
+ # @feeds src/commands/patent.ts
5
+ # @breaks throws PipelineError on 401/403/404
6
+ # @invariants output rows conform to PatentRecord; legal_status carries the latest transaction description
7
+ # @side-effects reads env USPTO_ODP_API_KEY; HTTPS egress to api.uspto.gov
8
+ # @perf single request
9
+ # @concurrency safe
10
+ # @test none yet
11
+ # @stability stable
12
+ # @since 2026-05-18
13
+ # @verification blocked-by-key — needs USPTO_ODP_API_KEY
14
+ site: uspto
15
+ name: legal-status
16
+ description: Legal-status / transaction history of a USPTO application
17
+ domain: api.uspto.gov
18
+ type: web-api
19
+ strategy: public
20
+ lint_listing_detail: skip
21
+
22
+ args:
23
+ application_number:
24
+ type: str
25
+ required: true
26
+ positional: true
27
+ description: USPTO application number
28
+
29
+ pipeline:
30
+ - fetch:
31
+ url: "https://api.uspto.gov/api/v1/patent/applications/${{ args.application_number | replace('/', '') | replace(',', '') }}/transactions"
32
+ method: GET
33
+ headers:
34
+ Accept: application/json
35
+ X-API-KEY: "${{ env.USPTO_ODP_API_KEY || '' }}"
36
+
37
+ - select: eventDataBag
38
+
39
+ # Each row is a transaction event; the ODP `transactions` endpoint returns
40
+ # eventCode + eventDescriptionText + eventDate per transaction.
41
+ - map:
42
+ publication_number: "${{ 'US-' + (args.application_number || '') }}"
43
+ application_number: "${{ args.application_number }}"
44
+ legal_status: "${{ (item.eventCode || '') + (item.eventDescriptionText ? (' ' + item.eventDescriptionText) : '') }}"
45
+ filing_date: "${{ item.eventDate || '' }}"
46
+ source_adapter: uspto
47
+ source_url: "${{ 'https://ppubs.uspto.gov/dirsearch-public/patents/' + (args.application_number || '') }}"
48
+ retrieved_at: ""
49
+
50
+ columns: [publication_number, legal_status, filing_date]
51
+
52
+ # schema-v2 metadata
53
+ capabilities: ["http.fetch", "patent.legal-status"]
54
+ minimum_capability: http.fetch
55
+ trust: public
56
+ confidentiality: public
57
+ quarantine: false
58
+ schema_version: v2
@@ -0,0 +1,88 @@
1
+ # @owner src::adapters::uspto::search
2
+ # @does Search USPTO patents/applications via the Open Data Portal (ODP) `applications/search` endpoint.
3
+ # @needs src/engine/steps/fetch.ts, src/engine/steps/select.ts, src/engine/steps/map.ts, src/engine/steps/limit.ts
4
+ # @feeds src/commands/patent.ts (meta-command aggregator)
5
+ # @breaks throws PipelineError on 401/403 (missing/invalid X-API-KEY) or 5xx; ODP enforces a 6 MB response cap — narrow the query if hit
6
+ # @invariants output rows conform to PatentRecord; publication_number is canonicalized to ST.16 form `US-<doc>-<kind>`
7
+ # @side-effects reads env USPTO_ODP_API_KEY; HTTPS egress to api.uspto.gov
8
+ # @perf single request, ODP returns up to 500 records per page
9
+ # @concurrency single-call; no shared mutable state
10
+ # @test none yet (adapter ships; live verification gated on key)
11
+ # @stability stable
12
+ # @since 2026-05-18
13
+ # @verification blocked-by-key — needs USPTO_ODP_API_KEY (free tier at developer.uspto.gov)
14
+ site: uspto
15
+ name: search
16
+ description: Search USPTO patents/applications via the Open Data Portal (ODP)
17
+ domain: api.uspto.gov
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: Free-text query (mapped to ODP `q` field, matches title/abstract/claims)
28
+ limit:
29
+ type: int
30
+ default: 25
31
+ description: Maximum results to return (ODP allows up to 500 per page)
32
+ offset:
33
+ type: int
34
+ default: 0
35
+ description: Result offset for pagination
36
+
37
+ pipeline:
38
+ - fetch:
39
+ url: "https://api.uspto.gov/api/v1/patent/applications/search"
40
+ method: GET
41
+ headers:
42
+ Accept: application/json
43
+ X-API-KEY: "${{ env.USPTO_ODP_API_KEY || '' }}"
44
+ params:
45
+ q: "${{ args.query }}"
46
+ limit: "${{ args.limit }}"
47
+ offset: "${{ args.offset }}"
48
+
49
+ - select: patentFileWrapperDataBag
50
+
51
+ # Field mapping references data.uspto.gov/swagger v1 patent applications schema.
52
+ # Every field below maps to a documented ODP response path — adapters must
53
+ # not synthesise values upstream did not return.
54
+ - map:
55
+ publication_number: "${{ item.applicationMetaData && item.applicationMetaData.earliestPublicationNumber ? ('US-' + item.applicationMetaData.earliestPublicationNumber) : ('US-' + (item.applicationNumberText || '')) }}"
56
+ application_number: "${{ item.applicationNumberText || '' }}"
57
+ title: "${{ item.applicationMetaData ? (item.applicationMetaData.inventionTitle || '') : '' }}"
58
+ abstract: "${{ item.applicationMetaData ? (item.applicationMetaData.abstractText || '') : '' }}"
59
+ filing_date: "${{ item.applicationMetaData ? (item.applicationMetaData.filingDate || '') : '' }}"
60
+ publication_date: "${{ item.applicationMetaData ? (item.applicationMetaData.earliestPublicationDate || '') : '' }}"
61
+ grant_date: "${{ item.applicationMetaData ? (item.applicationMetaData.grantDate || '') : '' }}"
62
+ # ODP `applicationMetaData.earliestPublicationNumber` is the compact form
63
+ # (`20240123456A1`); the trailing A1/A2/B1/B2 IS the ST.16 kind code.
64
+ kind_code: "${{ (item.applicationMetaData && item.applicationMetaData.earliestPublicationNumber) ? (item.applicationMetaData.earliestPublicationNumber.match(/[A-Z]\\d?$/) || [''])[0] : '' }}"
65
+ # ODP `inventorBag[]` and `applicantBag[]` carry per-party records.
66
+ # We serialise via JSON.stringify so the array survives the template
67
+ # engine's string projection; coerceToPatentRecords parses it back.
68
+ inventors: "${{ JSON.stringify((item.applicationMetaData && item.applicationMetaData.inventorBag) ? item.applicationMetaData.inventorBag.map(p => ({ name: p.inventorNameText || ((p.firstName || '') + ' ' + (p.lastName || '')).trim(), country: p.countryCode || undefined })) : []) }}"
69
+ assignees: "${{ JSON.stringify((item.applicationMetaData && item.applicationMetaData.applicantBag) ? item.applicationMetaData.applicantBag.map(p => ({ name: p.applicantNameText || p.organizationNameText || '', country: p.countryCode || undefined })) : []) }}"
70
+ # `cpcClassificationBag[]` is the ODP path for Cooperative Patent Classification codes.
71
+ classifications: "${{ JSON.stringify((item.applicationMetaData && item.applicationMetaData.cpcClassificationBag) ? item.applicationMetaData.cpcClassificationBag.map(c => ({ scheme: 'cpc', code: c.cpcSymbol || c })) : []) }}"
72
+ legal_status: "${{ item.applicationMetaData ? (item.applicationMetaData.applicationStatusDescriptionText || '') : '' }}"
73
+ source_adapter: uspto
74
+ source_url: "${{ 'https://ppubs.uspto.gov/dirsearch-public/patents/' + (item.applicationNumberText || '') }}"
75
+ # retrieved_at is stamped by assemblePatentRecord in the normalizer; YAML emits the empty string
76
+ retrieved_at: ""
77
+
78
+ - limit: "${{ args.limit }}"
79
+
80
+ columns: [publication_number, title, filing_date, publication_date]
81
+
82
+ # schema-v2 metadata
83
+ capabilities: ["http.fetch", "patent.search"]
84
+ minimum_capability: http.fetch
85
+ trust: public
86
+ confidentiality: public
87
+ quarantine: false
88
+ schema_version: v2
@@ -0,0 +1,43 @@
1
+ # @owner src::adapters::wipo-patentscope::info
2
+ # @does Registry placeholder for WIPO PATENTSCOPE — surfaces a structured PATENT_API_DEPRECATED envelope so `unicli patent doctor` and `unicli list` advertise the gap, without claiming false coverage.
3
+ # @needs src/engine/steps/assert.ts
4
+ # @feeds src/commands/patent.ts (meta-command discovery via `patent.*` capability)
5
+ # @breaks always throws PipelineError carrying a PATENT_API_DEPRECATED message; never silently returns rows
6
+ # @invariants no HTTPS egress; no env reads; no caller-visible state beyond the error envelope
7
+ # @side-effects none — the assertion is purely local
8
+ # @perf n/a — fails before any I/O
9
+ # @concurrency safe (pure local assertion)
10
+ # @test none yet
11
+ # @stability experimental — replace with a real adapter when WIPO ships a token-based REST/GraphQL API
12
+ # @since 2026-05-18
13
+ # @verification blocked-by-subscription — PATENTSCOPE exposes only a SOAP web service that requires a paid subscription (~CHF 600/year per third-party gem README; see https://patentscope.wipo.int/search/en/sub_user.jsf). Until WIPO ships a token-based REST/GraphQL surface, this adapter is a registry placeholder.
14
+ site: wipo-patentscope
15
+ name: info
16
+ description: WIPO PATENTSCOPE registry placeholder — no public REST API; SOAP requires subscription
17
+ domain: patentscope.wipo.int
18
+ type: web-api
19
+ strategy: public
20
+ lint_listing_detail: skip
21
+
22
+ args: {}
23
+
24
+ pipeline:
25
+ # Fail closed with a structured envelope that the agent can read and act on.
26
+ # The message names the upstream channel and the subscription URL so the
27
+ # caller has a concrete next step — no silent fallback, no fake row.
28
+ - assert:
29
+ condition: "false"
30
+ message: "PATENT_API_DEPRECATED: WIPO PATENTSCOPE exposes only a SOAP web service that requires a paid subscription. Subscribe at https://patentscope.wipo.int/search/en/sub_user.jsf, or fall back to Espacenet for WO-prefixed publications (EPO brokers PCT family lookups)."
31
+
32
+ columns: []
33
+
34
+ # schema-v2 metadata
35
+ # The patent.* capability is what makes `unicli patent doctor` discover this
36
+ # adapter so the gap is reported in the doctor table; assert.fail is the
37
+ # step the dispatcher actually invokes at runtime.
38
+ capabilities: ["assert", "patent.search", "patent.get"]
39
+ minimum_capability: assert
40
+ trust: public
41
+ confidentiality: public
42
+ quarantine: false
43
+ schema_version: v2
@@ -0,0 +1,95 @@
1
+ /**
2
+ * @owner Xiaohongshu browser adapters.
3
+ * @does Detects login, risk-control, and rendered-feed state in XHS web pages.
4
+ * @needs Browser-backed IPage from Uni-CLI runtime.
5
+ * @feeds xiaohongshu.search and xiaohongshu.trending.
6
+ * @breaks XHS copy or route changes can require updating page-state detection.
7
+ */
8
+
9
+ import type { IPage } from "../../types.js";
10
+ import {
11
+ socialAuthError,
12
+ socialChallengeError,
13
+ } from "../../social/browser-errors.js";
14
+
15
+ interface XhsPageState {
16
+ url: string;
17
+ title: string;
18
+ text: string;
19
+ }
20
+
21
+ export async function readXhsPageState(page: IPage): Promise<XhsPageState> {
22
+ const raw = await page.evaluate(`
23
+ (() => ({
24
+ url: window.location.href,
25
+ title: document.title || '',
26
+ text: (document.body?.innerText || '').replace(/\\s+/g, ' ').slice(0, 2000)
27
+ }))()
28
+ `);
29
+ const state = raw as Partial<XhsPageState>;
30
+ return {
31
+ url: String(state.url ?? ""),
32
+ title: String(state.title ?? ""),
33
+ text: String(state.text ?? ""),
34
+ };
35
+ }
36
+
37
+ export function assertXhsReadableState(
38
+ command: string,
39
+ state: XhsPageState,
40
+ ): void {
41
+ const haystack = `${state.url}\n${state.title}\n${state.text}`;
42
+ if (
43
+ /website-login\/error|安全限制|IP存在风险|风险|风控|安全验证|验证码|人机验证|verify|captcha/i.test(
44
+ haystack,
45
+ )
46
+ ) {
47
+ throw socialChallengeError(
48
+ "xiaohongshu",
49
+ command,
50
+ `Xiaohongshu is showing a risk-control or verification page: ${state.title || state.url}`,
51
+ );
52
+ }
53
+ if (/登录后查看|登录后|请先登录|login/i.test(haystack)) {
54
+ throw socialAuthError("xiaohongshu", command);
55
+ }
56
+ }
57
+
58
+ export async function assertXhsReadable(
59
+ page: IPage,
60
+ command: string,
61
+ ): Promise<void> {
62
+ assertXhsReadableState(command, await readXhsPageState(page));
63
+ }
64
+
65
+ export async function fetchXhsFeedItems(page: IPage): Promise<unknown[]> {
66
+ const raw = await page.evaluate(`
67
+ (async () => {
68
+ const app = document.querySelector('#app')?.__vue_app__;
69
+ if (!app) throw new Error('Xiaohongshu Vue app not found');
70
+ const pinia = app.config?.globalProperties?.$pinia;
71
+ if (!pinia || !pinia._s?.has('feed')) throw new Error('Xiaohongshu feed store not found');
72
+ const store = pinia._s.get('feed');
73
+ const captured = [];
74
+ const originalFetch = window.fetch;
75
+ window.fetch = async (...args) => {
76
+ const response = await originalFetch(...args);
77
+ try {
78
+ const url = String(args[0]?.url || args[0] || '');
79
+ if (/homefeed|feed/i.test(url)) {
80
+ captured.push(await response.clone().json());
81
+ }
82
+ } catch {}
83
+ return response;
84
+ };
85
+ try {
86
+ await store.fetchFeeds();
87
+ } finally {
88
+ window.fetch = originalFetch;
89
+ }
90
+ const payload = captured.find((item) => item?.data?.items?.length) || captured[0];
91
+ return payload?.data?.items || [];
92
+ })()
93
+ `);
94
+ return Array.isArray(raw) ? raw : [];
95
+ }
@@ -7,6 +7,7 @@
7
7
 
8
8
  import { cli, Strategy } from "../../registry.js";
9
9
  import type { IPage } from "../../types.js";
10
+ import { normalizeCommentRows } from "../../social/comments.js";
10
11
  import { buildNoteUrl } from "./note-helpers.js";
11
12
 
12
13
  function parseCommentLimit(raw: unknown, fallback = 20): number {
@@ -42,7 +43,23 @@ cli({
42
43
  description: "Include nested replies",
43
44
  },
44
45
  ],
45
- columns: ["rank", "author", "text", "likes", "time", "is_reply", "reply_to"],
46
+ columns: [
47
+ "rank",
48
+ "platform",
49
+ "content_id",
50
+ "comment_id",
51
+ "parent_id",
52
+ "depth",
53
+ "path",
54
+ "author",
55
+ "text",
56
+ "likes",
57
+ "replies",
58
+ "created",
59
+ "time",
60
+ "is_reply",
61
+ "reply_to",
62
+ ],
46
63
  func: async (page, kwargs) => {
47
64
  const p = page as IPage;
48
65
  const limit = parseCommentLimit(kwargs.limit);
@@ -100,7 +117,7 @@ cli({
100
117
  const likes = parseLikes(item.querySelector('.count'))
101
118
  const time = clean(item.querySelector('.date, .time'))
102
119
  if (!text) continue
103
- results.push({ author, text, likes, time, is_reply: false, reply_to: '' })
120
+ results.push({ author, text, likes, replies: 0, created: time, time, is_reply: false, reply_to: '' })
104
121
  if (withReplies) {
105
122
  await expandReplyThreads(p)
106
123
  p.querySelectorAll('.reply-container .comment-item-sub, .sub-comment-list .comment-item').forEach(sub => {
@@ -109,7 +126,7 @@ cli({
109
126
  const sLikes = parseLikes(sub.querySelector('.count'))
110
127
  const sTime = clean(sub.querySelector('.date, .time'))
111
128
  if (!sText) return
112
- results.push({ author: sAuthor, text: sText, likes: sLikes, time: sTime, is_reply: true, reply_to: author })
129
+ results.push({ author: sAuthor, text: sText, likes: sLikes, replies: 0, created: sTime, time: sTime, is_reply: true, reply_to: author })
113
130
  })
114
131
  }
115
132
  }
@@ -125,7 +142,7 @@ cli({
125
142
  throw new Error("Note comments require login to www.xiaohongshu.com");
126
143
  }
127
144
 
128
- interface CommentRow {
145
+ interface CommentRow extends Record<string, unknown> {
129
146
  author: string;
130
147
  text: string;
131
148
  likes: number;
@@ -144,9 +161,15 @@ cli({
144
161
  if (topCount > limit) break;
145
162
  limited.push(c);
146
163
  }
147
- return limited.map((c, i) => ({ rank: i + 1, ...c }));
164
+ return normalizeCommentRows(limited, {
165
+ platform: "xiaohongshu",
166
+ contentId: raw,
167
+ }).map((c, i) => ({ rank: i + 1, ...c }));
148
168
  }
149
169
 
150
- return all.slice(0, limit).map((c, i) => ({ rank: i + 1, ...c }));
170
+ return normalizeCommentRows(all.slice(0, limit), {
171
+ platform: "xiaohongshu",
172
+ contentId: raw,
173
+ }).map((c, i) => ({ rank: i + 1, ...c }));
151
174
  },
152
175
  });