@jackwener/opencli 1.4.1 → 1.5.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 (322) hide show
  1. package/.github/workflows/build-extension.yml +2 -6
  2. package/.github/workflows/ci.yml +21 -1
  3. package/README.md +35 -6
  4. package/README.zh-CN.md +12 -5
  5. package/SKILL.md +2 -0
  6. package/dist/browser/cdp.d.ts +2 -1
  7. package/dist/browser/discover.d.ts +4 -1
  8. package/dist/browser/discover.js +6 -2
  9. package/dist/browser/errors.d.ts +2 -2
  10. package/dist/browser/errors.js +4 -12
  11. package/dist/browser/mcp.d.ts +2 -1
  12. package/dist/build-manifest.d.ts +2 -0
  13. package/dist/build-manifest.js +39 -14
  14. package/dist/build-manifest.test.js +21 -0
  15. package/dist/capabilityRouting.d.ts +2 -0
  16. package/dist/capabilityRouting.js +2 -1
  17. package/dist/cli-manifest.json +1111 -112
  18. package/dist/cli.js +34 -3
  19. package/dist/clis/36kr/article.d.ts +1 -0
  20. package/dist/clis/36kr/article.js +62 -0
  21. package/dist/clis/36kr/hot.d.ts +3 -0
  22. package/dist/clis/36kr/hot.js +80 -0
  23. package/dist/clis/36kr/hot.test.d.ts +1 -0
  24. package/dist/clis/36kr/hot.test.js +15 -0
  25. package/dist/clis/36kr/news.d.ts +1 -0
  26. package/dist/clis/36kr/news.js +51 -0
  27. package/dist/clis/36kr/news.test.d.ts +1 -0
  28. package/dist/clis/36kr/news.test.js +85 -0
  29. package/dist/clis/36kr/search.d.ts +1 -0
  30. package/dist/clis/36kr/search.js +72 -0
  31. package/dist/clis/bilibili/comments.d.ts +5 -0
  32. package/dist/clis/bilibili/comments.js +40 -0
  33. package/dist/clis/bilibili/comments.test.d.ts +1 -0
  34. package/dist/clis/bilibili/comments.test.js +82 -0
  35. package/dist/clis/chatgpt/ask.js +29 -14
  36. package/dist/clis/chatgpt/ax.d.ts +6 -0
  37. package/dist/clis/chatgpt/ax.js +172 -1
  38. package/dist/clis/chatgpt/model.d.ts +1 -0
  39. package/dist/clis/chatgpt/model.js +24 -0
  40. package/dist/clis/chatgpt/send.js +12 -3
  41. package/dist/clis/douban/download.d.ts +1 -0
  42. package/dist/clis/douban/download.js +67 -0
  43. package/dist/clis/douban/download.test.d.ts +1 -0
  44. package/dist/clis/douban/download.test.js +170 -0
  45. package/dist/clis/douban/photos.d.ts +1 -0
  46. package/dist/clis/douban/photos.js +34 -0
  47. package/dist/clis/douban/utils.d.ts +25 -0
  48. package/dist/clis/douban/utils.js +190 -1
  49. package/dist/clis/douban/utils.test.d.ts +1 -0
  50. package/dist/clis/douban/utils.test.js +64 -0
  51. package/dist/clis/imdb/person.d.ts +1 -0
  52. package/dist/clis/imdb/person.js +203 -0
  53. package/dist/clis/imdb/reviews.d.ts +1 -0
  54. package/dist/clis/imdb/reviews.js +88 -0
  55. package/dist/clis/imdb/search.d.ts +1 -0
  56. package/dist/clis/imdb/search.js +161 -0
  57. package/dist/clis/imdb/title.d.ts +1 -0
  58. package/dist/clis/imdb/title.js +93 -0
  59. package/dist/clis/imdb/top.d.ts +1 -0
  60. package/dist/clis/imdb/top.js +53 -0
  61. package/dist/clis/imdb/trending.d.ts +1 -0
  62. package/dist/clis/imdb/trending.js +52 -0
  63. package/dist/clis/imdb/utils.d.ts +46 -0
  64. package/dist/clis/imdb/utils.js +285 -0
  65. package/dist/clis/imdb/utils.test.d.ts +1 -0
  66. package/dist/clis/imdb/utils.test.js +88 -0
  67. package/dist/clis/jd/item.d.ts +4 -0
  68. package/dist/clis/jd/item.js +16 -15
  69. package/dist/clis/jd/item.test.js +16 -1
  70. package/dist/clis/linux-do/categories.yaml +38 -9
  71. package/dist/clis/linux-do/category.d.ts +1 -0
  72. package/dist/clis/linux-do/category.js +36 -0
  73. package/dist/clis/linux-do/feed.d.ts +45 -0
  74. package/dist/clis/linux-do/feed.js +397 -0
  75. package/dist/clis/linux-do/feed.test.d.ts +1 -0
  76. package/dist/clis/linux-do/feed.test.js +118 -0
  77. package/dist/clis/linux-do/hot.d.ts +1 -0
  78. package/dist/clis/linux-do/hot.js +25 -0
  79. package/dist/clis/linux-do/latest.d.ts +1 -0
  80. package/dist/clis/linux-do/latest.js +18 -0
  81. package/dist/clis/linux-do/tags.yaml +41 -0
  82. package/dist/clis/linux-do/topic.yaml +41 -3
  83. package/dist/clis/linux-do/user-posts.yaml +67 -0
  84. package/dist/clis/linux-do/user-topics.yaml +54 -0
  85. package/dist/clis/paperreview/commands.test.d.ts +3 -0
  86. package/dist/clis/paperreview/commands.test.js +243 -0
  87. package/dist/clis/paperreview/feedback.d.ts +1 -0
  88. package/dist/clis/paperreview/feedback.js +52 -0
  89. package/dist/clis/paperreview/review.d.ts +1 -0
  90. package/dist/clis/paperreview/review.js +37 -0
  91. package/dist/clis/paperreview/submit.d.ts +1 -0
  92. package/dist/clis/paperreview/submit.js +85 -0
  93. package/dist/clis/paperreview/utils.d.ts +46 -0
  94. package/dist/clis/paperreview/utils.js +197 -0
  95. package/dist/clis/paperreview/utils.test.d.ts +1 -0
  96. package/dist/clis/paperreview/utils.test.js +49 -0
  97. package/dist/clis/producthunt/browse.d.ts +1 -0
  98. package/dist/clis/producthunt/browse.js +99 -0
  99. package/dist/clis/producthunt/hot.d.ts +1 -0
  100. package/dist/clis/producthunt/hot.js +110 -0
  101. package/dist/clis/producthunt/posts.d.ts +1 -0
  102. package/dist/clis/producthunt/posts.js +28 -0
  103. package/dist/clis/producthunt/today.d.ts +1 -0
  104. package/dist/clis/producthunt/today.js +35 -0
  105. package/dist/clis/producthunt/utils.d.ts +29 -0
  106. package/dist/clis/producthunt/utils.js +99 -0
  107. package/dist/clis/producthunt/utils.test.d.ts +1 -0
  108. package/dist/clis/producthunt/utils.test.js +64 -0
  109. package/dist/clis/twitter/article.js +4 -28
  110. package/dist/clis/twitter/likes.d.ts +24 -0
  111. package/dist/clis/twitter/likes.js +217 -0
  112. package/dist/clis/twitter/likes.test.d.ts +1 -0
  113. package/dist/clis/twitter/likes.test.js +85 -0
  114. package/dist/clis/twitter/profile.js +4 -28
  115. package/dist/clis/twitter/search.js +2 -1
  116. package/dist/clis/twitter/search.test.js +2 -0
  117. package/dist/clis/twitter/shared.d.ts +6 -0
  118. package/dist/clis/twitter/shared.js +35 -0
  119. package/dist/clis/twitter/timeline.js +2 -13
  120. package/dist/clis/weixin/download.d.ts +17 -0
  121. package/dist/clis/weixin/download.js +88 -20
  122. package/dist/clis/weread/book.js +2 -2
  123. package/dist/clis/weread/commands.test.d.ts +3 -0
  124. package/dist/clis/weread/commands.test.js +43 -0
  125. package/dist/clis/weread/highlights.js +2 -2
  126. package/dist/clis/weread/notebooks.js +2 -2
  127. package/dist/clis/weread/notes.js +3 -3
  128. package/dist/clis/weread/shelf.js +2 -2
  129. package/dist/clis/weread/utils.d.ts +4 -4
  130. package/dist/clis/weread/utils.js +32 -14
  131. package/dist/clis/weread/utils.test.js +1 -28
  132. package/dist/clis/xiaohongshu/comments.d.ts +5 -0
  133. package/dist/clis/xiaohongshu/comments.js +74 -0
  134. package/dist/clis/xiaohongshu/comments.test.d.ts +1 -0
  135. package/dist/clis/xiaohongshu/comments.test.js +79 -0
  136. package/dist/clis/xiaohongshu/publish.js +114 -18
  137. package/dist/clis/xiaohongshu/publish.test.d.ts +1 -0
  138. package/dist/clis/xiaohongshu/publish.test.js +119 -0
  139. package/dist/commanderAdapter.d.ts +1 -0
  140. package/dist/commanderAdapter.js +176 -29
  141. package/dist/commanderAdapter.test.d.ts +1 -0
  142. package/dist/commanderAdapter.test.js +62 -0
  143. package/dist/daemon.js +17 -1
  144. package/dist/discovery.js +8 -14
  145. package/dist/doctor.d.ts +1 -0
  146. package/dist/doctor.js +9 -2
  147. package/dist/download/index.js +63 -51
  148. package/dist/download/index.test.js +17 -4
  149. package/dist/errors.d.ts +3 -1
  150. package/dist/errors.js +15 -32
  151. package/dist/execution.d.ts +1 -3
  152. package/dist/execution.js +21 -1
  153. package/dist/hooks.js +2 -0
  154. package/dist/main.js +5 -0
  155. package/dist/output.js +5 -1
  156. package/dist/pipeline/executor.js +3 -4
  157. package/dist/plugin-manifest.d.ts +70 -0
  158. package/dist/plugin-manifest.js +160 -0
  159. package/dist/plugin-manifest.test.d.ts +4 -0
  160. package/dist/plugin-manifest.test.js +179 -0
  161. package/dist/plugin.d.ts +38 -5
  162. package/dist/plugin.js +267 -33
  163. package/dist/plugin.test.js +220 -3
  164. package/dist/registry.d.ts +4 -0
  165. package/dist/registry.js +2 -0
  166. package/dist/runtime-detect.d.ts +21 -0
  167. package/dist/runtime-detect.js +32 -0
  168. package/dist/runtime-detect.test.d.ts +1 -0
  169. package/dist/runtime-detect.test.js +27 -0
  170. package/dist/runtime.js +1 -1
  171. package/dist/serialization.d.ts +2 -0
  172. package/dist/serialization.js +6 -0
  173. package/dist/types.d.ts +1 -0
  174. package/dist/update-check.d.ts +22 -0
  175. package/dist/update-check.js +112 -0
  176. package/dist/weixin-download.test.d.ts +1 -0
  177. package/dist/weixin-download.test.js +30 -0
  178. package/dist/weread-private-api-regression.test.d.ts +1 -0
  179. package/dist/weread-private-api-regression.test.js +122 -0
  180. package/dist/yaml-schema.d.ts +3 -0
  181. package/dist/yaml-schema.js +18 -1
  182. package/docs/.vitepress/config.mts +4 -0
  183. package/docs/adapters/browser/36kr.md +47 -0
  184. package/docs/adapters/browser/douban.md +14 -0
  185. package/docs/adapters/browser/imdb.md +47 -0
  186. package/docs/adapters/browser/jd.md +2 -2
  187. package/docs/adapters/browser/linux-do.md +181 -20
  188. package/docs/adapters/browser/paperreview.md +43 -0
  189. package/docs/adapters/browser/producthunt.md +49 -0
  190. package/docs/adapters/desktop/chatgpt.md +5 -0
  191. package/docs/adapters/index.md +6 -2
  192. package/docs/advanced/download.md +4 -0
  193. package/docs/advanced/rate-limiter-plugin.md +99 -0
  194. package/docs/guide/electron-app-cli.md +200 -0
  195. package/docs/guide/getting-started.md +1 -0
  196. package/docs/guide/plugins.md +87 -0
  197. package/docs/zh/guide/electron-app-cli.md +188 -0
  198. package/docs/zh/guide/getting-started.md +1 -0
  199. package/docs/zh/guide/plugins.md +65 -0
  200. package/extension/package.json +1 -0
  201. package/extension/scripts/package-release.mjs +179 -0
  202. package/extension/src/background.ts +2 -0
  203. package/package.json +4 -1
  204. package/scripts/postinstall.js +10 -0
  205. package/src/browser/cdp.ts +2 -1
  206. package/src/browser/discover.ts +8 -3
  207. package/src/browser/errors.ts +13 -14
  208. package/src/browser/mcp.ts +2 -1
  209. package/src/build-manifest.test.ts +23 -0
  210. package/src/build-manifest.ts +40 -15
  211. package/src/capabilityRouting.ts +2 -1
  212. package/src/cli.ts +35 -3
  213. package/src/clis/36kr/article.ts +69 -0
  214. package/src/clis/36kr/hot.test.ts +19 -0
  215. package/src/clis/36kr/hot.ts +100 -0
  216. package/src/clis/36kr/news.test.ts +90 -0
  217. package/src/clis/36kr/news.ts +54 -0
  218. package/src/clis/36kr/search.ts +78 -0
  219. package/src/clis/bilibili/comments.test.ts +102 -0
  220. package/src/clis/bilibili/comments.ts +44 -0
  221. package/src/clis/chatgpt/ask.ts +28 -14
  222. package/src/clis/chatgpt/ax.ts +180 -1
  223. package/src/clis/chatgpt/model.ts +27 -0
  224. package/src/clis/chatgpt/send.ts +16 -6
  225. package/src/clis/douban/download.test.ts +196 -0
  226. package/src/clis/douban/download.ts +78 -0
  227. package/src/clis/douban/photos.ts +36 -0
  228. package/src/clis/douban/utils.test.ts +97 -0
  229. package/src/clis/douban/utils.ts +232 -1
  230. package/src/clis/imdb/person.ts +232 -0
  231. package/src/clis/imdb/reviews.ts +111 -0
  232. package/src/clis/imdb/search.ts +179 -0
  233. package/src/clis/imdb/title.ts +121 -0
  234. package/src/clis/imdb/top.ts +67 -0
  235. package/src/clis/imdb/trending.ts +66 -0
  236. package/src/clis/imdb/utils.test.ts +117 -0
  237. package/src/clis/imdb/utils.ts +305 -0
  238. package/src/clis/jd/item.test.ts +18 -1
  239. package/src/clis/jd/item.ts +18 -15
  240. package/src/clis/linux-do/categories.yaml +38 -9
  241. package/src/clis/linux-do/category.ts +37 -0
  242. package/src/clis/linux-do/feed.test.ts +132 -0
  243. package/src/clis/linux-do/feed.ts +501 -0
  244. package/src/clis/linux-do/hot.ts +26 -0
  245. package/src/clis/linux-do/latest.ts +19 -0
  246. package/src/clis/linux-do/tags.yaml +41 -0
  247. package/src/clis/linux-do/topic.yaml +41 -3
  248. package/src/clis/linux-do/user-posts.yaml +67 -0
  249. package/src/clis/linux-do/user-topics.yaml +54 -0
  250. package/src/clis/paperreview/commands.test.ts +283 -0
  251. package/src/clis/paperreview/feedback.ts +64 -0
  252. package/src/clis/paperreview/review.ts +47 -0
  253. package/src/clis/paperreview/submit.ts +119 -0
  254. package/src/clis/paperreview/utils.test.ts +68 -0
  255. package/src/clis/paperreview/utils.ts +276 -0
  256. package/src/clis/producthunt/browse.ts +109 -0
  257. package/src/clis/producthunt/hot.ts +127 -0
  258. package/src/clis/producthunt/posts.ts +29 -0
  259. package/src/clis/producthunt/today.ts +37 -0
  260. package/src/clis/producthunt/utils.test.ts +72 -0
  261. package/src/clis/producthunt/utils.ts +122 -0
  262. package/src/clis/twitter/article.ts +5 -28
  263. package/src/clis/twitter/likes.test.ts +91 -0
  264. package/src/clis/twitter/likes.ts +256 -0
  265. package/src/clis/twitter/profile.ts +5 -28
  266. package/src/clis/twitter/search.test.ts +2 -0
  267. package/src/clis/twitter/search.ts +3 -1
  268. package/src/clis/twitter/shared.ts +45 -0
  269. package/src/clis/twitter/timeline.ts +2 -13
  270. package/src/clis/weixin/download.ts +114 -20
  271. package/src/clis/weread/book.ts +2 -2
  272. package/src/clis/weread/commands.test.ts +57 -0
  273. package/src/clis/weread/highlights.ts +2 -2
  274. package/src/clis/weread/notebooks.ts +2 -2
  275. package/src/clis/weread/notes.ts +3 -3
  276. package/src/clis/weread/shelf.ts +2 -2
  277. package/src/clis/weread/utils.test.ts +1 -32
  278. package/src/clis/weread/utils.ts +41 -16
  279. package/src/clis/xiaohongshu/comments.test.ts +96 -0
  280. package/src/clis/xiaohongshu/comments.ts +81 -0
  281. package/src/clis/xiaohongshu/publish.test.ts +137 -0
  282. package/src/clis/xiaohongshu/publish.ts +129 -18
  283. package/src/commanderAdapter.test.ts +78 -0
  284. package/src/commanderAdapter.ts +188 -24
  285. package/src/daemon.ts +19 -1
  286. package/src/discovery.ts +8 -15
  287. package/src/doctor.ts +13 -2
  288. package/src/download/index.test.ts +14 -4
  289. package/src/download/index.ts +67 -55
  290. package/src/errors.ts +25 -66
  291. package/src/execution.ts +28 -3
  292. package/src/hooks.ts +1 -0
  293. package/src/main.ts +6 -0
  294. package/src/output.ts +3 -1
  295. package/src/pipeline/executor.ts +4 -6
  296. package/src/plugin-manifest.test.ts +223 -0
  297. package/src/plugin-manifest.ts +206 -0
  298. package/src/plugin.test.ts +246 -2
  299. package/src/plugin.ts +338 -36
  300. package/src/registry.ts +6 -1
  301. package/src/runtime-detect.test.ts +30 -0
  302. package/src/runtime-detect.ts +36 -0
  303. package/src/runtime.ts +1 -1
  304. package/src/serialization.ts +4 -0
  305. package/src/types.ts +1 -0
  306. package/src/update-check.ts +114 -0
  307. package/src/weixin-download.test.ts +64 -0
  308. package/src/weread-private-api-regression.test.ts +150 -0
  309. package/src/yaml-schema.ts +20 -0
  310. package/tests/e2e/browser-auth.test.ts +13 -9
  311. package/tests/e2e/browser-public-extended.test.ts +1 -1
  312. package/tests/e2e/browser-public.test.ts +62 -4
  313. package/tests/e2e/helpers.ts +2 -1
  314. package/tests/e2e/public-commands.test.ts +37 -3
  315. package/tests/smoke/api-health.test.ts +1 -1
  316. package/vitest.config.ts +10 -0
  317. package/dist/clis/linux-do/category.yaml +0 -51
  318. package/dist/clis/linux-do/hot.yaml +0 -50
  319. package/dist/clis/linux-do/latest.yaml +0 -40
  320. package/src/clis/linux-do/category.yaml +0 -51
  321. package/src/clis/linux-do/hot.yaml +0 -50
  322. package/src/clis/linux-do/latest.yaml +0 -40
