@zenalexa/unicli 0.220.1 → 0.221.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (586) hide show
  1. package/AGENTS.md +35 -13
  2. package/README.md +18 -16
  3. package/README.zh-CN.md +18 -16
  4. package/dist/adapters/acl-anthology/papers.d.ts +16 -0
  5. package/dist/adapters/acl-anthology/papers.d.ts.map +1 -0
  6. package/dist/adapters/acl-anthology/papers.js +135 -0
  7. package/dist/adapters/acl-anthology/papers.js.map +1 -0
  8. package/dist/adapters/arxiv/papers.js +2 -0
  9. package/dist/adapters/arxiv/papers.js.map +1 -1
  10. package/dist/adapters/baidu-scholar/search.js +5 -0
  11. package/dist/adapters/baidu-scholar/search.js.map +1 -1
  12. package/dist/adapters/bilibili/comments.js +66 -4
  13. package/dist/adapters/bilibili/comments.js.map +1 -1
  14. package/dist/adapters/bilibili/compat.js +2 -2
  15. package/dist/adapters/bilibili/compat.js.map +1 -1
  16. package/dist/adapters/bilibili/download.js +4 -4
  17. package/dist/adapters/bilibili/download.js.map +1 -1
  18. package/dist/adapters/bilibili/wbi.d.ts.map +1 -1
  19. package/dist/adapters/bilibili/wbi.js +3 -3
  20. package/dist/adapters/bilibili/wbi.js.map +1 -1
  21. package/dist/adapters/cipo/_shared.d.ts +21 -0
  22. package/dist/adapters/cipo/_shared.d.ts.map +1 -0
  23. package/dist/adapters/cipo/_shared.js +67 -0
  24. package/dist/adapters/cipo/_shared.js.map +1 -0
  25. package/dist/adapters/cipo/get.d.ts +19 -0
  26. package/dist/adapters/cipo/get.d.ts.map +1 -0
  27. package/dist/adapters/cipo/get.js +140 -0
  28. package/dist/adapters/cipo/get.js.map +1 -0
  29. package/dist/adapters/cipo/legal-status.d.ts +19 -0
  30. package/dist/adapters/cipo/legal-status.d.ts.map +1 -0
  31. package/dist/adapters/cipo/legal-status.js +111 -0
  32. package/dist/adapters/cipo/legal-status.js.map +1 -0
  33. package/dist/adapters/cipo/search.d.ts +20 -0
  34. package/dist/adapters/cipo/search.d.ts.map +1 -0
  35. package/dist/adapters/cipo/search.js +148 -0
  36. package/dist/adapters/cipo/search.js.map +1 -0
  37. package/dist/adapters/cnipa/_shared.d.ts +47 -0
  38. package/dist/adapters/cnipa/_shared.d.ts.map +1 -0
  39. package/dist/adapters/cnipa/_shared.js +97 -0
  40. package/dist/adapters/cnipa/_shared.js.map +1 -0
  41. package/dist/adapters/cnipa/get.d.ts +19 -0
  42. package/dist/adapters/cnipa/get.d.ts.map +1 -0
  43. package/dist/adapters/cnipa/get.js +149 -0
  44. package/dist/adapters/cnipa/get.js.map +1 -0
  45. package/dist/adapters/cnipa/legal-status.d.ts +19 -0
  46. package/dist/adapters/cnipa/legal-status.d.ts.map +1 -0
  47. package/dist/adapters/cnipa/legal-status.js +119 -0
  48. package/dist/adapters/cnipa/legal-status.js.map +1 -0
  49. package/dist/adapters/cnipa/search.d.ts +21 -0
  50. package/dist/adapters/cnipa/search.d.ts.map +1 -0
  51. package/dist/adapters/cnipa/search.js +170 -0
  52. package/dist/adapters/cnipa/search.js.map +1 -0
  53. package/dist/adapters/crossref/works.d.ts +42 -0
  54. package/dist/adapters/crossref/works.d.ts.map +1 -0
  55. package/dist/adapters/crossref/works.js +157 -0
  56. package/dist/adapters/crossref/works.js.map +1 -0
  57. package/dist/adapters/cvf/papers.d.ts +17 -0
  58. package/dist/adapters/cvf/papers.d.ts.map +1 -0
  59. package/dist/adapters/cvf/papers.js +124 -0
  60. package/dist/adapters/cvf/papers.js.map +1 -0
  61. package/dist/adapters/dblp/publications.js +4 -0
  62. package/dist/adapters/dblp/publications.js.map +1 -1
  63. package/dist/adapters/espacenet/_shared.d.ts +21 -0
  64. package/dist/adapters/espacenet/_shared.d.ts.map +1 -0
  65. package/dist/adapters/espacenet/_shared.js +67 -0
  66. package/dist/adapters/espacenet/_shared.js.map +1 -0
  67. package/dist/adapters/espacenet/family.d.ts +19 -0
  68. package/dist/adapters/espacenet/family.d.ts.map +1 -0
  69. package/dist/adapters/espacenet/family.js +118 -0
  70. package/dist/adapters/espacenet/family.js.map +1 -0
  71. package/dist/adapters/espacenet/get.d.ts +19 -0
  72. package/dist/adapters/espacenet/get.d.ts.map +1 -0
  73. package/dist/adapters/espacenet/get.js +130 -0
  74. package/dist/adapters/espacenet/get.js.map +1 -0
  75. package/dist/adapters/espacenet/legal-status.d.ts +19 -0
  76. package/dist/adapters/espacenet/legal-status.d.ts.map +1 -0
  77. package/dist/adapters/espacenet/legal-status.js +110 -0
  78. package/dist/adapters/espacenet/legal-status.js.map +1 -0
  79. package/dist/adapters/espacenet/search.d.ts +20 -0
  80. package/dist/adapters/espacenet/search.d.ts.map +1 -0
  81. package/dist/adapters/espacenet/search.js +165 -0
  82. package/dist/adapters/espacenet/search.js.map +1 -0
  83. package/dist/adapters/facebook/subtitles.d.ts +9 -0
  84. package/dist/adapters/facebook/subtitles.d.ts.map +1 -0
  85. package/dist/adapters/facebook/subtitles.js +42 -0
  86. package/dist/adapters/facebook/subtitles.js.map +1 -0
  87. package/dist/adapters/fips/_shared.d.ts +21 -0
  88. package/dist/adapters/fips/_shared.d.ts.map +1 -0
  89. package/dist/adapters/fips/_shared.js +77 -0
  90. package/dist/adapters/fips/_shared.js.map +1 -0
  91. package/dist/adapters/fips/get.d.ts +19 -0
  92. package/dist/adapters/fips/get.d.ts.map +1 -0
  93. package/dist/adapters/fips/get.js +139 -0
  94. package/dist/adapters/fips/get.js.map +1 -0
  95. package/dist/adapters/fips/search.d.ts +20 -0
  96. package/dist/adapters/fips/search.d.ts.map +1 -0
  97. package/dist/adapters/fips/search.js +148 -0
  98. package/dist/adapters/fips/search.js.map +1 -0
  99. package/dist/adapters/freepatentsonline-web/_shared.d.ts +72 -0
  100. package/dist/adapters/freepatentsonline-web/_shared.d.ts.map +1 -0
  101. package/dist/adapters/freepatentsonline-web/_shared.js +216 -0
  102. package/dist/adapters/freepatentsonline-web/_shared.js.map +1 -0
  103. package/dist/adapters/freepatentsonline-web/get.d.ts +21 -0
  104. package/dist/adapters/freepatentsonline-web/get.d.ts.map +1 -0
  105. package/dist/adapters/freepatentsonline-web/get.js +127 -0
  106. package/dist/adapters/freepatentsonline-web/get.js.map +1 -0
  107. package/dist/adapters/freepatentsonline-web/search.d.ts +22 -0
  108. package/dist/adapters/freepatentsonline-web/search.d.ts.map +1 -0
  109. package/dist/adapters/freepatentsonline-web/search.js +149 -0
  110. package/dist/adapters/freepatentsonline-web/search.js.map +1 -0
  111. package/dist/adapters/google-patents-web/_shared.d.ts +110 -0
  112. package/dist/adapters/google-patents-web/_shared.d.ts.map +1 -0
  113. package/dist/adapters/google-patents-web/_shared.js +164 -0
  114. package/dist/adapters/google-patents-web/_shared.js.map +1 -0
  115. package/dist/adapters/google-patents-web/get.d.ts +36 -0
  116. package/dist/adapters/google-patents-web/get.d.ts.map +1 -0
  117. package/dist/adapters/google-patents-web/get.js +187 -0
  118. package/dist/adapters/google-patents-web/get.js.map +1 -0
  119. package/dist/adapters/google-patents-web/search.d.ts +23 -0
  120. package/dist/adapters/google-patents-web/search.d.ts.map +1 -0
  121. package/dist/adapters/google-patents-web/search.js +169 -0
  122. package/dist/adapters/google-patents-web/search.js.map +1 -0
  123. package/dist/adapters/google-scholar/cite.js +1 -0
  124. package/dist/adapters/google-scholar/cite.js.map +1 -1
  125. package/dist/adapters/google-scholar/profile.js +5 -0
  126. package/dist/adapters/google-scholar/profile.js.map +1 -1
  127. package/dist/adapters/google-scholar/search.js +5 -0
  128. package/dist/adapters/google-scholar/search.js.map +1 -1
  129. package/dist/adapters/hf/paper.js +1 -0
  130. package/dist/adapters/hf/paper.js.map +1 -1
  131. package/dist/adapters/inpi-br/_shared.d.ts +21 -0
  132. package/dist/adapters/inpi-br/_shared.d.ts.map +1 -0
  133. package/dist/adapters/inpi-br/_shared.js +67 -0
  134. package/dist/adapters/inpi-br/_shared.js.map +1 -0
  135. package/dist/adapters/inpi-br/get.d.ts +19 -0
  136. package/dist/adapters/inpi-br/get.d.ts.map +1 -0
  137. package/dist/adapters/inpi-br/get.js +142 -0
  138. package/dist/adapters/inpi-br/get.js.map +1 -0
  139. package/dist/adapters/inpi-br/search.d.ts +20 -0
  140. package/dist/adapters/inpi-br/search.d.ts.map +1 -0
  141. package/dist/adapters/inpi-br/search.js +154 -0
  142. package/dist/adapters/inpi-br/search.js.map +1 -0
  143. package/dist/adapters/instagram/subtitles.d.ts +9 -0
  144. package/dist/adapters/instagram/subtitles.d.ts.map +1 -0
  145. package/dist/adapters/instagram/subtitles.js +42 -0
  146. package/dist/adapters/instagram/subtitles.js.map +1 -0
  147. package/dist/adapters/mastodon/statuses.d.ts +40 -0
  148. package/dist/adapters/mastodon/statuses.d.ts.map +1 -0
  149. package/dist/adapters/mastodon/statuses.js +153 -0
  150. package/dist/adapters/mastodon/statuses.js.map +1 -0
  151. package/dist/adapters/neurips/proceedings.d.ts +17 -0
  152. package/dist/adapters/neurips/proceedings.d.ts.map +1 -0
  153. package/dist/adapters/neurips/proceedings.js +112 -0
  154. package/dist/adapters/neurips/proceedings.js.map +1 -0
  155. package/dist/adapters/openalex/works.d.ts.map +1 -1
  156. package/dist/adapters/openalex/works.js +32 -0
  157. package/dist/adapters/openalex/works.js.map +1 -1
  158. package/dist/adapters/openreview/papers.js +5 -0
  159. package/dist/adapters/openreview/papers.js.map +1 -1
  160. package/dist/adapters/pmlr/proceedings.d.ts +35 -0
  161. package/dist/adapters/pmlr/proceedings.d.ts.map +1 -0
  162. package/dist/adapters/pmlr/proceedings.js +139 -0
  163. package/dist/adapters/pmlr/proceedings.js.map +1 -0
  164. package/dist/adapters/pubmed/articles.js +5 -0
  165. package/dist/adapters/pubmed/articles.js.map +1 -1
  166. package/dist/adapters/reddit/comments.d.ts +9 -0
  167. package/dist/adapters/reddit/comments.d.ts.map +1 -0
  168. package/dist/adapters/reddit/comments.js +124 -0
  169. package/dist/adapters/reddit/comments.js.map +1 -0
  170. package/dist/adapters/semantic-scholar/papers.d.ts +36 -0
  171. package/dist/adapters/semantic-scholar/papers.d.ts.map +1 -0
  172. package/dist/adapters/semantic-scholar/papers.js +214 -0
  173. package/dist/adapters/semantic-scholar/papers.js.map +1 -0
  174. package/dist/adapters/threads/post.d.ts +32 -0
  175. package/dist/adapters/threads/post.d.ts.map +1 -0
  176. package/dist/adapters/threads/post.js +287 -0
  177. package/dist/adapters/threads/post.js.map +1 -0
  178. package/dist/adapters/tiktok/subtitles.d.ts +9 -0
  179. package/dist/adapters/tiktok/subtitles.d.ts.map +1 -0
  180. package/dist/adapters/tiktok/subtitles.js +42 -0
  181. package/dist/adapters/tiktok/subtitles.js.map +1 -0
  182. package/dist/adapters/twitter/accept.js +2 -2
  183. package/dist/adapters/twitter/accept.js.map +1 -1
  184. package/dist/adapters/twitter/browser-fallback.d.ts +26 -0
  185. package/dist/adapters/twitter/browser-fallback.d.ts.map +1 -0
  186. package/dist/adapters/twitter/browser-fallback.js +93 -0
  187. package/dist/adapters/twitter/browser-fallback.js.map +1 -0
  188. package/dist/adapters/twitter/browser-state.d.ts +11 -0
  189. package/dist/adapters/twitter/browser-state.d.ts.map +1 -0
  190. package/dist/adapters/twitter/browser-state.js +46 -0
  191. package/dist/adapters/twitter/browser-state.js.map +1 -0
  192. package/dist/adapters/twitter/client.d.ts.map +1 -1
  193. package/dist/adapters/twitter/client.js +36 -13
  194. package/dist/adapters/twitter/client.js.map +1 -1
  195. package/dist/adapters/twitter/reply-dm.js +2 -2
  196. package/dist/adapters/twitter/reply-dm.js.map +1 -1
  197. package/dist/adapters/twitter/reply.js +1 -0
  198. package/dist/adapters/twitter/reply.js.map +1 -1
  199. package/dist/adapters/twitter/search.js +11 -18
  200. package/dist/adapters/twitter/search.js.map +1 -1
  201. package/dist/adapters/twitter/thread.d.ts +14 -0
  202. package/dist/adapters/twitter/thread.d.ts.map +1 -1
  203. package/dist/adapters/twitter/thread.js +28 -2
  204. package/dist/adapters/twitter/thread.js.map +1 -1
  205. package/dist/adapters/twitter/trending.js +13 -59
  206. package/dist/adapters/twitter/trending.js.map +1 -1
  207. package/dist/adapters/unpaywall/works.d.ts +33 -0
  208. package/dist/adapters/unpaywall/works.d.ts.map +1 -0
  209. package/dist/adapters/unpaywall/works.js +101 -0
  210. package/dist/adapters/unpaywall/works.js.map +1 -0
  211. package/dist/adapters/xiaohongshu/browser-state.d.ts +19 -0
  212. package/dist/adapters/xiaohongshu/browser-state.d.ts.map +1 -0
  213. package/dist/adapters/xiaohongshu/browser-state.js +67 -0
  214. package/dist/adapters/xiaohongshu/browser-state.js.map +1 -0
  215. package/dist/adapters/xiaohongshu/comments.js +28 -5
  216. package/dist/adapters/xiaohongshu/comments.js.map +1 -1
  217. package/dist/adapters/xiaohongshu/download.js +49 -11
  218. package/dist/adapters/xiaohongshu/download.js.map +1 -1
  219. package/dist/adapters/xiaohongshu/search.d.ts.map +1 -1
  220. package/dist/adapters/xiaohongshu/search.js +11 -5
  221. package/dist/adapters/xiaohongshu/search.js.map +1 -1
  222. package/dist/adapters/xiaohongshu/trending.d.ts +9 -0
  223. package/dist/adapters/xiaohongshu/trending.d.ts.map +1 -0
  224. package/dist/adapters/xiaohongshu/trending.js +94 -0
  225. package/dist/adapters/xiaohongshu/trending.js.map +1 -0
  226. package/dist/adapters/youtube/comments.d.ts +80 -0
  227. package/dist/adapters/youtube/comments.d.ts.map +1 -1
  228. package/dist/adapters/youtube/comments.js +108 -12
  229. package/dist/adapters/youtube/comments.js.map +1 -1
  230. package/dist/adapters/youtube/subtitles.d.ts +9 -0
  231. package/dist/adapters/youtube/subtitles.d.ts.map +1 -0
  232. package/dist/adapters/youtube/subtitles.js +42 -0
  233. package/dist/adapters/youtube/subtitles.js.map +1 -0
  234. package/dist/adapters/yt-dlp/subtitles.d.ts +9 -0
  235. package/dist/adapters/yt-dlp/subtitles.d.ts.map +1 -0
  236. package/dist/adapters/yt-dlp/subtitles.js +41 -0
  237. package/dist/adapters/yt-dlp/subtitles.js.map +1 -0
  238. package/dist/adapters/zhihu/answer-detail.d.ts +39 -0
  239. package/dist/adapters/zhihu/answer-detail.d.ts.map +1 -0
  240. package/dist/adapters/zhihu/answer-detail.js +204 -0
  241. package/dist/adapters/zhihu/answer-detail.js.map +1 -0
  242. package/dist/adapters/zhihu/comment.d.ts +9 -0
  243. package/dist/adapters/zhihu/comment.d.ts.map +1 -0
  244. package/dist/adapters/zhihu/comment.js +149 -0
  245. package/dist/adapters/zhihu/comment.js.map +1 -0
  246. package/dist/adapters/zhihu/recommend.d.ts +36 -0
  247. package/dist/adapters/zhihu/recommend.d.ts.map +1 -0
  248. package/dist/adapters/zhihu/recommend.js +151 -0
  249. package/dist/adapters/zhihu/recommend.js.map +1 -0
  250. package/dist/browser/bridge.d.ts.map +1 -1
  251. package/dist/browser/bridge.js +14 -3
  252. package/dist/browser/bridge.js.map +1 -1
  253. package/dist/browser/daemon-client.d.ts +6 -0
  254. package/dist/browser/daemon-client.d.ts.map +1 -1
  255. package/dist/browser/daemon-client.js +75 -15
  256. package/dist/browser/daemon-client.js.map +1 -1
  257. package/dist/browser/daemon.js +39 -15
  258. package/dist/browser/daemon.js.map +1 -1
  259. package/dist/browser/protocol.d.ts +1 -0
  260. package/dist/browser/protocol.d.ts.map +1 -1
  261. package/dist/browser/protocol.js +1 -0
  262. package/dist/browser/protocol.js.map +1 -1
  263. package/dist/cli.d.ts.map +1 -1
  264. package/dist/cli.js +21 -1
  265. package/dist/cli.js.map +1 -1
  266. package/dist/commands/approvals.d.ts.map +1 -1
  267. package/dist/commands/approvals.js +1 -37
  268. package/dist/commands/approvals.js.map +1 -1
  269. package/dist/commands/browser/index.d.ts.map +1 -1
  270. package/dist/commands/browser/index.js +7 -2
  271. package/dist/commands/browser/index.js.map +1 -1
  272. package/dist/commands/daemon.d.ts.map +1 -1
  273. package/dist/commands/daemon.js +7 -3
  274. package/dist/commands/daemon.js.map +1 -1
  275. package/dist/commands/dispatch.d.ts.map +1 -1
  276. package/dist/commands/dispatch.js +27 -3
  277. package/dist/commands/dispatch.js.map +1 -1
  278. package/dist/commands/do.d.ts +30 -0
  279. package/dist/commands/do.d.ts.map +1 -0
  280. package/dist/commands/do.js +248 -0
  281. package/dist/commands/do.js.map +1 -0
  282. package/dist/commands/extract.d.ts +34 -0
  283. package/dist/commands/extract.d.ts.map +1 -0
  284. package/dist/commands/extract.js +316 -0
  285. package/dist/commands/extract.js.map +1 -0
  286. package/dist/commands/patent-doctor.d.ts +48 -0
  287. package/dist/commands/patent-doctor.d.ts.map +1 -0
  288. package/dist/commands/patent-doctor.js +109 -0
  289. package/dist/commands/patent-doctor.js.map +1 -0
  290. package/dist/commands/patent.d.ts +78 -0
  291. package/dist/commands/patent.d.ts.map +1 -0
  292. package/dist/commands/patent.js +919 -0
  293. package/dist/commands/patent.js.map +1 -0
  294. package/dist/commands/scholar.d.ts +33 -0
  295. package/dist/commands/scholar.d.ts.map +1 -0
  296. package/dist/commands/scholar.js +494 -0
  297. package/dist/commands/scholar.js.map +1 -0
  298. package/dist/commands/search.d.ts.map +1 -1
  299. package/dist/commands/search.js +2 -5
  300. package/dist/commands/search.js.map +1 -1
  301. package/dist/commands/social.d.ts +19 -0
  302. package/dist/commands/social.d.ts.map +1 -0
  303. package/dist/commands/social.js +236 -0
  304. package/dist/commands/social.js.map +1 -0
  305. package/dist/core/registry.d.ts +1 -1
  306. package/dist/core/registry.d.ts.map +1 -1
  307. package/dist/core/registry.js +11 -2
  308. package/dist/core/registry.js.map +1 -1
  309. package/dist/discovery/aliases.d.ts +2 -2
  310. package/dist/discovery/aliases.d.ts.map +1 -1
  311. package/dist/discovery/aliases.js +182 -11
  312. package/dist/discovery/aliases.js.map +1 -1
  313. package/dist/discovery/intents.d.ts +10 -0
  314. package/dist/discovery/intents.d.ts.map +1 -0
  315. package/dist/discovery/intents.js +255 -0
  316. package/dist/discovery/intents.js.map +1 -0
  317. package/dist/discovery/loader.d.ts.map +1 -1
  318. package/dist/discovery/loader.js +4 -0
  319. package/dist/discovery/loader.js.map +1 -1
  320. package/dist/discovery/search.d.ts +4 -1
  321. package/dist/discovery/search.d.ts.map +1 -1
  322. package/dist/discovery/search.js +28 -140
  323. package/dist/discovery/search.js.map +1 -1
  324. package/dist/engine/approval-presenter.d.ts +10 -0
  325. package/dist/engine/approval-presenter.d.ts.map +1 -0
  326. package/dist/engine/approval-presenter.js +45 -0
  327. package/dist/engine/approval-presenter.js.map +1 -0
  328. package/dist/engine/approval-store.d.ts +4 -0
  329. package/dist/engine/approval-store.d.ts.map +1 -1
  330. package/dist/engine/approval-store.js +85 -11
  331. package/dist/engine/approval-store.js.map +1 -1
  332. package/dist/engine/auth/oauth2-cc.d.ts +67 -0
  333. package/dist/engine/auth/oauth2-cc.d.ts.map +1 -0
  334. package/dist/engine/auth/oauth2-cc.js +120 -0
  335. package/dist/engine/auth/oauth2-cc.js.map +1 -0
  336. package/dist/engine/cookies.d.ts +10 -0
  337. package/dist/engine/cookies.d.ts.map +1 -1
  338. package/dist/engine/cookies.js +64 -0
  339. package/dist/engine/cookies.js.map +1 -1
  340. package/dist/engine/download.d.ts +5 -0
  341. package/dist/engine/download.d.ts.map +1 -1
  342. package/dist/engine/download.js +11 -4
  343. package/dist/engine/download.js.map +1 -1
  344. package/dist/engine/executor.d.ts +1 -0
  345. package/dist/engine/executor.d.ts.map +1 -1
  346. package/dist/engine/executor.js +25 -0
  347. package/dist/engine/executor.js.map +1 -1
  348. package/dist/engine/framework.d.ts +5 -5
  349. package/dist/engine/framework.js +5 -5
  350. package/dist/engine/harden.d.ts +1 -1
  351. package/dist/engine/harden.js +1 -1
  352. package/dist/engine/kernel/stages.d.ts.map +1 -1
  353. package/dist/engine/kernel/stages.js +2 -1
  354. package/dist/engine/kernel/stages.js.map +1 -1
  355. package/dist/engine/normalizer/patent-envelope.d.ts +61 -0
  356. package/dist/engine/normalizer/patent-envelope.d.ts.map +1 -0
  357. package/dist/engine/normalizer/patent-envelope.js +132 -0
  358. package/dist/engine/normalizer/patent-envelope.js.map +1 -0
  359. package/dist/engine/research.d.ts +5 -7
  360. package/dist/engine/research.d.ts.map +1 -1
  361. package/dist/engine/research.js +6 -9
  362. package/dist/engine/research.js.map +1 -1
  363. package/dist/engine/steps/browser-helpers.d.ts +2 -2
  364. package/dist/engine/steps/browser-helpers.d.ts.map +1 -1
  365. package/dist/engine/steps/browser-helpers.js +39 -16
  366. package/dist/engine/steps/browser-helpers.js.map +1 -1
  367. package/dist/engine/steps/download.d.ts +1 -0
  368. package/dist/engine/steps/download.d.ts.map +1 -1
  369. package/dist/engine/steps/download.js +3 -1
  370. package/dist/engine/steps/download.js.map +1 -1
  371. package/dist/engine/steps/index.d.ts +2 -0
  372. package/dist/engine/steps/index.d.ts.map +1 -1
  373. package/dist/engine/steps/index.js +2 -0
  374. package/dist/engine/steps/index.js.map +1 -1
  375. package/dist/engine/steps/oauth2-token.d.ts +41 -0
  376. package/dist/engine/steps/oauth2-token.d.ts.map +1 -0
  377. package/dist/engine/steps/oauth2-token.js +115 -0
  378. package/dist/engine/steps/oauth2-token.js.map +1 -0
  379. package/dist/engine/steps/select-xml.d.ts +34 -0
  380. package/dist/engine/steps/select-xml.d.ts.map +1 -0
  381. package/dist/engine/steps/select-xml.js +222 -0
  382. package/dist/engine/steps/select-xml.js.map +1 -0
  383. package/dist/engine/template.d.ts.map +1 -1
  384. package/dist/engine/template.js +7 -0
  385. package/dist/engine/template.js.map +1 -1
  386. package/dist/engine/transport/mcp-browser.d.ts +128 -0
  387. package/dist/engine/transport/mcp-browser.d.ts.map +1 -0
  388. package/dist/engine/transport/mcp-browser.js +120 -0
  389. package/dist/engine/transport/mcp-browser.js.map +1 -0
  390. package/dist/fast-path/handlers/approvals.d.ts +11 -0
  391. package/dist/fast-path/handlers/approvals.d.ts.map +1 -0
  392. package/dist/fast-path/handlers/approvals.js +136 -0
  393. package/dist/fast-path/handlers/approvals.js.map +1 -0
  394. package/dist/fast-path/handlers/discovery.d.ts.map +1 -1
  395. package/dist/fast-path/handlers/discovery.js +17 -3
  396. package/dist/fast-path/handlers/discovery.js.map +1 -1
  397. package/dist/fast-path/manifest.d.ts +1 -0
  398. package/dist/fast-path/manifest.d.ts.map +1 -1
  399. package/dist/fast-path/manifest.js.map +1 -1
  400. package/dist/fast-path.d.ts.map +1 -1
  401. package/dist/fast-path.js +3 -0
  402. package/dist/fast-path.js.map +1 -1
  403. package/dist/index.d.ts +23 -0
  404. package/dist/index.d.ts.map +1 -0
  405. package/dist/index.js +38 -0
  406. package/dist/index.js.map +1 -0
  407. package/dist/manifest-compact.txt +13 -11
  408. package/dist/manifest-search.json +1 -1
  409. package/dist/manifest.json +2560 -103
  410. package/dist/mcp/handler.d.ts.map +1 -1
  411. package/dist/mcp/handler.js +14 -2
  412. package/dist/mcp/handler.js.map +1 -1
  413. package/dist/mcp/tools.d.ts.map +1 -1
  414. package/dist/mcp/tools.js +11 -3
  415. package/dist/mcp/tools.js.map +1 -1
  416. package/dist/output/auth-guidance.d.ts +14 -0
  417. package/dist/output/auth-guidance.d.ts.map +1 -0
  418. package/dist/output/auth-guidance.js +50 -0
  419. package/dist/output/auth-guidance.js.map +1 -0
  420. package/dist/output/error-map.d.ts +1 -1
  421. package/dist/output/error-map.d.ts.map +1 -1
  422. package/dist/output/error-map.js +28 -4
  423. package/dist/output/error-map.js.map +1 -1
  424. package/dist/output/next-actions.d.ts.map +1 -1
  425. package/dist/output/next-actions.js +19 -3
  426. package/dist/output/next-actions.js.map +1 -1
  427. package/dist/registry.d.ts +19 -1
  428. package/dist/registry.d.ts.map +1 -1
  429. package/dist/registry.js +10 -0
  430. package/dist/registry.js.map +1 -1
  431. package/dist/social/browser-errors.d.ts +13 -0
  432. package/dist/social/browser-errors.d.ts.map +1 -0
  433. package/dist/social/browser-errors.js +36 -0
  434. package/dist/social/browser-errors.js.map +1 -0
  435. package/dist/social/capabilities.d.ts +29 -0
  436. package/dist/social/capabilities.d.ts.map +1 -0
  437. package/dist/social/capabilities.js +448 -0
  438. package/dist/social/capabilities.js.map +1 -0
  439. package/dist/social/comments.d.ts +26 -0
  440. package/dist/social/comments.d.ts.map +1 -0
  441. package/dist/social/comments.js +97 -0
  442. package/dist/social/comments.js.map +1 -0
  443. package/dist/social/video-text.d.ts +27 -0
  444. package/dist/social/video-text.d.ts.map +1 -0
  445. package/dist/social/video-text.js +140 -0
  446. package/dist/social/video-text.js.map +1 -0
  447. package/dist/types/patent.d.ts +160 -0
  448. package/dist/types/patent.d.ts.map +1 -0
  449. package/dist/types/patent.js +16 -0
  450. package/dist/types/patent.js.map +1 -0
  451. package/dist/types/scholarly.d.ts +49 -0
  452. package/dist/types/scholarly.d.ts.map +1 -0
  453. package/dist/types/scholarly.js +16 -0
  454. package/dist/types/scholarly.js.map +1 -0
  455. package/dist/types.d.ts +12 -0
  456. package/dist/types.d.ts.map +1 -1
  457. package/dist/types.js.map +1 -1
  458. package/package.json +9 -4
  459. package/server.json +3 -3
  460. package/skills/unicli/SKILL.md +1 -1
  461. package/skills/unicli-claude-code/SKILL.md +1 -1
  462. package/skills/unicli-hermes/SKILL.md +1 -1
  463. package/src/adapters/acl-anthology/papers.ts +157 -0
  464. package/src/adapters/arxiv/download.yaml +1 -1
  465. package/src/adapters/arxiv/paper.yaml +1 -1
  466. package/src/adapters/arxiv/papers.ts +2 -0
  467. package/src/adapters/arxiv/search.yaml +1 -1
  468. package/src/adapters/arxiv/trending.yaml +1 -1
  469. package/src/adapters/baidu-scholar/search.ts +5 -0
  470. package/src/adapters/bilibili/comments-tree.test.ts +41 -0
  471. package/src/adapters/bilibili/comments.ts +78 -4
  472. package/src/adapters/bilibili/compat.ts +5 -2
  473. package/src/adapters/bilibili/download.ts +7 -4
  474. package/src/adapters/bilibili/wbi.ts +6 -3
  475. package/src/adapters/brave/search.yaml +53 -0
  476. package/src/adapters/cipo/_shared.ts +98 -0
  477. package/src/adapters/cipo/get.ts +188 -0
  478. package/src/adapters/cipo/legal-status.ts +148 -0
  479. package/src/adapters/cipo/search.ts +195 -0
  480. package/src/adapters/cnipa/_shared.ts +138 -0
  481. package/src/adapters/cnipa/get.ts +199 -0
  482. package/src/adapters/cnipa/legal-status.ts +162 -0
  483. package/src/adapters/cnipa/search.ts +229 -0
  484. package/src/adapters/crossref/works.ts +209 -0
  485. package/src/adapters/cvf/papers.ts +136 -0
  486. package/src/adapters/dblp/publications.ts +4 -0
  487. package/src/adapters/dpma/get.yaml +67 -0
  488. package/src/adapters/dpma/search.yaml +77 -0
  489. package/src/adapters/duckduckgo/search.yaml +54 -0
  490. package/src/adapters/duckduckgo/suggest.yaml +52 -0
  491. package/src/adapters/epo/family.yaml +69 -0
  492. package/src/adapters/epo/get.yaml +74 -0
  493. package/src/adapters/epo/legal-status.yaml +63 -0
  494. package/src/adapters/epo/search.yaml +84 -0
  495. package/src/adapters/espacenet/_shared.ts +98 -0
  496. package/src/adapters/espacenet/family.ts +161 -0
  497. package/src/adapters/espacenet/get.ts +185 -0
  498. package/src/adapters/espacenet/legal-status.ts +151 -0
  499. package/src/adapters/espacenet/search.ts +229 -0
  500. package/src/adapters/facebook/subtitles.ts +44 -0
  501. package/src/adapters/fips/_shared.ts +109 -0
  502. package/src/adapters/fips/get.ts +186 -0
  503. package/src/adapters/fips/search.ts +195 -0
  504. package/src/adapters/freepatentsonline-web/_shared.ts +273 -0
  505. package/src/adapters/freepatentsonline-web/get.ts +144 -0
  506. package/src/adapters/freepatentsonline-web/search.ts +170 -0
  507. package/src/adapters/google-patents-bq/prior-art.yaml +80 -0
  508. package/src/adapters/google-patents-bq/search.yaml +97 -0
  509. package/src/adapters/google-patents-web/_shared.ts +242 -0
  510. package/src/adapters/google-patents-web/get.ts +224 -0
  511. package/src/adapters/google-patents-web/search.ts +196 -0
  512. package/src/adapters/google-scholar/cite.ts +1 -0
  513. package/src/adapters/google-scholar/profile.ts +5 -0
  514. package/src/adapters/google-scholar/search.ts +5 -0
  515. package/src/adapters/hf/paper.test.ts +10 -0
  516. package/src/adapters/hf/paper.ts +1 -0
  517. package/src/adapters/hf/top.yaml +1 -1
  518. package/src/adapters/huggingface-papers/daily.yaml +1 -1
  519. package/src/adapters/huggingface-papers/search.yaml +1 -1
  520. package/src/adapters/inpi-br/_shared.ts +98 -0
  521. package/src/adapters/inpi-br/get.ts +193 -0
  522. package/src/adapters/inpi-br/search.ts +206 -0
  523. package/src/adapters/inpi-fr/get.yaml +62 -0
  524. package/src/adapters/inpi-fr/search.yaml +74 -0
  525. package/src/adapters/instagram/subtitles.ts +44 -0
  526. package/src/adapters/ipaustralia/get.yaml +67 -0
  527. package/src/adapters/ipaustralia/search.yaml +74 -0
  528. package/src/adapters/jpo/get.yaml +63 -0
  529. package/src/adapters/jpo/search.yaml +76 -0
  530. package/src/adapters/kipris/get.yaml +69 -0
  531. package/src/adapters/kipris/legal-status.yaml +58 -0
  532. package/src/adapters/kipris/search.yaml +79 -0
  533. package/src/adapters/lens/get.yaml +64 -0
  534. package/src/adapters/lens/search.yaml +82 -0
  535. package/src/adapters/mastodon/statuses.test.ts +82 -0
  536. package/src/adapters/mastodon/statuses.ts +208 -0
  537. package/src/adapters/neurips/proceedings.ts +126 -0
  538. package/src/adapters/openalex/works.ts +33 -0
  539. package/src/adapters/openreview/papers.ts +5 -0
  540. package/src/adapters/patsnap/get.yaml +65 -0
  541. package/src/adapters/patsnap/search.yaml +77 -0
  542. package/src/adapters/pmlr/proceedings.ts +167 -0
  543. package/src/adapters/pqai/prior-art.yaml +59 -0
  544. package/src/adapters/pqai/search.yaml +60 -0
  545. package/src/adapters/pubmed/articles.ts +5 -0
  546. package/src/adapters/reddit/comments-tree.test.ts +79 -0
  547. package/src/adapters/reddit/comments.ts +159 -0
  548. package/src/adapters/semantic-scholar/papers.ts +268 -0
  549. package/src/adapters/threads/post.test.ts +64 -0
  550. package/src/adapters/threads/post.ts +366 -0
  551. package/src/adapters/threads/user.yaml +73 -0
  552. package/src/adapters/tiktok/subtitles.ts +44 -0
  553. package/src/adapters/twitter/accept.ts +5 -2
  554. package/src/adapters/twitter/browser-fallback.ts +138 -0
  555. package/src/adapters/twitter/browser-state.ts +74 -0
  556. package/src/adapters/twitter/client.ts +51 -21
  557. package/src/adapters/twitter/reply-dm.ts +5 -2
  558. package/src/adapters/twitter/reply.ts +1 -0
  559. package/src/adapters/twitter/search.ts +12 -38
  560. package/src/adapters/twitter/thread.test.ts +43 -0
  561. package/src/adapters/twitter/thread.ts +44 -2
  562. package/src/adapters/twitter/trending.ts +14 -95
  563. package/src/adapters/ukipo/info.yaml +43 -0
  564. package/src/adapters/unpaywall/works.ts +138 -0
  565. package/src/adapters/uspto/get.yaml +67 -0
  566. package/src/adapters/uspto/legal-status.yaml +58 -0
  567. package/src/adapters/uspto/search.yaml +88 -0
  568. package/src/adapters/wipo-patentscope/info.yaml +43 -0
  569. package/src/adapters/xiaohongshu/browser-state.ts +95 -0
  570. package/src/adapters/xiaohongshu/comments.ts +29 -6
  571. package/src/adapters/xiaohongshu/download.ts +60 -11
  572. package/src/adapters/xiaohongshu/search.ts +18 -6
  573. package/src/adapters/xiaohongshu/trending.ts +112 -0
  574. package/src/adapters/yahoo/search.yaml +52 -0
  575. package/src/adapters/youtube/comments-microformat.test.ts +35 -0
  576. package/src/adapters/youtube/comments-tree.test.ts +74 -0
  577. package/src/adapters/youtube/comments.ts +166 -12
  578. package/src/adapters/youtube/subtitles.ts +44 -0
  579. package/src/adapters/yt-dlp/subtitles.ts +43 -0
  580. package/src/adapters/zhihu/answer-detail.test.ts +83 -0
  581. package/src/adapters/zhihu/answer-detail.ts +275 -0
  582. package/src/adapters/zhihu/comment-tree.test.ts +57 -0
  583. package/src/adapters/zhihu/comment.ts +186 -0
  584. package/src/adapters/zhihu/recommend.test.ts +65 -0
  585. package/src/adapters/zhihu/recommend.ts +207 -0
  586. package/src/adapters/zotero/search.yaml +1 -1
