@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
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
name: "🐛 Bug Report"
|
|
2
|
+
description: Report a bug or unexpected behavior in OpenCLI
|
|
3
|
+
title: "[Bug]: "
|
|
4
|
+
labels: ["bug"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for taking the time to report a bug. A short reproduction and any error output are usually enough.
|
|
10
|
+
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: description
|
|
13
|
+
attributes:
|
|
14
|
+
label: Description
|
|
15
|
+
description: A clear and concise description of the bug.
|
|
16
|
+
placeholder: What happened?
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: steps
|
|
22
|
+
attributes:
|
|
23
|
+
label: Steps to Reproduce
|
|
24
|
+
description: How can we reproduce this behavior?
|
|
25
|
+
value: |
|
|
26
|
+
1. Run `opencli ...`
|
|
27
|
+
2. ...
|
|
28
|
+
3. See error
|
|
29
|
+
validations:
|
|
30
|
+
required: true
|
|
31
|
+
|
|
32
|
+
- type: textarea
|
|
33
|
+
id: expected
|
|
34
|
+
attributes:
|
|
35
|
+
label: Expected Behavior
|
|
36
|
+
description: What did you expect to happen?
|
|
37
|
+
validations:
|
|
38
|
+
required: true
|
|
39
|
+
|
|
40
|
+
- type: input
|
|
41
|
+
id: version
|
|
42
|
+
attributes:
|
|
43
|
+
label: OpenCLI Version
|
|
44
|
+
description: "Run `opencli --version` to find out."
|
|
45
|
+
placeholder: "0.8.0"
|
|
46
|
+
validations:
|
|
47
|
+
required: true
|
|
48
|
+
|
|
49
|
+
- type: dropdown
|
|
50
|
+
id: node-version
|
|
51
|
+
attributes:
|
|
52
|
+
label: Node.js Version
|
|
53
|
+
options:
|
|
54
|
+
- "20.x"
|
|
55
|
+
- "22.x"
|
|
56
|
+
- Other
|
|
57
|
+
validations:
|
|
58
|
+
required: true
|
|
59
|
+
|
|
60
|
+
- type: dropdown
|
|
61
|
+
id: os
|
|
62
|
+
attributes:
|
|
63
|
+
label: Operating System
|
|
64
|
+
options:
|
|
65
|
+
- macOS
|
|
66
|
+
- Linux
|
|
67
|
+
- Windows
|
|
68
|
+
- Other
|
|
69
|
+
validations:
|
|
70
|
+
required: true
|
|
71
|
+
|
|
72
|
+
- type: textarea
|
|
73
|
+
id: logs
|
|
74
|
+
attributes:
|
|
75
|
+
label: Logs / Screenshots
|
|
76
|
+
description: |
|
|
77
|
+
Paste any relevant error output. Run with `-v` for verbose logs:
|
|
78
|
+
```
|
|
79
|
+
opencli <command> -v
|
|
80
|
+
```
|
|
81
|
+
render: shell
|
|
82
|
+
validations:
|
|
83
|
+
required: false
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
blank_issues_enabled: true
|
|
2
|
+
contact_links:
|
|
3
|
+
- name: 📖 Documentation
|
|
4
|
+
url: https://github.com/jackwener/opencli#readme
|
|
5
|
+
about: Check the README and docs before opening an issue.
|
|
6
|
+
- name: 🧪 Testing Guide
|
|
7
|
+
url: https://github.com/jackwener/opencli/blob/main/TESTING.md
|
|
8
|
+
about: How to run and write tests for OpenCLI.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: "✨ Feature Request"
|
|
2
|
+
description: Suggest a new feature or improvement
|
|
3
|
+
title: "[Feature]: "
|
|
4
|
+
labels: ["enhancement"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Have an idea to make OpenCLI better? We'd love to hear it!
|
|
10
|
+
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: description
|
|
13
|
+
attributes:
|
|
14
|
+
label: Feature Description
|
|
15
|
+
description: A clear and concise description of the feature you'd like.
|
|
16
|
+
validations:
|
|
17
|
+
required: true
|
|
18
|
+
|
|
19
|
+
- type: textarea
|
|
20
|
+
id: use-case
|
|
21
|
+
attributes:
|
|
22
|
+
label: Use Case
|
|
23
|
+
description: What problem does this solve? Who benefits from this feature?
|
|
24
|
+
placeholder: "As a user, I want to ... so that ..."
|
|
25
|
+
validations:
|
|
26
|
+
required: true
|
|
27
|
+
|
|
28
|
+
- type: textarea
|
|
29
|
+
id: proposed-solution
|
|
30
|
+
attributes:
|
|
31
|
+
label: Proposed Solution
|
|
32
|
+
description: If you have a specific implementation in mind, describe it here.
|
|
33
|
+
validations:
|
|
34
|
+
required: false
|
|
35
|
+
|
|
36
|
+
- type: textarea
|
|
37
|
+
id: alternatives
|
|
38
|
+
attributes:
|
|
39
|
+
label: Alternatives Considered
|
|
40
|
+
description: Any alternative approaches you've thought about?
|
|
41
|
+
validations:
|
|
42
|
+
required: false
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
name: "🌐 New Site Adapter Request"
|
|
2
|
+
description: Request support for a new website
|
|
3
|
+
title: "[Site]: "
|
|
4
|
+
labels: ["new-adapter"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Want OpenCLI to support a new site? Tell us about it!
|
|
10
|
+
|
|
11
|
+
- type: input
|
|
12
|
+
id: site-name
|
|
13
|
+
attributes:
|
|
14
|
+
label: Site Name
|
|
15
|
+
description: The name of the website.
|
|
16
|
+
placeholder: "e.g. Product Hunt"
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: input
|
|
21
|
+
id: site-url
|
|
22
|
+
attributes:
|
|
23
|
+
label: Site URL
|
|
24
|
+
description: The main URL of the website.
|
|
25
|
+
placeholder: "https://www.producthunt.com"
|
|
26
|
+
validations:
|
|
27
|
+
required: true
|
|
28
|
+
|
|
29
|
+
- type: textarea
|
|
30
|
+
id: commands
|
|
31
|
+
attributes:
|
|
32
|
+
label: Desired Commands
|
|
33
|
+
description: What commands would you like? List them with a brief description.
|
|
34
|
+
value: |
|
|
35
|
+
- `hot` — trending / popular items
|
|
36
|
+
- `search` — search the site
|
|
37
|
+
validations:
|
|
38
|
+
required: true
|
|
39
|
+
|
|
40
|
+
- type: textarea
|
|
41
|
+
id: api-examples
|
|
42
|
+
attributes:
|
|
43
|
+
label: Example Links or API Endpoints
|
|
44
|
+
description: Share any example page URLs or API endpoints if you have them (optional).
|
|
45
|
+
placeholder: |
|
|
46
|
+
Example page: https://www.producthunt.com/posts/example
|
|
47
|
+
GET https://api.producthunt.com/v2/posts?order=votes
|
|
48
|
+
Response: { "posts": [{ "name": "...", "tagline": "..." }] }
|
|
49
|
+
validations:
|
|
50
|
+
required: false
|
|
51
|
+
|
|
52
|
+
- type: checkboxes
|
|
53
|
+
id: contribution
|
|
54
|
+
attributes:
|
|
55
|
+
label: Willing to Contribute?
|
|
56
|
+
options:
|
|
57
|
+
- label: I'm willing to submit a PR for this adapter
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
|
|
3
|
+
updates:
|
|
4
|
+
# npm dependencies
|
|
5
|
+
- package-ecosystem: "npm"
|
|
6
|
+
directory: "/"
|
|
7
|
+
schedule:
|
|
8
|
+
interval: "weekly"
|
|
9
|
+
day: "monday"
|
|
10
|
+
open-pull-requests-limit: 10
|
|
11
|
+
labels:
|
|
12
|
+
- "dependencies"
|
|
13
|
+
commit-message:
|
|
14
|
+
prefix: "chore(deps)"
|
|
15
|
+
|
|
16
|
+
# GitHub Actions
|
|
17
|
+
- package-ecosystem: "github-actions"
|
|
18
|
+
directory: "/"
|
|
19
|
+
schedule:
|
|
20
|
+
interval: "weekly"
|
|
21
|
+
day: "monday"
|
|
22
|
+
open-pull-requests-limit: 5
|
|
23
|
+
labels:
|
|
24
|
+
- "dependencies"
|
|
25
|
+
- "ci"
|
|
26
|
+
commit-message:
|
|
27
|
+
prefix: "chore(ci)"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
## Description
|
|
2
|
+
|
|
3
|
+
<!-- Briefly describe your changes and link to any related issues. -->
|
|
4
|
+
|
|
5
|
+
Related issue:
|
|
6
|
+
|
|
7
|
+
## Type of Change
|
|
8
|
+
|
|
9
|
+
- [ ] 🐛 Bug fix
|
|
10
|
+
- [ ] ✨ New feature
|
|
11
|
+
- [ ] 🌐 New site adapter
|
|
12
|
+
- [ ] 📝 Documentation
|
|
13
|
+
- [ ] ♻️ Refactor
|
|
14
|
+
- [ ] 🔧 CI / build / tooling
|
|
15
|
+
|
|
16
|
+
## Checklist
|
|
17
|
+
|
|
18
|
+
- [ ] I ran the checks relevant to this PR
|
|
19
|
+
- [ ] I updated tests or docs if needed
|
|
20
|
+
- [ ] I included output or screenshots when useful
|
|
21
|
+
|
|
22
|
+
## Screenshots / Output
|
|
23
|
+
|
|
24
|
+
<!-- If applicable, paste CLI output or screenshots here. -->
|
package/.github/workflows/ci.yml
CHANGED
|
@@ -9,14 +9,18 @@ on:
|
|
|
9
9
|
- cron: '0 8 * * 1' # Weekly Monday 08:00 UTC — smoke tests
|
|
10
10
|
workflow_dispatch:
|
|
11
11
|
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ci-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
12
16
|
jobs:
|
|
13
17
|
# ── Fast gate: typecheck + build ──
|
|
14
18
|
build:
|
|
15
19
|
runs-on: ubuntu-latest
|
|
16
20
|
steps:
|
|
17
|
-
- uses: actions/checkout@
|
|
21
|
+
- uses: actions/checkout@v6
|
|
18
22
|
|
|
19
|
-
- uses: actions/setup-node@
|
|
23
|
+
- uses: actions/setup-node@v6
|
|
20
24
|
with:
|
|
21
25
|
node-version: '22'
|
|
22
26
|
cache: 'npm'
|
|
@@ -34,20 +38,22 @@ jobs:
|
|
|
34
38
|
unit-test:
|
|
35
39
|
runs-on: ubuntu-latest
|
|
36
40
|
strategy:
|
|
41
|
+
fail-fast: false
|
|
37
42
|
matrix:
|
|
43
|
+
node-version: ['20', '22']
|
|
38
44
|
shard: [1, 2]
|
|
39
45
|
steps:
|
|
40
|
-
- uses: actions/checkout@
|
|
46
|
+
- uses: actions/checkout@v6
|
|
41
47
|
|
|
42
|
-
- uses: actions/setup-node@
|
|
48
|
+
- uses: actions/setup-node@v6
|
|
43
49
|
with:
|
|
44
|
-
node-version:
|
|
50
|
+
node-version: ${{ matrix.node-version }}
|
|
45
51
|
cache: 'npm'
|
|
46
52
|
|
|
47
53
|
- name: Install dependencies
|
|
48
54
|
run: npm ci
|
|
49
55
|
|
|
50
|
-
- name: Run unit tests (shard ${{ matrix.shard }}/2)
|
|
56
|
+
- name: Run unit tests (Node ${{ matrix.node-version }}, shard ${{ matrix.shard }}/2)
|
|
51
57
|
run: npx vitest run src/ --reporter=verbose --shard=${{ matrix.shard }}/2
|
|
52
58
|
|
|
53
59
|
# ── Smoke tests (scheduled / manual only) ──
|
|
@@ -56,9 +62,9 @@ jobs:
|
|
|
56
62
|
needs: build
|
|
57
63
|
runs-on: ubuntu-latest
|
|
58
64
|
steps:
|
|
59
|
-
- uses: actions/checkout@
|
|
65
|
+
- uses: actions/checkout@v6
|
|
60
66
|
|
|
61
|
-
- uses: actions/setup-node@
|
|
67
|
+
- uses: actions/setup-node@v6
|
|
62
68
|
with:
|
|
63
69
|
node-version: '22'
|
|
64
70
|
cache: 'npm'
|
|
@@ -7,14 +7,18 @@ on:
|
|
|
7
7
|
branches: [main, dev]
|
|
8
8
|
workflow_dispatch:
|
|
9
9
|
|
|
10
|
+
concurrency:
|
|
11
|
+
group: e2e-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
10
14
|
jobs:
|
|
11
15
|
e2e-headed:
|
|
12
16
|
runs-on: ubuntu-latest
|
|
13
17
|
timeout-minutes: 20
|
|
14
18
|
steps:
|
|
15
|
-
- uses: actions/checkout@
|
|
19
|
+
- uses: actions/checkout@v6
|
|
16
20
|
|
|
17
|
-
- uses: actions/setup-node@
|
|
21
|
+
- uses: actions/setup-node@v6
|
|
18
22
|
with:
|
|
19
23
|
node-version: '22'
|
|
20
24
|
cache: 'npm'
|
|
@@ -13,9 +13,9 @@ jobs:
|
|
|
13
13
|
if: ${{ vars.PKG_PR_NEW_ENABLED == 'true' }}
|
|
14
14
|
runs-on: ubuntu-latest
|
|
15
15
|
steps:
|
|
16
|
-
- uses: actions/checkout@
|
|
16
|
+
- uses: actions/checkout@v6
|
|
17
17
|
|
|
18
|
-
- uses: actions/setup-node@
|
|
18
|
+
- uses: actions/setup-node@v6
|
|
19
19
|
with:
|
|
20
20
|
node-version: '22'
|
|
21
21
|
cache: 'npm'
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Release Please
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: write
|
|
9
|
+
pull-requests: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
release-please:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- name: Ensure release-please token is configured
|
|
16
|
+
run: |
|
|
17
|
+
if [ -z "${{ secrets.RELEASE_PLEASE_TOKEN }}" ]; then
|
|
18
|
+
echo "RELEASE_PLEASE_TOKEN secret is required so release PRs can trigger downstream CI workflows." >&2
|
|
19
|
+
exit 1
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
- uses: googleapis/release-please-action@v4
|
|
23
|
+
with:
|
|
24
|
+
release-type: node
|
|
25
|
+
token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
|
|
@@ -13,9 +13,9 @@ jobs:
|
|
|
13
13
|
release:
|
|
14
14
|
runs-on: ubuntu-latest
|
|
15
15
|
steps:
|
|
16
|
-
- uses: actions/checkout@
|
|
16
|
+
- uses: actions/checkout@v6
|
|
17
17
|
|
|
18
|
-
- uses: actions/setup-node@
|
|
18
|
+
- uses: actions/setup-node@v6
|
|
19
19
|
with:
|
|
20
20
|
node-version: '22'
|
|
21
21
|
registry-url: 'https://registry.npmjs.org'
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: Security Audit
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main, dev]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main, dev]
|
|
8
|
+
schedule:
|
|
9
|
+
- cron: '0 9 * * 1' # Weekly Monday 09:00 UTC
|
|
10
|
+
|
|
11
|
+
permissions:
|
|
12
|
+
contents: read
|
|
13
|
+
|
|
14
|
+
concurrency:
|
|
15
|
+
group: security-${{ github.ref }}
|
|
16
|
+
cancel-in-progress: true
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
audit:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
steps:
|
|
22
|
+
- uses: actions/checkout@v6
|
|
23
|
+
|
|
24
|
+
- uses: actions/setup-node@v6
|
|
25
|
+
with:
|
|
26
|
+
node-version: '22'
|
|
27
|
+
cache: 'npm'
|
|
28
|
+
|
|
29
|
+
- name: Install dependencies
|
|
30
|
+
run: npm ci
|
|
31
|
+
|
|
32
|
+
- name: npm audit (production)
|
|
33
|
+
run: npm audit --omit=dev --audit-level=high
|
|
34
|
+
|
|
35
|
+
- name: Check for known vulnerabilities
|
|
36
|
+
run: npx --yes audit-ci@^7 --high --skip-dev
|
package/CDP.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Connecting OpenCLI via CDP (Remote/Headless Servers)
|
|
2
2
|
|
|
3
|
-
If you cannot use the
|
|
3
|
+
If you cannot use the opencli Browser Bridge extension (e.g., in a remote headless server environment without a UI), OpenCLI provides an alternative: connecting directly to Chrome via **CDP (Chrome DevTools Protocol)**.
|
|
4
4
|
|
|
5
5
|
Because CDP binds to `localhost` by default for security reasons, accessing it from a remote server requires an additional networking tunnel.
|
|
6
6
|
|
package/CDP.zh-CN.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 通过 CDP 远程连接 OpenCLI (服务器/无头环境)
|
|
2
2
|
|
|
3
|
-
如果你无法使用
|
|
3
|
+
如果你无法使用 opencli Browser Bridge 浏览器扩展(例如:在无界面的远程服务器上运行 OpenCLI 时),OpenCLI 提供了备选方案:通过连接 **CDP (Chrome DevTools Protocol,即 Chrome 开发者工具协议)** 来直接控制本地 Chrome。
|
|
4
4
|
|
|
5
5
|
出于安全考虑,CDP 默认仅绑定在 `localhost` 的本地端口。所以,若是想让**远程服务器**调用本地的 CDP 服务,我们需要依靠一层额外的网络隧道。
|
|
6
6
|
|
package/CLI-ELECTRON.md
CHANGED
|
@@ -4,30 +4,51 @@ description: How to CLI-ify and automate any Electron Desktop Application via CD
|
|
|
4
4
|
|
|
5
5
|
# CLI-ifying Electron Applications (Skill Guide)
|
|
6
6
|
|
|
7
|
-
Based on the successful
|
|
7
|
+
Based on the successful automation of **Cursor**, **Codex**, **Antigravity**, **ChatWise**, **Notion**, and **Discord** desktop apps, this guide serves as the standard operating procedure (SOP) for adapting ANY Electron-based application into an OpenCLI adapter.
|
|
8
8
|
|
|
9
|
-
##
|
|
10
|
-
Electron 应用本质上是运行在本地的 Chromium 浏览器实例。只要在启动应用时暴露了调试端口(CDP,Chrome DevTools Protocol),我们就可以利用 Playwright MCP 直接穿透其 UI 层,获取并操控包括 React/Vue 组件、Shadow DOM 等在内的所有底层状态,实现“从应用外挂入自动化脚本”。
|
|
9
|
+
## Core Concept
|
|
11
10
|
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
Electron apps are essentially local Chromium browser instances. By exposing a debugging port (CDP — Chrome DevTools Protocol) at launch time, we can use the Browser Bridge to pierce through the UI layer, accessing and controlling all underlying state including React/Vue components and Shadow DOM.
|
|
12
|
+
|
|
13
|
+
> **Note:** Not all desktop apps are Electron. WeChat (native Cocoa) and Feishu/Lark (custom Lark Framework) embed Chromium but do NOT expose CDP. For those apps, use the AppleScript + clipboard approach instead (see [Non-Electron Pattern](#non-electron-pattern-applescript)).
|
|
14
|
+
|
|
15
|
+
### Launching the Target App
|
|
14
16
|
```bash
|
|
15
17
|
/Applications/AppName.app/Contents/MacOS/AppName --remote-debugging-port=9222
|
|
16
18
|
```
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
### Verifying Electron
|
|
21
|
+
```bash
|
|
22
|
+
# Check for Electron Framework in the app bundle
|
|
23
|
+
ls /Applications/AppName.app/Contents/Frameworks/Electron\ Framework.framework
|
|
24
|
+
# If this directory exists → Electron → CDP works
|
|
25
|
+
# If not → check for libEGL.dylib (embedded Chromium/CEF, CDP may not work)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## The 5-Command Pattern (CDP / Electron)
|
|
19
29
|
|
|
20
|
-
|
|
30
|
+
Every new Electron adapter should implement these 5 commands in `src/clis/<app_name>/`:
|
|
21
31
|
|
|
22
|
-
### 1. `status.ts`
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
### 1. `status.ts` — Connection Test
|
|
33
|
+
```typescript
|
|
34
|
+
export const statusCommand = cli({
|
|
35
|
+
site: 'myapp',
|
|
36
|
+
name: 'status',
|
|
37
|
+
domain: 'localhost',
|
|
38
|
+
strategy: Strategy.UI,
|
|
39
|
+
browser: true, // Requires CDP connection
|
|
40
|
+
args: [],
|
|
41
|
+
columns: ['Status', 'Url', 'Title'],
|
|
42
|
+
func: async (page: IPage) => {
|
|
43
|
+
const url = await page.evaluate('window.location.href');
|
|
44
|
+
const title = await page.evaluate('document.title');
|
|
45
|
+
return [{ Status: 'Connected', Url: url, Title: title }];
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
```
|
|
27
49
|
|
|
28
|
-
### 2. `dump.ts`
|
|
29
|
-
|
|
30
|
-
首先编写 dump 脚本,将当前页面的 DOM 与 Accessibility Tree 导出到 `/tmp/`,方便用 AI (或者 `grep`) 提取精确的容器名称和 Class。
|
|
50
|
+
### 2. `dump.ts` — Reverse Engineering Core
|
|
51
|
+
Modern app DOMs are huge and obfuscated. **Never guess selectors.** Dump first, then extract precise class names with AI or `grep`:
|
|
31
52
|
```typescript
|
|
32
53
|
const dom = await page.evaluate('document.body.innerHTML');
|
|
33
54
|
fs.writeFileSync('/tmp/app-dom.html', dom);
|
|
@@ -35,38 +56,70 @@ const snap = await page.snapshot({ interactive: false });
|
|
|
35
56
|
fs.writeFileSync('/tmp/app-snapshot.json', JSON.stringify(snap, null, 2));
|
|
36
57
|
```
|
|
37
58
|
|
|
38
|
-
### 3. `send.ts`
|
|
39
|
-
Electron
|
|
40
|
-
|
|
59
|
+
### 3. `send.ts` — Advanced Text Injection
|
|
60
|
+
Electron apps often use complex rich-text editors (Monaco, Lexical, ProseMirror). Setting `.value` directly is ignored by React state.
|
|
61
|
+
|
|
62
|
+
**Best practice:** Use `document.execCommand('insertText')` to perfectly simulate real user input, fully piercing React state:
|
|
41
63
|
```javascript
|
|
42
|
-
|
|
43
|
-
let composer = document.querySelector('[contenteditable="true"]');
|
|
64
|
+
const composer = document.querySelector('[contenteditable="true"]');
|
|
44
65
|
composer.focus();
|
|
45
|
-
document.execCommand('insertText', false,
|
|
66
|
+
document.execCommand('insertText', false, 'Hello');
|
|
46
67
|
```
|
|
47
|
-
|
|
68
|
+
Then submit with `await page.pressKey('Enter')`.
|
|
48
69
|
|
|
49
|
-
### 4. `read.ts`
|
|
50
|
-
|
|
51
|
-
-
|
|
52
|
-
-
|
|
70
|
+
### 4. `read.ts` — Context Extraction
|
|
71
|
+
Don't extract the entire page text. Use `dump.ts` output to find the real "conversation container":
|
|
72
|
+
- Look for semantic selectors: `[role="log"]`, `[data-testid="conversation"]`, `[data-content-search-turn-key]`
|
|
73
|
+
- Format output as Markdown — readable by both humans and LLMs
|
|
53
74
|
|
|
54
|
-
### 5. `new.ts`
|
|
55
|
-
|
|
56
|
-
- **最佳实践**: 模拟系统级快捷键直接驱动 `(Meta+N / Control+N)`。
|
|
75
|
+
### 5. `new.ts` — Keyboard Shortcuts
|
|
76
|
+
Many GUI actions respond to native shortcuts rather than button clicks:
|
|
57
77
|
```typescript
|
|
58
78
|
const isMac = process.platform === 'darwin';
|
|
59
79
|
await page.pressKey(isMac ? 'Meta+N' : 'Control+N');
|
|
60
|
-
await page.wait(1); //
|
|
80
|
+
await page.wait(1); // Wait for re-render
|
|
61
81
|
```
|
|
62
82
|
|
|
63
|
-
##
|
|
64
|
-
为了让 Core Framework 挂载到我们指定的端口,必须在执行指令前(或在 README 中指导用户)注入目标环境端口:
|
|
83
|
+
## Environment Variable
|
|
65
84
|
```bash
|
|
66
85
|
export OPENCLI_CDP_ENDPOINT="http://127.0.0.1:9222"
|
|
67
86
|
```
|
|
68
87
|
|
|
69
|
-
##
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
88
|
+
## Non-Electron Pattern (AppleScript)
|
|
89
|
+
|
|
90
|
+
For native macOS apps (WeChat, Feishu) that don't expose CDP:
|
|
91
|
+
```typescript
|
|
92
|
+
export const statusCommand = cli({
|
|
93
|
+
site: 'myapp',
|
|
94
|
+
strategy: Strategy.PUBLIC,
|
|
95
|
+
browser: false, // No browser needed
|
|
96
|
+
func: async (page: IPage | null) => {
|
|
97
|
+
const output = execSync("osascript -e 'application \"MyApp\" is running'", { encoding: 'utf-8' }).trim();
|
|
98
|
+
return [{ Status: output === 'true' ? 'Running' : 'Stopped' }];
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Core techniques:
|
|
104
|
+
- **status**: `osascript -e 'application "AppName" is running'`
|
|
105
|
+
- **send**: `pbcopy` → activate window → `Cmd+V` → `Enter`
|
|
106
|
+
- **read**: `Cmd+A` → `Cmd+C` → `pbpaste`
|
|
107
|
+
- **search**: Activate → `Cmd+F`/`Cmd+K` → `keystroke "query"`
|
|
108
|
+
|
|
109
|
+
## Pitfalls & Gotchas
|
|
110
|
+
|
|
111
|
+
1. **Port conflicts (EADDRINUSE)**: Only one app per port. Use unique ports: Codex=9222, ChatGPT=9224, Cursor=9226, ChatWise=9228, Notion=9230, Discord=9232
|
|
112
|
+
2. **IPage abstraction**: OpenCLI wraps the browser page as `IPage` (`src/types.ts`). Use `page.pressKey()` and `page.evaluate()`, NOT direct DOM APIs
|
|
113
|
+
3. **Timing**: Always add `await page.wait(0.5)` to `1.0` after DOM mutations. Returning too early disconnects prematurely
|
|
114
|
+
4. **AppleScript requires Accessibility**: Terminal app must be granted permission in System Settings → Privacy & Security → Accessibility
|
|
115
|
+
|
|
116
|
+
## Port Assignment Table
|
|
117
|
+
|
|
118
|
+
| App | Port | Mode |
|
|
119
|
+
|-----|------|------|
|
|
120
|
+
| Codex | 9222 | CDP |
|
|
121
|
+
| ChatGPT | 9224 | CDP / AppleScript |
|
|
122
|
+
| Cursor | 9226 | CDP |
|
|
123
|
+
| ChatWise | 9228 | CDP |
|
|
124
|
+
| Notion | 9230 | CDP |
|
|
125
|
+
| Discord App | 9232 | CDP |
|
package/CLI-EXPLORER.md
CHANGED
|
@@ -9,12 +9,12 @@
|
|
|
9
9
|
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
## AI Agent
|
|
12
|
+
## AI Agent 开发者必读:用浏览器探索
|
|
13
13
|
|
|
14
14
|
> [!CAUTION]
|
|
15
|
-
> **你(AI Agent
|
|
15
|
+
> **你(AI Agent)必须通过浏览器打开目标网站去探索!**
|
|
16
16
|
> 不要只靠 `opencli explore` 命令或静态分析来发现 API。
|
|
17
|
-
>
|
|
17
|
+
> 你拥有浏览器工具,必须主动用它们浏览网页、观察网络请求、模拟用户交互。
|
|
18
18
|
|
|
19
19
|
### 为什么?
|
|
20
20
|
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
| ❌ 错误做法 | ✅ 正确做法 |
|
|
38
38
|
|------------|------------|
|
|
39
|
-
| 只用 `opencli explore` 命令,等结果自动出来 |
|
|
39
|
+
| 只用 `opencli explore` 命令,等结果自动出来 | 用浏览器工具打开页面,主动浏览 |
|
|
40
40
|
| 直接在代码里 `fetch(url)`,不看浏览器实际请求 | 先在浏览器中确认 API 可用,再写代码 |
|
|
41
41
|
| 页面打开后直接抓包,期望所有 API 都出现 | 模拟点击交互(展开评论/切换标签/加载更多) |
|
|
42
42
|
| 遇到 HTTP 200 但空数据就放弃 | 检查是否需要 Wbi 签名或 Cookie 鉴权 |
|