@@ -6,37 +6,198 @@
6
6
 
7
7
  | Command | Description |
8
8
  |---------|-------------|
9
- | `opencli linux-do hot` | 热门话题 |
10
- | `opencli linux-do latest` | 最新话题 |
11
- | `opencli linux-do categories` | 板块列表 |
12
- | `opencli linux-do category` | 板块话题 |
13
- | `opencli linux-do search` | 搜索话题 |
14
- | `opencli linux-do topic` | 话题详情 |
9
+ | `opencli linux-do feed` | Browse topics (site-wide, by tag, or by category) |
10
+ | `opencli linux-do categories` | List all categories |
11
+ | `opencli linux-do tags` | List popular tags |
12
+ | `opencli linux-do search <query>` | Search topics |
13
+ | `opencli linux-do topic <id>` | View topic posts |
14
+ | `opencli linux-do user-topics <username>` | Topics created by a user |
15
+ | `opencli linux-do user-posts <username>` | Replies posted by a user |
15
16
 
16
- ## Usage Examples
17
+ ## feed
18
+
19
+ Browse topic listings. Defaults to latest topics when called with no arguments.
20
+
21
+ - Supports filtering by `--tag`, `--category`, or both
22
+ - `--tag` accepts tag name, slug, or ID
23
+ - `--category` accepts category name, slug, ID, or `Parent / Child` path for sub-categories
24
+ - Use `--view` to switch between latest / hot / top
25
+
26
+ ### Basic
17
27
 
