@jackwener/opencli 1.0.6 → 1.1.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 (400) hide show
  1. package/.agents/skills/cross-project-adapter-migration/SKILL.md +2 -2
  2. package/.github/pull_request_template.md +7 -0
  3. package/.github/workflows/doc-check.yml +36 -0
  4. package/.github/workflows/docs.yml +7 -42
  5. package/CHANGELOG.md +23 -0
  6. package/CLI-EXPLORER.md +9 -8
  7. package/README.md +51 -10
  8. package/README.zh-CN.md +29 -11
  9. package/SKILL.md +102 -33
  10. package/dist/browser/cdp.js +6 -1
  11. package/dist/browser/page.d.ts +4 -1
  12. package/dist/browser/page.js +7 -1
  13. package/dist/build-manifest.js +23 -16
  14. package/dist/cli-manifest.json +951 -296
  15. package/dist/cli.d.ts +6 -0
  16. package/dist/cli.js +225 -148
  17. package/dist/clis/antigravity/serve.js +296 -47
  18. package/dist/clis/apple-podcasts/commands.test.d.ts +2 -0
  19. package/dist/clis/apple-podcasts/commands.test.js +76 -0
  20. package/dist/clis/apple-podcasts/search.js +2 -2
  21. package/dist/clis/apple-podcasts/top.js +9 -2
  22. package/dist/clis/arxiv/paper.js +21 -0
  23. package/dist/clis/arxiv/search.js +24 -0
  24. package/dist/clis/arxiv/utils.d.ts +18 -0
  25. package/dist/clis/arxiv/utils.js +49 -0
  26. package/dist/clis/bilibili/dynamic.js +1 -1
  27. package/dist/clis/bilibili/favorite.js +1 -1
  28. package/dist/clis/bilibili/feed.js +1 -1
  29. package/dist/clis/bilibili/following.js +1 -1
  30. package/dist/clis/bilibili/history.js +1 -1
  31. package/dist/clis/bilibili/me.js +1 -1
  32. package/dist/clis/bilibili/ranking.js +1 -1
  33. package/dist/clis/bilibili/search.js +3 -3
  34. package/dist/clis/bilibili/subtitle.js +1 -1
  35. package/dist/clis/bilibili/user-videos.js +1 -1
  36. package/dist/{bilibili.d.ts → clis/bilibili/utils.d.ts} +1 -1
  37. package/dist/clis/bloomberg/businessweek.d.ts +1 -0
  38. package/dist/clis/bloomberg/businessweek.js +17 -0
  39. package/dist/clis/bloomberg/economics.d.ts +1 -0
  40. package/dist/clis/bloomberg/economics.js +17 -0
  41. package/dist/clis/bloomberg/feeds.d.ts +1 -0
  42. package/dist/clis/bloomberg/feeds.js +15 -0
  43. package/dist/clis/bloomberg/industries.d.ts +1 -0
  44. package/dist/clis/bloomberg/industries.js +17 -0
  45. package/dist/clis/bloomberg/main.d.ts +1 -0
  46. package/dist/clis/bloomberg/main.js +17 -0
  47. package/dist/clis/bloomberg/markets.d.ts +1 -0
  48. package/dist/clis/bloomberg/markets.js +17 -0
  49. package/dist/clis/bloomberg/news.d.ts +1 -0
  50. package/dist/clis/bloomberg/news.js +105 -0
  51. package/dist/clis/bloomberg/opinions.d.ts +1 -0
  52. package/dist/clis/bloomberg/opinions.js +17 -0
  53. package/dist/clis/bloomberg/politics.d.ts +1 -0
  54. package/dist/clis/bloomberg/politics.js +17 -0
  55. package/dist/clis/bloomberg/tech.d.ts +1 -0
  56. package/dist/clis/bloomberg/tech.js +17 -0
  57. package/dist/clis/bloomberg/utils.d.ts +34 -0
  58. package/dist/clis/bloomberg/utils.js +364 -0
  59. package/dist/clis/bloomberg/utils.test.d.ts +1 -0
  60. package/dist/clis/bloomberg/utils.test.js +129 -0
  61. package/dist/clis/boss/batchgreet.d.ts +1 -0
  62. package/dist/clis/boss/batchgreet.js +147 -0
  63. package/dist/clis/boss/chatlist.js +2 -2
  64. package/dist/clis/boss/detail.js +2 -2
  65. package/dist/clis/boss/exchange.d.ts +1 -0
  66. package/dist/clis/boss/exchange.js +111 -0
  67. package/dist/clis/boss/greet.d.ts +1 -0
  68. package/dist/clis/boss/greet.js +175 -0
  69. package/dist/clis/boss/invite.d.ts +1 -0
  70. package/dist/clis/boss/invite.js +158 -0
  71. package/dist/clis/boss/joblist.d.ts +1 -0
  72. package/dist/clis/boss/joblist.js +55 -0
  73. package/dist/clis/boss/mark.d.ts +1 -0
  74. package/dist/clis/boss/mark.js +141 -0
  75. package/dist/clis/boss/recommend.d.ts +1 -0
  76. package/dist/clis/boss/recommend.js +83 -0
  77. package/dist/clis/boss/search.js +1 -1
  78. package/dist/clis/boss/send.js +1 -1
  79. package/dist/clis/boss/stats.d.ts +1 -0
  80. package/dist/clis/boss/stats.js +116 -0
  81. package/dist/clis/chaoxing/assignments.js +1 -1
  82. package/dist/clis/chaoxing/exams.js +1 -1
  83. package/dist/{chaoxing.d.ts → clis/chaoxing/utils.d.ts} +1 -1
  84. package/dist/{chaoxing.js → clis/chaoxing/utils.js} +0 -2
  85. package/dist/clis/chaoxing/utils.test.d.ts +1 -0
  86. package/dist/{chaoxing.test.js → clis/chaoxing/utils.test.js} +1 -1
  87. package/dist/clis/chatgpt/read.js +1 -1
  88. package/dist/clis/chatwise/export.js +1 -1
  89. package/dist/clis/chatwise/model.js +2 -2
  90. package/dist/clis/chatwise/screenshot.js +1 -1
  91. package/dist/clis/codex/export.js +1 -1
  92. package/dist/clis/codex/model.js +2 -2
  93. package/dist/clis/codex/screenshot.js +1 -1
  94. package/dist/clis/coupang/add-to-cart.js +3 -4
  95. package/dist/clis/coupang/search.js +2 -4
  96. package/dist/clis/coupang/utils.test.d.ts +1 -0
  97. package/dist/{coupang.test.js → clis/coupang/utils.test.js} +1 -1
  98. package/dist/clis/ctrip/search.js +1 -1
  99. package/dist/clis/cursor/export.js +1 -1
  100. package/dist/clis/cursor/model.js +2 -2
  101. package/dist/clis/cursor/screenshot.js +1 -1
  102. package/dist/clis/jike/comment.js +2 -3
  103. package/dist/clis/jike/create.js +1 -2
  104. package/dist/clis/jike/feed.js +0 -1
  105. package/dist/clis/jike/like.js +1 -2
  106. package/dist/clis/jike/notifications.js +0 -1
  107. package/dist/clis/jike/post.yaml +1 -0
  108. package/dist/clis/jike/repost.js +1 -2
  109. package/dist/clis/jike/search.js +2 -3
  110. package/dist/clis/jike/topic.yaml +1 -0
  111. package/dist/clis/jike/user.yaml +1 -0
  112. package/dist/clis/jimeng/history.yaml +0 -1
  113. package/dist/clis/linkedin/search.js +7 -7
  114. package/dist/clis/linux-do/category.yaml +1 -0
  115. package/dist/clis/linux-do/search.yaml +4 -3
  116. package/dist/clis/linux-do/topic.yaml +1 -0
  117. package/dist/clis/notion/export.js +1 -1
  118. package/dist/clis/reddit/comment.js +3 -4
  119. package/dist/clis/reddit/read.js +4 -5
  120. package/dist/clis/reddit/save.js +2 -3
  121. package/dist/clis/reddit/saved.js +0 -1
  122. package/dist/clis/reddit/search.yaml +1 -0
  123. package/dist/clis/reddit/subscribe.js +0 -1
  124. package/dist/clis/reddit/upvote.js +2 -3
  125. package/dist/clis/reddit/upvoted.js +0 -1
  126. package/dist/clis/reddit/user-comments.yaml +1 -0
  127. package/dist/clis/reddit/user-posts.yaml +1 -0
  128. package/dist/clis/reddit/user.yaml +1 -0
  129. package/dist/clis/reuters/search.js +1 -1
  130. package/dist/clis/sinafinance/news.d.ts +7 -0
  131. package/dist/clis/sinafinance/news.js +61 -0
  132. package/dist/clis/smzdm/search.js +2 -3
  133. package/dist/clis/stackoverflow/search.yaml +1 -0
  134. package/dist/clis/steam/top-sellers.yaml +29 -0
  135. package/dist/clis/twitter/accept.js +2 -2
  136. package/dist/clis/twitter/article.js +2 -2
  137. package/dist/clis/twitter/block.d.ts +1 -0
  138. package/dist/clis/twitter/block.js +88 -0
  139. package/dist/clis/twitter/delete.js +1 -1
  140. package/dist/clis/twitter/hide-reply.d.ts +1 -0
  141. package/dist/clis/twitter/hide-reply.js +66 -0
  142. package/dist/clis/twitter/like.js +1 -1
  143. package/dist/clis/twitter/post.js +1 -1
  144. package/dist/clis/twitter/reply-dm.js +1 -1
  145. package/dist/clis/twitter/reply.js +2 -2
  146. package/dist/clis/twitter/search.js +1 -1
  147. package/dist/clis/twitter/thread.js +2 -2
  148. package/dist/clis/twitter/trending.d.ts +1 -0
  149. package/dist/clis/twitter/trending.js +91 -0
  150. package/dist/clis/twitter/unblock.d.ts +1 -0
  151. package/dist/clis/twitter/unblock.js +71 -0
  152. package/dist/clis/v2ex/topic.yaml +1 -0
  153. package/dist/clis/weibo/hot.js +0 -1
  154. package/dist/clis/weread/book.js +1 -1
  155. package/dist/clis/weread/highlights.js +1 -1
  156. package/dist/clis/weread/notes.js +1 -1
  157. package/dist/clis/weread/search.js +1 -1
  158. package/dist/clis/wikipedia/search.d.ts +1 -0
  159. package/dist/clis/wikipedia/search.js +30 -0
  160. package/dist/clis/wikipedia/summary.d.ts +1 -0
  161. package/dist/clis/wikipedia/summary.js +28 -0
  162. package/dist/clis/wikipedia/utils.d.ts +8 -0
  163. package/dist/clis/wikipedia/utils.js +18 -0
  164. package/dist/clis/xiaohongshu/creator-note-detail.d.ts +79 -5
  165. package/dist/clis/xiaohongshu/creator-note-detail.js +323 -70
  166. package/dist/clis/xiaohongshu/creator-note-detail.test.d.ts +1 -0
  167. package/dist/clis/xiaohongshu/creator-note-detail.test.js +258 -0
  168. package/dist/clis/xiaohongshu/creator-notes-summary.d.ts +28 -0
  169. package/dist/clis/xiaohongshu/creator-notes-summary.js +92 -0
  170. package/dist/clis/xiaohongshu/creator-notes-summary.test.d.ts +1 -0
  171. package/dist/clis/xiaohongshu/creator-notes-summary.test.js +49 -0
  172. package/dist/clis/xiaohongshu/creator-notes.d.ts +18 -5
  173. package/dist/clis/xiaohongshu/creator-notes.js +189 -71
  174. package/dist/clis/xiaohongshu/creator-notes.test.d.ts +1 -0
  175. package/dist/clis/xiaohongshu/creator-notes.test.js +191 -0
  176. package/dist/clis/xiaohongshu/creator-profile.js +0 -1
  177. package/dist/clis/xiaohongshu/creator-stats.js +0 -1
  178. package/dist/clis/xiaohongshu/download.js +2 -3
  179. package/dist/clis/xiaohongshu/feed.yaml +0 -1
  180. package/dist/clis/xiaohongshu/notifications.yaml +0 -1
  181. package/dist/clis/xiaohongshu/search.js +2 -2
  182. package/dist/clis/xiaohongshu/user.js +1 -2
  183. package/dist/clis/yahoo-finance/quote.js +0 -1
  184. package/dist/clis/youtube/search.js +1 -1
  185. package/dist/clis/youtube/transcript.js +1 -1
  186. package/dist/clis/youtube/video.js +1 -1
  187. package/dist/clis/zhihu/download.js +1 -2
  188. package/dist/clis/zhihu/question.js +1 -1
  189. package/dist/clis/zhihu/search.yaml +4 -3
  190. package/dist/commanderAdapter.d.ts +21 -0
  191. package/dist/commanderAdapter.js +111 -0
  192. package/dist/{engine.d.ts → discovery.d.ts} +0 -6
  193. package/dist/{engine.js → discovery.js} +1 -98
  194. package/dist/download/index.d.ts +2 -6
  195. package/dist/download/index.js +19 -46
  196. package/dist/engine.test.d.ts +1 -1
  197. package/dist/engine.test.js +8 -7
  198. package/dist/execution.d.ts +22 -0
  199. package/dist/execution.js +129 -0
  200. package/dist/explore.js +121 -107
  201. package/dist/external-clis.yaml +48 -0
  202. package/dist/external.d.ts +25 -0
  203. package/dist/external.js +156 -0
  204. package/dist/main.js +1 -1
  205. package/dist/pipeline/steps/browser.js +8 -2
  206. package/dist/registry.d.ts +2 -0
  207. package/dist/registry.js +2 -0
  208. package/dist/runtime.d.ts +5 -0
  209. package/dist/runtime.js +8 -0
  210. package/dist/serialization.d.ts +34 -0
  211. package/dist/serialization.js +63 -0
  212. package/dist/types.d.ts +4 -1
  213. package/docs/.vitepress/config.mts +14 -3
  214. package/docs/adapters/browser/arxiv.md +27 -0
  215. package/docs/adapters/browser/barchart.md +32 -0
  216. package/docs/adapters/browser/bloomberg.md +70 -0
  217. package/docs/adapters/browser/chaoxing.md +39 -0
  218. package/docs/adapters/browser/grok.md +35 -0
  219. package/docs/adapters/browser/hf.md +42 -0
  220. package/docs/adapters/browser/jike.md +45 -0
  221. package/docs/adapters/browser/jimeng.md +39 -0
  222. package/docs/adapters/browser/linux-do.md +45 -0
  223. package/docs/adapters/browser/sinafinance.md +35 -0
  224. package/docs/adapters/browser/stackoverflow.md +35 -0
  225. package/docs/adapters/browser/steam.md +26 -0
  226. package/docs/adapters/browser/twitter.md +3 -0
  227. package/docs/adapters/browser/weread.md +48 -0
  228. package/docs/adapters/browser/wikipedia.md +30 -0
  229. package/docs/adapters/browser/xiaohongshu.md +5 -1
  230. package/docs/adapters/desktop/chatgpt.md +3 -3
  231. package/docs/adapters/index.md +13 -0
  232. package/docs/advanced/download.md +4 -4
  233. package/docs/developer/architecture.md +17 -4
  234. package/package.json +1 -1
  235. package/scripts/check-doc-coverage.sh +69 -0
  236. package/scripts/copy-yaml.cjs +7 -0
  237. package/src/browser/cdp.ts +9 -4
  238. package/src/browser/page.ts +7 -1
  239. package/src/build-manifest.ts +25 -19
  240. package/src/cli.ts +253 -119
  241. package/src/clis/antigravity/serve.ts +323 -50
  242. package/src/clis/apple-podcasts/commands.test.ts +95 -0
  243. package/src/clis/apple-podcasts/search.ts +2 -2
  244. package/src/clis/apple-podcasts/top.ts +12 -2
  245. package/src/clis/arxiv/paper.ts +21 -0
  246. package/src/clis/arxiv/search.ts +24 -0
  247. package/src/clis/arxiv/utils.ts +63 -0
  248. package/src/clis/bilibili/dynamic.ts +1 -1
  249. package/src/clis/bilibili/favorite.ts +1 -1
  250. package/src/clis/bilibili/feed.ts +1 -1
  251. package/src/clis/bilibili/following.ts +1 -1
  252. package/src/clis/bilibili/history.ts +1 -1
  253. package/src/clis/bilibili/me.ts +1 -1
  254. package/src/clis/bilibili/ranking.ts +1 -1
  255. package/src/clis/bilibili/search.ts +3 -3
  256. package/src/clis/bilibili/subtitle.ts +1 -1
  257. package/src/clis/bilibili/user-videos.ts +1 -1
  258. package/src/{bilibili.ts → clis/bilibili/utils.ts} +1 -1
  259. package/src/clis/bloomberg/businessweek.ts +18 -0
  260. package/src/clis/bloomberg/economics.ts +18 -0
  261. package/src/clis/bloomberg/feeds.ts +16 -0
  262. package/src/clis/bloomberg/industries.ts +18 -0
  263. package/src/clis/bloomberg/main.ts +18 -0
  264. package/src/clis/bloomberg/markets.ts +18 -0
  265. package/src/clis/bloomberg/news.ts +136 -0
  266. package/src/clis/bloomberg/opinions.ts +18 -0
  267. package/src/clis/bloomberg/politics.ts +18 -0
  268. package/src/clis/bloomberg/tech.ts +18 -0
  269. package/src/clis/bloomberg/utils.test.ts +135 -0
  270. package/src/clis/bloomberg/utils.ts +429 -0
  271. package/src/clis/boss/batchgreet.ts +167 -0
  272. package/src/clis/boss/chatlist.ts +2 -2
  273. package/src/clis/boss/detail.ts +2 -2
  274. package/src/clis/boss/exchange.ts +126 -0
  275. package/src/clis/boss/greet.ts +198 -0
  276. package/src/clis/boss/invite.ts +177 -0
  277. package/src/clis/boss/joblist.ts +63 -0
  278. package/src/clis/boss/mark.ts +155 -0
  279. package/src/clis/boss/recommend.ts +94 -0
  280. package/src/clis/boss/search.ts +1 -1
  281. package/src/clis/boss/send.ts +1 -1
  282. package/src/clis/boss/stats.ts +130 -0
  283. package/src/clis/chaoxing/assignments.ts +1 -1
  284. package/src/clis/chaoxing/exams.ts +1 -1
  285. package/src/{chaoxing.test.ts → clis/chaoxing/utils.test.ts} +1 -1
  286. package/src/{chaoxing.ts → clis/chaoxing/utils.ts} +1 -3
  287. package/src/clis/chatgpt/README.zh-CN.md +3 -3
  288. package/src/clis/chatgpt/read.ts +1 -1
  289. package/src/clis/chatwise/export.ts +1 -1
  290. package/src/clis/chatwise/model.ts +2 -2
  291. package/src/clis/chatwise/screenshot.ts +1 -1
  292. package/src/clis/codex/export.ts +1 -1
  293. package/src/clis/codex/model.ts +2 -2
  294. package/src/clis/codex/screenshot.ts +1 -1
  295. package/src/clis/coupang/add-to-cart.ts +3 -4
  296. package/src/clis/coupang/search.ts +2 -4
  297. package/src/{coupang.test.ts → clis/coupang/utils.test.ts} +1 -1
  298. package/src/clis/ctrip/search.ts +1 -1
  299. package/src/clis/cursor/export.ts +1 -1
  300. package/src/clis/cursor/model.ts +2 -2
  301. package/src/clis/cursor/screenshot.ts +1 -1
  302. package/src/clis/jike/comment.ts +2 -3
  303. package/src/clis/jike/create.ts +1 -2
  304. package/src/clis/jike/feed.ts +0 -1
  305. package/src/clis/jike/like.ts +1 -2
  306. package/src/clis/jike/notifications.ts +0 -1
  307. package/src/clis/jike/post.yaml +1 -0
  308. package/src/clis/jike/repost.ts +1 -2
  309. package/src/clis/jike/search.ts +2 -3
  310. package/src/clis/jike/topic.yaml +1 -0
  311. package/src/clis/jike/user.yaml +1 -0
  312. package/src/clis/jimeng/history.yaml +0 -1
  313. package/src/clis/linkedin/search.ts +7 -7
  314. package/src/clis/linux-do/category.yaml +1 -0
  315. package/src/clis/linux-do/search.yaml +4 -3
  316. package/src/clis/linux-do/topic.yaml +1 -0
  317. package/src/clis/notion/export.ts +1 -1
  318. package/src/clis/reddit/comment.ts +3 -4
  319. package/src/clis/reddit/read.ts +4 -5
  320. package/src/clis/reddit/save.ts +2 -3
  321. package/src/clis/reddit/saved.ts +0 -1
  322. package/src/clis/reddit/search.yaml +1 -0
  323. package/src/clis/reddit/subscribe.ts +0 -1
  324. package/src/clis/reddit/upvote.ts +2 -3
  325. package/src/clis/reddit/upvoted.ts +0 -1
  326. package/src/clis/reddit/user-comments.yaml +1 -0
  327. package/src/clis/reddit/user-posts.yaml +1 -0
  328. package/src/clis/reddit/user.yaml +1 -0
  329. package/src/clis/reuters/search.ts +1 -1
  330. package/src/clis/sinafinance/news.ts +76 -0
  331. package/src/clis/smzdm/search.ts +2 -3
  332. package/src/clis/stackoverflow/search.yaml +1 -0
  333. package/src/clis/steam/top-sellers.yaml +29 -0
  334. package/src/clis/twitter/accept.ts +2 -2
  335. package/src/clis/twitter/article.ts +2 -2
  336. package/src/clis/twitter/block.ts +92 -0
  337. package/src/clis/twitter/delete.ts +1 -1
  338. package/src/clis/twitter/hide-reply.ts +70 -0
  339. package/src/clis/twitter/like.ts +1 -1
  340. package/src/clis/twitter/post.ts +1 -1
  341. package/src/clis/twitter/reply-dm.ts +1 -1
  342. package/src/clis/twitter/reply.ts +2 -2
  343. package/src/clis/twitter/search.ts +1 -1
  344. package/src/clis/twitter/thread.ts +2 -2
  345. package/src/clis/twitter/trending.ts +113 -0
  346. package/src/clis/twitter/unblock.ts +75 -0
  347. package/src/clis/v2ex/topic.yaml +1 -0
  348. package/src/clis/weibo/hot.ts +0 -1
  349. package/src/clis/weread/book.ts +1 -1
  350. package/src/clis/weread/highlights.ts +1 -1
  351. package/src/clis/weread/notes.ts +1 -1
  352. package/src/clis/weread/search.ts +1 -1
  353. package/src/clis/wikipedia/search.ts +32 -0
  354. package/src/clis/wikipedia/summary.ts +28 -0
  355. package/src/clis/wikipedia/utils.ts +20 -0
  356. package/src/clis/xiaohongshu/creator-note-detail.test.ts +272 -0
  357. package/src/clis/xiaohongshu/creator-note-detail.ts +425 -73
  358. package/src/clis/xiaohongshu/creator-notes-summary.test.ts +54 -0
  359. package/src/clis/xiaohongshu/creator-notes-summary.ts +120 -0
  360. package/src/clis/xiaohongshu/creator-notes.test.ts +211 -0
  361. package/src/clis/xiaohongshu/creator-notes.ts +254 -75
  362. package/src/clis/xiaohongshu/creator-profile.ts +0 -1
  363. package/src/clis/xiaohongshu/creator-stats.ts +0 -1
  364. package/src/clis/xiaohongshu/download.ts +2 -3
  365. package/src/clis/xiaohongshu/feed.yaml +0 -1
  366. package/src/clis/xiaohongshu/notifications.yaml +0 -1
  367. package/src/clis/xiaohongshu/search.ts +2 -2
  368. package/src/clis/xiaohongshu/user.ts +1 -2
  369. package/src/clis/yahoo-finance/quote.ts +0 -1
  370. package/src/clis/youtube/search.ts +1 -1
  371. package/src/clis/youtube/transcript.ts +1 -1
  372. package/src/clis/youtube/video.ts +1 -1
  373. package/src/clis/zhihu/download.ts +1 -2
  374. package/src/clis/zhihu/question.ts +1 -1
  375. package/src/clis/zhihu/search.yaml +4 -3
  376. package/src/commanderAdapter.ts +113 -0
  377. package/src/daemon.ts +3 -3
  378. package/src/{engine.ts → discovery.ts} +1 -108
  379. package/src/download/index.ts +21 -54
  380. package/src/engine.test.ts +8 -7
  381. package/src/execution.ts +138 -0
  382. package/src/explore.ts +135 -109
  383. package/src/external-clis.yaml +48 -0
  384. package/src/external.ts +185 -0
  385. package/src/main.ts +1 -1
  386. package/src/pipeline/steps/browser.ts +7 -2
  387. package/src/registry.ts +5 -0
  388. package/src/runtime.ts +9 -0
  389. package/src/serialization.ts +79 -0
  390. package/src/types.ts +1 -1
  391. package/tests/e2e/browser-public.test.ts +25 -0
  392. package/tests/e2e/public-commands.test.ts +55 -1
  393. package/dist/clis/twitter/trending.yaml +0 -46
  394. package/src/clis/twitter/trending.yaml +0 -46
  395. /package/dist/{chaoxing.test.d.ts → clis/arxiv/paper.d.ts} +0 -0
  396. /package/dist/{coupang.test.d.ts → clis/arxiv/search.d.ts} +0 -0
  397. /package/dist/{bilibili.js → clis/bilibili/utils.js} +0 -0
  398. /package/dist/{coupang.d.ts → clis/coupang/utils.d.ts} +0 -0
  399. /package/dist/{coupang.js → clis/coupang/utils.js} +0 -0
  400. /package/src/{coupang.ts → clis/coupang/utils.ts} +0 -0