@@ -0,0 +1,74 @@
1
+ /**
2
+ * @owner Twitter browser adapters.
3
+ * @does Detects X/Twitter login and challenge pages in browser fallback flows.
4
+ * @needs Browser-backed IPage from Uni-CLI runtime.
5
+ * @feeds twitter.search and twitter.trending.
6
+ * @breaks X/Twitter 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 TwitterPageState {
16
+ url: string;
17
+ title: string;
18
+ text: string;
19
+ }
20
+
21
+ async function readTwitterPageState(page: IPage): Promise<TwitterPageState> {
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<TwitterPageState>;
30
+ return {
31
+ url: String(state.url ?? ""),
32
+ title: String(state.title ?? ""),
33
+ text: String(state.text ?? ""),
34
+ };
35
+ }
36
+
37
+ export async function gotoTwitterPage(
38
+ page: IPage,
39
+ url: string,
40
+ command: string,
41
+ ): Promise<void> {
42
+ try {
43
+ await page.goto(url, { settleMs: 2500 });
44
+ } catch (err) {
45
+ const message = err instanceof Error ? err.message : String(err);
46
+ if (!/net::ERR_ABORTED/i.test(message)) throw err;
47
+ }
48
+ await page.wait(2);
49
+ await assertTwitterReadable(page, command);
50
+ }
51
+
52
+ export async function assertTwitterReadable(
53
+ page: IPage,
54
+ command: string,
55
+ ): Promise<void> {
56
+ const state = await readTwitterPageState(page);
57
+ const haystack = `${state.url}\n${state.title}\n${state.text}`;
58
+ if (
59
+ /captcha|cloudflare|challenge|verify you are human|unusual traffic/i.test(
60
+ haystack,
61
+ )
62
+ ) {
63
+ throw socialChallengeError(
64
+ "twitter",
65
+ command,
66
+ `Twitter/X is showing a challenge page: ${state.title || state.url}`,
67
+ );
68
+ }
69
+ if (
70
+ /\/i\/flow\/login|Sign in to X|Log in to X|登录 X|登录后/i.test(haystack)
71
+ ) {
72
+ throw socialAuthError("twitter", command);
73
+ }
74
+ }
@@ -5,7 +5,10 @@
5
5
  * Requires ct0 (CSRF token) and auth_token cookies in ~/.unicli/cookies/twitter.json
6
6
  */