18
28
  ```bash
19
- # Hot topics this week
20
- opencli linux-do hot --limit 20
29
+ # Latest topics (default)
30
+ opencli linux-do feed
31
+
32
+ # Hot topics
33
+ opencli linux-do feed --view hot
34
+
35
+ # Top topics — default period is weekly
36
+ opencli linux-do feed --view top
37
+ opencli linux-do feed --view top --period daily
38
+ opencli linux-do feed --view top --period monthly
21
39
 
22
- # Hot topics by period
23
- opencli linux-do hot --period daily
24
- opencli linux-do hot --period monthly
40
+ # Sort by views descending
41
+ opencli linux-do feed --order views
42
+
43
+ # Sort by created time ascending
44
+ opencli linux-do feed --order created --ascending
45
+
46
+ # Limit results
47
+ opencli linux-do feed --limit 10
48
+
49
+ # JSON output
50
+ opencli linux-do feed -f json
51
+ ```
25
52
 
26
- # Latest topics
27
- opencli linux-do latest --limit 10
53
+ ### Filter by tag
54
+
55
+ ```bash
56
+ # By tag name, slug, or ID — all equivalent
57
+ opencli linux-do feed --tag "ChatGPT"
58
+ opencli linux-do feed --tag chatgpt
59
+ opencli linux-do feed --tag 3
60
+
61
+ # Tag + hot view
62
+ opencli linux-do feed --tag "ChatGPT" --view hot
63
+
64
+ # Tag + top view with period
65
+ opencli linux-do feed --tag "OpenAI" --view top --period monthly
66
+ ```
67
+
68
+ ### Filter by category
69
+
70
+ Supports both top-level and sub-categories. Sub-categories auto-resolve their parent path.
71
+
72
+ ```bash
73
+ # Top-level category — name, slug, or ID
74
+ opencli linux-do feed --category "开发调优"
75
+ opencli linux-do feed --category develop
76
+ opencli linux-do feed --category 4
28
77
 
29
- # List all categories
78
+ # Sub-category
79
+ opencli linux-do feed --category "开发调优 / Lv1"
80
+ opencli linux-do feed --category "网盘资源"
81
+
82
+ # Category + hot / top view
83
+ opencli linux-do feed --category "开发调优" --view hot
84
+ opencli linux-do feed --category "开发调优" --view top --period weekly
85
+ ```
86
+
87
+ ### Category + tag
88
+
89
+ Combine `--category` and `--tag` to narrow results within a category.
90
+
91
+ ```bash
92
+ opencli linux-do feed --category "开发调优" --tag "ChatGPT"
93
+ opencli linux-do feed --category "网盘资源" --tag "OpenAI"
94
+ opencli linux-do feed --category 94 --tag 4 --view top --period monthly
95
+ ```
96
+
97
+ ### Parameters
98
+
99
+ | Parameter | Description | Default |
100
+ |-----------|-------------|---------|
101
+ | `--view V` | `latest`, `hot`, `top` | `latest` |
102
+ | `--tag VALUE` | Tag name, slug, or ID | — |
103
+ | `--category VALUE` | Category name, slug, or ID | — |
104
+ | `--limit N` | Number of results | `20` |
105
+ | `--order O` | `default`, `created`, `activity`, `views`, `posts`, `category`, `likes`, `op_likes`, `posters` | `default` |
106
+ | `--ascending` | Sort ascending instead of descending | off |
107
+ | `--period P` | `all`, `daily`, `weekly`, `monthly`, `quarterly`, `yearly` (only with `--view top`) | `weekly` |
108
+
109
+ Output columns: `title`, `replies`, `created`, `likes`, `views`, `url`
110
+
111
+ ## categories
112
+
113
+ List forum categories with optional sub-category expansion.
114
+
115
+ ```bash
30
116
  opencli linux-do categories
117
+ opencli linux-do categories --subcategories
118
+ opencli linux-do categories --limit 50
119
+ ```
120
+
121
+ When `--subcategories` is enabled, sub-categories are rendered as `Parent / Child` so the `name` value can be copied directly into `opencli linux-do feed --category ...`.
122
+
123
+ Output columns: `name`, `slug`, `id`, `topics`, `description`
124
+
125
+ ## tags
31
126
 
