@jackwener/opencli 0.9.6 → 1.0.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 (307) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.yml +83 -0
  2. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  3. package/.github/ISSUE_TEMPLATE/feature_request.yml +42 -0
  4. package/.github/ISSUE_TEMPLATE/new_site_adapter.yml +57 -0
  5. package/.github/dependabot.yml +27 -0
  6. package/.github/pull_request_template.md +24 -0
  7. package/.github/workflows/ci.yml +14 -8
  8. package/.github/workflows/e2e-headed.yml +6 -2
  9. package/.github/workflows/pkg-pr-new.yml +2 -2
  10. package/.github/workflows/release-please.yml +25 -0
  11. package/.github/workflows/release.yml +2 -2
  12. package/.github/workflows/security.yml +36 -0
  13. package/CDP.md +1 -1
  14. package/CDP.zh-CN.md +1 -1
  15. package/CLI-ELECTRON.md +89 -36
  16. package/CLI-EXPLORER.md +4 -4
  17. package/CONTRIBUTING.md +167 -0
  18. package/README.md +113 -89
  19. package/README.zh-CN.md +114 -91
  20. package/SKILL.md +10 -8
  21. package/TESTING.md +7 -7
  22. package/dist/browser/daemon-client.d.ts +37 -0
  23. package/dist/browser/daemon-client.js +82 -0
  24. package/dist/browser/discover.d.ts +11 -34
  25. package/dist/browser/discover.js +15 -190
  26. package/dist/browser/errors.d.ts +6 -20
  27. package/dist/browser/errors.js +24 -63
  28. package/dist/browser/index.d.ts +2 -11
  29. package/dist/browser/index.js +5 -11
  30. package/dist/browser/mcp.d.ts +9 -18
  31. package/dist/browser/mcp.js +70 -284
  32. package/dist/browser/page.d.ts +28 -6
  33. package/dist/browser/page.js +210 -85
  34. package/dist/browser.test.js +4 -202
  35. package/dist/build-manifest.d.ts +26 -0
  36. package/dist/build-manifest.js +132 -60
  37. package/dist/build-manifest.test.d.ts +1 -0
  38. package/dist/build-manifest.test.js +26 -0
  39. package/dist/cli-manifest.json +1582 -29
  40. package/dist/clis/bilibili/download.d.ts +10 -0
  41. package/dist/clis/bilibili/download.js +135 -0
  42. package/dist/clis/chatwise/ask.d.ts +1 -0
  43. package/dist/clis/chatwise/ask.js +76 -0
  44. package/dist/clis/chatwise/export.d.ts +1 -0
  45. package/dist/clis/chatwise/export.js +46 -0
  46. package/dist/clis/chatwise/history.d.ts +1 -0
  47. package/dist/clis/chatwise/history.js +43 -0
  48. package/dist/clis/chatwise/model.d.ts +1 -0
  49. package/dist/clis/chatwise/model.js +81 -0
  50. package/dist/clis/chatwise/new.d.ts +1 -0
  51. package/dist/clis/chatwise/new.js +18 -0
  52. package/dist/clis/chatwise/read.d.ts +1 -0
  53. package/dist/clis/chatwise/read.js +39 -0
  54. package/dist/clis/chatwise/screenshot.d.ts +1 -0
  55. package/dist/clis/chatwise/screenshot.js +27 -0
  56. package/dist/clis/chatwise/send.d.ts +1 -0
  57. package/dist/clis/chatwise/send.js +45 -0
  58. package/dist/clis/chatwise/status.d.ts +1 -0
  59. package/dist/clis/chatwise/status.js +22 -0
  60. package/dist/clis/discord-app/channels.d.ts +1 -0
  61. package/dist/clis/discord-app/channels.js +45 -0
  62. package/dist/clis/discord-app/members.d.ts +1 -0
  63. package/dist/clis/discord-app/members.js +38 -0
  64. package/dist/clis/discord-app/read.d.ts +1 -0
  65. package/dist/clis/discord-app/read.js +45 -0
  66. package/dist/clis/discord-app/search.d.ts +1 -0
  67. package/dist/clis/discord-app/search.js +56 -0
  68. package/dist/clis/discord-app/send.d.ts +1 -0
  69. package/dist/clis/discord-app/send.js +27 -0
  70. package/dist/clis/discord-app/servers.d.ts +1 -0
  71. package/dist/clis/discord-app/servers.js +36 -0
  72. package/dist/clis/discord-app/status.d.ts +1 -0
  73. package/dist/clis/discord-app/status.js +16 -0
  74. package/dist/clis/feishu/new.d.ts +1 -0
  75. package/dist/clis/feishu/new.js +27 -0
  76. package/dist/clis/feishu/read.d.ts +1 -0
  77. package/dist/clis/feishu/read.js +40 -0
  78. package/dist/clis/feishu/search.d.ts +1 -0
  79. package/dist/clis/feishu/search.js +30 -0
  80. package/dist/clis/feishu/send.d.ts +1 -0
  81. package/dist/clis/feishu/send.js +39 -0
  82. package/dist/clis/feishu/status.d.ts +1 -0
  83. package/dist/clis/feishu/status.js +28 -0
  84. package/dist/clis/grok/ask.d.ts +1 -0
  85. package/dist/clis/grok/ask.js +82 -0
  86. package/dist/clis/grok/debug.d.ts +1 -0
  87. package/dist/clis/grok/debug.js +45 -0
  88. package/dist/clis/jimeng/generate.yaml +84 -0
  89. package/dist/clis/jimeng/history.yaml +47 -0
  90. package/dist/clis/linux-do/categories.yaml +41 -0
  91. package/dist/clis/linux-do/category.yaml +49 -0
  92. package/dist/clis/linux-do/hot.yaml +50 -0
  93. package/dist/clis/linux-do/latest.yaml +40 -0
  94. package/dist/clis/linux-do/search.yaml +45 -0
  95. package/dist/clis/linux-do/topic.yaml +38 -0
  96. package/dist/clis/neteasemusic/like.d.ts +1 -0
  97. package/dist/clis/neteasemusic/like.js +25 -0
  98. package/dist/clis/neteasemusic/lyrics.d.ts +1 -0
  99. package/dist/clis/neteasemusic/lyrics.js +47 -0
  100. package/dist/clis/neteasemusic/next.d.ts +1 -0
  101. package/dist/clis/neteasemusic/next.js +26 -0
  102. package/dist/clis/neteasemusic/play.d.ts +1 -0
  103. package/dist/clis/neteasemusic/play.js +26 -0
  104. package/dist/clis/neteasemusic/playing.d.ts +1 -0
  105. package/dist/clis/neteasemusic/playing.js +59 -0
  106. package/dist/clis/neteasemusic/playlist.d.ts +1 -0
  107. package/dist/clis/neteasemusic/playlist.js +46 -0
  108. package/dist/clis/neteasemusic/prev.d.ts +1 -0
  109. package/dist/clis/neteasemusic/prev.js +25 -0
  110. package/dist/clis/neteasemusic/search.d.ts +1 -0
  111. package/dist/clis/neteasemusic/search.js +52 -0
  112. package/dist/clis/neteasemusic/status.d.ts +1 -0
  113. package/dist/clis/neteasemusic/status.js +16 -0
  114. package/dist/clis/neteasemusic/volume.d.ts +1 -0
  115. package/dist/clis/neteasemusic/volume.js +54 -0
  116. package/dist/clis/notion/export.d.ts +1 -0
  117. package/dist/clis/notion/export.js +31 -0
  118. package/dist/clis/notion/favorites.d.ts +1 -0
  119. package/dist/clis/notion/favorites.js +84 -0
  120. package/dist/clis/notion/new.d.ts +1 -0
  121. package/dist/clis/notion/new.js +34 -0
  122. package/dist/clis/notion/read.d.ts +1 -0
  123. package/dist/clis/notion/read.js +30 -0
  124. package/dist/clis/notion/search.d.ts +1 -0
  125. package/dist/clis/notion/search.js +46 -0
  126. package/dist/clis/notion/sidebar.d.ts +1 -0
  127. package/dist/clis/notion/sidebar.js +41 -0
  128. package/dist/clis/notion/status.d.ts +1 -0
  129. package/dist/clis/notion/status.js +16 -0
  130. package/dist/clis/notion/write.d.ts +1 -0
  131. package/dist/clis/notion/write.js +40 -0
  132. package/dist/clis/twitter/download.d.ts +8 -0
  133. package/dist/clis/twitter/download.js +204 -0
  134. package/dist/clis/wechat/chats.d.ts +1 -0
  135. package/dist/clis/wechat/chats.js +28 -0
  136. package/dist/clis/wechat/contacts.d.ts +1 -0
  137. package/dist/clis/wechat/contacts.js +28 -0
  138. package/dist/clis/wechat/read.d.ts +1 -0
  139. package/dist/clis/wechat/read.js +58 -0
  140. package/dist/clis/wechat/search.d.ts +1 -0
  141. package/dist/clis/wechat/search.js +31 -0
  142. package/dist/clis/wechat/send.d.ts +1 -0
  143. package/dist/clis/wechat/send.js +42 -0
  144. package/dist/clis/wechat/status.d.ts +1 -0
  145. package/dist/clis/wechat/status.js +29 -0
  146. package/dist/clis/xiaohongshu/creator-note-detail.d.ts +10 -0
  147. package/dist/clis/xiaohongshu/creator-note-detail.js +88 -0
  148. package/dist/clis/xiaohongshu/creator-notes.d.ts +11 -0
  149. package/dist/clis/xiaohongshu/creator-notes.js +109 -0
  150. package/dist/clis/xiaohongshu/creator-profile.d.ts +10 -0
  151. package/dist/clis/xiaohongshu/creator-profile.js +54 -0
  152. package/dist/clis/xiaohongshu/creator-stats.d.ts +10 -0
  153. package/dist/clis/xiaohongshu/creator-stats.js +74 -0
  154. package/dist/clis/xiaohongshu/download.d.ts +7 -0
  155. package/dist/clis/xiaohongshu/download.js +155 -0
  156. package/dist/clis/xiaohongshu/search.js +1 -1
  157. package/dist/clis/xiaohongshu/user-helpers.d.ts +15 -0
  158. package/dist/clis/xiaohongshu/user-helpers.js +67 -0
  159. package/dist/clis/xiaohongshu/user-helpers.test.d.ts +1 -0
  160. package/dist/clis/xiaohongshu/user-helpers.test.js +81 -0
  161. package/dist/clis/xiaohongshu/user.js +46 -29
  162. package/dist/clis/zhihu/download.d.ts +11 -0
  163. package/dist/clis/zhihu/download.js +186 -0
  164. package/dist/clis/zhihu/download.test.d.ts +1 -0
  165. package/dist/clis/zhihu/download.test.js +10 -0
  166. package/dist/daemon.d.ts +13 -0
  167. package/dist/daemon.js +187 -0
  168. package/dist/doctor.d.ts +27 -61
  169. package/dist/doctor.js +70 -601
  170. package/dist/doctor.test.js +30 -170
  171. package/dist/download/index.d.ts +79 -0
  172. package/dist/download/index.js +325 -0
  173. package/dist/download/progress.d.ts +36 -0
  174. package/dist/download/progress.js +111 -0
  175. package/dist/engine.test.js +15 -0
  176. package/dist/main.js +22 -28
  177. package/dist/pipeline/executor.test.js +1 -0
  178. package/dist/pipeline/registry.js +2 -0
  179. package/dist/pipeline/steps/browser.js +2 -2
  180. package/dist/pipeline/steps/download.d.ts +34 -0
  181. package/dist/pipeline/steps/download.js +251 -0
  182. package/dist/pipeline/steps/intercept.js +1 -2
  183. package/dist/pipeline/template.js +28 -0
  184. package/dist/setup.d.ts +6 -0
  185. package/dist/setup.js +46 -160
  186. package/dist/types.d.ts +6 -0
  187. package/extension/icons/icon-128.png +0 -0
  188. package/extension/icons/icon-16.png +0 -0
  189. package/extension/icons/icon-32.png +0 -0
  190. package/extension/icons/icon-48.png +0 -0
  191. package/extension/manifest.json +31 -0
  192. package/extension/package.json +16 -0
  193. package/extension/src/background.ts +293 -0
  194. package/extension/src/cdp.ts +125 -0
  195. package/extension/src/protocol.ts +57 -0
  196. package/extension/store-assets/screenshot-1280x800.png +0 -0
  197. package/extension/tsconfig.json +15 -0
  198. package/extension/vite.config.ts +18 -0
  199. package/package.json +8 -7
  200. package/scripts/test-site.mjs +70 -0
  201. package/src/browser/daemon-client.ts +113 -0
  202. package/src/browser/discover.ts +18 -216
  203. package/src/browser/errors.ts +30 -100
  204. package/src/browser/index.ts +6 -12
  205. package/src/browser/mcp.ts +78 -278
  206. package/src/browser/page.ts +222 -88
  207. package/src/browser.test.ts +3 -210
  208. package/src/build-manifest.test.ts +28 -0
  209. package/src/build-manifest.ts +147 -57
  210. package/src/clis/bilibili/download.ts +161 -0
  211. package/src/clis/chatgpt/README.md +1 -1
  212. package/src/clis/chatgpt/README.zh-CN.md +1 -1
  213. package/src/clis/chatwise/README.md +38 -0
  214. package/src/clis/chatwise/README.zh-CN.md +38 -0
  215. package/src/clis/chatwise/ask.ts +87 -0
  216. package/src/clis/chatwise/export.ts +51 -0
  217. package/src/clis/chatwise/history.ts +47 -0
  218. package/src/clis/chatwise/model.ts +87 -0
  219. package/src/clis/chatwise/new.ts +21 -0
  220. package/src/clis/chatwise/read.ts +42 -0
  221. package/src/clis/chatwise/screenshot.ts +33 -0
  222. package/src/clis/chatwise/send.ts +50 -0
  223. package/src/clis/chatwise/status.ts +25 -0
  224. package/src/clis/discord-app/README.md +28 -0
  225. package/src/clis/discord-app/README.zh-CN.md +28 -0
  226. package/src/clis/discord-app/channels.ts +48 -0
  227. package/src/clis/discord-app/members.ts +41 -0
  228. package/src/clis/discord-app/read.ts +49 -0
  229. package/src/clis/discord-app/search.ts +64 -0
  230. package/src/clis/discord-app/send.ts +32 -0
  231. package/src/clis/discord-app/servers.ts +39 -0
  232. package/src/clis/discord-app/status.ts +18 -0
  233. package/src/clis/feishu/README.md +20 -0
  234. package/src/clis/feishu/README.zh-CN.md +20 -0
  235. package/src/clis/feishu/new.ts +32 -0
  236. package/src/clis/feishu/read.ts +48 -0
  237. package/src/clis/feishu/search.ts +35 -0
  238. package/src/clis/feishu/send.ts +46 -0
  239. package/src/clis/feishu/status.ts +34 -0
  240. package/src/clis/grok/ask.ts +90 -0
  241. package/src/clis/grok/debug.ts +49 -0
  242. package/src/clis/jimeng/generate.yaml +84 -0
  243. package/src/clis/jimeng/history.yaml +47 -0
  244. package/src/clis/linux-do/categories.yaml +41 -0
  245. package/src/clis/linux-do/category.yaml +49 -0
  246. package/src/clis/linux-do/hot.yaml +50 -0
  247. package/src/clis/linux-do/latest.yaml +40 -0
  248. package/src/clis/linux-do/search.yaml +45 -0
  249. package/src/clis/linux-do/topic.yaml +38 -0
  250. package/src/clis/neteasemusic/README.md +31 -0
  251. package/src/clis/neteasemusic/README.zh-CN.md +31 -0
  252. package/src/clis/neteasemusic/like.ts +28 -0
  253. package/src/clis/neteasemusic/lyrics.ts +53 -0
  254. package/src/clis/neteasemusic/next.ts +30 -0
  255. package/src/clis/neteasemusic/play.ts +30 -0
  256. package/src/clis/neteasemusic/playing.ts +62 -0
  257. package/src/clis/neteasemusic/playlist.ts +51 -0
  258. package/src/clis/neteasemusic/prev.ts +29 -0
  259. package/src/clis/neteasemusic/search.ts +58 -0
  260. package/src/clis/neteasemusic/status.ts +18 -0
  261. package/src/clis/neteasemusic/volume.ts +61 -0
  262. package/src/clis/notion/README.md +29 -0
  263. package/src/clis/notion/README.zh-CN.md +29 -0
  264. package/src/clis/notion/export.ts +36 -0
  265. package/src/clis/notion/favorites.ts +87 -0
  266. package/src/clis/notion/new.ts +39 -0
  267. package/src/clis/notion/read.ts +33 -0
  268. package/src/clis/notion/search.ts +54 -0
  269. package/src/clis/notion/sidebar.ts +44 -0
  270. package/src/clis/notion/status.ts +18 -0
  271. package/src/clis/notion/write.ts +45 -0
  272. package/src/clis/twitter/download.ts +227 -0
  273. package/src/clis/wechat/README.md +28 -0
  274. package/src/clis/wechat/README.zh-CN.md +28 -0
  275. package/src/clis/wechat/chats.ts +33 -0
  276. package/src/clis/wechat/contacts.ts +33 -0
  277. package/src/clis/wechat/read.ts +72 -0
  278. package/src/clis/wechat/search.ts +36 -0
  279. package/src/clis/wechat/send.ts +49 -0
  280. package/src/clis/wechat/status.ts +35 -0
  281. package/src/clis/xiaohongshu/creator-note-detail.ts +95 -0
  282. package/src/clis/xiaohongshu/creator-notes.ts +116 -0
  283. package/src/clis/xiaohongshu/creator-profile.ts +60 -0
  284. package/src/clis/xiaohongshu/creator-stats.ts +81 -0
  285. package/src/clis/xiaohongshu/download.ts +173 -0
  286. package/src/clis/xiaohongshu/search.ts +1 -1
  287. package/src/clis/xiaohongshu/user-helpers.test.ts +106 -0
  288. package/src/clis/xiaohongshu/user-helpers.ts +85 -0
  289. package/src/clis/xiaohongshu/user.ts +52 -32
  290. package/src/clis/zhihu/download.test.ts +12 -0
  291. package/src/clis/zhihu/download.ts +223 -0
  292. package/src/daemon.ts +217 -0
  293. package/src/doctor.test.ts +32 -193
  294. package/src/doctor.ts +74 -668
  295. package/src/download/index.ts +395 -0
  296. package/src/download/progress.ts +125 -0
  297. package/src/engine.test.ts +17 -0
  298. package/src/main.ts +18 -26
  299. package/src/pipeline/executor.test.ts +1 -0
  300. package/src/pipeline/registry.ts +2 -0
  301. package/src/pipeline/steps/browser.ts +2 -2
  302. package/src/pipeline/steps/download.ts +310 -0
  303. package/src/pipeline/steps/intercept.ts +1 -2
  304. package/src/pipeline/template.ts +26 -0
  305. package/src/setup.ts +47 -183
  306. package/src/types.ts +1 -0
  307. package/tests/e2e/browser-auth.test.ts +25 -0