7
7
 
8
- import { loadCookies, formatCookieHeader } from "../../engine/cookies.js";
8
+ import {
9
+ loadCookiesWithCDP,
10
+ formatCookieHeader,
11
+ } from "../../engine/cookies.js";
9
12
  import { USER_AGENT } from "../../constants.js";
10
13
 
11
14
  // Public bearer token — same for all Twitter web clients, not a secret
@@ -14,6 +17,45 @@ const BEARER_TOKEN =
14
17
 
15
18
  const GRAPHQL_BASE = "https://x.com/i/api/graphql";
16
19
 
20
+ function throwTwitterApiError(
21
+ label: string,
22
+ status: number,
23
+ preview: string,
24
+ ): never {
25
+ const err = new Error(
26
+ `Twitter API error: HTTP ${status} on ${label}\n${preview.slice(0, 200)}`,
27
+ ) as Error & {
28
+ code?: string;
29
+ suggestion?: string;
30
+ retryable?: boolean;
31
+ alternatives?: string[];
32
+ };
33
+ err.code =
34
+ status === 401 || status === 403
35
+ ? "auth_required"
36
+ : status === 404
37
+ ? "upstream_error"
38
+ : status === 429
39
+ ? "rate_limited"
40
+ : status >= 500
41
+ ? "upstream_error"
42
+ : "api_error";
43
+ err.retryable = status === 429 || status >= 500;
44
+ err.suggestion =
45
+ status === 404
46
+ ? "Twitter/X changed or removed this web API operation. Run `unicli repair twitter <command>` or use a browser-backed command while the GraphQL operation is refreshed."
47
+ : status === 401 || status === 403
48
+ ? "Refresh X login state with `unicli --auth-retry twitter <command> --args-file <path.json>`, or open https://x.com in Chrome and sign in."
49
+ : status === 429
50
+ ? "Twitter/X rate-limited the request. Wait, reduce limit, then retry."
51
+ : "Twitter/X API returned an upstream error. Retry once; if it persists, run `unicli repair twitter <command>`.";
52
+ err.alternatives = [
53
+ "unicli auth import twitter --domain x.com",
54
+ "unicli browser open https://x.com",
55
+ ];
56
+ throw err;
57
+ }
58
+
17
59
  /** Standard Twitter GraphQL feature flags */