32
- # Search topics
127
+ List tags sorted by usage count.
128
+
129
+ ```bash
130
+ opencli linux-do tags
131
+ opencli linux-do tags --limit 50
132
+ ```
133
+
134
+ Output columns: `rank`, `name`, `count`, `url`
135
+
136
+ ## search
137
+
138
+ Search topics by keyword.
139
+
140
+ ```bash
33
141
  opencli linux-do search "NixOS"
142
+ opencli linux-do search "Docker" --limit 10
143
+ opencli linux-do search "Claude" -f json
144
+ ```
34
145
 
35
- # View topic details
36
- opencli linux-do topic 12345
146
+ Output columns: `rank`, `title`, `views`, `likes`, `replies`, `url`
37
147
 
38
- # JSON output
39
- opencli linux-do hot -f json
148
+ ## topic
149
+
150
+ View posts within a topic (first page).
151
+
152
+ ```bash
153
+ opencli linux-do topic 1234
154
+ opencli linux-do topic 1234 --limit 50
155
+ opencli linux-do topic 1234 --main_only -f json | jq -r '.[0].content'
156
+ ```
157
+
158
+ Notes:
159
+ - `--main_only` returns only the main post row and keeps the body untruncated
160
+
161
+ Output columns: `author`, `content`, `likes`, `created_at`
162
+
163
+ ## user-topics
164
+
165
+ List topics created by a user.
166
+
167
+ ```bash
168
+ opencli linux-do user-topics neo
169
+ opencli linux-do user-topics neo --limit 10
170
+ ```
171
+
172
+ Output columns: `rank`, `title`, `replies`, `created_at`, `likes`, `views`, `url`
173
+
174
+ ## user-posts
175
+
176
+ List replies posted by a user.
177
+
178
+ ```bash
179
+ opencli linux-do user-posts neo
180
+ opencli linux-do user-posts neo --limit 10
181
+ ```
182
+
183
+ Output columns: `index`, `topic_user`, `topic`, `reply`, `time`, `url`
184
+
185
+ ## Compatibility
186
+
187
+ The legacy commands below are still available as compatibility wrappers while `feed` becomes the canonical entrypoint:
188
+
189
+ ```bash
190
+ opencli linux-do latest
191
+ opencli linux-do hot --period weekly
192
+ opencli linux-do category develop 4
193
+ ```
194
+
195
+ Preferred modern forms:
196
+
197
+ ```bash
198
+ opencli linux-do feed --view latest
199
+ opencli linux-do feed --view top --period weekly
200
+ opencli linux-do feed --category 4
40
201
  ```