@@ -0,0 +1,167 @@
1
+ # Contributing to OpenCLI
2
+
3
+ Thanks for your interest in contributing to OpenCLI.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # 1. Fork & clone
9
+ git clone git@github.com:<your-username>/opencli.git
10
+ cd opencli
11
+
12
+ # 2. Install dependencies
13
+ npm install
14
+
15
+ # 3. Build
16
+ npm run build
17
+
18
+ # 4. Run a few checks
19
+ npx tsc --noEmit
20
+ npx vitest run src/
21
+
22
+ # 5. Link globally (optional, for testing `opencli` command)
23
+ npm link
24
+ ```
25
+
26
+ ## Adding a New Site Adapter
27
+
28
+ This is the most common type of contribution. Start with YAML when possible, and use TypeScript only when you need browser-side logic or multi-step flows.
29
+
30
+ ### YAML Adapter (Recommended for data-fetching commands)
31
+
32
+ Create a file like `src/clis/<site>/<command>.yaml`:
33
+
34
+ ```yaml
35
+ site: mysite
36
+ name: trending
37
+ description: Trending posts on MySite
38
+ domain: www.mysite.com
39
+ strategy: public # public | cookie | header
40
+ browser: false # true if browser session is needed
41
+
42
+ args:
43
+ limit:
44
+ type: int
45
+ default: 20
46
+ description: Number of items
47
+
48
+ pipeline:
49
+ - fetch:
50
+ url: https://api.mysite.com/trending
51
+
52
+ - map:
53
+ rank: ${{ index + 1 }}
54
+ title: ${{ item.title }}
55
+ score: ${{ item.score }}
56
+ url: ${{ item.url }}
57
+
58
+ - limit: ${{ args.limit }}
59
+
60
+ columns: [rank, title, score, url]
61
+ ```
62
+
63
+ See [`hackernews/top.yaml`](src/clis/hackernews/top.yaml) for a real example.
64
+
65
+ ### TypeScript Adapter (For complex browser interactions)
66
+
67
+ Create a file like `src/clis/<site>/<command>.ts`:
68
+
69
+ ```typescript
70
+ import { cli, Strategy } from '../../registry.js';
71
+
72
+ cli({
73
+ site: 'mysite',
74
+ name: 'search',
75
+ description: 'Search MySite',
76
+ domain: 'www.mysite.com',
77
+ strategy: Strategy.COOKIE,
78
+ args: [
79
+ { name: 'query', required: true, help: 'Search query' },
80
+ { name: 'limit', type: 'int', default: 10, help: 'Max results' },
81
+ ],
82
+ columns: ['title', 'url', 'date'],
83
+
84
+ func: async (page, kwargs) => {
85
+ const { query, limit = 10 } = kwargs;
86
+ await page.goto('https://www.mysite.com');
87
+
88
+ const data = await page.evaluate(`
89
+ (async () => {
90
+ const res = await fetch('/api/search?q=${encodeURIComponent(query)}', {
91
+ credentials: 'include'
92
+ });
93
+ return (await res.json()).results;
94
+ })()
95
+ `);
96
+
97
+ return data.slice(0, Number(limit)).map((item: any) => ({
98
+ title: item.title,
99
+ url: item.url,
100
+ date: item.created_at,
101
+ }));
102
+ },
103
+ });
104
+ ```
105
+
106
+ Use `opencli explore <url>` to discover APIs and see [CLI-EXPLORER.md](./CLI-EXPLORER.md) if you need the full adapter workflow.
107
+
108
+ ### Validate Your Adapter
109
+
110
+ ```bash
111
+ # Validate YAML syntax and schema
112
+ opencli validate
113
+
114
+ # Test your command
115
+ opencli <site> <command> --limit 3 -f json
116
+
117
+ # Verbose mode for debugging
118
+ opencli <site> <command> -v
119
+ ```
120
+
121
+ ## Testing
122
+
123
+ See [TESTING.md](./TESTING.md) for the full guide and exact test locations.
124
+
125
+ ```bash
126
+ npx vitest run src/ # Unit tests
127
+ npx vitest run tests/e2e/ # E2E tests
128
+ npx vitest run # All tests
129
+ ```
130
+
131
+ ## Code Style
132
+
133
+ - **TypeScript strict mode** — avoid `any` where possible.
134
+ - **ES Modules** — use `.js` extensions in imports (TypeScript output).
135
+ - **Naming**: `kebab-case` for files, `camelCase` for variables/functions, `PascalCase` for types/classes.
136
+ - **No default exports** — use named exports.
137
+
138
+ ## Commit Convention
139
+
140
+ We use [Conventional Commits](https://www.conventionalcommits.org/):
141
+
142
+ ```
143
+ feat(twitter): add thread command
144
+ fix(browser): handle CDP timeout gracefully
145
+ docs: update CONTRIBUTING.md
146
+ test(reddit): add e2e test for save command
147
+ chore: bump vitest to v4
148
+ ```
149
+
150
+ Common scopes: site name (`twitter`, `reddit`) or module name (`browser`, `pipeline`, `engine`).
151
+
152
+ ## Submitting a Pull Request
153
+
154
+ 1. Create a feature branch: `git checkout -b feat/mysite-trending`
155
+ 2. Make your changes and add tests when relevant
156
+ 3. Run the checks that apply:
157
+ ```bash
158
+ npx tsc --noEmit # Type check
159
+ npx vitest run src/ # Unit tests
160
+ opencli validate # YAML validation (if applicable)
161
+ ```
162
+ 4. Commit using conventional commit format
163
+ 5. Push and open a PR
164
+
165
+ ## License
166
+
167
+ By contributing, you agree that your contributions will be licensed under the [Apache-2.0 License](./LICENSE).
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # OpenCLI
2
2
 
3
3
  > **Make any website or Electron App your CLI.**
4
- > Zero risk · Reuse Chrome login · AI-powered discovery · 80+ commands · 19 sites
4
+ > Zero risk · Reuse Chrome login · AI-powered discovery · Browser + Desktop automation
5
5
 
6
6
  [中文文档](./README.zh-CN.md)
7
7
 
@@ -22,6 +22,7 @@ Turn ANY Electron application into a CLI tool! Recombine, script, and extend app
22
22
  - [Prerequisites](#prerequisites)
23
23
  - [Quick Start](#quick-start)
24
24
  - [Built-in Commands](#built-in-commands)
25
+ - [Download Support](#download-support)
25
26
  - [Output Formats](#output-formats)
26
27
  - [For AI Agents (Developer Guide)](#for-ai-agents-developer-guide)
27
28
  - [Remote Chrome (Server/Headless)](#remote-chrome-serverheadless)
@@ -43,74 +44,32 @@ Turn ANY Electron application into a CLI tool! Recombine, script, and extend app
43
44
 
44
45
  ## Prerequisites
45
46
 
46
- - **Node.js**: >= 18.0.0
47
+ - **Node.js**: >= 20.0.0
47
48
  - **Chrome** running **and logged into the target site** (e.g. bilibili.com, zhihu.com, xiaohongshu.com).
48
49
 
49
50
  > **⚠️ Important**: Browser commands reuse your Chrome login session. You must be logged into the target website in Chrome before running commands. If you get empty data or errors, check your login status first.
50
51
 
51
- OpenCLI connects to your browser through the Playwright MCP Bridge extension.
52
- It prefers an existing local/global `@playwright/mcp` install and falls back to `npx -y @playwright/mcp@latest` automatically when no local MCP server is found.
52
+ OpenCLI connects to your browser through a lightweight **Browser Bridge** Chrome Extension + micro-daemon (zero config, auto-start).
53
53
 
54
- ### Playwright MCP Bridge Extension Setup
54
+ ### Browser Bridge Extension Setup
55
55
 
56
- 1. Install **[Playwright MCP Bridge](https://chromewebstore.google.com/detail/playwright-mcp-bridge/mmlmfjhmonkocbjadbfplnigmagldckm)** extension in Chrome.
57
- 2. Run `opencli setup` discovers the token, distributes it to your tools, and verifies connectivity:
56
+ 1. Install the **opencli Browser Bridge** extension in Chrome:
57
+ - Open `chrome://extensions`, enable **Developer mode** (top-right toggle)
58
+ - Click **Load unpacked**, select the `extension/` folder from this repo
59
+ 2. That's it! The daemon auto-starts when you run any browser command. No tokens, no manual configuration.
58
60
 
