@jackwener/opencli 1.3.2 → 1.4.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 (508) hide show
  1. package/.github/pull_request_template.md +3 -1
  2. package/.github/workflows/build-extension.yml +7 -1
  3. package/.github/workflows/ci.yml +29 -3
  4. package/.github/workflows/docs.yml +1 -1
  5. package/.github/workflows/e2e-headed.yml +20 -0
  6. package/.github/workflows/release.yml +1 -1
  7. package/.github/workflows/security.yml +0 -3
  8. package/CHANGELOG.md +55 -0
  9. package/CONTRIBUTING.md +6 -3
  10. package/README.md +37 -10
  11. package/README.zh-CN.md +37 -10
  12. package/SKILL.md +7 -2
  13. package/TESTING.md +1 -0
  14. package/chatwise-opencli.ps1 +82 -0
  15. package/dist/analysis.d.ts +38 -0
  16. package/dist/analysis.js +166 -0
  17. package/dist/browser/cdp.d.ts +0 -4
  18. package/dist/browser/cdp.js +59 -38
  19. package/dist/browser/cdp.test.d.ts +1 -0
  20. package/dist/browser/cdp.test.js +52 -0
  21. package/dist/browser/daemon-client.js +2 -1
  22. package/dist/browser/discover.js +2 -1
  23. package/dist/browser/dom-snapshot.d.ts +2 -2
  24. package/dist/browser/dom-snapshot.js +54 -1
  25. package/dist/browser/dom-snapshot.test.js +36 -0
  26. package/dist/browser/errors.js +2 -1
  27. package/dist/browser/index.d.ts +3 -2
  28. package/dist/browser/index.js +2 -1
  29. package/dist/browser/mcp.d.ts +0 -2
  30. package/dist/browser/mcp.js +2 -3
  31. package/dist/browser/page.d.ts +4 -3
  32. package/dist/browser/page.js +44 -35
  33. package/dist/browser/stealth.d.ts +16 -0
  34. package/dist/browser/stealth.js +155 -0
  35. package/dist/browser.test.js +47 -1
  36. package/dist/build-manifest.js +15 -9
  37. package/dist/build-manifest.test.js +12 -0
  38. package/dist/cascade.js +4 -2
  39. package/dist/cli-manifest.json +639 -258
  40. package/dist/cli.js +57 -29
  41. package/dist/clis/_shared/desktop-commands.d.ts +22 -0
  42. package/dist/clis/_shared/desktop-commands.js +108 -0
  43. package/dist/clis/antigravity/serve.js +5 -2
  44. package/dist/clis/arxiv/search.js +1 -1
  45. package/dist/clis/bilibili/dynamic.test.d.ts +1 -0
  46. package/dist/clis/bilibili/dynamic.test.js +68 -0
  47. package/dist/clis/bilibili/favorite.js +4 -2
  48. package/dist/clis/bilibili/following.js +3 -2
  49. package/dist/clis/bilibili/subtitle.js +8 -7
  50. package/dist/clis/bilibili/utils.js +2 -2
  51. package/dist/clis/boss/batchgreet.js +1 -1
  52. package/dist/clis/boss/chatlist.js +1 -1
  53. package/dist/clis/boss/chatmsg.js +1 -1
  54. package/dist/clis/boss/detail.js +1 -1
  55. package/dist/clis/boss/exchange.js +1 -1
  56. package/dist/clis/boss/greet.js +1 -1
  57. package/dist/clis/boss/invite.js +1 -1
  58. package/dist/clis/boss/joblist.js +1 -1
  59. package/dist/clis/boss/mark.js +4 -3
  60. package/dist/clis/boss/recommend.js +1 -1
  61. package/dist/clis/boss/resume.js +1 -1
  62. package/dist/clis/boss/search.js +1 -1
  63. package/dist/clis/boss/send.js +5 -4
  64. package/dist/clis/boss/stats.js +1 -1
  65. package/dist/clis/chatgpt/ask.js +4 -0
  66. package/dist/clis/chatgpt/new.js +5 -1
  67. package/dist/clis/chatgpt/read.js +5 -1
  68. package/dist/clis/chatgpt/send.js +2 -1
  69. package/dist/clis/chatgpt/status.js +5 -1
  70. package/dist/clis/chatwise/ask.js +8 -2
  71. package/dist/clis/chatwise/export.js +2 -0
  72. package/dist/clis/chatwise/history.js +2 -0
  73. package/dist/clis/chatwise/model.js +8 -3
  74. package/dist/clis/chatwise/new.js +3 -18
  75. package/dist/clis/chatwise/read.js +2 -0
  76. package/dist/clis/chatwise/screenshot.js +3 -27
  77. package/dist/clis/chatwise/send.js +8 -2
  78. package/dist/clis/chatwise/shared.d.ts +2 -0
  79. package/dist/clis/chatwise/shared.js +6 -0
  80. package/dist/clis/chatwise/status.js +3 -22
  81. package/dist/clis/codex/ask.js +6 -2
  82. package/dist/clis/codex/dump.js +2 -25
  83. package/dist/clis/codex/new.js +2 -25
  84. package/dist/clis/codex/screenshot.js +2 -27
  85. package/dist/clis/codex/send.js +6 -4
  86. package/dist/clis/codex/status.js +2 -22
  87. package/dist/clis/cursor/ask.js +2 -1
  88. package/dist/clis/cursor/composer.js +2 -1
  89. package/dist/clis/cursor/dump.js +2 -25
  90. package/dist/clis/cursor/new.js +2 -18
  91. package/dist/clis/cursor/read.js +2 -1
  92. package/dist/clis/cursor/screenshot.js +1 -30
  93. package/dist/clis/cursor/send.js +2 -1
  94. package/dist/clis/cursor/status.js +2 -21
  95. package/dist/clis/dictionary/examples.yaml +25 -0
  96. package/dist/clis/dictionary/search.yaml +27 -0
  97. package/dist/clis/dictionary/synonyms.yaml +25 -0
  98. package/dist/clis/douban/book-hot.js +1 -1
  99. package/dist/clis/douban/movie-hot.js +1 -1
  100. package/dist/clis/douban/search.js +1 -1
  101. package/dist/clis/douban/utils.d.ts +4 -1
  102. package/dist/clis/douban/utils.js +156 -1
  103. package/dist/clis/doubao/ask.js +1 -1
  104. package/dist/clis/doubao/new.js +1 -1
  105. package/dist/clis/doubao/read.js +1 -1
  106. package/dist/clis/doubao/send.js +1 -1
  107. package/dist/clis/doubao/status.js +1 -1
  108. package/dist/clis/doubao-app/ask.js +1 -1
  109. package/dist/clis/doubao-app/new.js +1 -1
  110. package/dist/clis/doubao-app/read.js +1 -1
  111. package/dist/clis/doubao-app/send.js +1 -1
  112. package/dist/clis/grok/ask.d.ts +4 -0
  113. package/dist/clis/grok/ask.js +28 -10
  114. package/dist/clis/grok/ask.test.js +18 -0
  115. package/dist/clis/jd/item.d.ts +1 -0
  116. package/dist/clis/jd/item.js +96 -0
  117. package/dist/clis/jd/item.test.d.ts +1 -0
  118. package/dist/clis/jd/item.test.js +28 -0
  119. package/dist/clis/jike/feed.js +1 -1
  120. package/dist/clis/jike/search.js +1 -1
  121. package/dist/clis/linkedin/search.js +5 -4
  122. package/dist/clis/linkedin/timeline.d.ts +21 -0
  123. package/dist/clis/linkedin/timeline.js +503 -0
  124. package/dist/clis/linkedin/timeline.test.d.ts +1 -0
  125. package/dist/clis/linkedin/timeline.test.js +81 -0
  126. package/dist/clis/medium/feed.js +1 -1
  127. package/dist/clis/medium/search.js +1 -1
  128. package/dist/clis/medium/user.js +1 -1
  129. package/dist/clis/medium/{shared.js → utils.js} +2 -1
  130. package/dist/clis/pixiv/detail.yaml +49 -0
  131. package/dist/clis/pixiv/download.d.ts +7 -0
  132. package/dist/clis/pixiv/download.js +78 -0
  133. package/dist/clis/pixiv/download.test.d.ts +1 -0
  134. package/dist/clis/pixiv/download.test.js +87 -0
  135. package/dist/clis/pixiv/illusts.d.ts +8 -0
  136. package/dist/clis/pixiv/illusts.js +65 -0
  137. package/dist/clis/pixiv/illusts.test.d.ts +1 -0
  138. package/dist/clis/pixiv/illusts.test.js +99 -0
  139. package/dist/clis/pixiv/ranking.yaml +53 -0
  140. package/dist/clis/pixiv/search.d.ts +6 -0
  141. package/dist/clis/pixiv/search.js +43 -0
  142. package/dist/clis/pixiv/search.test.d.ts +1 -0
  143. package/dist/clis/pixiv/search.test.js +83 -0
  144. package/dist/clis/pixiv/test-utils.d.ts +12 -0
  145. package/dist/clis/pixiv/test-utils.js +23 -0
  146. package/dist/clis/pixiv/user.yaml +46 -0
  147. package/dist/clis/pixiv/utils.d.ts +27 -0
  148. package/dist/clis/pixiv/utils.js +49 -0
  149. package/dist/clis/reddit/comment.js +2 -1
  150. package/dist/clis/reddit/read.js +4 -3
  151. package/dist/clis/reddit/read.test.d.ts +1 -0
  152. package/dist/clis/reddit/read.test.js +28 -0
  153. package/dist/clis/reddit/save.js +2 -1
  154. package/dist/clis/reddit/saved.js +7 -3
  155. package/dist/clis/reddit/subscribe.js +2 -1
  156. package/dist/clis/reddit/upvote.js +2 -1
  157. package/dist/clis/reddit/upvoted.js +7 -3
  158. package/dist/clis/sinablog/article.js +1 -1
  159. package/dist/clis/sinablog/hot.js +1 -1
  160. package/dist/clis/sinablog/user.js +1 -1
  161. package/dist/clis/substack/feed.js +1 -1
  162. package/dist/clis/substack/publication.js +1 -1
  163. package/dist/clis/substack/search.js +3 -2
  164. package/dist/clis/substack/{shared.js → utils.js} +3 -2
  165. package/dist/clis/tiktok/search.yaml +2 -1
  166. package/dist/clis/twitter/accept.js +2 -1
  167. package/dist/clis/twitter/article.js +4 -1
  168. package/dist/clis/twitter/block.js +2 -1
  169. package/dist/clis/twitter/bookmark.js +2 -1
  170. package/dist/clis/twitter/bookmarks.js +3 -2
  171. package/dist/clis/twitter/delete.js +2 -1
  172. package/dist/clis/twitter/follow.js +2 -1
  173. package/dist/clis/twitter/followers.js +3 -2
  174. package/dist/clis/twitter/following.js +3 -2
  175. package/dist/clis/twitter/hide-reply.js +2 -1
  176. package/dist/clis/twitter/like.js +2 -1
  177. package/dist/clis/twitter/notifications.js +2 -1
  178. package/dist/clis/twitter/post.js +2 -1
  179. package/dist/clis/twitter/profile.js +5 -2
  180. package/dist/clis/twitter/reply-dm.js +2 -1
  181. package/dist/clis/twitter/reply.js +2 -1
  182. package/dist/clis/twitter/search.js +30 -13
  183. package/dist/clis/twitter/search.test.d.ts +1 -0
  184. package/dist/clis/twitter/search.test.js +104 -0
  185. package/dist/clis/twitter/thread.js +2 -2
  186. package/dist/clis/twitter/timeline.js +3 -2
  187. package/dist/clis/twitter/trending.js +3 -2
  188. package/dist/clis/twitter/unblock.js +2 -1
  189. package/dist/clis/twitter/unbookmark.js +2 -1
  190. package/dist/clis/twitter/unfollow.js +2 -1
  191. package/dist/clis/v2ex/daily.js +3 -2
  192. package/dist/clis/v2ex/me.js +3 -2
  193. package/dist/clis/v2ex/notifications.js +4 -4
  194. package/dist/clis/web/read.d.ts +16 -0
  195. package/dist/clis/web/read.js +202 -0
  196. package/dist/clis/xueqiu/danjuan-utils.d.ts +55 -0
  197. package/dist/clis/xueqiu/danjuan-utils.js +126 -0
  198. package/dist/clis/xueqiu/danjuan-utils.test.d.ts +1 -0
  199. package/dist/clis/xueqiu/danjuan-utils.test.js +41 -0
  200. package/dist/clis/xueqiu/fund-holdings.d.ts +1 -0
  201. package/dist/clis/xueqiu/fund-holdings.js +28 -0
  202. package/dist/clis/xueqiu/fund-snapshot.d.ts +1 -0
  203. package/dist/clis/xueqiu/fund-snapshot.js +25 -0
  204. package/dist/clis/youtube/transcript.js +5 -4
  205. package/dist/clis/youtube/video.js +3 -2
  206. package/dist/constants.d.ts +2 -0
  207. package/dist/constants.js +2 -0
  208. package/dist/daemon.js +9 -4
  209. package/dist/discovery.js +11 -10
  210. package/dist/doctor.js +4 -2
  211. package/dist/download/index.d.ts +4 -12
  212. package/dist/download/index.js +33 -12
  213. package/dist/download/index.test.js +79 -2
  214. package/dist/download/media-download.js +4 -2
  215. package/dist/engine.test.js +76 -4
  216. package/dist/execution.d.ts +1 -9
  217. package/dist/execution.js +56 -46
  218. package/dist/explore.js +12 -111
  219. package/dist/external-clis.yaml +0 -8
  220. package/dist/external.js +7 -5
  221. package/dist/external.test.js +4 -0
  222. package/dist/generate.d.ts +0 -9
  223. package/dist/generate.js +4 -20
  224. package/dist/hooks.d.ts +46 -0
  225. package/dist/hooks.js +56 -0
  226. package/dist/hooks.test.d.ts +4 -0
  227. package/dist/hooks.test.js +92 -0
  228. package/dist/interceptor.js +70 -23
  229. package/dist/main.js +2 -0
  230. package/dist/output.js +12 -6
  231. package/dist/pipeline/executor.js +1 -1
  232. package/dist/pipeline/steps/browser.js +1 -3
  233. package/dist/pipeline/steps/download.js +42 -26
  234. package/dist/pipeline/steps/download.test.d.ts +1 -0
  235. package/dist/pipeline/steps/download.test.js +101 -0
  236. package/dist/pipeline/steps/fetch.js +40 -22
  237. package/dist/pipeline/steps/fetch.test.d.ts +1 -0
  238. package/dist/pipeline/steps/fetch.test.js +123 -0
  239. package/dist/pipeline/steps/transform.js +2 -6
  240. package/dist/pipeline/template.js +66 -52
  241. package/dist/pipeline/template.test.js +28 -0
  242. package/dist/pipeline/transform.test.js +18 -0
  243. package/dist/plugin.d.ts +40 -1
  244. package/dist/plugin.js +214 -17
  245. package/dist/plugin.test.d.ts +1 -1
  246. package/dist/plugin.test.js +219 -3
  247. package/dist/record.js +6 -98
  248. package/dist/registry-api.d.ts +2 -0
  249. package/dist/registry-api.js +1 -0
  250. package/dist/registry.d.ts +5 -2
  251. package/dist/registry.js +1 -2
  252. package/dist/runtime.d.ts +0 -1
  253. package/dist/runtime.js +14 -4
  254. package/dist/snapshotFormatter.d.ts +7 -14
  255. package/dist/snapshotFormatter.js +38 -78
  256. package/dist/utils.d.ts +9 -0
  257. package/dist/utils.js +29 -0
  258. package/dist/validate.js +3 -5
  259. package/dist/yaml-schema.d.ts +26 -0
  260. package/dist/yaml-schema.js +5 -0
  261. package/docs/.vitepress/config.mts +3 -0
  262. package/docs/adapters/browser/dictionary.md +27 -0
  263. package/docs/adapters/browser/douban.md +18 -8
  264. package/docs/adapters/browser/jd.md +27 -0
  265. package/docs/adapters/browser/linkedin.md +6 -0
  266. package/docs/adapters/browser/pixiv.md +92 -0
  267. package/docs/adapters/browser/web.md +30 -0
  268. package/docs/adapters/browser/wikipedia.md +0 -9
  269. package/docs/adapters/browser/xueqiu.md +27 -9
  270. package/docs/adapters/desktop/antigravity.md +0 -3
  271. package/docs/adapters/index.md +11 -9
  272. package/docs/comparison.md +125 -0
  273. package/docs/developer/contributing.md +21 -2
  274. package/docs/developer/testing.md +14 -8
  275. package/docs/developer/ts-adapter.md +18 -0
  276. package/docs/developer/yaml-adapter.md +16 -0
  277. package/docs/guide/plugins.md +10 -0
  278. package/docs/zh/guide/plugins.md +10 -0
  279. package/extension/dist/background.js +519 -444
  280. package/extension/manifest.json +1 -1
  281. package/extension/package.json +1 -1
  282. package/extension/src/background.test.ts +46 -1
  283. package/extension/src/background.ts +108 -33
  284. package/extension/src/cdp.ts +9 -9
  285. package/package.json +3 -2
  286. package/scripts/check-doc-coverage.sh +2 -0
  287. package/src/analysis.ts +170 -0
  288. package/src/browser/cdp.test.ts +66 -0
  289. package/src/browser/cdp.ts +64 -41
  290. package/src/browser/daemon-client.ts +4 -3
  291. package/src/browser/discover.ts +2 -1
  292. package/src/browser/dom-snapshot.test.ts +42 -0
  293. package/src/browser/dom-snapshot.ts +56 -3
  294. package/src/browser/errors.ts +2 -1
  295. package/src/browser/index.ts +3 -2
  296. package/src/browser/mcp.ts +2 -4
  297. package/src/browser/page.ts +43 -35
  298. package/src/browser/stealth.ts +156 -0
  299. package/src/browser.test.ts +51 -1
  300. package/src/build-manifest.test.ts +14 -0
  301. package/src/build-manifest.ts +13 -32
  302. package/src/cascade.ts +5 -3
  303. package/src/cli.ts +66 -34
  304. package/src/clis/_shared/desktop-commands.ts +121 -0
  305. package/src/clis/antigravity/serve.ts +6 -3
  306. package/src/clis/arxiv/search.ts +1 -1
  307. package/src/clis/bilibili/dynamic.test.ts +79 -0
  308. package/src/clis/bilibili/favorite.ts +5 -2
  309. package/src/clis/bilibili/following.ts +3 -2
  310. package/src/clis/bilibili/subtitle.ts +8 -7
  311. package/src/clis/bilibili/utils.ts +2 -2
  312. package/src/clis/boss/batchgreet.ts +1 -1
  313. package/src/clis/boss/chatlist.ts +1 -1
  314. package/src/clis/boss/chatmsg.ts +1 -1
  315. package/src/clis/boss/detail.ts +1 -1
  316. package/src/clis/boss/exchange.ts +1 -1
  317. package/src/clis/boss/greet.ts +1 -1
  318. package/src/clis/boss/invite.ts +1 -1
  319. package/src/clis/boss/joblist.ts +1 -1
  320. package/src/clis/boss/mark.ts +4 -3
  321. package/src/clis/boss/recommend.ts +1 -1
  322. package/src/clis/boss/resume.ts +1 -1
  323. package/src/clis/boss/search.ts +1 -1
  324. package/src/clis/boss/send.ts +5 -4
  325. package/src/clis/boss/stats.ts +1 -1
  326. package/src/clis/chatgpt/ask.ts +5 -0
  327. package/src/clis/chatgpt/new.ts +7 -2
  328. package/src/clis/chatgpt/read.ts +7 -2
  329. package/src/clis/chatgpt/send.ts +3 -2
  330. package/src/clis/chatgpt/status.ts +6 -1
  331. package/src/clis/chatwise/ask.ts +7 -2
  332. package/src/clis/chatwise/export.ts +2 -0
  333. package/src/clis/chatwise/history.ts +2 -0
  334. package/src/clis/chatwise/model.ts +7 -3
  335. package/src/clis/chatwise/new.ts +3 -20
  336. package/src/clis/chatwise/read.ts +2 -0
  337. package/src/clis/chatwise/screenshot.ts +3 -32
  338. package/src/clis/chatwise/send.ts +7 -2
  339. package/src/clis/chatwise/shared.ts +8 -0
  340. package/src/clis/chatwise/status.ts +3 -24
  341. package/src/clis/codex/ask.ts +5 -2
  342. package/src/clis/codex/dump.ts +2 -27
  343. package/src/clis/codex/new.ts +2 -28
  344. package/src/clis/codex/screenshot.ts +2 -32
  345. package/src/clis/codex/send.ts +5 -4
  346. package/src/clis/codex/status.ts +2 -24
  347. package/src/clis/cursor/ask.ts +2 -1
  348. package/src/clis/cursor/composer.ts +2 -1
  349. package/src/clis/cursor/dump.ts +2 -27
  350. package/src/clis/cursor/new.ts +2 -20
  351. package/src/clis/cursor/read.ts +2 -1
  352. package/src/clis/cursor/screenshot.ts +1 -36
  353. package/src/clis/cursor/send.ts +2 -1
  354. package/src/clis/cursor/status.ts +2 -22
  355. package/src/clis/dictionary/examples.yaml +25 -0
  356. package/src/clis/dictionary/search.yaml +27 -0
  357. package/src/clis/dictionary/synonyms.yaml +25 -0
  358. package/src/clis/douban/book-hot.ts +1 -1
  359. package/src/clis/douban/movie-hot.ts +1 -1
  360. package/src/clis/douban/search.ts +1 -1
  361. package/src/clis/douban/utils.ts +165 -1
  362. package/src/clis/doubao/ask.ts +1 -1
  363. package/src/clis/doubao/new.ts +1 -1
  364. package/src/clis/doubao/read.ts +1 -1
  365. package/src/clis/doubao/send.ts +1 -1
  366. package/src/clis/doubao/status.ts +1 -1
  367. package/src/clis/doubao-app/ask.ts +1 -1
  368. package/src/clis/doubao-app/new.ts +1 -1
  369. package/src/clis/doubao-app/read.ts +1 -1
  370. package/src/clis/doubao-app/send.ts +1 -1
  371. package/src/clis/grok/ask.test.ts +25 -0
  372. package/src/clis/grok/ask.ts +25 -12
  373. package/src/clis/jd/item.test.ts +35 -0
  374. package/src/clis/jd/item.ts +101 -0
  375. package/src/clis/jike/feed.ts +1 -1
  376. package/src/clis/jike/search.ts +1 -1
  377. package/src/clis/linkedin/search.ts +5 -4
  378. package/src/clis/linkedin/timeline.test.ts +99 -0
  379. package/src/clis/linkedin/timeline.ts +532 -0
  380. package/src/clis/medium/feed.ts +1 -1
  381. package/src/clis/medium/search.ts +1 -1
  382. package/src/clis/medium/user.ts +1 -1
  383. package/src/clis/medium/{shared.ts → utils.ts} +2 -1
  384. package/src/clis/pixiv/detail.yaml +49 -0
  385. package/src/clis/pixiv/download.test.ts +114 -0
  386. package/src/clis/pixiv/download.ts +91 -0
  387. package/src/clis/pixiv/illusts.test.ts +115 -0
  388. package/src/clis/pixiv/illusts.ts +78 -0
  389. package/src/clis/pixiv/ranking.yaml +53 -0
  390. package/src/clis/pixiv/search.test.ts +97 -0
  391. package/src/clis/pixiv/search.ts +53 -0
  392. package/src/clis/pixiv/test-utils.ts +29 -0
  393. package/src/clis/pixiv/user.yaml +46 -0
  394. package/src/clis/pixiv/utils.ts +62 -0
  395. package/src/clis/reddit/comment.ts +2 -1
  396. package/src/clis/reddit/read.test.ts +34 -0
  397. package/src/clis/reddit/read.ts +4 -3
  398. package/src/clis/reddit/save.ts +2 -1
  399. package/src/clis/reddit/saved.ts +6 -2
  400. package/src/clis/reddit/subscribe.ts +2 -1
  401. package/src/clis/reddit/upvote.ts +2 -1
  402. package/src/clis/reddit/upvoted.ts +6 -2
  403. package/src/clis/sinablog/article.ts +1 -1
  404. package/src/clis/sinablog/hot.ts +1 -1
  405. package/src/clis/sinablog/user.ts +1 -1
  406. package/src/clis/substack/feed.ts +1 -1
  407. package/src/clis/substack/publication.ts +1 -1
  408. package/src/clis/substack/search.ts +3 -2
  409. package/src/clis/substack/{shared.ts → utils.ts} +3 -2
  410. package/src/clis/tiktok/search.yaml +2 -1
  411. package/src/clis/twitter/accept.ts +2 -1
  412. package/src/clis/twitter/article.ts +3 -1
  413. package/src/clis/twitter/block.ts +2 -1
  414. package/src/clis/twitter/bookmark.ts +2 -1
  415. package/src/clis/twitter/bookmarks.ts +3 -2
  416. package/src/clis/twitter/delete.ts +2 -1
  417. package/src/clis/twitter/follow.ts +2 -1
  418. package/src/clis/twitter/followers.ts +3 -2
  419. package/src/clis/twitter/following.ts +3 -2
  420. package/src/clis/twitter/hide-reply.ts +2 -1
  421. package/src/clis/twitter/like.ts +2 -1
  422. package/src/clis/twitter/notifications.ts +2 -1
  423. package/src/clis/twitter/post.ts +2 -1
  424. package/src/clis/twitter/profile.ts +4 -2
  425. package/src/clis/twitter/reply-dm.ts +2 -1
  426. package/src/clis/twitter/reply.ts +2 -1
  427. package/src/clis/twitter/search.test.ts +113 -0
  428. package/src/clis/twitter/search.ts +38 -14
  429. package/src/clis/twitter/thread.ts +2 -2
  430. package/src/clis/twitter/timeline.ts +3 -2
  431. package/src/clis/twitter/trending.ts +3 -2
  432. package/src/clis/twitter/unblock.ts +2 -1
  433. package/src/clis/twitter/unbookmark.ts +2 -1
  434. package/src/clis/twitter/unfollow.ts +2 -1
  435. package/src/clis/v2ex/daily.ts +3 -2
  436. package/src/clis/v2ex/me.ts +3 -2
  437. package/src/clis/v2ex/notifications.ts +3 -4
  438. package/src/clis/web/read.ts +210 -0
  439. package/src/clis/xueqiu/danjuan-utils.test.ts +49 -0
  440. package/src/clis/xueqiu/danjuan-utils.ts +176 -0
  441. package/src/clis/xueqiu/fund-holdings.ts +32 -0
  442. package/src/clis/xueqiu/fund-snapshot.ts +27 -0
  443. package/src/clis/youtube/transcript.ts +5 -4
  444. package/src/clis/youtube/video.ts +3 -2
  445. package/src/constants.ts +3 -0
  446. package/src/daemon.ts +7 -5
  447. package/src/discovery.ts +12 -34
  448. package/src/doctor.ts +5 -3
  449. package/src/download/index.test.ts +93 -2
  450. package/src/download/index.ts +44 -23
  451. package/src/download/media-download.ts +5 -3
  452. package/src/engine.test.ts +84 -3
  453. package/src/execution.ts +62 -46
  454. package/src/explore.ts +21 -90
  455. package/src/external-clis.yaml +0 -8
  456. package/src/external.test.ts +9 -0
  457. package/src/external.ts +12 -10
  458. package/src/generate.ts +4 -41
  459. package/src/hooks.test.ts +126 -0
  460. package/src/hooks.ts +90 -0
  461. package/src/interceptor.ts +73 -23
  462. package/src/main.ts +2 -0
  463. package/src/output.ts +14 -6
  464. package/src/pipeline/executor.ts +1 -1
  465. package/src/pipeline/steps/browser.ts +1 -3
  466. package/src/pipeline/steps/download.test.ts +136 -0
  467. package/src/pipeline/steps/download.ts +47 -34
  468. package/src/pipeline/steps/fetch.test.ts +179 -0
  469. package/src/pipeline/steps/fetch.ts +39 -23
  470. package/src/pipeline/steps/transform.ts +2 -6
  471. package/src/pipeline/template.test.ts +28 -0
  472. package/src/pipeline/template.ts +67 -79
  473. package/src/pipeline/transform.test.ts +20 -0
  474. package/src/plugin.test.ts +251 -3
  475. package/src/plugin.ts +265 -21
  476. package/src/record.ts +12 -84
  477. package/src/registry-api.ts +2 -0
  478. package/src/registry.ts +7 -4
  479. package/src/runtime.ts +14 -4
  480. package/src/snapshotFormatter.ts +43 -121
  481. package/src/utils.ts +39 -0
  482. package/src/validate.ts +3 -6
  483. package/src/yaml-schema.ts +28 -0
  484. package/tests/e2e/browser-auth.test.ts +25 -0
  485. package/tests/e2e/plugin-management.test.ts +137 -0
  486. package/tests/e2e/public-commands.test.ts +34 -1
  487. package/vitest.config.ts +19 -1
  488. package/.github/workflows/pkg-pr-new.yml +0 -30
  489. package/dist/clis/douban/shared.d.ts +0 -4
  490. package/dist/clis/douban/shared.js +0 -155
  491. package/src/clis/douban/shared.ts +0 -165
  492. /package/dist/clis/boss/{common.d.ts → utils.d.ts} +0 -0
  493. /package/dist/clis/boss/{common.js → utils.js} +0 -0
  494. /package/dist/clis/doubao/{common.d.ts → utils.d.ts} +0 -0
  495. /package/dist/clis/doubao/{common.js → utils.js} +0 -0
  496. /package/dist/clis/doubao-app/{common.d.ts → utils.d.ts} +0 -0
  497. /package/dist/clis/doubao-app/{common.js → utils.js} +0 -0
  498. /package/dist/clis/jike/{shared.d.ts → utils.d.ts} +0 -0
  499. /package/dist/clis/jike/{shared.js → utils.js} +0 -0
  500. /package/dist/clis/medium/{shared.d.ts → utils.d.ts} +0 -0
  501. /package/dist/clis/sinablog/{shared.d.ts → utils.d.ts} +0 -0
  502. /package/dist/clis/sinablog/{shared.js → utils.js} +0 -0
  503. /package/dist/clis/substack/{shared.d.ts → utils.d.ts} +0 -0
  504. /package/src/clis/boss/{common.ts → utils.ts} +0 -0
  505. /package/src/clis/doubao/{common.ts → utils.ts} +0 -0
  506. /package/src/clis/doubao-app/{common.ts → utils.ts} +0 -0
  507. /package/src/clis/jike/{shared.ts → utils.ts} +0 -0
  508. /package/src/clis/sinablog/{shared.ts → utils.ts} +0 -0