41
202
 
42
203
  ## Prerequisites
@@ -0,0 +1,43 @@
1
+ # paperreview.ai
2
+
3
+ **Mode**: 🌐 Public · **Domain**: `paperreview.ai`
4
+
5
+ ## Commands
6
+
7
+ | Command | Description |
8
+ |---------|-------------|
9
+ | `opencli paperreview submit` | Submit a PDF to paperreview.ai for review |
10
+ | `opencli paperreview review` | Fetch a review by token |
11
+ | `opencli paperreview feedback` | Send feedback on a completed review |
12
+
13
+ ## Usage Examples
14
+
15
+ ```bash
16
+ # Validate a local PDF without uploading it
17
+ opencli paperreview submit ./paper.pdf --email you@example.com --venue RAL --dry-run true
18
+
19
+ # Request an upload slot but stop before the actual upload
20
+ opencli paperreview submit ./paper.pdf --email you@example.com --venue RAL --prepare-only true
21
+
22
+ # Submit a paper for review
23
+ opencli paperreview submit ./paper.pdf --email you@example.com --venue RAL -f json
24
+
25
+ # Check the review status or fetch the final review
26
+ opencli paperreview review tok_123 -f json
27
+
28
+ # Submit feedback on the review quality
29
+ opencli paperreview feedback tok_123 --helpfulness 4 --critical-error no --actionable-suggestions yes
30
+ ```
31
+
32
+ ## Prerequisites
33
+
34
+ - No browser required — uses public paperreview.ai endpoints
35
+ - The input file must be a local `.pdf`
36
+ - paperreview.ai currently rejects files larger than `10MB`
37
+ - `submit` requires `--email`; `--venue` is optional
38
+
39
+ ## Notes
40
+
41
+ - `submit` returns both the review token and the review URL when submission succeeds
42
+ - `review` returns `processing` until the paperreview.ai result is ready
43
+ - `feedback` expects `yes` / `no` values for `--critical-error` and `--actionable-suggestions`
@@ -0,0 +1,49 @@
1
+ # Product Hunt
2
+
3
+ **Mode**: 🌐 Public / 🔐 Browser · **Domain**: `www.producthunt.com`
4
+
5
+ ## Commands
6
+
7
+ | Command | Description |
8
+ |---------|-------------|
9
+ | `opencli producthunt posts` | Latest Product Hunt launches (optional category filter) |
10
+ | `opencli producthunt today` | Today's Product Hunt launches (most recent day in feed) |
11
+ | `opencli producthunt hot` | Today's top Product Hunt launches with vote counts |
12
+ | `opencli producthunt browse <category>` | Best products in a Product Hunt category |
13
+
14
+ ## Usage Examples
15
+
16
+ ```bash
17
+ # Today's top launches with vote counts
18
+ opencli producthunt hot --limit 10
19
+
20
+ # Latest posts (RSS feed)
21
+ opencli producthunt posts --limit 20
22
+
23
+ # Filter by category
24
+ opencli producthunt posts --category developer-tools --limit 10
25
+
26
+ # Today's launches only
27
+ opencli producthunt today --limit 10
28
+
29
+ # Browse best products in a category
30
+ opencli producthunt browse vibe-coding --limit 10
31
+ opencli producthunt browse ai-agents --limit 10
32
+ opencli producthunt browse developer-tools --limit 10
33
+
34
+ # JSON output
35
+ opencli producthunt hot -f json
36
+ ```
37
+
38
+ ## Category Slugs
39
+
40
+ Common categories for `browse` and `posts --category`:
41
+
42
+ `ai-agents`, `ai-coding-agents`, `ai-code-editors`, `ai-chatbots`, `ai-workflow-automation`,
43
+ `vibe-coding`, `developer-tools`, `productivity`, `design-creative`, `marketing-sales`,
44
+ `no-code-platforms`, `llms`, `finance`, `social-community`, `engineering-development`
45
+
46
+ ## Prerequisites
47
+
48
+ - `posts` and `today` — no browser required (public RSS feed)
49
+ - `hot` and `browse` — Chrome running with [Browser Bridge extension](/guide/browser-bridge) installed
@@ -14,8 +14,13 @@ The current built-in commands use native AppleScript automation — no extra lau
14
14
  - `opencli chatgpt status`: Check if the ChatGPT app is currently running.