18
60
  export const FEATURES: Record<string, boolean> = {
19
61
  rweb_tipjar_consumption_enabled: true,
@@ -56,7 +98,7 @@ export async function twitterFetch(
56
98
  variables: Record<string, unknown>,
57
99
  features: Record<string, boolean> = FEATURES,
58
100
  ): Promise<unknown> {
59
- const cookies = loadCookies("twitter");
101
+ const cookies = await loadCookiesWithCDP("twitter", "x.com");
60
102
  if (!cookies) {
61
103
  throw new Error(
62
104
  'No cookies found for "twitter". Run: unicli auth setup twitter',
@@ -92,10 +134,7 @@ export async function twitterFetch(
92
134
 
93
135
  if (!resp.ok) {
94
136
  const preview = await resp.text().catch(() => "");
95
- throw new Error(
96
- `Twitter API error: HTTP ${resp.status} on ${endpoint}\n` +
97
- `${preview.slice(0, 200)}`,
98
- );
137
+ throwTwitterApiError(endpoint, resp.status, preview);
99
138
  }
100
139
 
101
140
  return resp.json();
@@ -110,7 +149,7 @@ export async function twitterPostFetch(
110
149
  variables: Record<string, unknown>,
111
150
  features: Record<string, boolean> = FEATURES,
112
151
  ): Promise<unknown> {
113
- const cookies = loadCookies("twitter");
152
+ const cookies = await loadCookiesWithCDP("twitter", "x.com");
114
153
  if (!cookies) {
115
154
  throw new Error(
116
155
  'No cookies found for "twitter". Run: unicli auth setup twitter',
@@ -143,10 +182,7 @@ export async function twitterPostFetch(
143
182
 
144
183
  if (!resp.ok) {
145
184
  const preview = await resp.text().catch(() => "");
146
- throw new Error(
147
- `Twitter API error: HTTP ${resp.status} on ${endpoint}\n` +
148
- `${preview.slice(0, 200)}`,
149
- );
185
+ throwTwitterApiError(endpoint, resp.status, preview);
150
186
  }
151
187
 
152
188
  return resp.json();
@@ -163,7 +199,7 @@ export async function twitterRestFetch(
163
199
  path: string,
164
200
  params: Record<string, string> = {},
165
201
  ): Promise<unknown> {
166
- const cookies = loadCookies("twitter");
202
+ const cookies = await loadCookiesWithCDP("twitter", "x.com");
167
203
  if (!cookies) {
168
204
  throw new Error(
169
205
  'No cookies found for "twitter". Run: unicli auth setup twitter',
@@ -195,10 +231,7 @@ export async function twitterRestFetch(
195
231
 
196
232
  if (!resp.ok) {
197
233
  const preview = await resp.text().catch(() => "");
198
- throw new Error(
199
- `Twitter REST API error: HTTP ${resp.status} on ${path}\n` +
200
- `${preview.slice(0, 200)}`,
201
- );
234
+ throwTwitterApiError(path, resp.status, preview);
202
235
  }
203
236
 
204
237
  return resp.json();
@@ -215,7 +248,7 @@ export async function twitterGuideFetch(
215
248
  url: string,
216
249
  params: Record<string, string> = {},
217
250
  ): Promise<unknown> {
218
- const cookies = loadCookies("twitter");
251
+ const cookies = await loadCookiesWithCDP("twitter", "x.com");
219
252
  if (!cookies) {
220
253
  throw new Error(
221
254
  'No cookies found for "twitter". Run: unicli auth setup twitter',
@@ -247,10 +280,7 @@ export async function twitterGuideFetch(
247
280
 
248
281
  if (!resp.ok) {
249
282
  const preview = await resp.text().catch(() => "");
250
- throw new Error(
251
- `Twitter Guide API error: HTTP ${resp.status}\n` +
252
- `${preview.slice(0, 200)}`,
253
- );
283
+ throwTwitterApiError("guide", resp.status, preview);
254
284
  }
255
285
 
256
286
  return resp.json();
@@ -6,7 +6,10 @@
6
6
 
7
7
  import { cli } from "../../registry.js";
8
8
  import { Strategy } from "../../types.js";
9
- import { loadCookies, formatCookieHeader } from "../../engine/cookies.js";
9
+ import {
10
+ loadCookiesWithCDP,
11
+ formatCookieHeader,
12
+ } from "../../engine/cookies.js";
10
13
  import { USER_AGENT } from "../../constants.js";
11
14
 
12
15
  const BEARER_TOKEN =
@@ -36,7 +39,7 @@ cli({
36
39
  const conversationId = String(kwargs.conversation_id);
37
40
  const text = kwargs.text as string;
38
41
 
39
- const cookies = loadCookies("twitter");
42
+ const cookies = await loadCookiesWithCDP("twitter", "x.com");
40
43
  if (!cookies) {
41
44
  throw new Error(
42
45
  'No cookies found for "twitter". Run: unicli auth setup twitter',
@@ -15,6 +15,7 @@ cli({
15
15
  description: "Reply to a tweet",
16
16
  domain: "x.com",
17
17
  strategy: Strategy.COOKIE,
18
+ socialCapabilities: ["write_comment"],
18
19
  args: [
19
20
  {
20
21
  name: "tweet_id",
@@ -4,14 +4,8 @@
4
4
 
5
5
  import { cli } from "../../registry.js";
6
6
  import { Strategy } from "../../types.js";
7
- import {
8
- twitterFetch,
9
- FEATURES,
10
- extractTweetsFromInstructions,
11
- } from "./client.js";
12
-
13
- const QUERY_ID = "nK1dw4oV3k4w5TdtcAdSww";
14
- const ENDPOINT = "SearchTimeline";
7
+ import { browserSearchTweets } from "./browser-fallback.js";
8
+ import type { IPage } from "../../types.js";
15
9
 
16
10
  cli({
17
11
  site: "twitter",
@@ -19,6 +13,8 @@ cli({
19
13
  description: "Search tweets by keyword",
20
14
  domain: "x.com",
21
15
  strategy: Strategy.COOKIE,
16
+ browser: true,
17
+ browserSession: "user",
22
18
  args: [
23
19
  {
24
20
  name: "query",
@@ -26,39 +22,17 @@ cli({
26
22
  positional: true,
27
23
  description: "Search query",
28
24
  },
25
+ {
26
+ name: "limit",
27
+ type: "int",
28
+ default: 20,
29
+ description: "Number of tweets",
30
+ },
29
31
  ],
30
32
  columns: ["id", "author", "text", "likes", "retweets", "views", "url"],
31
- func: async (_page, kwargs) => {
33
+ func: async (page, kwargs) => {
32
34
  const query = kwargs.query as string;
33
35
  const count = Math.min((kwargs.limit as number) ?? 20, 50);
34
-
35
- const variables = {
36
- rawQuery: query,
37
- count,
38
- querySource: "typed_query",
39
- product: "Latest",
40
- };
41
-
42
- const data = (await twitterFetch(
43
- ENDPOINT,
44
- QUERY_ID,
45
- variables,
46
- FEATURES,
47
- )) as Record<string, unknown>;
48
-
49
- // Navigate: data.search_by_raw_query.search_timeline.timeline.instructions
50
- const searchByRawQuery = data.data as Record<string, unknown> | undefined;
51
- const searchResult = searchByRawQuery?.search_by_raw_query as
52
- | Record<string, unknown>
53
- | undefined;
54
- const searchTimeline = searchResult?.search_timeline as
55
- | Record<string, unknown>
56
- | undefined;
57
- const timeline = searchTimeline?.timeline as
58
- | Record<string, unknown>
59
- | undefined;
60
- const instructions = (timeline?.instructions as unknown[]) ?? [];
61
-
62
- return extractTweetsFromInstructions(instructions);
36
+ return browserSearchTweets(page as IPage, query, count);
63
37
  },
64
38
  });
@@ -0,0 +1,43 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import { normalizeTwitterThreadRows } from "./thread.js";
4
+
5
+ describe("normalizeTwitterThreadRows", () => {
6
+ it("adds normalized comment hierarchy fields to thread rows", () => {
7
+ const rows = normalizeTwitterThreadRows("root", [
8
+ {
9
+ id: "root",
10
+ author: "Root",
11
+ text: "Root tweet",
12
+ likes: 10,
13
+ retweets: 2,
14
+ views: "100",
15
+ url: "https://x.com/i/status/root",
16
+ },
17
+ {
18
+ id: "reply-1",
19
+ author: "Reply",
20
+ text: "Reply tweet",
21
+ likes: 1,
22
+ retweets: 0,
23
+ views: "5",
24
+ url: "https://x.com/i/status/reply-1",
25
+ },
26
+ ]);
27
+
28
+ expect(rows).toEqual([
29
+ expect.objectContaining({
30
+ id: "root",
31
+ parent_id: "",
32
+ depth: 0,
33
+ path: "0001",
34
+ }),
35
+ expect.objectContaining({
36
+ id: "reply-1",
37
+ parent_id: "root",
38
+ depth: 1,
39
+ path: "0001.0001",
40
+ }),
41
+ ]);
42
+ });
43
+ });
@@ -13,12 +13,40 @@ import {
13
13
  const QUERY_ID = "B9_KmbkLhXt6jRwGjJrweg";
14
14
  const ENDPOINT = "TweetDetail";
15
15
 
16
+ interface TweetRow {
17
+ id: string;
18
+ author: string;
19
+ text: string;
20
+ likes: number;
21
+ retweets: number;
22
+ views: string;
23
+ url: string;
24
+ }
25
+
26
+ export function normalizeTwitterThreadRows(
27
+ tweetId: string,
28
+ tweets: TweetRow[],
29
+ ): Array<TweetRow & { parent_id: string; depth: number; path: string }> {
30
+ let replyRank = 0;
31
+ return tweets.map((tweet) => {
32
+ const isRoot = tweet.id === tweetId;
33
+ if (!isRoot) replyRank += 1;
34
+ return {
35
+ ...tweet,
36
+ parent_id: isRoot ? "" : tweetId,
37
+ depth: isRoot ? 0 : 1,
38
+ path: isRoot ? "0001" : `0001.${String(replyRank).padStart(4, "0")}`,
39
+ };
40
+ });
41
+ }
42
+
16
43
  cli({
17
44
  site: "twitter",
18
45
  name: "thread",
19
46
  description: "Get a tweet and its conversation thread",
20
47
  domain: "x.com",
21
48
  strategy: Strategy.COOKIE,
49
+ socialCapabilities: ["read", "comments", "comment_replies"],
22
50
  args: [
23
51
  {
24
52
  name: "tweet_id",
@@ -27,7 +55,18 @@ cli({
27
55
  description: "Tweet ID (numeric)",
28
56
  },
29
57
  ],
30
- columns: ["id", "author", "text", "likes", "retweets", "views", "url"],
58
+ columns: [
59
+ "id",
60
+ "parent_id",
61
+ "author",
62
+ "text",
63
+ "likes",
64
+ "retweets",
65
+ "views",
66
+ "url",
67
+ "depth",
68
+ "path",
69
+ ],
31
70
  func: async (_page, kwargs) => {
32
71
  const tweetId = String(kwargs.tweet_id);
33
72
 
@@ -56,6 +95,9 @@ cli({
56
95
  | undefined;
57
96
  const instructions = (conversation?.instructions as unknown[]) ?? [];
58
97
 
59
- return extractTweetsFromInstructions(instructions);
98
+ return normalizeTwitterThreadRows(
99
+ tweetId,
100
+ extractTweetsFromInstructions(instructions),
101
+ );
60
102
  },
61
103
  });
@@ -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