59
- ```bash
60
- opencli setup
61
- ```
62
-
63
- The interactive TUI will:
64
- - 🔍 Auto-discover `PLAYWRIGHT_MCP_EXTENSION_TOKEN` from Chrome (no manual copy needed)
65
- - ☑️ Show all detected tools (Codex, Cursor, Claude Code, Gemini CLI, etc.)
66
- - ✏️ Update only the files you select (Space to toggle, Enter to confirm)
67
- - 🔌 Auto-verify browser connectivity after writing configs
68
-
69
- > **Tip**: Use `opencli doctor` for ongoing diagnosis and maintenance:
61
+ > **Tip**: Use `opencli doctor` for ongoing diagnosis:
70
62
  > ```bash
71
- > opencli doctor # Read-only token & config diagnosis
72
- > opencli doctor --live # Also test live browser connectivity
73
- > opencli doctor --fix # Fix mismatched configs (interactive)
74
- > opencli doctor --fix -y # Fix all configs non-interactively
63
+ > opencli doctor # Check extension + daemon connectivity
64
+ > opencli doctor --live # Also test live browser commands
75
65
  > ```
76
66
 
77
- **Alternative: CDP Mode (For Servers/Headless)**
78
- If you cannot install the browser extension (e.g. running OpenCLI on a remote headless server), you can connect OpenCLI to your local Chrome via CDP using SSH tunnels or reverse proxies. See the [CDP Connection Guide](./CDP.md) for detailed instructions.
79
-
80
- <details>
81
- <summary>Manual setup (alternative)</summary>
82
-
83
- Add token to your MCP client config (e.g. Claude/Cursor):
84
-
85
- ```json
86
- {
87
- "mcpServers": {
88
- "playwright": {
89
- "command": "npx",
90
- "args": ["-y", "@playwright/mcp@latest", "--extension"],
91
- "env": {
92
- "PLAYWRIGHT_MCP_EXTENSION_TOKEN": "<your-token-here>"
93
- }
94
- }
95
- }
96
- }
97
- ```
98
-
99
- Export in shell (e.g. `~/.zshrc`):
100
-
101
- ```bash
102
- export PLAYWRIGHT_MCP_EXTENSION_TOKEN="<your-token-here>"
103
- ```
104
-
105
- </details>
106
-
107
67
  ## Quick Start