15
15
  - `opencli chatgpt new`: Activate ChatGPT and press `Cmd+N` to start a new conversation.
16
16
  - `opencli chatgpt send "message"`: Copy your message to clipboard, activate ChatGPT, paste, and submit.
17
+ - `opencli chatgpt send "message" --model thinking`: Switch model/mode first, then send the message.
17
18
  - `opencli chatgpt read`: Read the last visible message from the focused ChatGPT window via the Accessibility tree.
18
19
  - `opencli chatgpt ask "message"`: Send a prompt and wait for the visible reply in one shot.
20
+ - `opencli chatgpt ask "message" --model instant`: Run a one-shot prompt using a specific model/mode.
21
+ - `opencli chatgpt model thinking`: Switch the active ChatGPT model/mode without sending a message.
22
+
23
+ Supported model choices: `auto`, `instant`, `thinking`, `5.2-instant`, `5.2-thinking`.
19
24
 
20
25
  ## Approach 2: CDP (Advanced, Electron Debug Mode)
21
26
 
@@ -25,13 +25,14 @@ Run `opencli list` for the live registry.
25
25
  | **[jike](/adapters/browser/jike)** | `feed` `search` `post` `topic` `user` `create` `comment` `like` `repost` `notifications` | 🔐 Browser |
26
26
  | **[jimeng](/adapters/browser/jimeng)** | `generate` `history` | 🔐 Browser |
27
27
  | **[yollomi](/adapters/browser/yollomi)** | `generate` `video` `edit` `upload` `models` `remove-bg` `upscale` `face-swap` `restore` `try-on` `background` `object-remover` | 🔐 Browser |
28
- | **[linux-do](/adapters/browser/linux-do)** | `hot` `latest` `categories` `category` `search` `topic` | 🔐 Browser |
28
+ | **[linux-do](/adapters/browser/linux-do)** | `feed` `categories` `tags` `search` `topic` `user-topics` `user-posts` | 🔐 Browser |
29
29
  | **[chaoxing](/adapters/browser/chaoxing)** | `assignments` `exams` | 🔐 Browser |
30
30
  | **[grok](/adapters/browser/grok)** | `ask` | 🔐 Browser |
31
31
  | **[doubao](/adapters/browser/doubao)** | `status` `new` `send` `read` `ask` | 🔐 Browser |
32
32
  | **[weread](/adapters/browser/weread)** | `shelf` `search` `book` `ranking` `notebooks` `highlights` `notes` | 🔐 Browser |
33
- | **[douban](/adapters/browser/douban)** | `search` `top250` `subject` `marks` `reviews` `movie-hot` `book-hot` | 🔐 Browser |
33
+ | **[douban](/adapters/browser/douban)** | `search` `top250` `subject` `photos` `download` `marks` `reviews` `movie-hot` `book-hot` | 🔐 Browser |
34
34
  | **[facebook](/adapters/browser/facebook)** | `feed` `profile` `search` `friends` `groups` `events` `notifications` `memories` `add-friend` `join-group` | 🔐 Browser |
35
+ | **[imdb](/adapters/browser/imdb)** | `search` `title` `top` `trending` `person` `reviews` | 🌐 / 🔐 |
35
36
  | **[instagram](/adapters/browser/instagram)** | `explore` `profile` `search` `user` `followers` `following` `follow` `unfollow` `like` `unlike` `comment` `save` `unsave` `saved` | 🔐 Browser |
36
37
  | **[medium](/adapters/browser/medium)** | `feed` `search` `user` | 🔐 Browser |
37
38
  | **[sinablog](/adapters/browser/sinablog)** | `hot` `search` `article` `user` | 🔐 Browser |
@@ -42,6 +43,8 @@ Run `opencli list` for the live registry.
42
43
  | **[jd](/adapters/browser/jd)** | `item` | 🔐 Browser |
43
44
  | **[web](/adapters/browser/web)** | `read` | 🔐 Browser |
44
45
  | **[weixin](/adapters/browser/weixin)** | `download` | 🔐 Browser |
46
+ | **[36kr](/adapters/browser/36kr)** | `news` `hot` `search` `article` | 🌐 / 🔐 |
47
+ | **[producthunt](/adapters/browser/producthunt)** | `posts` `today` `hot` `browse` | 🌐 / 🔐 |
45
48
 
46
49
  ## Public API Adapters
47
50
 
@@ -55,6 +58,7 @@ Run `opencli list` for the live registry.
55
58
  | **[xiaoyuzhou](/adapters/browser/xiaoyuzhou)** | `podcast` `podcast-episodes` `episode` | 🌐 Public |
56
59
  | **[yahoo-finance](/adapters/browser/yahoo-finance)** | `quote` | 🌐 Public |
57
60
  | **[arxiv](/adapters/browser/arxiv)** | `search` `paper` | 🌐 Public |
61
+ | **[paperreview](/adapters/browser/paperreview)** | `submit` `review` `feedback` | 🌐 Public |
58
62
  | **[barchart](/adapters/browser/barchart)** | `quote` `options` `greeks` `flow` | 🌐 Public |
59
63
  | **[hf](/adapters/browser/hf)** | `top` | 🌐 Public |
60
64
  | **[sinafinance](/adapters/browser/sinafinance)** | `news` | 🌐 Public |
@@ -9,6 +9,7 @@ OpenCLI supports downloading images, videos, and articles from supported platfor
9
9
  | **xiaohongshu** | Images, Videos | Downloads all media from a note |
10
10
  | **bilibili** | Videos | Requires `yt-dlp` installed |
11
11
  | **twitter** | Images, Videos | Downloads from user media tab or single tweet |
12
+ | **douban** | Images | Downloads poster / still image lists from movie subjects |
12
13
  | **zhihu** | Articles (Markdown) | Exports articles with optional image download |
13
14
  | **weixin** | Articles (Markdown) | Exports WeChat Official Account articles |
14
15
 
@@ -39,6 +40,9 @@ opencli twitter download elonmusk --limit 20 --output ./twitter
39
40
  # Download single tweet media