@@ -1,13 +1,11 @@
1
1
  /**
2
2
  * Aria snapshot formatter: parses Playwright MCP snapshot text into clean format.
3
3
  *
4
- * Multi-pass pipeline:
5
- * 1. Parse & filter: strip annotations, metadata, noise roles, ads, decorators
6
- * 2. Deduplicate: generic/text child matching parent label
7
- * 3. Deduplicate: heading + link with identical labels
8
- * 4. Deduplicate: nested identical links
9
- * 5. Prune: empty containers (iterative bottom-up)
10
- * 6. Collapse: single-child containers
4
+ * 4-pass pipeline:
5
+ * 1. Parse & filter: strip annotations, metadata, noise, ads, boilerplate subtrees
6
+ * 2. Deduplicate: generic/text parent match, heading+link, nested identical links
7
+ * 3. Prune: empty containers (iterative bottom-up)
8
+ * 4. Collapse: single-child containers
11
9
  */
12
10
  const DEFAULT_MAX_TEXT_LENGTH = 200;
13
11
  // Roles that are pure noise and should always be filtered
@@ -174,88 +172,64 @@ export function formatSnapshot(raw, opts = {}) {
174
172
  return '';
175
173
  const maxTextLen = opts.maxTextLength ?? DEFAULT_MAX_TEXT_LENGTH;
176
174
  const lines = raw.split('\n');
177
- // === Pass 1: Parse, filter, and collect entries ===
178
- const entries = [];
175
+ // === Pass 1: Parse, filter, and collect entries (merged with ad/boilerplate subtree skip) ===
176
+ const parsed = [];
179
177
  let refCounter = 0;
180
- let skipUntilDepth = -1; // When >= 0, skip all nodes at depth > this value
178
+ let skipUntilDepth = -1;
181
179
  for (let i = 0; i < lines.length; i++) {
182
180
  const line = lines[i];
183
181
  if (!line.trim())
184
182
  continue;
185
183
  const indent = line.length - line.trimStart().length;
186
184
  const depth = Math.floor(indent / 2);
187
- // If we're in a subtree skip zone, check depth
185
+ // Subtree skip zone (noise roles, ads, boilerplate)
188
186
  if (skipUntilDepth >= 0) {
189
187
  if (depth > skipUntilDepth)
190
- continue; // still inside subtree
191
- skipUntilDepth = -1; // exited subtree
188
+ continue;
189
+ skipUntilDepth = -1;
192
190
  }
193
191
  let content = line.trimStart();
194
- // Strip leading "- "
195
- if (content.startsWith('- ')) {
192
+ if (content.startsWith('- '))
196
193
  content = content.slice(2);
197
- }
198
- // Skip metadata lines
199
194
  if (isMetadataLine(content))
200
195
  continue;
201
- // Apply maxDepth filter
202
196
  if (opts.maxDepth !== undefined && depth > opts.maxDepth)
203
197
  continue;
204
198
  const { role, text, hasText, trailingText } = parseLine(content);
205
- // Skip noise nodes
206
199
  if (isNoiseNode(role, hasText, text, trailingText))
207
200
  continue;
208
- // Skip subtree noise roles (contentinfo footer, etc.) — skip entire subtree
201
+ // Subtree noise roles (contentinfo footer, etc.)
209
202
  if (SUBTREE_NOISE_ROLES.has(role)) {
210
203
  skipUntilDepth = depth;
211
204
  continue;
212
205
  }
213
- // Strip annotations
206
+ // Ads and boilerplate — skip entire subtree (merged from old Pass 2)
207
+ if (isAdNode(text, trailingText) || isBoilerplateNode(text)) {
208
+ skipUntilDepth = depth;
209
+ continue;
210
+ }
214
211
  content = stripAnnotations(content);
215
- // Check if node should trigger subtree skip (ads, boilerplate)
216
- const isSubtreeSkip = isAdNode(text, trailingText) || isBoilerplateNode(text);
217
- // Interactive mode filter
218
212
  const isInteractive = INTERACTIVE_ROLES.has(role);
219
213
  const isLandmark = LANDMARK_ROLES.has(role);
220
214
  if (opts.interactive && !isInteractive && !isLandmark && !hasText)
221
215
  continue;
222
- // Compact mode
223
216
  if (opts.compact) {
224
- content = content
225
- .replace(/\s*\[.*?\]\s*/g, ' ')
226
- .replace(/\s+/g, ' ')
227
- .trim();
217
+ content = content.replace(/\s*\[.*?\]\s*/g, ' ').replace(/\s+/g, ' ').trim();
228
218
  }
229
- // Text truncation
230
219
  if (maxTextLen > 0 && content.length > maxTextLen) {
231
220
  content = content.slice(0, maxTextLen) + '…';
232
221
  }
233
- // Assign refs to interactive elements
234
222
  if (isInteractive) {
235
223
  refCounter++;
236
224
  content = `[@${refCounter}] ${content}`;
237
225
  }
238
- entries.push({ depth, content, role, text, trailingText, isInteractive, isLandmark, isSubtreeSkip });
226
+ parsed.push({ depth, content, role, text, trailingText, isInteractive, isLandmark });
239
227
  }
240
- // === Pass 2: Remove subtree-skip nodes (ads, boilerplate, contentinfo) ===
241
- let noAds = [];
242
- for (let i = 0; i < entries.length; i++) {
243
- const entry = entries[i];
244
- if (entry.isSubtreeSkip) {
245
- const skipDepth = entry.depth;
246
- i++;
247
- while (i < entries.length && entries[i].depth > skipDepth) {
248
- i++;
249
- }
250
- i--;
251
- continue;
252
- }
253
- noAds.push(entry);
254
- }
255
- // === Pass 3: Deduplicate child generic/text matching parent label ===
256
- let deduped = [];
257
- for (let i = 0; i < noAds.length; i++) {
258
- const entry = noAds[i];
228
+ // === Pass 2: Deduplicate (merged: generic/text parent match + heading+link + nested links) ===
229
+ const deduped = [];
230
+ for (let i = 0; i < parsed.length; i++) {
231
+ const entry = parsed[i];
232
+ // Dedup: generic/text child matching parent label
259
233
  if (entry.role === 'generic' || entry.role === 'text') {
260
234
  let parent;
261
235
  for (let j = deduped.length - 1; j >= 0; j--) {
@@ -268,43 +242,30 @@ export function formatSnapshot(raw, opts = {}) {
268
242
  }
269
243
  if (parent) {
270
244
  const childText = entry.trailingText || entry.text;
271
- if (childText && parent.text && childText === parent.text) {
245
+ if (childText && parent.text && childText === parent.text)
272
246
  continue;
273
- }
274
247
  }
275
248
  }
276
- deduped.push(entry);
277
- }
278
- // === Pass 4: Deduplicate heading + child link with identical label ===
279
- // Pattern: heading "Title": → link "Title": (same text) → skip the link
280
- const deduped2 = [];
281
- for (let i = 0; i < deduped.length; i++) {
282
- const entry = deduped[i];
249
+ // Dedup: heading + child link with identical label
283
250
  if (entry.role === 'heading' && entry.text) {
284
- const next = deduped[i + 1];
251
+ const next = parsed[i + 1];
285
252
  if (next && next.role === 'link' && next.text === entry.text && next.depth === entry.depth + 1) {
286
- // Keep the heading, skip the link. But preserve link's children re-parented.
287
- deduped2.push(entry);
288
- i++; // skip the link
253
+ deduped.push(entry);
254
+ i++; // skip the link, preserve its children
289
255
  continue;
290
256
  }
291
257
  }
292
- deduped2.push(entry);
293
- }
294
- // === Pass 5: Deduplicate nested identical links ===
295
- const deduped3 = [];
296
- for (let i = 0; i < deduped2.length; i++) {
297
- const entry = deduped2[i];
258
+ // Dedup: nested identical links (skip parent, keep child)
298
259
  if (entry.role === 'link' && entry.text) {
299
- const next = deduped2[i + 1];
260
+ const next = parsed[i + 1];
300
261
  if (next && next.role === 'link' && next.text === entry.text && next.depth === entry.depth + 1) {
301
- continue; // Skip parent, keep child
262
+ continue;
302
263
  }
303
264
  }
304
- deduped3.push(entry);
265
+ deduped.push(entry);
305
266
  }
306
- // === Pass 6: Iteratively prune empty containers (bottom-up) ===
307
- let current = deduped3;
267
+ // === Pass 3: Iteratively prune empty containers (bottom-up) ===
268
+ let current = deduped;
308
269
  let changed = true;
309
270
  while (changed) {
310
271
  changed = false;
@@ -330,7 +291,7 @@ export function formatSnapshot(raw, opts = {}) {
330
291
  }
331
292
  current = next;
332
293
  }
333
- // === Pass 7: Collapse single-child containers ===
294
+ // === Pass 4: Collapse single-child containers ===
334
295
  const collapsed = [];
335
296
  for (let i = 0; i < current.length; i++) {
336
297
  const entry = current[i];
@@ -358,10 +319,9 @@ export function formatSnapshot(raw, opts = {}) {
358
319
  }
359
320
  }
360
321
  if (!hasGrandchildren) {
361
- const mergedContent = entry.content.replace(/:$/, '') + ' > ' + child.content;
362
322
  collapsed.push({
363
323
  ...entry,
364
- content: mergedContent,
324
+ content: entry.content.replace(/:$/, '') + ' > ' + child.content,
365
325
  role: child.role,
366
326
  text: child.text,
367
327
  trailingText: child.trailingText,
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Shared utility functions used across the codebase.
3
+ */
4
+ /** Type guard: checks if a value is a non-null, non-array object. */
5
+ export declare function isRecord(value: unknown): value is Record<string, unknown>;
6
+ /** Simple async concurrency limiter. */
7
+ export declare function mapConcurrent<T, R>(items: T[], limit: number, fn: (item: T, index: number) => Promise<R>): Promise<R[]>;
8
+ /** Save a base64-encoded string to a file, creating parent directories as needed. */
9
+ export declare function saveBase64ToFile(base64: string, filePath: string): Promise<void>;
package/dist/utils.js ADDED
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Shared utility functions used across the codebase.
3
+ */
4
+ import * as fs from 'node:fs';
5
+ import * as path from 'node:path';
6
+ /** Type guard: checks if a value is a non-null, non-array object. */
7
+ export function isRecord(value) {
8
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
9
+ }
10
+ /** Simple async concurrency limiter. */
11
+ export async function mapConcurrent(items, limit, fn) {
12
+ const results = new Array(items.length);
13
+ let index = 0;
14
+ async function worker() {
15
+ while (index < items.length) {
16
+ const i = index++;
17
+ results[i] = await fn(items[i], i);
18
+ }
19
+ }
20
+ const workers = Array.from({ length: Math.min(limit, items.length) }, () => worker());
21
+ await Promise.all(workers);
22
+ return results;
23
+ }
24
+ /** Save a base64-encoded string to a file, creating parent directories as needed. */
25
+ export async function saveBase64ToFile(base64, filePath) {
26
+ const dir = path.dirname(filePath);
27
+ await fs.promises.mkdir(dir, { recursive: true });
28
+ await fs.promises.writeFile(filePath, Buffer.from(base64, 'base64'));
29
+ }
package/dist/validate.js CHANGED
@@ -5,14 +5,12 @@ import yaml from 'js-yaml';
5
5
  import { getErrorMessage } from './errors.js';
6
6
  /** All recognized pipeline step names */
7
7
  const KNOWN_STEP_NAMES = new Set([
8
- 'navigate', 'click', 'type', 'wait', 'press', 'snapshot', 'scroll',
8
+ 'navigate', 'click', 'type', 'wait', 'press', 'snapshot',
9
9
  'fetch', 'evaluate',
10
10
  'select', 'map', 'filter', 'sort', 'limit',
11
- 'intercept', 'tap',
11
+ 'intercept', 'tap', 'download',
12
12
  ]);
13
- function isRecord(value) {
14
- return typeof value === 'object' && value !== null && !Array.isArray(value);
15
- }
13
+ import { isRecord } from './utils.js';
16
14
  export function validateClisWithTarget(dirs, target) {
17
15
  const results = [];
18
16
  let errors = 0;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Shared YAML CLI definition types.
3
+ * Used by both discovery.ts (runtime) and build-manifest.ts (build-time).
4
+ */
5
+ export interface YamlArgDefinition {
6
+ type?: string;
7
+ default?: unknown;
8
+ required?: boolean;
9
+ positional?: boolean;
10
+ description?: string;
11
+ help?: string;
12
+ choices?: string[];
13
+ }
14
+ export interface YamlCliDefinition {
15
+ site?: string;
16
+ name?: string;
17
+ description?: string;
18
+ domain?: string;
19
+ strategy?: string;
20
+ browser?: boolean;
21
+ args?: Record<string, YamlArgDefinition>;
22
+ columns?: string[];
23
+ pipeline?: Record<string, unknown>[];
24
+ timeout?: number;
25
+ navigateBefore?: boolean | string;
26
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Shared YAML CLI definition types.
3
+ * Used by both discovery.ts (runtime) and build-manifest.ts (build-time).
4
+ */
5
+ export {};
@@ -29,6 +29,7 @@ export default defineConfig({
29
29
  items: [
30
30
  { text: 'Getting Started', link: '/guide/getting-started' },
31
31
  { text: 'Installation', link: '/guide/installation' },
32
+ { text: 'Comparison', link: '/comparison' },
32
33
  { text: 'Browser Bridge', link: '/guide/browser-bridge' },
33
34
  { text: 'Troubleshooting', link: '/guide/troubleshooting' },
34
35
  { text: 'Plugins', link: '/guide/plugins' },
@@ -72,6 +73,7 @@ export default defineConfig({
72
73
  { text: 'Douban', link: '/adapters/browser/douban' },
73
74
  { text: 'Sina Blog', link: '/adapters/browser/sinablog' },
74
75
  { text: 'Substack', link: '/adapters/browser/substack' },
76
+ { text: 'Pixiv', link: '/adapters/browser/pixiv' },
75
77
  ],
76
78
  },
77
79
  {
@@ -80,6 +82,7 @@ export default defineConfig({
80
82
  items: [
81
83
  { text: 'HackerNews', link: '/adapters/browser/hackernews' },
82
84
  { text: 'Dev.to', link: '/adapters/browser/devto' },
85
+ { text: 'Dictionary', link: '/adapters/browser/dictionary' },
83
86
  { text: 'BBC', link: '/adapters/browser/bbc' },
84
87
  { text: 'Apple Podcasts', link: '/adapters/browser/apple-podcasts' },
85
88
  { text: 'Xiaoyuzhou', link: '/adapters/browser/xiaoyuzhou' },
@@ -0,0 +1,27 @@
1
+ # Dictionary
2
+
3
+ **Mode**: 🌐 Public · **Domain**: `api.dictionaryapi.dev`
4
+
5
+ Search the open dictionary to quickly fetch native definitions, part of speech contexts, and phonetic pronunciations directly in your IDE terminal.
6
+
7
+ ## Commands
8
+
9
+ | Command | Description |
10
+ |---------|-------------|
11
+ | `opencli dictionary search` | Fetch the exact definition of a word |
12
+ | `opencli dictionary synonyms` | Find related synonyms for a word |
13
+ | `opencli dictionary examples` | Read real-world sentence usage examples |
14
+
15
+ ## Usage Examples
16
+
17
+ ```bash
18
+ # Look up a complex term
19
+ opencli dictionary search serendipity
20
+
21
+ # Discover phonetics
22
+ opencli dictionary search ephemeral
23
+ ```
24
+
25
+ ## Prerequisites
26
+
27
+ - No browser required — utilizes the fast, open JSON definitions API.
@@ -6,19 +6,17 @@
6
6
 
7
7
  | Command | Description |
8
8
  |---------|-------------|
9
+ | `opencli douban search` | 搜索豆瓣电影、图书或音乐 |
10
+ | `opencli douban top250` | 豆瓣电影 Top 250 |
11
+ | `opencli douban subject` | 条目详情 |
12
+ | `opencli douban marks` | 我的标记 |
13
+ | `opencli douban reviews` | 我的短评 |
9
14
  | `opencli douban movie-hot` | 豆瓣电影热门榜单 |
10
15
  | `opencli douban book-hot` | 豆瓣图书热门榜单 |
11
- | `opencli douban search` | 搜索豆瓣电影、图书或音乐 |
12
16
 
13
17
  ## Usage Examples
14
18
 
15
19
  ```bash
16
- # 电影热门
17
- opencli douban movie-hot --limit 10
18
-
19
- # 图书热门
20
- opencli douban book-hot --limit 10
21
-
22
20
  # 搜索电影
23
21
  opencli douban search "流浪地球"
24
22
 
@@ -28,8 +26,20 @@ opencli douban search --type book "三体"
28
26
  # 搜索音乐
29
27
  opencli douban search --type music "周杰伦"
30
28
 
29
+ # 电影 Top 250
30
+ opencli douban top250 --limit 10
31
+
32
+ # 条目详情
33
+ opencli douban subject 1292052
34
+
35
+ # 电影热门
36
+ opencli douban movie-hot --limit 10
37
+
38
+ # 图书热门
39
+ opencli douban book-hot --limit 10
40
+
31
41
  # JSON output
32
- opencli douban movie-hot -f json
42
+ opencli douban top250 -f json
33
43
  ```
34
44
 
35
45
  ## Prerequisites
@@ -0,0 +1,27 @@
1
+ # JD.com
2
+
3
+ **Mode**: 🔐 Browser · **Domain**: `item.jd.com`
4
+
5
+ ## Commands
6
+
7
+ | Command | Description |
8
+ |---------|-------------|
9
+ | `opencli jd item <sku>` | Fetch product details (price, images, specs) |
10
+
11
+ ## Usage Examples
12
+
13
+ ```bash
14
+ # Get product details by SKU
15
+ opencli jd item 100291143898
16
+
17
+ # Limit detail images
18
+ opencli jd item 100291143898 --images 5
19
+
20
+ # JSON output
21
+ opencli jd item 100291143898 -f json
22
+ ```
23
+
24
+ ## Prerequisites
25
+
26
+ - Chrome running and **logged into** jd.com
27
+ - [Browser Bridge extension](/guide/browser-bridge) installed
@@ -7,6 +7,7 @@
7
7
  | Command | Description |
8
8
  |---------|-------------|
9
9
  | `opencli linkedin search` | |
10
+ | `opencli linkedin timeline` | Read posts from your LinkedIn home feed |
10
11
 
11
12
  ## Usage Examples
12
13
 
@@ -14,9 +15,14 @@
14
15
  # Quick start
15
16
  opencli linkedin search --limit 5
16
17
 
18
+ # Read your home timeline
19
+ opencli linkedin timeline --limit 5
20
+
17
21
  # JSON output
18
22
  opencli linkedin search -f json
19
23
 
24
+ opencli linkedin timeline -f json
25
+
20
26
  # Verbose mode
21
27
  opencli linkedin search -v
22
28
  ```
@@ -0,0 +1,92 @@
1
+ # Pixiv
2
+
3
+ **Mode**: 🔐 Browser · **Domain**: `www.pixiv.net`
4
+
5
+ ## Commands
6
+
7
+ | Command | Description |
8
+ |---------|-------------|
9
+ | `opencli pixiv ranking` | Daily/weekly/monthly illustration rankings |
10
+ | `opencli pixiv search <query>` | Search illustrations by keyword or tag |
11
+ | `opencli pixiv user <uid>` | View artist profile info |
12
+ | `opencli pixiv illusts <user-id>` | List illustrations by artist |
13
+ | `opencli pixiv detail <id>` | View illustration details |
14
+ | `opencli pixiv download <illust-id>` | Download original-quality images |
15
+
16
+ ## Usage Examples
17
+
18
+ ### Ranking
19
+
20
+ ```bash
21
+ # Daily rankings (default)
22
+ opencli pixiv ranking --limit 10
23
+
24
+ # Weekly / monthly rankings
25
+ opencli pixiv ranking --mode weekly
26
+ opencli pixiv ranking --mode monthly
27
+
28
+ # R18 rankings
29
+ opencli pixiv ranking --mode daily_r18
30
+ opencli pixiv ranking --mode weekly_r18
31
+
32
+ # Other modes: rookie, original, male, female
33
+ opencli pixiv ranking --mode rookie
34
+ ```
35
+
36
+ ### Search
37
+
38
+ ```bash
39
+ # Search by keyword or tag
40
+ opencli pixiv search "初音ミク" --limit 20
41
+
42
+ # Filter by content rating
43
+ opencli pixiv search "風景" --mode safe # Safe-for-work only
44
+ opencli pixiv search "風景" --mode r18 # R18 only
45
+ opencli pixiv search "風景" --mode all # All (default)
46
+
47
+ # Sort by popularity
48
+ opencli pixiv search "VOCALOID" --order popular_d
49
+
50
+ # All sort options: date_d (newest), date (oldest), popular_d, popular_male_d, popular_female_d
51
+
52
+ # Pagination
53
+ opencli pixiv search "オリジナル" --page 2 --limit 30
54
+ ```
55
+
56
+ ### User & Illustrations
57
+
58
+ ```bash
59
+ # View artist profile
60
+ opencli pixiv user 11
61
+
62
+ # List artist's illustrations (newest first)
63
+ opencli pixiv illusts 11 --limit 10
64
+
65
+ # View illustration details (tags, stats, type)
66
+ opencli pixiv detail 12345678
67
+ ```
68
+
69
+ ### Download
70
+
71
+ ```bash
72
+ # Download all images from an illustration
73
+ opencli pixiv download 12345678
74
+
75
+ # Download to a custom directory
76
+ opencli pixiv download 12345678 --output ./my-images
77
+ ```
78
+
79
+ ### Output Formats
80
+
81
+ ```bash
82
+ # JSON output
83
+ opencli pixiv ranking -f json
84
+
85
+ # Verbose mode
86
+ opencli pixiv search "test" -v
87
+ ```
88
+
89
+ ## Prerequisites
90
+
91
+ - Chrome running and **logged into** pixiv.net
92
+ - [Browser Bridge extension](/guide/browser-bridge) installed
@@ -0,0 +1,30 @@
1
+ # Web
2
+
3
+ **Mode**: 🔐 Browser · **Domain**: any URL
4
+
5
+ ## Commands
6
+
7
+ | Command | Description |
8
+ |---------|-------------|
9
+ | `opencli web read <url>` | Fetch any web page and export as Markdown |
10
+
11
+ ## Usage Examples
12
+
13
+ ```bash
14
+ # Read a web page and save as Markdown
15
+ opencli web read https://example.com/article
16
+
17
+ # Custom output directory
18
+ opencli web read https://example.com/article --output ./my-articles
19
+
20
+ # Skip image download
21
+ opencli web read https://example.com/article --download-images false
22
+
23
+ # JSON output
24
+ opencli web read https://example.com/article -f json
25
+ ```
26
+
27
+ ## Prerequisites
28
+
29
+ - Chrome running
30
+ - [Browser Bridge extension](/guide/browser-bridge) installed
@@ -8,8 +8,6 @@
8
8
  |---------|-------------|
9
9
  | `opencli wikipedia search` | Search Wikipedia articles |
10
10
  | `opencli wikipedia summary` | Get Wikipedia article summary |
11
- | `opencli wikipedia random` | Get a random Wikipedia article |
12
- | `opencli wikipedia trending` | Most-read articles (yesterday) |
13
11
 
14
12
  ## Usage Examples
15
13
 
@@ -20,15 +18,8 @@ opencli wikipedia search "quantum computing" --limit 10
20
18
  # Get article summary
21
19
  opencli wikipedia summary "Artificial intelligence"
22
20
 
23
- # Get a random article
24
- opencli wikipedia random
25
-
26
- # Most-read articles (yesterday)
27
- opencli wikipedia trending --limit 5
28
-
29
21
  # Use with other languages
30
22
  opencli wikipedia search "人工智能" --lang zh
31
- opencli wikipedia random --lang ja
32
23
 
33
24
  # JSON output
34
25
  opencli wikipedia search "Rust" -f json
@@ -1,18 +1,20 @@
1
1
  # Xueqiu (雪球)
2
2
 
3
- **Mode**: 🔐 Browser · **Domain**: `xueqiu.com`
3
+ **Mode**: 🔐 Browser · **Domain**: `xueqiu.com` / `danjuanfunds.com`
4
4
 
5
5
  ## Commands
6
6
 
7
7
  | Command | Description |
8
8
  |---------|-------------|
9
- | `opencli xueqiu feed` | |
10
- | `opencli xueqiu earnings-date` | |
11
- | `opencli xueqiu hot-stock` | |
12
- | `opencli xueqiu hot` | |
13
- | `opencli xueqiu search` | |
14
- | `opencli xueqiu stock` | |
15
- | `opencli xueqiu watchlist` | |
9
+ | `opencli xueqiu feed` | 获取雪球首页时间线 |
10
+ | `opencli xueqiu earnings-date` | 获取股票预计财报发布日期 |
11
+ | `opencli xueqiu hot-stock` | 获取雪球热门股票榜 |
12
+ | `opencli xueqiu hot` | 获取雪球热门动态 |
13
+ | `opencli xueqiu search` | 搜索雪球股票(代码或名称) |
14
+ | `opencli xueqiu stock` | 获取雪球股票实时行情 |
15
+ | `opencli xueqiu watchlist` | 获取雪球自选股列表 |
16
+ | `opencli xueqiu fund-holdings` | 获取蛋卷基金持仓明细(可用 `--account` 按子账户过滤) |
17
+ | `opencli xueqiu fund-snapshot` | 获取蛋卷基金快照(总资产、子账户、持仓,推荐 `-f json`) |
16
18
 
17
19
  ## Usage Examples
18
20
 
@@ -29,6 +31,15 @@ opencli xueqiu stock SH600519
29
31
  # Upcoming earnings dates
30
32
  opencli xueqiu earnings-date SH600519 --next
31
33
 
34
+ # Danjuan all holdings
35
+ opencli xueqiu fund-holdings
36
+
37
+ # Filter one Danjuan sub-account
38
+ opencli xueqiu fund-holdings --account 默认账户
39
+
40
+ # Full Danjuan snapshot as JSON
41
+ opencli xueqiu fund-snapshot -f json
42
+
32
43
  # JSON output
33
44
  opencli xueqiu feed -f json
34
45
 
@@ -38,5 +49,12 @@ opencli xueqiu feed -v
38
49
 
39
50
  ## Prerequisites
40
51
 
41
- - Chrome running and **logged into** xueqiu.com
52
+ - Chrome running and **logged into** `xueqiu.com`
53
+ - For fund commands, Chrome must also be logged into `danjuanfunds.com` and able to open `https://danjuanfunds.com/my-money`
42
54
  - [Browser Bridge extension](/guide/browser-bridge) installed
55
+
56
+ ## Notes
57
+
58
+ - `fund-holdings` exposes both market value and share fields (`volume`, `usableRemainShare`)
59
+ - `fund-snapshot -f json` is the easiest way to persist a full account snapshot for later analysis or diffing
60
+ - If the commands return empty data, first confirm the logged-in browser can directly see the Danjuan asset page
@@ -47,6 +47,3 @@ Quickly target and switch the active LLM engine. Example: `opencli antigravity m
47
47
 
48
48
  ### `opencli antigravity watch`
49
49
  A long-running, streaming process that continuously polls the Antigravity UI for chat updates and outputs them in real-time to standard output.
50
-
51
- ### `opencli antigravity serve --port 8082`
52
- Start an Anthropic-compatible `/v1/messages` proxy backed by the local Antigravity app. Useful when you want external tools to talk to Antigravity through an API-shaped interface.