108
68
 
109
69
  ### Install via npm (recommended)
110
70
 
111
71
  ```bash
112
72
  npm install -g @jackwener/opencli
113
- opencli setup # One-time: configure Playwright MCP token
114
73
  ```
115
74
 
116
75
  Then use directly:
@@ -143,34 +102,99 @@ npm install -g @jackwener/opencli@latest
143
102
 
144
103
  ## Built-in Commands
145
104
 
146
- **26 sites · 128 commands** — run `opencli list` for the live registry.
147
-
148
- | Site | Commands | Count | Mode |
149
- |------|----------|:-----:|------|
150
- | **twitter** | `trending` `bookmarks` `profile` `search` `timeline` `thread` `following` `followers` `notifications` `post` `reply` `delete` `like` `article` `follow` `unfollow` `bookmark` `unbookmark` | 18 | 🔐 Browser |
151
- | **reddit** | `hot` `frontpage` `popular` `search` `subreddit` `read` `user` `user-posts` `user-comments` `upvote` `save` `comment` `subscribe` `saved` `upvoted` | 15 | 🔐 Browser |
152
- | **bilibili** | `hot` `search` `me` `favorite` `history` `feed` `subtitle` `dynamic` `ranking` `following` `user-videos` | 11 | 🔐 Browser |
153
- | **cursor** | `status` `send` `read` `new` `dump` `composer` `model` `extract-code` `ask` `screenshot` `history` `export` | 12 | 🖥️ Desktop |
154
- | **codex** | `status` `send` `read` `new` `extract-diff` `model` `ask` `screenshot` `history` `export` | 10 | 🖥️ Desktop |
155
- | **v2ex** | `hot` `latest` `topic` `daily` `me` `notifications` | 6 | 🌐 / 🔐 |
156
- | **xueqiu** | `feed` `hot-stock` `hot` `search` `stock` `watchlist` | 6 | 🔐 Browser |
157
- | **antigravity** | `status` `send` `read` `new` `evaluate` | 5 | 🖥️ Desktop |
158
- | **xiaohongshu** | `search` `notifications` `feed` `me` `user` | 5 | 🔐 Browser |
159
- | **chatgpt** | `status` `new` `send` `read` `ask` | 5 | 🖥️ Desktop |
160
- | **xiaoyuzhou** | `podcast` `podcast-episodes` `episode` | 3 | 🌐 Public |
161
- | **youtube** | `search` `video` `transcript` | 3 | 🔐 Browser |
162
- | **zhihu** | `hot` `search` `question` | 3 | 🔐 Browser |
163
- | **boss** | `search` `detail` | 2 | 🔐 Browser |
164
- | **coupang** | `search` `add-to-cart` | 2 | 🔐 Browser |
165
- | **bbc** | `news` | 1 | 🌐 Public |
166
- | **ctrip** | `search` | 1 | 🔐 Browser |
167
- | **github** | `search` | 1 | 🌐 Public |
168
- | **hackernews** | `top` | 1 | 🌐 Public |
169
- | **linkedin** | `search` | 1 | 🔐 Browser |
170
- | **reuters** | `search` | 1 | 🔐 Browser |
171
- | **smzdm** | `search` | 1 | 🔐 Browser |
172
- | **weibo** | `hot` | 1 | 🔐 Browser |
173
- | **yahoo-finance** | `quote` | 1 | 🔐 Browser |
105
+ Run `opencli list` for the live registry.
106
+
107
+ | Site | Commands | Mode |
108
+ |------|----------|------|
109
+ | **twitter** | `trending` `bookmarks` `profile` `search` `timeline` `thread` `following` `followers` `notifications` `post` `reply` `delete` `like` `article` `follow` `unfollow` `bookmark` `unbookmark` `download` | 🔐 Browser |
110
+ | **reddit** | `hot` `frontpage` `popular` `search` `subreddit` `read` `user` `user-posts` `user-comments` `upvote` `save` `comment` `subscribe` `saved` `upvoted` | 🔐 Browser |
111
+ | **cursor** | `status` `send` `read` `new` `dump` `composer` `model` `extract-code` `ask` `screenshot` `history` `export` | 🖥️ Desktop |
112
+ | **bilibili** | `hot` `search` `me` `favorite` `history` `feed` `subtitle` `dynamic` `ranking` `following` `user-videos` `download` | 🔐 Browser |
113
+ | **codex** | `status` `send` `read` `new` `extract-diff` `model` `ask` `screenshot` `history` `export` | 🖥️ Desktop |
114
+ | **chatwise** | `status` `new` `send` `read` `ask` `model` `history` `export` `screenshot` | 🖥️ Desktop |
115
+ | **notion** | `status` `search` `read` `new` `write` `sidebar` `favorites` `export` | 🖥️ Desktop |
116
+ | **discord-app** | `status` `send` `read` `channels` `servers` `search` `members` | 🖥️ Desktop |
117
+ | **v2ex** | `hot` `latest` `topic` `daily` `me` `notifications` | 🌐 / 🔐 |
118
+ | **xueqiu** | `feed` `hot-stock` `hot` `search` `stock` `watchlist` | 🔐 Browser |
119
+ | **antigravity** | `status` `send` `read` `new` `evaluate` | 🖥️ Desktop |
120
+ | **chatgpt** | `status` `new` `send` `read` `ask` | 🖥️ Desktop |
121
+ | **xiaohongshu** | `search` `notifications` `feed` `me` `user` `download` | 🔐 Browser |
122
+ | **xiaoyuzhou** | `podcast` `podcast-episodes` `episode` | 🌐 Public |
123
+ | **zhihu** | `hot` `search` `question` `download` | 🔐 Browser |
124
+ | **youtube** | `search` `video` `transcript` | 🔐 Browser |
125
+ | **boss** | `search` `detail` | 🔐 Browser |
126
+ | **coupang** | `search` `add-to-cart` | 🔐 Browser |
127
+ | **bbc** | `news` | 🌐 Public |
128
+ | **ctrip** | `search` | 🔐 Browser |
129
+ | **github** | `search` | 🌐 Public |
130
+ | **hackernews** | `top` | 🌐 Public |
131
+ | **linkedin** | `search` | 🔐 Browser |
132
+ | **reuters** | `search` | 🔐 Browser |
133
+ | **smzdm** | `search` | 🔐 Browser |
134
+ | **weibo** | `hot` | 🔐 Browser |
135
+ | **yahoo-finance** | `quote` | 🔐 Browser |
136
+
137
+ ## Download Support
138
+
139
+ OpenCLI supports downloading images, videos, and articles from supported platforms.
140
+
141
+ ### Supported Platforms
142
+
143
+ | Platform | Content Types | Notes |
144
+ |----------|---------------|-------|
145
+ | **xiaohongshu** | Images, Videos | Downloads all media from a note |
146
+ | **bilibili** | Videos | Requires `yt-dlp` installed |
147
+ | **twitter** | Images, Videos | Downloads from user media tab or single tweet |
148
+ | **zhihu** | Articles (Markdown) | Exports articles with optional image download |
149
+
150
+ ### Prerequisites
151
+
152
+ For video downloads from streaming platforms, you need to install `yt-dlp`:
153
+
154
+ ```bash
155
+ # Install yt-dlp
156
+ pip install yt-dlp
157
+ # or
158
+ brew install yt-dlp
159
+ ```
160
+
161
+ ### Usage Examples
162
+
163
+ ```bash
164
+ # Download images/videos from Xiaohongshu note
165
+ opencli xiaohongshu download --note-id abc123 --output ./xhs
166
+
167
+ # Download Bilibili video (requires yt-dlp)
168
+ opencli bilibili download --bvid BV1xxx --output ./bilibili
169
+ opencli bilibili download --bvid BV1xxx --quality 1080p # Specify quality
170
+
171
+ # Download Twitter media from user
172
+ opencli twitter download --username elonmusk --limit 20 --output ./twitter
173
+
174
+ # Download single tweet media
175
+ opencli twitter download --tweet-url "https://x.com/user/status/123" --output ./twitter
176
+
177
+ # Export Zhihu article to Markdown
178
+ opencli zhihu download --url "https://zhuanlan.zhihu.com/p/xxx" --output ./zhihu
179
+
180
+ # Export with local images
181
+ opencli zhihu download --url "https://zhuanlan.zhihu.com/p/xxx" --download-images
182
+ ```
183
+
184
+ ### Pipeline Step (for YAML adapters)
185
+
186
+ The `download` step can be used in YAML pipelines:
187
+
188
+ ```yaml
189
+ pipeline:
190
+ - fetch: https://api.example.com/media
191
+ - download:
192
+ url: ${{ item.imageUrl }}
193
+ dir: ./downloads
194
+ filename: ${{ item.title | sanitize }}.jpg
195
+ concurrency: 5
196
+ skip_existing: true
197
+ ```
174
198
 