@@ -97,12 +97,12 @@ cli({
97
97
  strategy: Strategy.COOKIE,
98
98
  browser: true,
99
99
  args: [
100
- { name: 'tweet_id', type: 'string', required: true },
100
+ { name: 'tweet-id', type: 'string', required: true },
101
101
  { name: 'limit', type: 'int', default: 50 },
102
102
  ],
103
103
  columns: ['id', 'author', 'text', 'likes', 'retweets', 'url'],
104
104
  func: async (page, kwargs) => {
105
- let tweetId = kwargs.tweet_id;
105
+ let tweetId = kwargs['tweet-id'];
106
106
  const urlMatch = tweetId.match(/\/status\/(\d+)/);
107
107
  if (urlMatch)
108
108
  tweetId = urlMatch[1];
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,91 @@
1
+ import { cli, Strategy } from '../../registry.js';
2
+ // ── Twitter GraphQL constants ──────────────────────────────────────────
3
+ const BEARER_TOKEN = 'AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA';
4
+ // ── CLI definition ────────────────────────────────────────────────────
5
+ cli({
6
+ site: 'twitter',
7
+ name: 'trending',
8
+ description: 'Twitter/X trending topics',
9
+ domain: 'x.com',
10
+ strategy: Strategy.COOKIE,
11
+ browser: true,
12
+ args: [
13
+ { name: 'limit', type: 'int', default: 20, help: 'Number of trends to show' },
14
+ ],
15
+ columns: ['rank', 'topic', 'tweets', 'category'],
16
+ func: async (page, kwargs) => {
17
+ const limit = kwargs.limit || 20;
18
+ // Navigate to trending page
19
+ await page.goto('https://x.com/explore/tabs/trending');
20
+ await page.wait(3);
21
+ // Extract CSRF token to verify login
22
+ const ct0 = await page.evaluate(`(() => {
23
+ return document.cookie.split(';').map(c=>c.trim()).find(c=>c.startsWith('ct0='))?.split('=')[1] || null;
24
+ })()`);
25
+ if (!ct0)
26
+ throw new Error('Not logged into x.com (no ct0 cookie)');
27
+ // Try legacy guide.json API first (faster than DOM scraping)
28
+ let trends = [];
29
+ const apiData = await page.evaluate(`(async () => {
30
+ const ct0 = document.cookie.split(';').map(c=>c.trim()).find(c=>c.startsWith('ct0='))?.split('=')[1] || '';
31
+ const r = await fetch('/i/api/2/guide.json?include_page_configuration=true', {
32
+ credentials: 'include',
33
+ headers: {
34
+ 'x-twitter-active-user': 'yes',
35
+ 'x-csrf-token': ct0,
36
+ 'authorization': 'Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA'
37
+ }
38
+ });
39
+ return r.ok ? await r.json() : null;
40
+ })()`);
41
+ if (apiData) {
42
+ const instructions = apiData?.timeline?.instructions || [];
43
+ const entries = instructions.flatMap((inst) => inst?.addEntries?.entries || inst?.entries || []);
44
+ const apiTrends = entries
45
+ .filter((e) => e.content?.timelineModule)
46
+ .flatMap((e) => e.content.timelineModule.items || [])
47
+ .map((t) => t?.item?.content?.trend)
48
+ .filter(Boolean);
49
+ trends = apiTrends.map((t, i) => ({
50
+ rank: i + 1,
51
+ topic: t.name,
52
+ tweets: t.tweetCount ? String(t.tweetCount) : 'N/A',
53
+ category: t.trendMetadata?.domainContext || '',
54
+ }));
55
+ }
56
+ // Fallback: scrape from the loaded DOM
57
+ if (trends.length === 0) {
58
+ await page.wait(2);
59
+ const domTrends = await page.evaluate(`(() => {
60
+ const items = [];
61
+ const cells = document.querySelectorAll('[data-testid="trend"]');
62
+ cells.forEach((cell) => {
63
+ const text = cell.textContent || '';
64
+ if (text.includes('Promoted')) return;
65
+ const container = cell.querySelector(':scope > div');
66
+ if (!container) return;
67
+ const divs = container.children;
68
+ // Structure: divs[0] = rank + category, divs[1] = topic name, divs[2] = extra
69
+ const topicEl = divs.length >= 2 ? divs[1] : null;
70
+ const topic = topicEl ? topicEl.textContent.trim() : '';
71
+ const catEl = divs.length >= 1 ? divs[0] : null;
72
+ const catText = catEl ? catEl.textContent.trim() : '';
73
+ const category = catText.replace(/^\\d+\\s*/, '').replace(/^\\xB7\\s*/, '').trim();
74
+ const extraEl = divs.length >= 3 ? divs[2] : null;
75
+ const extra = extraEl ? extraEl.textContent.trim() : '';
76
+ if (topic) {
77
+ items.push({ rank: items.length + 1, topic, tweets: extra || 'N/A', category });
78
+ }
79
+ });
80
+ return items;
81
+ })()`);
82
+ if (Array.isArray(domTrends) && domTrends.length > 0) {
83
+ trends = domTrends;
84
+ }
85
+ }
86
+ if (trends.length === 0) {
87
+ throw new Error('No trending data found. API may have changed or login may be required.');
88
+ }
89
+ return trends.slice(0, limit);
90
+ },
91
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,71 @@
1
+ import { cli, Strategy } from '../../registry.js';
2
+ cli({
3
+ site: 'twitter',
4
+ name: 'unblock',
5
+ description: 'Unblock a Twitter user',
6
+ domain: 'x.com',
7
+ strategy: Strategy.UI,
8
+ browser: true,
9
+ args: [
10
+ { name: 'username', type: 'string', positional: true, required: true, help: 'Twitter screen name (without @)' },
11
+ ],
12
+ columns: ['status', 'message'],
13
+ func: async (page, kwargs) => {
14
+ if (!page)
15
+ throw new Error('Requires browser');
16
+ const username = kwargs.username.replace(/^@/, '');
17
+ await page.goto(`https://x.com/${username}`);
18
+ await page.wait(5);
19
+ const result = await page.evaluate(`(async () => {
20
+ try {
21
+ let attempts = 0;
22
+ let unblockBtn = null;
23
+
24
+ while (attempts < 20) {
25
+ // Check if not blocked (follow button visible means not blocked)
26
+ const followBtn = document.querySelector('[data-testid$="-follow"]');
27
+ if (followBtn) {
28
+ return { ok: true, message: 'Not blocking @${username} (already unblocked).' };
29
+ }
30
+
31
+ unblockBtn = document.querySelector('[data-testid$="-unblock"]');
32
+ if (unblockBtn) break;
33
+
34
+ await new Promise(r => setTimeout(r, 500));
35
+ attempts++;
36
+ }
37
+
38
+ if (!unblockBtn) {
39
+ return { ok: false, message: 'Could not find Unblock button. Are you logged in?' };
40
+ }
41
+
42
+ // Click the unblock button — this opens a confirmation dialog
43
+ unblockBtn.click();
44
+ await new Promise(r => setTimeout(r, 1000));
45
+
46
+ // Confirm the unblock in the dialog
47
+ const confirmBtn = document.querySelector('[data-testid="confirmationSheetConfirm"]');
48
+ if (confirmBtn) {
49
+ confirmBtn.click();
50
+ await new Promise(r => setTimeout(r, 1000));
51
+ }
52
+
53
+ // Verify
54
+ const verify = document.querySelector('[data-testid$="-follow"]');
55
+ if (verify) {
56
+ return { ok: true, message: 'Successfully unblocked @${username}.' };
57
+ } else {
58
+ return { ok: false, message: 'Unblock action initiated but UI did not update.' };
59
+ }
60
+ } catch (e) {
61
+ return { ok: false, message: e.toString() };
62
+ }
63
+ })()`);
64
+ if (result.ok)
65
+ await page.wait(2);
66
+ return [{
67
+ status: result.ok ? 'success' : 'failed',
68
+ message: result.message
69
+ }];
70
+ }
71
+ });
@@ -7,6 +7,7 @@ browser: false
7
7
 
8
8
  args:
9
9
  id:
10
+ positional: true
10
11
  type: str
11
12
  required: true
12
13
  description: Topic ID
@@ -16,7 +16,6 @@ cli({
16
16
  func: async (page, kwargs) => {
17
17
  const count = Math.min(kwargs.limit || 30, 50);
18
18
  await page.goto('https://weibo.com');
19
- await page.wait(2);
20
19
  const data = await page.evaluate(`
21
20
  (async () => {
22
21
  const resp = await fetch('/ajax/statuses/hot_band', {credentials: 'include'});
@@ -7,7 +7,7 @@ cli({
7
7
  domain: 'weread.qq.com',
8
8
  strategy: Strategy.COOKIE,
9
9
  args: [
10
- { name: 'bookId', positional: true, required: true, help: 'Book ID (numeric, from search or shelf results)' },
10
+ { name: 'book-id', positional: true, required: true, help: 'Book ID (numeric, from search or shelf results)' },
11
11
  ],
12
12
  columns: ['title', 'author', 'publisher', 'intro', 'category', 'rating'],
13
13
  func: async (page, args) => {
@@ -7,7 +7,7 @@ cli({
7
7
  domain: 'weread.qq.com',
8
8
  strategy: Strategy.COOKIE,
9
9
  args: [
10
- { name: 'bookId', positional: true, required: true, help: 'Book ID (from shelf or search results)' },
10
+ { name: 'book-id', positional: true, required: true, help: 'Book ID (from shelf or search results)' },
11
11
  { name: 'limit', type: 'int', default: 20, help: 'Max results' },
12
12
  ],
13
13
  columns: ['chapter', 'text', 'createTime'],
@@ -7,7 +7,7 @@ cli({
7
7
  domain: 'weread.qq.com',
8
8
  strategy: Strategy.COOKIE,
9
9
  args: [
10
- { name: 'bookId', positional: true, required: true, help: 'Book ID (from shelf or search results)' },
10
+ { name: 'book-id', positional: true, required: true, help: 'Book ID (from shelf or search results)' },
11
11
  { name: 'limit', type: 'int', default: 20, help: 'Max results' },
12
12
  ],
13
13
  columns: ['chapter', 'text', 'review', 'createTime'],
@@ -8,7 +8,7 @@ cli({
8
8
  strategy: Strategy.PUBLIC,
9
9
  browser: false,
10
10
  args: [
11
- { name: 'keyword', positional: true, required: true, help: 'Search keyword' },
11
+ { name: 'query', positional: true, required: true, help: 'Search keyword' },
12
12
  { name: 'limit', type: 'int', default: 10, help: 'Max results' },
13
13
  ],
14
14
  columns: ['rank', 'title', 'author', 'bookId'],
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,30 @@
1
+ import { cli, Strategy } from '../../registry.js';
2
+ import { CliError } from '../../errors.js';
3
+ import { wikiFetch } from './utils.js';
4
+ cli({
5
+ site: 'wikipedia',
6
+ name: 'search',
7
+ description: 'Search Wikipedia articles',
8
+ strategy: Strategy.PUBLIC,
9
+ browser: false,
10
+ args: [
11
+ { name: 'query', positional: true, required: true, help: 'Search keyword' },
12
+ { name: 'limit', type: 'int', default: 10, help: 'Max results' },
13
+ { name: 'lang', default: 'en', help: 'Language code (e.g. en, zh, ja)' },
14
+ ],
15
+ columns: ['title', 'snippet', 'url'],
16
+ func: async (_page, args) => {
17
+ const limit = Math.max(1, Math.min(Number(args.limit), 50));
18
+ const lang = args.lang || 'en';
19
+ const q = encodeURIComponent(args.keyword);
20
+ const data = await wikiFetch(lang, `/w/api.php?action=query&list=search&srsearch=${q}&srlimit=${limit}&format=json&utf8=1`);
21
+ const results = data?.query?.search;
22
+ if (!results?.length)
23
+ throw new CliError('NOT_FOUND', 'No articles found', 'Try a different keyword');
24
+ return results.map((r) => ({
25
+ title: r.title,
26
+ snippet: r.snippet.replace(/<[^>]+>/g, '').slice(0, 120),
27
+ url: `https://${lang}.wikipedia.org/wiki/${encodeURIComponent(r.title.replace(/ /g, '_'))}`,
28
+ }));
29
+ },
30
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ import { cli, Strategy } from '../../registry.js';
2
+ import { CliError } from '../../errors.js';
3
+ import { wikiFetch } from './utils.js';
4
+ cli({
5
+ site: 'wikipedia',
6
+ name: 'summary',
7
+ description: 'Get Wikipedia article summary',
8
+ strategy: Strategy.PUBLIC,
9
+ browser: false,
10
+ args: [
11
+ { name: 'title', positional: true, required: true, help: 'Article title (e.g. "Transformer (machine learning model)")' },
12
+ { name: 'lang', default: 'en', help: 'Language code (e.g. en, zh, ja)' },
13
+ ],
14
+ columns: ['title', 'description', 'extract', 'url'],
15
+ func: async (_page, args) => {
16
+ const lang = args.lang || 'en';
17
+ const title = encodeURIComponent(args.title.replace(/ /g, '_'));
18
+ const data = await wikiFetch(lang, `/api/rest_v1/page/summary/${title}`);
19
+ if (!data?.title)
20
+ throw new CliError('NOT_FOUND', `Article "${args.title}" not found`, 'Try searching first: opencli wikipedia search <keyword>');
21
+ return [{
22
+ title: data.title,
23
+ description: data.description ?? '-',
24
+ extract: (data.extract ?? '').slice(0, 300),
25
+ url: data.content_urls?.desktop?.page ?? `https://${lang}.wikipedia.org/wiki/${title}`,
26
+ }];
27
+ },
28
+ });
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Wikipedia adapter utilities.
3
+ *
4
+ * Uses the public MediaWiki REST API and Action API — no key required.
5
+ * REST API: https://en.wikipedia.org/api/rest_v1/
6
+ * Action API: https://en.wikipedia.org/w/api.php
7
+ */
8
+ export declare function wikiFetch(lang: string, path: string): Promise<unknown>;
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Wikipedia adapter utilities.
3
+ *
4
+ * Uses the public MediaWiki REST API and Action API — no key required.
5
+ * REST API: https://en.wikipedia.org/api/rest_v1/
6
+ * Action API: https://en.wikipedia.org/w/api.php
7
+ */
8
+ import { CliError } from '../../errors.js';
9
+ export async function wikiFetch(lang, path) {
10
+ const url = `https://${lang}.wikipedia.org${path}`;
11
+ const resp = await fetch(url, {
12
+ headers: { 'User-Agent': 'opencli/1.0 (https://github.com/jackwener/opencli)' },
13
+ });
14
+ if (!resp.ok) {
15
+ throw new CliError('FETCH_ERROR', `Wikipedia API HTTP ${resp.status}`, `Check your title or search term`);
16
+ }
17
+ return resp.json();
18
+ }
@@ -1,10 +1,84 @@
1
1
  /**
2
- * Xiaohongshu Creator Note Detail — per-note analytics breakdown.
2
+ * Xiaohongshu Creator Note Detail — per-note analytics from the creator detail page.
3
3
  *
4
- * Uses the creator.xiaohongshu.com internal API (cookie auth).
5
- * Returns total reads, engagement, likes, collects, comments, shares
6
- * for a specific note, split by channel (organic vs promoted vs video).
4
+ * The current creator center no longer serves stable single-note metrics from the legacy
5
+ * `/api/galaxy/creator/data/note_detail` endpoint. The real note detail page loads data
6
+ * through the newer `datacenter/note/*` API family, so this command navigates to the
7
+ * detail page and parses the rendered metrics that are backed by those APIs.
7
8
  *
8
9
  * Requires: logged into creator.xiaohongshu.com in Chrome.
9
10
  */
10
- export {};
11
+ import type { IPage } from '../../types.js';
12
+ type CreatorNoteDetailRow = {
13
+ section: string;
14
+ metric: string;
15
+ value: string;
16
+ extra: string;
17
+ };
18
+ export type { CreatorNoteDetailRow };
19
+ type CreatorNoteDetailDomMetric = {
20
+ label: string;
21
+ value: string;
22
+ extra: string;
23
+ };
24
+ type CreatorNoteDetailDomSection = {
25
+ title: string;
26
+ metrics: CreatorNoteDetailDomMetric[];
27
+ };
28
+ type CreatorNoteDetailDomData = {
29
+ title: string;
30
+ infoText: string;
31
+ sections: CreatorNoteDetailDomSection[];
32
+ };
33
+ type AudienceSourceItem = {
34
+ title?: string;
35
+ value_with_double?: number;
36
+ info?: {
37
+ imp_count?: number;
38
+ view_count?: number;
39
+ interaction_count?: number;
40
+ };
41
+ };
42
+ type AudiencePortraitItem = {
43
+ title?: string;
44
+ value?: number;
45
+ };
46
+ type NoteTrendPoint = {
47
+ date?: number;
48
+ count?: number;
49
+ count_with_double?: number;
50
+ };
51
+ type NoteTrendBucket = {
52
+ imp_list?: NoteTrendPoint[];
53
+ view_list?: NoteTrendPoint[];
54
+ view_time_list?: NoteTrendPoint[];
55
+ like_list?: NoteTrendPoint[];
56
+ comment_list?: NoteTrendPoint[];
57
+ collect_list?: NoteTrendPoint[];
58
+ share_list?: NoteTrendPoint[];
59
+ rise_fans_list?: NoteTrendPoint[];
60
+ };
61
+ type NoteDetailApiPayload = {
62
+ noteBase?: {
63
+ hour?: NoteTrendBucket;
64
+ day?: NoteTrendBucket;
65
+ };
66
+ audienceTrend?: {
67
+ no_data?: boolean;
68
+ no_data_tip_msg?: string;
69
+ };
70
+ audienceSource?: {
71
+ source?: AudienceSourceItem[];
72
+ };
73
+ audienceSourceDetail?: {
74
+ gender?: AudiencePortraitItem[];
75
+ age?: AudiencePortraitItem[];
76
+ city?: AudiencePortraitItem[];
77
+ interest?: AudiencePortraitItem[];
78
+ };
79
+ };
80
+ export declare function parseCreatorNoteDetailText(bodyText: string, noteId: string): CreatorNoteDetailRow[];
81
+ export declare function parseCreatorNoteDetailDomData(dom: CreatorNoteDetailDomData | null | undefined, noteId: string): CreatorNoteDetailRow[];
82
+ export declare function appendAudienceRows(rows: CreatorNoteDetailRow[], payload?: NoteDetailApiPayload): CreatorNoteDetailRow[];
83
+ export declare function appendTrendRows(rows: CreatorNoteDetailRow[], payload?: NoteDetailApiPayload): CreatorNoteDetailRow[];
84
+ export declare function fetchCreatorNoteDetailRows(page: IPage, noteId: string): Promise<CreatorNoteDetailRow[]>;