40
41
  opencli twitter download --tweet-url "https://x.com/user/status/123" --output ./twitter
41
42
 
43
+ # Download Douban posters / stills
44
+ opencli douban download 30382501 --output ./douban
45
+
42
46
  # Export Zhihu article to Markdown
43
47
  opencli zhihu download "https://zhuanlan.zhihu.com/p/xxx" --output ./zhihu
44
48
 
@@ -0,0 +1,99 @@
1
+ # Rate Limiter Plugin
2
+
3
+ An optional plugin that adds a random sleep between browser-based commands to reduce the risk of platform rate-limiting or bot detection.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ opencli plugin install github:jackwener/opencli-plugin-rate-limiter
9
+ ```
10
+
11
+ Or copy the example below into `~/.opencli/plugins/rate-limiter/` to use it locally without installing from GitHub.
12
+
13
+ ## What it does
14
+
15
+ After every command targeting a browser platform (xiaohongshu, weibo, bilibili, douyin, tiktok, …), the plugin sleeps for a random duration — 5–30 seconds by default — before returning control to the caller.
16
+
17
+ ## Configuration
18
+
19
+ | Variable | Default | Description |
20
+ |---|---|---|
21
+ | `OPENCLI_RATE_MIN` | `5` | Minimum sleep in seconds |
22
+ | `OPENCLI_RATE_MAX` | `30` | Maximum sleep in seconds |
23
+ | `OPENCLI_NO_RATE` | — | Set to `1` to disable entirely (local dev) |
24
+
25
+ ```bash
26
+ # Shorter delays for light scraping
27
+ OPENCLI_RATE_MIN=3 OPENCLI_RATE_MAX=10 opencli xiaohongshu search "AI眼镜"
28
+
29
+ # Skip delays when iterating locally
30
+ OPENCLI_NO_RATE=1 opencli bilibili comments BV1WtAGzYEBm
31
+ ```
32
+
33
+ ## Local installation (without GitHub)
34
+
35
+ 1. Create the plugin directory:
36
+
37
+ ```bash
38
+ mkdir -p ~/.opencli/plugins/rate-limiter
39
+ ```
40
+
41
+ 2. Create `~/.opencli/plugins/rate-limiter/package.json`:
42
+
43
+ ```json
44
+ { "type": "module" }
45
+ ```
46
+
47
+ 3. Create `~/.opencli/plugins/rate-limiter/index.js`:
48
+
49
+ ```js
50
+ import { onAfterExecute } from '@jackwener/opencli/hooks'
51
+
52
+ const BROWSER_DOMAINS = [
53
+ 'xiaohongshu', 'weibo', 'bilibili', 'douyin', 'tiktok',
54
+ 'instagram', 'twitter', 'youtube', 'zhihu', 'douban',
55
+ 'jike', 'weixin', 'xiaoyuzhou',
56
+ ]
57
+
58
+ onAfterExecute(async (ctx) => {
59
+ if (process.env.OPENCLI_NO_RATE === '1') return
60
+
61
+ const site = ctx.command?.split('/')?.[0] ?? ''
62
+ if (!BROWSER_DOMAINS.includes(site)) return
63
+
64
+ const min = Number(process.env.OPENCLI_RATE_MIN ?? 5)
65
+ const max = Number(process.env.OPENCLI_RATE_MAX ?? 30)
66
+ const ms = Math.floor(Math.random() * (max - min + 1) + min) * 1000
67
+
68
+ process.stderr.write(`[rate-limiter] ${site}: sleeping ${(ms / 1000).toFixed(0)}s\n`)
69
+ await new Promise(r => setTimeout(r, ms))
70
+ })
71
+ ```
72
+
73
+ 4. Verify it loaded:
74
+
75
+ ```bash
76
+ OPENCLI_NO_RATE=1 opencli xiaohongshu search "test" 2>&1 | grep rate-limiter
77
+ # → (no output — plugin loaded but rate limit skipped)
78
+
79
+ opencli xiaohongshu search "test" 2>&1 | grep rate-limiter
80
+ # → [rate-limiter] xiaohongshu: sleeping 12s
81
+ ```
82
+
83
+ ## Writing your own plugin
84
+
85
+ Plugins are plain JS/TS files in `~/.opencli/plugins/<name>/`. A plugin file must export a hook registration call that matches the pattern `onStartup(`, `onBeforeExecute(`, or `onAfterExecute(` — opencli's discovery engine uses this pattern to identify hook files vs. command files.
86
+
87
+ ```js
88
+ // ~/.opencli/plugins/my-plugin/index.js
89
+ import { onAfterExecute } from '@jackwener/opencli/hooks'
90
+
91
+ onAfterExecute(async (ctx) => {
92
+ // ctx.command — e.g. "bilibili/comments"
93
+ // ctx.args — coerced command arguments
94
+ // ctx.error — set if the command threw
95
+ console.error(`[my-plugin] finished: ${ctx.command}`)
96
+ })
97
+ ```
98
+
99
+ See [hooks.ts](../../src/hooks.ts) for the full `HookContext` type.
@@ -0,0 +1,200 @@
1
+ ---
2
+ description: How to turn a new Electron desktop app into an OpenCLI adapter
3
+ ---
4
+
5
+ # Add a New Electron App CLI
6
+
7
+ This guide is the **fast entry point** for turning a new Electron desktop application into an OpenCLI adapter.
8
+
9
+ If you want the full background and deeper SOP, read:
10
+ - [CLI-ifying Electron Applications](/advanced/electron)
11
+ - [Chrome DevTools Protocol](/advanced/cdp)
12
+ - [TypeScript Adapter Guide](/developer/ts-adapter)
13
+
14
+ ## When to use this guide
15
+
16
+ Use this workflow when the target app:
17
+ - is built with **Electron**, or at least exposes a working **Chrome DevTools Protocol (CDP)** endpoint
18
+ - can be launched with `--remote-debugging-port=<port>`
19
+ - should be automated through its real UI instead of a public HTTP API
20
+
21
+ If the app is **not** Electron and does **not** expose CDP, use the native desktop automation pattern instead. See [CLI-ifying Electron Applications](/advanced/electron#non-electron-pattern-applescript).
22
+
23
+ ## The shortest path
24
+
25
+ ### 1. Confirm the app is Electron
26
+
27
+ Typical macOS check:
28
+
29
+ ```bash
30
+ ls /Applications/AppName.app/Contents/Frameworks/Electron\ Framework.framework
31
+ ```
32
+
33
+ If Electron is present, the next step is usually to launch the app with a debugging port.
34
+
35
+ ### 2. Launch it with CDP enabled
36
+
37
+ ```bash
38
+ /Applications/AppName.app/Contents/MacOS/AppName --remote-debugging-port=9222
39
+ ```
40
+
41
+ Then point OpenCLI at that CDP endpoint:
42
+
43
+ ```bash
44
+ export OPENCLI_CDP_ENDPOINT="http://127.0.0.1:9222"
45
+ ```
46
+
47
+ ### 3. Start with the 5-command pattern
48
+
49
+ For a new Electron adapter, implement these commands first in `src/clis/<app>/`:
50
+
51
+ - `status.ts` — verify the app is reachable through CDP
52
+ - `dump.ts` — inspect DOM and snapshot structure before guessing selectors
53
+ - `read.ts` — extract the visible context you actually need
54
+ - `send.ts` — inject text and submit through the real editor
55
+ - `new.ts` — create a new session, tab, thread, or document
56
+
57
+ This is the standard baseline because it gives you:
58
+ - a connection check
59
+ - a reverse-engineering tool
60
+ - one read path
61
+ - one write path
62
+ - one session reset path
63
+
64
+ The full rationale and examples are in [CLI-ifying Electron Applications](/advanced/electron).
65
+
66
+ ## Recommended implementation workflow
67
+
68
+ ### Step 1: Build `status`
69
+
70
+ Goal: prove CDP connectivity before touching app-specific logic.
71
+
72
+ Typical checks:
73
+ - current URL
74
+ - document title
75
+ - app shell presence
76
+
77
+ If `status` is unstable, stop there and fix connectivity first.
78
+
79
+ ### Step 2: Build `dump`
80
+
81
+ Do **not** guess selectors from the rendered UI.
82
+
83
+ Dump:
84
+ - `document.body.innerHTML`
85
+ - accessibility snapshot
86
+ - any stable attributes such as `data-testid`, `role`, `aria-*`, framework-specific markers
87
+
88
+ Use the dump to identify real containers, buttons, composers, and conversation regions.
89
+
90
+ ### Step 3: Build `read`
91
+
92
+ Target only the app region that matters.
93
+
94
+ Good targets:
95
+ - message list
96
+ - editor history
97
+ - visible thread content
98
+ - selected document panel
99
+
100
+ Avoid dumping the entire page text into the final command output.
101
+
102
+ ### Step 4: Build `send`
103
+
104
+ Most Electron apps use React-style controlled editors, so direct `.value = ...` assignments are often ignored.
105
+
106
+ Prefer editor-aware input patterns such as:
107
+ - focus the editable region
108
+ - use `document.execCommand('insertText', false, text)` when applicable
109
+ - use real key presses like `Enter`, `Meta+Enter`, or app-specific shortcuts
110
+
111
+ ### Step 5: Build `new`
112
+
113
+ Many desktop apps rely on keyboard shortcuts for “new chat”, “new tab”, or “new note”.
114
+
115
+ Typical pattern:
116
+
117
+ ```ts
118
+ const isMac = process.platform === 'darwin';
119
+ await page.pressKey(isMac ? 'Meta+N' : 'Control+N');
120
+ await page.wait(1);
121
+ ```
122
+
123
+ ## Where to put files
124
+
125
+ For a TypeScript desktop adapter, the usual layout is:
126
+
127
+ ```text
128
+ src/clis/<app>/status.ts
129
+ src/clis/<app>/dump.ts
130
+ src/clis/<app>/read.ts
131
+ src/clis/<app>/send.ts
132
+ src/clis/<app>/new.ts
133
+ src/clis/<app>/utils.ts
134
+ ```
135
+
136
+ If the app grows beyond the baseline, add higher-level commands such as:
137
+ - `ask`
138
+ - `history`
139
+ - `model`
140
+ - `screenshot`
141
+ - `export`
142
+
143
+ ## What to document when you add a new app
144
+
145
+ When the adapter is ready, also add:
146
+
147
+ - an adapter doc under `docs/adapters/desktop/`
148
+ - command list and examples
149
+ - launch instructions with `--remote-debugging-port`
150
+ - any required environment variables
151
+ - platform-specific caveats
152
+
153
+ Examples to study:
154
+ - `docs/adapters/desktop/codex.md`
155
+ - `docs/adapters/desktop/chatwise.md`
156
+ - `docs/adapters/desktop/notion.md`
157
+ - `docs/adapters/desktop/discord.md`
158
+
159
+ ## Common failure modes
160
+
161
+ ### CDP endpoint exists, but commands are flaky
162
+
163
+ Usually one of these:
164
+ - the wrong window/tab is selected
165
+ - the app has not finished rendering
166
+ - selectors were guessed instead of discovered from `dump`
167
+ - the editor is controlled and ignores direct value assignment
168
+
169
+ ### The app is Chromium-based but not truly controllable
170
+
171
+ Some desktop apps embed Chromium but do not expose a usable CDP surface.
172
+ In that case, switch to the non-Electron desktop automation approach instead of forcing the Electron pattern.
173
+
174
+ ### You already have a browser workflow and wonder whether to reuse it
175
+
176
+ If the app exposes a normal web URL and the browser flow is enough, a browser adapter is usually simpler.
177
+ Use an Electron adapter only when the desktop app is the real integration surface.
178
+
179
+ ## Recommended reading order
180
+
181
+ If you are starting from zero:
182
+
183
+ 1. This page
184
+ 2. [CLI-ifying Electron Applications](/advanced/electron)
185
+ 3. [Chrome DevTools Protocol](/advanced/cdp)
186
+ 4. [TypeScript Adapter Guide](/developer/ts-adapter)
187
+ 5. One concrete desktop adapter doc under `docs/adapters/desktop/`
188
+
189
+ ## Practical rule
190
+
191
+ Do not start with a large feature surface.
192
+
193
+ Start with:
194
+ - `status`
195
+ - `dump`
196
+ - `read`
197
+ - `send`
198
+ - `new`
199
+
200
+ Once those are stable, extend outward.
@@ -55,3 +55,4 @@ opencli bilibili hot -v # Verbose: show pipeline debug
55
55
  - [Plugins — extend with community adapters](/guide/plugins)
56
56
  - [All available adapters](/adapters/)
57
57
  - [For developers / AI agents](/developer/contributing)
58
+ - [Add a new Electron app CLI](/guide/electron-app-cli)