175
199
  ## Output Formats
176
200
 
@@ -215,7 +239,7 @@ Explore outputs to `.opencli/explore/<site>/` (manifest.json, endpoints.json, ca
215
239
 
216
240
  See **[TESTING.md](./TESTING.md)** for the full testing guide, including:
217
241
 
218
- - Current test coverage (unit + E2E tests across 19 sites)
242
+ - Current test coverage (unit + E2E tests across browser and desktop adapters)
219
243
  - How to run tests locally
220
244
  - How to add tests when creating new adapters
221
245
  - CI/CD pipeline with sharding
@@ -231,15 +255,15 @@ npx vitest run tests/e2e/ # E2E tests
231
255
 
232
256
  ## Troubleshooting
233
257
 
234
- - **"Failed to connect to Playwright MCP Bridge"**
235
- - Ensure the Playwright MCP extension is installed and **enabled** in your running Chrome.
236
- - Restart the Chrome browser if you just installed the extension.
258
+ - **"Extension not connected"**
259
+ - Ensure the opencli Browser Bridge extension is installed and **enabled** in `chrome://extensions`.
237
260
  - **Empty data returns or 'Unauthorized' error**
238
- - Your login session in Chrome might have expired. Open a normal Chrome tab, navigate to the target site, and log in or refresh the page to prove you are human.
261
+ - Your login session in Chrome might have expired. Open a normal Chrome tab, navigate to the target site, and log in or refresh the page.
239
262
  - **Node API errors**
240
- - Make sure you are using Node.js >= 18. Some dependencies require modern Node APIs.
241
- - **Token issues**
242
- - Run `opencli doctor` to diagnose token configuration across all tools.
263
+ - Make sure you are using Node.js >= 20. Some dependencies require modern Node APIs.
264
+ - **Daemon issues**
265
+ - Check daemon status: `curl localhost:19825/status`
266
+ - View extension logs: `curl localhost:19825/logs`
243
267
 
244
268
  ## Releasing New Versions
245
269