@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.
- package/.github/workflows/build-extension.yml +2 -6
- package/.github/workflows/ci.yml +21 -1
- package/README.md +35 -6
- package/README.zh-CN.md +12 -5
- package/SKILL.md +2 -0
- package/dist/browser/cdp.d.ts +2 -1
- package/dist/browser/discover.d.ts +4 -1
- package/dist/browser/discover.js +6 -2
- package/dist/browser/errors.d.ts +2 -2
- package/dist/browser/errors.js +4 -12
- package/dist/browser/mcp.d.ts +2 -1
- package/dist/build-manifest.d.ts +2 -0
- package/dist/build-manifest.js +39 -14
- package/dist/build-manifest.test.js +21 -0
- package/dist/capabilityRouting.d.ts +2 -0
- package/dist/capabilityRouting.js +2 -1
- package/dist/cli-manifest.json +1111 -112
- package/dist/cli.js +34 -3
- package/dist/clis/36kr/article.d.ts +1 -0
- package/dist/clis/36kr/article.js +62 -0
- package/dist/clis/36kr/hot.d.ts +3 -0
- package/dist/clis/36kr/hot.js +80 -0
- package/dist/clis/36kr/hot.test.d.ts +1 -0
- package/dist/clis/36kr/hot.test.js +15 -0
- package/dist/clis/36kr/news.d.ts +1 -0
- package/dist/clis/36kr/news.js +51 -0
- package/dist/clis/36kr/news.test.d.ts +1 -0
- package/dist/clis/36kr/news.test.js +85 -0
- package/dist/clis/36kr/search.d.ts +1 -0
- package/dist/clis/36kr/search.js +72 -0
- package/dist/clis/bilibili/comments.d.ts +5 -0
- package/dist/clis/bilibili/comments.js +40 -0
- package/dist/clis/bilibili/comments.test.d.ts +1 -0
- package/dist/clis/bilibili/comments.test.js +82 -0
- package/dist/clis/chatgpt/ask.js +29 -14
- package/dist/clis/chatgpt/ax.d.ts +6 -0
- package/dist/clis/chatgpt/ax.js +172 -1
- package/dist/clis/chatgpt/model.d.ts +1 -0
- package/dist/clis/chatgpt/model.js +24 -0
- package/dist/clis/chatgpt/send.js +12 -3
- package/dist/clis/douban/download.d.ts +1 -0
- package/dist/clis/douban/download.js +67 -0
- package/dist/clis/douban/download.test.d.ts +1 -0
- package/dist/clis/douban/download.test.js +170 -0
- package/dist/clis/douban/photos.d.ts +1 -0
- package/dist/clis/douban/photos.js +34 -0
- package/dist/clis/douban/utils.d.ts +25 -0
- package/dist/clis/douban/utils.js +190 -1
- package/dist/clis/douban/utils.test.d.ts +1 -0
- package/dist/clis/douban/utils.test.js +64 -0
- package/dist/clis/imdb/person.d.ts +1 -0
- package/dist/clis/imdb/person.js +203 -0
- package/dist/clis/imdb/reviews.d.ts +1 -0
- package/dist/clis/imdb/reviews.js +88 -0
- package/dist/clis/imdb/search.d.ts +1 -0
- package/dist/clis/imdb/search.js +161 -0
- package/dist/clis/imdb/title.d.ts +1 -0
- package/dist/clis/imdb/title.js +93 -0
- package/dist/clis/imdb/top.d.ts +1 -0
- package/dist/clis/imdb/top.js +53 -0
- package/dist/clis/imdb/trending.d.ts +1 -0
- package/dist/clis/imdb/trending.js +52 -0
- package/dist/clis/imdb/utils.d.ts +46 -0
- package/dist/clis/imdb/utils.js +285 -0
- package/dist/clis/imdb/utils.test.d.ts +1 -0
- package/dist/clis/imdb/utils.test.js +88 -0
- package/dist/clis/jd/item.d.ts +4 -0
- package/dist/clis/jd/item.js +16 -15
- package/dist/clis/jd/item.test.js +16 -1
- package/dist/clis/linux-do/categories.yaml +38 -9
- package/dist/clis/linux-do/category.d.ts +1 -0
- package/dist/clis/linux-do/category.js +36 -0
- package/dist/clis/linux-do/feed.d.ts +45 -0
- package/dist/clis/linux-do/feed.js +397 -0
- package/dist/clis/linux-do/feed.test.d.ts +1 -0
- package/dist/clis/linux-do/feed.test.js +118 -0
- package/dist/clis/linux-do/hot.d.ts +1 -0
- package/dist/clis/linux-do/hot.js +25 -0
- package/dist/clis/linux-do/latest.d.ts +1 -0
- package/dist/clis/linux-do/latest.js +18 -0
- package/dist/clis/linux-do/tags.yaml +41 -0
- package/dist/clis/linux-do/topic.yaml +41 -3
- package/dist/clis/linux-do/user-posts.yaml +67 -0
- package/dist/clis/linux-do/user-topics.yaml +54 -0
- package/dist/clis/paperreview/commands.test.d.ts +3 -0
- package/dist/clis/paperreview/commands.test.js +243 -0
- package/dist/clis/paperreview/feedback.d.ts +1 -0
- package/dist/clis/paperreview/feedback.js +52 -0
- package/dist/clis/paperreview/review.d.ts +1 -0
- package/dist/clis/paperreview/review.js +37 -0
- package/dist/clis/paperreview/submit.d.ts +1 -0
- package/dist/clis/paperreview/submit.js +85 -0
- package/dist/clis/paperreview/utils.d.ts +46 -0
- package/dist/clis/paperreview/utils.js +197 -0
- package/dist/clis/paperreview/utils.test.d.ts +1 -0
- package/dist/clis/paperreview/utils.test.js +49 -0
- package/dist/clis/producthunt/browse.d.ts +1 -0
- package/dist/clis/producthunt/browse.js +99 -0
- package/dist/clis/producthunt/hot.d.ts +1 -0
- package/dist/clis/producthunt/hot.js +110 -0
- package/dist/clis/producthunt/posts.d.ts +1 -0
- package/dist/clis/producthunt/posts.js +28 -0
- package/dist/clis/producthunt/today.d.ts +1 -0
- package/dist/clis/producthunt/today.js +35 -0
- package/dist/clis/producthunt/utils.d.ts +29 -0
- package/dist/clis/producthunt/utils.js +99 -0
- package/dist/clis/producthunt/utils.test.d.ts +1 -0
- package/dist/clis/producthunt/utils.test.js +64 -0
- package/dist/clis/twitter/article.js +4 -28
- package/dist/clis/twitter/likes.d.ts +24 -0
- package/dist/clis/twitter/likes.js +217 -0
- package/dist/clis/twitter/likes.test.d.ts +1 -0
- package/dist/clis/twitter/likes.test.js +85 -0
- package/dist/clis/twitter/profile.js +4 -28
- package/dist/clis/twitter/search.js +2 -1
- package/dist/clis/twitter/search.test.js +2 -0
- package/dist/clis/twitter/shared.d.ts +6 -0
- package/dist/clis/twitter/shared.js +35 -0
- package/dist/clis/twitter/timeline.js +2 -13
- package/dist/clis/weixin/download.d.ts +17 -0
- package/dist/clis/weixin/download.js +88 -20
- package/dist/clis/weread/book.js +2 -2
- package/dist/clis/weread/commands.test.d.ts +3 -0
- package/dist/clis/weread/commands.test.js +43 -0
- package/dist/clis/weread/highlights.js +2 -2
- package/dist/clis/weread/notebooks.js +2 -2
- package/dist/clis/weread/notes.js +3 -3
- package/dist/clis/weread/shelf.js +2 -2
- package/dist/clis/weread/utils.d.ts +4 -4
- package/dist/clis/weread/utils.js +32 -14
- package/dist/clis/weread/utils.test.js +1 -28
- package/dist/clis/xiaohongshu/comments.d.ts +5 -0
- package/dist/clis/xiaohongshu/comments.js +74 -0
- package/dist/clis/xiaohongshu/comments.test.d.ts +1 -0
- package/dist/clis/xiaohongshu/comments.test.js +79 -0
- package/dist/clis/xiaohongshu/publish.js +114 -18
- package/dist/clis/xiaohongshu/publish.test.d.ts +1 -0
- package/dist/clis/xiaohongshu/publish.test.js +119 -0
- package/dist/commanderAdapter.d.ts +1 -0
- package/dist/commanderAdapter.js +176 -29
- package/dist/commanderAdapter.test.d.ts +1 -0
- package/dist/commanderAdapter.test.js +62 -0
- package/dist/daemon.js +17 -1
- package/dist/discovery.js +8 -14
- package/dist/doctor.d.ts +1 -0
- package/dist/doctor.js +9 -2
- package/dist/download/index.js +63 -51
- package/dist/download/index.test.js +17 -4
- package/dist/errors.d.ts +3 -1
- package/dist/errors.js +15 -32
- package/dist/execution.d.ts +1 -3
- package/dist/execution.js +21 -1
- package/dist/hooks.js +2 -0
- package/dist/main.js +5 -0
- package/dist/output.js +5 -1
- package/dist/pipeline/executor.js +3 -4
- package/dist/plugin-manifest.d.ts +70 -0
- package/dist/plugin-manifest.js +160 -0
- package/dist/plugin-manifest.test.d.ts +4 -0
- package/dist/plugin-manifest.test.js +179 -0
- package/dist/plugin.d.ts +38 -5
- package/dist/plugin.js +267 -33
- package/dist/plugin.test.js +220 -3
- package/dist/registry.d.ts +4 -0
- package/dist/registry.js +2 -0
- package/dist/runtime-detect.d.ts +21 -0
- package/dist/runtime-detect.js +32 -0
- package/dist/runtime-detect.test.d.ts +1 -0
- package/dist/runtime-detect.test.js +27 -0
- package/dist/runtime.js +1 -1
- package/dist/serialization.d.ts +2 -0
- package/dist/serialization.js +6 -0
- package/dist/types.d.ts +1 -0
- package/dist/update-check.d.ts +22 -0
- package/dist/update-check.js +112 -0
- package/dist/weixin-download.test.d.ts +1 -0
- package/dist/weixin-download.test.js +30 -0
- package/dist/weread-private-api-regression.test.d.ts +1 -0
- package/dist/weread-private-api-regression.test.js +122 -0
- package/dist/yaml-schema.d.ts +3 -0
- package/dist/yaml-schema.js +18 -1
- package/docs/.vitepress/config.mts +4 -0
- package/docs/adapters/browser/36kr.md +47 -0
- package/docs/adapters/browser/douban.md +14 -0
- package/docs/adapters/browser/imdb.md +47 -0
- package/docs/adapters/browser/jd.md +2 -2
- package/docs/adapters/browser/linux-do.md +181 -20
- package/docs/adapters/browser/paperreview.md +43 -0
- package/docs/adapters/browser/producthunt.md +49 -0
- package/docs/adapters/desktop/chatgpt.md +5 -0
- package/docs/adapters/index.md +6 -2
- package/docs/advanced/download.md +4 -0
- package/docs/advanced/rate-limiter-plugin.md +99 -0
- package/docs/guide/electron-app-cli.md +200 -0
- package/docs/guide/getting-started.md +1 -0
- package/docs/guide/plugins.md +87 -0
- package/docs/zh/guide/electron-app-cli.md +188 -0
- package/docs/zh/guide/getting-started.md +1 -0
- package/docs/zh/guide/plugins.md +65 -0
- package/extension/package.json +1 -0
- package/extension/scripts/package-release.mjs +179 -0
- package/extension/src/background.ts +2 -0
- package/package.json +4 -1
- package/scripts/postinstall.js +10 -0
- package/src/browser/cdp.ts +2 -1
- package/src/browser/discover.ts +8 -3
- package/src/browser/errors.ts +13 -14
- package/src/browser/mcp.ts +2 -1
- package/src/build-manifest.test.ts +23 -0
- package/src/build-manifest.ts +40 -15
- package/src/capabilityRouting.ts +2 -1
- package/src/cli.ts +35 -3
- package/src/clis/36kr/article.ts +69 -0
- package/src/clis/36kr/hot.test.ts +19 -0
- package/src/clis/36kr/hot.ts +100 -0
- package/src/clis/36kr/news.test.ts +90 -0
- package/src/clis/36kr/news.ts +54 -0
- package/src/clis/36kr/search.ts +78 -0
- package/src/clis/bilibili/comments.test.ts +102 -0
- package/src/clis/bilibili/comments.ts +44 -0
- package/src/clis/chatgpt/ask.ts +28 -14
- package/src/clis/chatgpt/ax.ts +180 -1
- package/src/clis/chatgpt/model.ts +27 -0
- package/src/clis/chatgpt/send.ts +16 -6
- package/src/clis/douban/download.test.ts +196 -0
- package/src/clis/douban/download.ts +78 -0
- package/src/clis/douban/photos.ts +36 -0
- package/src/clis/douban/utils.test.ts +97 -0
- package/src/clis/douban/utils.ts +232 -1
- package/src/clis/imdb/person.ts +232 -0
- package/src/clis/imdb/reviews.ts +111 -0
- package/src/clis/imdb/search.ts +179 -0
- package/src/clis/imdb/title.ts +121 -0
- package/src/clis/imdb/top.ts +67 -0
- package/src/clis/imdb/trending.ts +66 -0
- package/src/clis/imdb/utils.test.ts +117 -0
- package/src/clis/imdb/utils.ts +305 -0
- package/src/clis/jd/item.test.ts +18 -1
- package/src/clis/jd/item.ts +18 -15
- package/src/clis/linux-do/categories.yaml +38 -9
- package/src/clis/linux-do/category.ts +37 -0
- package/src/clis/linux-do/feed.test.ts +132 -0
- package/src/clis/linux-do/feed.ts +501 -0
- package/src/clis/linux-do/hot.ts +26 -0
- package/src/clis/linux-do/latest.ts +19 -0
- package/src/clis/linux-do/tags.yaml +41 -0
- package/src/clis/linux-do/topic.yaml +41 -3
- package/src/clis/linux-do/user-posts.yaml +67 -0
- package/src/clis/linux-do/user-topics.yaml +54 -0
- package/src/clis/paperreview/commands.test.ts +283 -0
- package/src/clis/paperreview/feedback.ts +64 -0
- package/src/clis/paperreview/review.ts +47 -0
- package/src/clis/paperreview/submit.ts +119 -0
- package/src/clis/paperreview/utils.test.ts +68 -0
- package/src/clis/paperreview/utils.ts +276 -0
- package/src/clis/producthunt/browse.ts +109 -0
- package/src/clis/producthunt/hot.ts +127 -0
- package/src/clis/producthunt/posts.ts +29 -0
- package/src/clis/producthunt/today.ts +37 -0
- package/src/clis/producthunt/utils.test.ts +72 -0
- package/src/clis/producthunt/utils.ts +122 -0
- package/src/clis/twitter/article.ts +5 -28
- package/src/clis/twitter/likes.test.ts +91 -0
- package/src/clis/twitter/likes.ts +256 -0
- package/src/clis/twitter/profile.ts +5 -28
- package/src/clis/twitter/search.test.ts +2 -0
- package/src/clis/twitter/search.ts +3 -1
- package/src/clis/twitter/shared.ts +45 -0
- package/src/clis/twitter/timeline.ts +2 -13
- package/src/clis/weixin/download.ts +114 -20
- package/src/clis/weread/book.ts +2 -2
- package/src/clis/weread/commands.test.ts +57 -0
- package/src/clis/weread/highlights.ts +2 -2
- package/src/clis/weread/notebooks.ts +2 -2
- package/src/clis/weread/notes.ts +3 -3
- package/src/clis/weread/shelf.ts +2 -2
- package/src/clis/weread/utils.test.ts +1 -32
- package/src/clis/weread/utils.ts +41 -16
- package/src/clis/xiaohongshu/comments.test.ts +96 -0
- package/src/clis/xiaohongshu/comments.ts +81 -0
- package/src/clis/xiaohongshu/publish.test.ts +137 -0
- package/src/clis/xiaohongshu/publish.ts +129 -18
- package/src/commanderAdapter.test.ts +78 -0
- package/src/commanderAdapter.ts +188 -24
- package/src/daemon.ts +19 -1
- package/src/discovery.ts +8 -15
- package/src/doctor.ts +13 -2
- package/src/download/index.test.ts +14 -4
- package/src/download/index.ts +67 -55
- package/src/errors.ts +25 -66
- package/src/execution.ts +28 -3
- package/src/hooks.ts +1 -0
- package/src/main.ts +6 -0
- package/src/output.ts +3 -1
- package/src/pipeline/executor.ts +4 -6
- package/src/plugin-manifest.test.ts +223 -0
- package/src/plugin-manifest.ts +206 -0
- package/src/plugin.test.ts +246 -2
- package/src/plugin.ts +338 -36
- package/src/registry.ts +6 -1
- package/src/runtime-detect.test.ts +30 -0
- package/src/runtime-detect.ts +36 -0
- package/src/runtime.ts +1 -1
- package/src/serialization.ts +4 -0
- package/src/types.ts +1 -0
- package/src/update-check.ts +114 -0
- package/src/weixin-download.test.ts +64 -0
- package/src/weread-private-api-regression.test.ts +150 -0
- package/src/yaml-schema.ts +20 -0
- package/tests/e2e/browser-auth.test.ts +13 -9
- package/tests/e2e/browser-public-extended.test.ts +1 -1
- package/tests/e2e/browser-public.test.ts +62 -4
- package/tests/e2e/helpers.ts +2 -1
- package/tests/e2e/public-commands.test.ts +37 -3
- package/tests/smoke/api-health.test.ts +1 -1
- package/vitest.config.ts +10 -0
- package/dist/clis/linux-do/category.yaml +0 -51
- package/dist/clis/linux-do/hot.yaml +0 -50
- package/dist/clis/linux-do/latest.yaml +0 -40
- package/src/clis/linux-do/category.yaml +0 -51
- package/src/clis/linux-do/hot.yaml +0 -50
- 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
|
|
10
|
-
| `opencli linux-do
|
|
11
|
-
| `opencli linux-do
|
|
12
|
-
| `opencli linux-do
|
|
13
|
-
| `opencli linux-do
|
|
14
|
-
| `opencli linux-do
|
|
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
|
-
##
|
|
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
|
-
#
|
|
20
|
-
opencli linux-do
|
|
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
|
-
#
|
|
23
|
-
opencli linux-do
|
|
24
|
-
|
|
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
|
-
|
|
27
|
-
|
|
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
|
-
#
|
|
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
|
-
|
|
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
|
-
|
|
36
|
-
opencli linux-do topic 12345
|
|
146
|
+
Output columns: `rank`, `title`, `views`, `likes`, `replies`, `url`
|
|
37
147
|
|
|
38
|
-
|
|
39
|
-
|
|
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
|
|
package/docs/adapters/index.md
CHANGED
|
@@ -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)** | `
|
|
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)
|