@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.
- package/.github/ISSUE_TEMPLATE/bug_report.yml +83 -0
- package/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +42 -0
- package/.github/ISSUE_TEMPLATE/new_site_adapter.yml +57 -0
- package/.github/dependabot.yml +27 -0
- package/.github/pull_request_template.md +24 -0
- package/.github/workflows/ci.yml +14 -8
- package/.github/workflows/e2e-headed.yml +6 -2
- package/.github/workflows/pkg-pr-new.yml +2 -2
- package/.github/workflows/release-please.yml +25 -0
- package/.github/workflows/release.yml +2 -2
- package/.github/workflows/security.yml +36 -0
- package/CDP.md +1 -1
- package/CDP.zh-CN.md +1 -1
- package/CLI-ELECTRON.md +89 -36
- package/CLI-EXPLORER.md +4 -4
- package/CONTRIBUTING.md +167 -0
- package/README.md +113 -89
- package/README.zh-CN.md +114 -91
- package/SKILL.md +10 -8
- package/TESTING.md +7 -7
- package/dist/browser/daemon-client.d.ts +37 -0
- package/dist/browser/daemon-client.js +82 -0
- package/dist/browser/discover.d.ts +11 -34
- package/dist/browser/discover.js +15 -190
- package/dist/browser/errors.d.ts +6 -20
- package/dist/browser/errors.js +24 -63
- package/dist/browser/index.d.ts +2 -11
- package/dist/browser/index.js +5 -11
- package/dist/browser/mcp.d.ts +9 -18
- package/dist/browser/mcp.js +70 -284
- package/dist/browser/page.d.ts +28 -6
- package/dist/browser/page.js +210 -85
- package/dist/browser.test.js +4 -202
- package/dist/build-manifest.d.ts +26 -0
- package/dist/build-manifest.js +132 -60
- package/dist/build-manifest.test.d.ts +1 -0
- package/dist/build-manifest.test.js +26 -0
- package/dist/cli-manifest.json +1582 -29
- package/dist/clis/bilibili/download.d.ts +10 -0
- package/dist/clis/bilibili/download.js +135 -0
- package/dist/clis/chatwise/ask.d.ts +1 -0
- package/dist/clis/chatwise/ask.js +76 -0
- package/dist/clis/chatwise/export.d.ts +1 -0
- package/dist/clis/chatwise/export.js +46 -0
- package/dist/clis/chatwise/history.d.ts +1 -0
- package/dist/clis/chatwise/history.js +43 -0
- package/dist/clis/chatwise/model.d.ts +1 -0
- package/dist/clis/chatwise/model.js +81 -0
- package/dist/clis/chatwise/new.d.ts +1 -0
- package/dist/clis/chatwise/new.js +18 -0
- package/dist/clis/chatwise/read.d.ts +1 -0
- package/dist/clis/chatwise/read.js +39 -0
- package/dist/clis/chatwise/screenshot.d.ts +1 -0
- package/dist/clis/chatwise/screenshot.js +27 -0
- package/dist/clis/chatwise/send.d.ts +1 -0
- package/dist/clis/chatwise/send.js +45 -0
- package/dist/clis/chatwise/status.d.ts +1 -0
- package/dist/clis/chatwise/status.js +22 -0
- package/dist/clis/discord-app/channels.d.ts +1 -0
- package/dist/clis/discord-app/channels.js +45 -0
- package/dist/clis/discord-app/members.d.ts +1 -0
- package/dist/clis/discord-app/members.js +38 -0
- package/dist/clis/discord-app/read.d.ts +1 -0
- package/dist/clis/discord-app/read.js +45 -0
- package/dist/clis/discord-app/search.d.ts +1 -0
- package/dist/clis/discord-app/search.js +56 -0
- package/dist/clis/discord-app/send.d.ts +1 -0
- package/dist/clis/discord-app/send.js +27 -0
- package/dist/clis/discord-app/servers.d.ts +1 -0
- package/dist/clis/discord-app/servers.js +36 -0
- package/dist/clis/discord-app/status.d.ts +1 -0
- package/dist/clis/discord-app/status.js +16 -0
- package/dist/clis/feishu/new.d.ts +1 -0
- package/dist/clis/feishu/new.js +27 -0
- package/dist/clis/feishu/read.d.ts +1 -0
- package/dist/clis/feishu/read.js +40 -0
- package/dist/clis/feishu/search.d.ts +1 -0
- package/dist/clis/feishu/search.js +30 -0
- package/dist/clis/feishu/send.d.ts +1 -0
- package/dist/clis/feishu/send.js +39 -0
- package/dist/clis/feishu/status.d.ts +1 -0
- package/dist/clis/feishu/status.js +28 -0
- package/dist/clis/grok/ask.d.ts +1 -0
- package/dist/clis/grok/ask.js +82 -0
- package/dist/clis/grok/debug.d.ts +1 -0
- package/dist/clis/grok/debug.js +45 -0
- package/dist/clis/jimeng/generate.yaml +84 -0
- package/dist/clis/jimeng/history.yaml +47 -0
- package/dist/clis/linux-do/categories.yaml +41 -0
- package/dist/clis/linux-do/category.yaml +49 -0
- package/dist/clis/linux-do/hot.yaml +50 -0
- package/dist/clis/linux-do/latest.yaml +40 -0
- package/dist/clis/linux-do/search.yaml +45 -0
- package/dist/clis/linux-do/topic.yaml +38 -0
- package/dist/clis/neteasemusic/like.d.ts +1 -0
- package/dist/clis/neteasemusic/like.js +25 -0
- package/dist/clis/neteasemusic/lyrics.d.ts +1 -0
- package/dist/clis/neteasemusic/lyrics.js +47 -0
- package/dist/clis/neteasemusic/next.d.ts +1 -0
- package/dist/clis/neteasemusic/next.js +26 -0
- package/dist/clis/neteasemusic/play.d.ts +1 -0
- package/dist/clis/neteasemusic/play.js +26 -0
- package/dist/clis/neteasemusic/playing.d.ts +1 -0
- package/dist/clis/neteasemusic/playing.js +59 -0
- package/dist/clis/neteasemusic/playlist.d.ts +1 -0
- package/dist/clis/neteasemusic/playlist.js +46 -0
- package/dist/clis/neteasemusic/prev.d.ts +1 -0
- package/dist/clis/neteasemusic/prev.js +25 -0
- package/dist/clis/neteasemusic/search.d.ts +1 -0
- package/dist/clis/neteasemusic/search.js +52 -0
- package/dist/clis/neteasemusic/status.d.ts +1 -0
- package/dist/clis/neteasemusic/status.js +16 -0
- package/dist/clis/neteasemusic/volume.d.ts +1 -0
- package/dist/clis/neteasemusic/volume.js +54 -0
- package/dist/clis/notion/export.d.ts +1 -0
- package/dist/clis/notion/export.js +31 -0
- package/dist/clis/notion/favorites.d.ts +1 -0
- package/dist/clis/notion/favorites.js +84 -0
- package/dist/clis/notion/new.d.ts +1 -0
- package/dist/clis/notion/new.js +34 -0
- package/dist/clis/notion/read.d.ts +1 -0
- package/dist/clis/notion/read.js +30 -0
- package/dist/clis/notion/search.d.ts +1 -0
- package/dist/clis/notion/search.js +46 -0
- package/dist/clis/notion/sidebar.d.ts +1 -0
- package/dist/clis/notion/sidebar.js +41 -0
- package/dist/clis/notion/status.d.ts +1 -0
- package/dist/clis/notion/status.js +16 -0
- package/dist/clis/notion/write.d.ts +1 -0
- package/dist/clis/notion/write.js +40 -0
- package/dist/clis/twitter/download.d.ts +8 -0
- package/dist/clis/twitter/download.js +204 -0
- package/dist/clis/wechat/chats.d.ts +1 -0
- package/dist/clis/wechat/chats.js +28 -0
- package/dist/clis/wechat/contacts.d.ts +1 -0
- package/dist/clis/wechat/contacts.js +28 -0
- package/dist/clis/wechat/read.d.ts +1 -0
- package/dist/clis/wechat/read.js +58 -0
- package/dist/clis/wechat/search.d.ts +1 -0
- package/dist/clis/wechat/search.js +31 -0
- package/dist/clis/wechat/send.d.ts +1 -0
- package/dist/clis/wechat/send.js +42 -0
- package/dist/clis/wechat/status.d.ts +1 -0
- package/dist/clis/wechat/status.js +29 -0
- package/dist/clis/xiaohongshu/creator-note-detail.d.ts +10 -0
- package/dist/clis/xiaohongshu/creator-note-detail.js +88 -0
- package/dist/clis/xiaohongshu/creator-notes.d.ts +11 -0
- package/dist/clis/xiaohongshu/creator-notes.js +109 -0
- package/dist/clis/xiaohongshu/creator-profile.d.ts +10 -0
- package/dist/clis/xiaohongshu/creator-profile.js +54 -0
- package/dist/clis/xiaohongshu/creator-stats.d.ts +10 -0
- package/dist/clis/xiaohongshu/creator-stats.js +74 -0
- package/dist/clis/xiaohongshu/download.d.ts +7 -0
- package/dist/clis/xiaohongshu/download.js +155 -0
- package/dist/clis/xiaohongshu/search.js +1 -1
- package/dist/clis/xiaohongshu/user-helpers.d.ts +15 -0
- package/dist/clis/xiaohongshu/user-helpers.js +67 -0
- package/dist/clis/xiaohongshu/user-helpers.test.d.ts +1 -0
- package/dist/clis/xiaohongshu/user-helpers.test.js +81 -0
- package/dist/clis/xiaohongshu/user.js +46 -29
- package/dist/clis/zhihu/download.d.ts +11 -0
- package/dist/clis/zhihu/download.js +186 -0
- package/dist/clis/zhihu/download.test.d.ts +1 -0
- package/dist/clis/zhihu/download.test.js +10 -0
- package/dist/daemon.d.ts +13 -0
- package/dist/daemon.js +187 -0
- package/dist/doctor.d.ts +27 -61
- package/dist/doctor.js +70 -601
- package/dist/doctor.test.js +30 -170
- package/dist/download/index.d.ts +79 -0
- package/dist/download/index.js +325 -0
- package/dist/download/progress.d.ts +36 -0
- package/dist/download/progress.js +111 -0
- package/dist/engine.test.js +15 -0
- package/dist/main.js +22 -28
- package/dist/pipeline/executor.test.js +1 -0
- package/dist/pipeline/registry.js +2 -0
- package/dist/pipeline/steps/browser.js +2 -2
- package/dist/pipeline/steps/download.d.ts +34 -0
- package/dist/pipeline/steps/download.js +251 -0
- package/dist/pipeline/steps/intercept.js +1 -2
- package/dist/pipeline/template.js +28 -0
- package/dist/setup.d.ts +6 -0
- package/dist/setup.js +46 -160
- package/dist/types.d.ts +6 -0
- package/extension/icons/icon-128.png +0 -0
- package/extension/icons/icon-16.png +0 -0
- package/extension/icons/icon-32.png +0 -0
- package/extension/icons/icon-48.png +0 -0
- package/extension/manifest.json +31 -0
- package/extension/package.json +16 -0
- package/extension/src/background.ts +293 -0
- package/extension/src/cdp.ts +125 -0
- package/extension/src/protocol.ts +57 -0
- package/extension/store-assets/screenshot-1280x800.png +0 -0
- package/extension/tsconfig.json +15 -0
- package/extension/vite.config.ts +18 -0
- package/package.json +8 -7
- package/scripts/test-site.mjs +70 -0
- package/src/browser/daemon-client.ts +113 -0
- package/src/browser/discover.ts +18 -216
- package/src/browser/errors.ts +30 -100
- package/src/browser/index.ts +6 -12
- package/src/browser/mcp.ts +78 -278
- package/src/browser/page.ts +222 -88
- package/src/browser.test.ts +3 -210
- package/src/build-manifest.test.ts +28 -0
- package/src/build-manifest.ts +147 -57
- package/src/clis/bilibili/download.ts +161 -0
- package/src/clis/chatgpt/README.md +1 -1
- package/src/clis/chatgpt/README.zh-CN.md +1 -1
- package/src/clis/chatwise/README.md +38 -0
- package/src/clis/chatwise/README.zh-CN.md +38 -0
- package/src/clis/chatwise/ask.ts +87 -0
- package/src/clis/chatwise/export.ts +51 -0
- package/src/clis/chatwise/history.ts +47 -0
- package/src/clis/chatwise/model.ts +87 -0
- package/src/clis/chatwise/new.ts +21 -0
- package/src/clis/chatwise/read.ts +42 -0
- package/src/clis/chatwise/screenshot.ts +33 -0
- package/src/clis/chatwise/send.ts +50 -0
- package/src/clis/chatwise/status.ts +25 -0
- package/src/clis/discord-app/README.md +28 -0
- package/src/clis/discord-app/README.zh-CN.md +28 -0
- package/src/clis/discord-app/channels.ts +48 -0
- package/src/clis/discord-app/members.ts +41 -0
- package/src/clis/discord-app/read.ts +49 -0
- package/src/clis/discord-app/search.ts +64 -0
- package/src/clis/discord-app/send.ts +32 -0
- package/src/clis/discord-app/servers.ts +39 -0
- package/src/clis/discord-app/status.ts +18 -0
- package/src/clis/feishu/README.md +20 -0
- package/src/clis/feishu/README.zh-CN.md +20 -0
- package/src/clis/feishu/new.ts +32 -0
- package/src/clis/feishu/read.ts +48 -0
- package/src/clis/feishu/search.ts +35 -0
- package/src/clis/feishu/send.ts +46 -0
- package/src/clis/feishu/status.ts +34 -0
- package/src/clis/grok/ask.ts +90 -0
- package/src/clis/grok/debug.ts +49 -0
- package/src/clis/jimeng/generate.yaml +84 -0
- package/src/clis/jimeng/history.yaml +47 -0
- package/src/clis/linux-do/categories.yaml +41 -0
- package/src/clis/linux-do/category.yaml +49 -0
- package/src/clis/linux-do/hot.yaml +50 -0
- package/src/clis/linux-do/latest.yaml +40 -0
- package/src/clis/linux-do/search.yaml +45 -0
- package/src/clis/linux-do/topic.yaml +38 -0
- package/src/clis/neteasemusic/README.md +31 -0
- package/src/clis/neteasemusic/README.zh-CN.md +31 -0
- package/src/clis/neteasemusic/like.ts +28 -0
- package/src/clis/neteasemusic/lyrics.ts +53 -0
- package/src/clis/neteasemusic/next.ts +30 -0
- package/src/clis/neteasemusic/play.ts +30 -0
- package/src/clis/neteasemusic/playing.ts +62 -0
- package/src/clis/neteasemusic/playlist.ts +51 -0
- package/src/clis/neteasemusic/prev.ts +29 -0
- package/src/clis/neteasemusic/search.ts +58 -0
- package/src/clis/neteasemusic/status.ts +18 -0
- package/src/clis/neteasemusic/volume.ts +61 -0
- package/src/clis/notion/README.md +29 -0
- package/src/clis/notion/README.zh-CN.md +29 -0
- package/src/clis/notion/export.ts +36 -0
- package/src/clis/notion/favorites.ts +87 -0
- package/src/clis/notion/new.ts +39 -0
- package/src/clis/notion/read.ts +33 -0
- package/src/clis/notion/search.ts +54 -0
- package/src/clis/notion/sidebar.ts +44 -0
- package/src/clis/notion/status.ts +18 -0
- package/src/clis/notion/write.ts +45 -0
- package/src/clis/twitter/download.ts +227 -0
- package/src/clis/wechat/README.md +28 -0
- package/src/clis/wechat/README.zh-CN.md +28 -0
- package/src/clis/wechat/chats.ts +33 -0
- package/src/clis/wechat/contacts.ts +33 -0
- package/src/clis/wechat/read.ts +72 -0
- package/src/clis/wechat/search.ts +36 -0
- package/src/clis/wechat/send.ts +49 -0
- package/src/clis/wechat/status.ts +35 -0
- package/src/clis/xiaohongshu/creator-note-detail.ts +95 -0
- package/src/clis/xiaohongshu/creator-notes.ts +116 -0
- package/src/clis/xiaohongshu/creator-profile.ts +60 -0
- package/src/clis/xiaohongshu/creator-stats.ts +81 -0
- package/src/clis/xiaohongshu/download.ts +173 -0
- package/src/clis/xiaohongshu/search.ts +1 -1
- package/src/clis/xiaohongshu/user-helpers.test.ts +106 -0
- package/src/clis/xiaohongshu/user-helpers.ts +85 -0
- package/src/clis/xiaohongshu/user.ts +52 -32
- package/src/clis/zhihu/download.test.ts +12 -0
- package/src/clis/zhihu/download.ts +223 -0
- package/src/daemon.ts +217 -0
- package/src/doctor.test.ts +32 -193
- package/src/doctor.ts +74 -668
- package/src/download/index.ts +395 -0
- package/src/download/progress.ts +125 -0
- package/src/engine.test.ts +17 -0
- package/src/main.ts +18 -26
- package/src/pipeline/executor.test.ts +1 -0
- package/src/pipeline/registry.ts +2 -0
- package/src/pipeline/steps/browser.ts +2 -2
- package/src/pipeline/steps/download.ts +310 -0
- package/src/pipeline/steps/intercept.ts +1 -2
- package/src/pipeline/template.ts +26 -0
- package/src/setup.ts +47 -183
- package/src/types.ts +1 -0
- package/tests/e2e/browser-auth.test.ts +25 -0
package/CONTRIBUTING.md
ADDED
|
@@ -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 ·
|
|
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**: >=
|
|
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
|
|
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
|
-
###
|
|
54
|
+
### Browser Bridge Extension Setup
|
|
55
55
|
|
|
56
|
-
1. Install **
|
|
57
|
-
|
|
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
|
-
|
|
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 #
|
|
72
|
-
> opencli doctor --live # Also test live browser
|
|
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
|
-
|
|
147
|
-
|
|
148
|
-
| Site | Commands |
|
|
149
|
-
|
|
150
|
-
| **twitter** | `trending` `bookmarks` `profile` `search` `timeline` `thread` `following` `followers` `notifications` `post` `reply` `delete` `like` `article` `follow` `unfollow` `bookmark` `unbookmark`
|
|
151
|
-
| **reddit** | `hot` `frontpage` `popular` `search` `subreddit` `read` `user` `user-posts` `user-comments` `upvote` `save` `comment` `subscribe` `saved` `upvoted` |
|
|
152
|
-
| **
|
|
153
|
-
| **
|
|
154
|
-
| **codex** | `status` `send` `read` `new` `extract-diff` `model` `ask` `screenshot` `history` `export` |
|
|
155
|
-
| **
|
|
156
|
-
| **
|
|
157
|
-
| **
|
|
158
|
-
| **
|
|
159
|
-
| **
|
|
160
|
-
| **
|
|
161
|
-
| **
|
|
162
|
-
| **
|
|
163
|
-
| **
|
|
164
|
-
| **
|
|
165
|
-
| **
|
|
166
|
-
| **
|
|
167
|
-
| **
|
|
168
|
-
| **
|
|
169
|
-
| **
|
|
170
|
-
| **
|
|
171
|
-
| **
|
|
172
|
-
| **
|
|
173
|
-
| **
|
|
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
|
|
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
|
-
- **"
|
|
235
|
-
- Ensure the
|
|
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
|
|
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 >=
|
|
241
|
-
- **
|
|
242
|
-
-
|
|
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
|
|