@jackwener/opencli 1.0.5 → 1.0.6

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/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ ## [1.0.6](https://github.com/jackwener/opencli/compare/v1.0.5...v1.0.6) (2026-03-20)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * use %20 instead of + for spaces in Bilibili WBI signed requests ([#126](https://github.com/jackwener/opencli/issues/126)) ([4cabca1](https://github.com/jackwener/opencli/commit/4cabca12dfa6ca027b938b80ee6b940b5e89ea5c)), closes [#125](https://github.com/jackwener/opencli/issues/125)
package/README.md CHANGED
@@ -150,16 +150,16 @@ Each desktop adapter has its own detailed documentation with commands reference,
150
150
 
151
151
  | App | Description | Doc |
152
152
  |-----|-------------|-----|
153
- | **Cursor** | Control Cursor IDE — Composer, chat, code extraction | [README](./src/clis/cursor/README.md) |
154
- | **Codex** | Drive OpenAI Codex CLI agent headlessly | [README](./src/clis/codex/README.md) |
155
- | **Antigravity** | Control Antigravity Ultra from terminal | [README](./src/clis/antigravity/README.md) |
156
- | **ChatGPT** | Automate ChatGPT macOS desktop app | [README](./src/clis/chatgpt/README.md) |
157
- | **ChatWise** | Multi-LLM client (GPT-4, Claude, Gemini) | [README](./src/clis/chatwise/README.md) |
158
- | **Notion** | Search, read, write Notion pages | [README](./src/clis/notion/README.md) |
159
- | **Discord** | Discord Desktop — messages, channels, servers | [README](./src/clis/discord-app/README.md) |
160
- | **Feishu** | 飞书/Lark Desktop via AppleScript | [README](./src/clis/feishu/README.md) |
161
- | **WeChat** | 微信 Desktop via AppleScript + Accessibility | [README](./src/clis/wechat/README.md) |
162
- | **NeteaseMusic** | 网易云音乐 Desktop via CEF/CDP | [README](./src/clis/neteasemusic/README.md) |
153
+ | **Cursor** | Control Cursor IDE — Composer, chat, code extraction | [Doc](./docs/adapters/desktop/cursor.md) |
154
+ | **Codex** | Drive OpenAI Codex CLI agent headlessly | [Doc](./docs/adapters/desktop/codex.md) |
155
+ | **Antigravity** | Control Antigravity Ultra from terminal | [Doc](./docs/adapters/desktop/antigravity.md) |
156
+ | **ChatGPT** | Automate ChatGPT macOS desktop app | [Doc](./docs/adapters/desktop/chatgpt.md) |
157
+ | **ChatWise** | Multi-LLM client (GPT-4, Claude, Gemini) | [Doc](./docs/adapters/desktop/chatwise.md) |
158
+ | **Notion** | Search, read, write Notion pages | [Doc](./docs/adapters/desktop/notion.md) |
159
+ | **Discord** | Discord Desktop — messages, channels, servers | [Doc](./docs/adapters/desktop/discord.md) |
160
+ | **Feishu** | 飞书/Lark Desktop via AppleScript | [Doc](./docs/adapters/desktop/feishu.md) |
161
+ | **WeChat** | 微信 Desktop via AppleScript + Accessibility | [Doc](./docs/adapters/desktop/wechat.md) |
162
+ | **NeteaseMusic** | 网易云音乐 Desktop via CEF/CDP | [Doc](./docs/adapters/desktop/neteasemusic.md) |
163
163
 
164
164
  ## Download Support
165
165
 
package/dist/bilibili.js CHANGED
@@ -47,7 +47,9 @@ export async function wbiSign(page, params) {
47
47
  for (const key of Object.keys(allParams).sort()) {
48
48
  sorted[key] = String(allParams[key]).replace(/[!'()*]/g, '');
49
49
  }
50
- const query = new URLSearchParams(sorted).toString();
50
+ // Bilibili WBI verification expects %20 for spaces, not + (URLSearchParams default).
51
+ // Using + causes signature mismatch → CORS-blocked error response → TypeError: Failed to fetch.
52
+ const query = new URLSearchParams(sorted).toString().replace(/\+/g, '%20');
51
53
  const wRid = await md5(query + mixinKey);
52
54
  sorted.w_rid = wRid;
53
55
  return sorted;
@@ -58,7 +60,7 @@ export async function apiGet(page, path, opts = {}) {
58
60
  if (opts.signed) {
59
61
  params = await wbiSign(page, params);
60
62
  }
61
- const qs = new URLSearchParams(Object.fromEntries(Object.entries(params).map(([k, v]) => [k, String(v)])));
63
+ const qs = new URLSearchParams(Object.fromEntries(Object.entries(params).map(([k, v]) => [k, String(v)]))).toString().replace(/\+/g, '%20');
62
64
  const url = `${baseUrl}${path}?${qs}`;
63
65
  return fetchJson(page, url);
64
66
  }
@@ -1,6 +1,7 @@
1
1
  import { defineConfig } from 'vitepress'
2
2
 
3
3
  export default defineConfig({
4
+ base: '/opencli/',
4
5
  title: 'OpenCLI',
5
6
  description: 'Make any website or Electron App your CLI — AI-powered, account-safe, self-healing.',
6
7
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jackwener/opencli",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
package/src/bilibili.ts CHANGED
@@ -60,7 +60,9 @@ export async function wbiSign(
60
60
  for (const key of Object.keys(allParams).sort()) {
61
61
  sorted[key] = String(allParams[key]).replace(/[!'()*]/g, '');
62
62
  }
63
- const query = new URLSearchParams(sorted).toString();
63
+ // Bilibili WBI verification expects %20 for spaces, not + (URLSearchParams default).
64
+ // Using + causes signature mismatch → CORS-blocked error response → TypeError: Failed to fetch.
65
+ const query = new URLSearchParams(sorted).toString().replace(/\+/g, '%20');
64
66
  const wRid = await md5(query + mixinKey);
65
67
  sorted.w_rid = wRid;
66
68
  return sorted;
@@ -78,7 +80,7 @@ export async function apiGet(
78
80
  }
79
81
  const qs = new URLSearchParams(
80
82
  Object.fromEntries(Object.entries(params).map(([k, v]) => [k, String(v)])),
81
- );
83
+ ).toString().replace(/\+/g, '%20');
82
84
  const url = `${baseUrl}${path}?${qs}`;
83
85
  return fetchJson(page, url);
84
86
  }
@@ -1,48 +1,5 @@
1
- # Antigravity CLI Adapter
1
+ # Antigravity Adapter
2
2
 
3
- 🔥 **CLI All Electron Apps! The Most Powerful Update Has Arrived!** 🔥
3
+ Control **Antigravity Ultra** from the terminal via Chrome DevTools Protocol (CDP).
4
4
 
5
- Turn ANY Electron application into a CLI tool! Recombine, script, and extend applications like Antigravity Ultra seamlessly. Now AI can control itself natively. Unlimited possibilities await!
6
-
7
- Turn your local Antigravity desktop application into a programmable AI node via Chrome DevTools Protocol (CDP). This allows you to compose complex LLM workflows entirely through the terminal by manipulating the actual UI natively, bypassing any API restrictions.
8
-
9
- ## Prerequisites
10
-
11
- Start the Antigravity desktop app with the Chrome DevTools `remote-debugging-port` flag:
12
-
13
- \`\`\`bash
14
- # Start Antigravity in the background
15
- /Applications/Antigravity.app/Contents/MacOS/Electron \
16
- --remote-debugging-port=9224
17
- \`\`\`
18
-
19
- *(Note: Depending on your installation, the executable might be named differently, e.g., \`Antigravity\` instead of \`Electron\`.)*
20
-
21
- Next, set the target port in your terminal session to tell OpenCLI where to connect:
22
-
23
- \`\`\`bash
24
- export OPENCLI_CDP_ENDPOINT="http://127.0.0.1:9224"
25
- \`\`\`
26
-
27
- ## Available Commands
28
-
29
- ### \`opencli antigravity status\`
30
- Check the Chromium CDP connection. Returns the current window title and active internal URL.
31
-
32
- ### \`opencli antigravity send <message>\`
33
- Send a text prompt to the AI. Automatically locates the Lexical editor input box, types the prompt securely, and hits Enter.
34
-
35
- ### \`opencli antigravity read\`
36
- Scrape the entire current conversation history block as pure text. Useful for feeding the context to another script.
37
-
38
- ### \`opencli antigravity new\`
39
- Click the "New Conversation" button to instantly clear the UI state and start fresh.
40
-
41
- ### \`opencli antigravity extract-code\`
42
- Extract any multi-line code blocks from the current conversation view. Ideal for automated script extraction (e.g. \`opencli antigravity extract-code > script.sh\`).
43
-
44
- ### \`opencli antigravity model <name>\`
45
- Quickly target and switch the active LLM engine. Example: \`opencli antigravity model claude\` or \`opencli antigravity model gemini\`.
46
-
47
- ### \`opencli antigravity watch\`
48
- A long-running, streaming process that continuously polls the Antigravity UI for chat updates and outputs them in real-time to standard output.
5
+ 📖 **Full documentation**: [docs/adapters/desktop/antigravity](../../../docs/adapters/desktop/antigravity.md)
@@ -2,35 +2,13 @@
2
2
 
3
3
  View your Chaoxing assignments and exams from the terminal by reusing your Chrome login session.
4
4
 
5
- ## Prerequisites
6
-
7
- 1. Chrome must be running and already logged into Chaoxing (`i.chaoxing.com`).
8
- 2. The opencli Browser Bridge extension must be installed.
5
+ 📖 **Full documentation**: See commands and usage below.
9
6
 
10
7
  ## Commands
11
8
 
12
9
  | Command | Description |
13
10
  |---------|-------------|
14
11
  | `opencli chaoxing assignments` | List assignments across all courses |
15
- | `opencli chaoxing assignments --course "数学"` | Filter by course name (fuzzy match) |
16
- | `opencli chaoxing assignments --status pending` | Filter: `all` / `pending` / `submitted` / `graded` |
17
12
  | `opencli chaoxing exams` | List exams across all courses |
18
- | `opencli chaoxing exams --course "数学"` | Filter by course name |
19
- | `opencli chaoxing exams --status upcoming` | Filter: `all` / `upcoming` / `ongoing` / `finished` |
20
-
21
- ## How It Works
22
-
23
- Chaoxing has no flat API for listing assignments/exams. The adapter follows the same
24
- flow a student would in the browser:
25
-
26
- 1. Establish session via the interaction page
27
- 2. Fetch enrolled course list (`backclazzdata` JSON API)
28
- 3. Enter each course via `stucoursemiddle` redirect (obtains session `enc`)
29
- 4. Click the 作业/考试 tab and capture the iframe URL
30
- 5. Navigate to that URL and parse the DOM
31
-
32
- ## Limitations
33
13
 
34
- - Requires `--course` filter for practical use (scanning all 40+ courses is slow)
35
- - Does not submit homework or exams
36
- - If Chaoxing changes page structure, the DOM parser may need updates
14
+ Supports `--course` and `--status` filters. Requires Chrome logged into `i.chaoxing.com` with Browser Bridge extension installed.
@@ -1,44 +1,5 @@
1
- # ChatGPT Desktop Adapter for OpenCLI
1
+ # ChatGPT Adapter
2
2
 
3
- Control the **ChatGPT macOS Desktop App** directly from the terminal. OpenCLI supports two automation approaches for ChatGPT.
3
+ Control the **ChatGPT macOS Desktop App** from the terminal via AppleScript or CDP.
4
4
 
5
- ## Approach 1: AppleScript (Default, No Setup)
6
-
7
- The current built-in commands use native AppleScript automation — no extra launch flags needed.
8
-
9
- ### Prerequisites
10
- 1. Install the official [ChatGPT Desktop App](https://openai.com/chatgpt/mac/) from OpenAI.
11
- 2. Grant **Accessibility permissions** to your terminal app (Terminal / iTerm / Warp) in **System Settings → Privacy & Security → Accessibility**. This is required for System Events keystroke simulation.
12
-
13
- ### Commands
14
- - `opencli chatgpt status`: Check if the ChatGPT app is currently running.
15
- - `opencli chatgpt new`: Activate ChatGPT and press `Cmd+N` to start a new conversation.
16
- - `opencli chatgpt send "message"`: Copy your message to clipboard, activate ChatGPT, paste, and submit.
17
- - `opencli chatgpt read`: Copy the last AI response via `Cmd+Shift+C` and return it as text.
18
-
19
- ## Approach 2: CDP (Advanced, Electron Debug Mode)
20
-
21
- ChatGPT Desktop is also an Electron app and can be launched with a remote debugging port for deeper automation via CDP:
22
-
23
- ```bash
24
- /Applications/ChatGPT.app/Contents/MacOS/ChatGPT \
25
- --remote-debugging-port=9224
26
- ```
27
-
28
- Then set the endpoint:
29
- ```bash
30
- export OPENCLI_CDP_ENDPOINT="http://127.0.0.1:9224"
31
- ```
32
-
33
- > **Note**: The CDP approach enables future advanced commands like DOM inspection, model switching, and code extraction — similar to the Cursor and Codex adapters.
34
-
35
- ## How It Works
36
-
37
- - **AppleScript mode**: Uses `osascript` and `pbcopy`/`pbpaste` for clipboard-based text transfer. No remote debugging port needed.
38
- - **CDP mode**: Connects via Chrome DevTools Protocol to the Electron renderer process for direct DOM manipulation.
39
-
40
- ## Limitations
41
-
42
- - macOS only (AppleScript dependency)
43
- - AppleScript mode requires Accessibility permissions
44
- - `read` command copies the last response — earlier messages need manual scroll
5
+ 📖 **Full documentation**: [docs/adapters/desktop/chatgpt](../../../docs/adapters/desktop/chatgpt.md)
@@ -1,38 +1,5 @@
1
- # ChatWise Adapter for OpenCLI
1
+ # ChatWise Adapter
2
2
 
3
- Control the **ChatWise Desktop App** from the terminal via Chrome DevTools Protocol (CDP). ChatWise is an Electron-based multi-LLM client supporting GPT-4, Claude, Gemini, and more.
3
+ Control the **ChatWise Desktop App** (multi-LLM client) from the terminal via CDP.
4
4
 
5
- ## Prerequisites
6
-
7
- 1. Install [ChatWise](https://chatwise.app/).
8
- 2. Launch with remote debugging port:
9
- ```bash
10
- /Applications/ChatWise.app/Contents/MacOS/ChatWise \
11
- --remote-debugging-port=9228
12
- ```
13
-
14
- ## Setup
15
-
16
- ```bash
17
- export OPENCLI_CDP_ENDPOINT="http://127.0.0.1:9228"
18
- ```
19
-
20
- ## Commands
21
-
22
- ### Diagnostics
23
- - `opencli chatwise status`: Check CDP connection status.
24
- - `opencli chatwise screenshot`: Export DOM + accessibility snapshot.
25
-
26
- ### Chat
27
- - `opencli chatwise new`: Start a new conversation (`Cmd+N`).
28
- - `opencli chatwise send "message"`: Send a message to the active chat.
29
- - `opencli chatwise read`: Read the current conversation.
30
- - `opencli chatwise ask "prompt"`: Send + wait for response + return it (one-shot).
31
-
32
- ### AI Features
33
- - `opencli chatwise model`: Get the current AI model.
34
- - `opencli chatwise model gpt-4`: Switch to a different model.
35
-
36
- ### Organization
37
- - `opencli chatwise history`: List conversations from the sidebar.
38
- - `opencli chatwise export`: Export conversation as Markdown.
5
+ 📖 **Full documentation**: [docs/adapters/desktop/chatwise](../../../docs/adapters/desktop/chatwise.md)
@@ -1,34 +1,5 @@
1
- # OpenAI Codex Adapter for OpenCLI
1
+ # Codex Adapter
2
2
 
3
- Control the **OpenAI Codex Desktop App** headless or headfully via Chrome DevTools Protocol (CDP).
4
- Because Codex is built on Electron, OpenCLI can directly drive its internal UI, automate slash commands, and manipulate its AI agent threads.
3
+ Control the **OpenAI Codex Desktop App** via Chrome DevTools Protocol (CDP).
5
4
 
6
- ## Prerequisites
7
-
8
- 1. You must have the official OpenAI Codex app installed.
9
- 2. Launch it via the terminal and expose the remote debugging port:
10
- ```bash
11
- # macOS
12
- /Applications/Codex.app/Contents/MacOS/Codex --remote-debugging-port=9222
13
- ```
14
-
15
- ## Setup
16
-
17
- Export the CDP endpoint in your shell:
18
- ```bash
19
- export OPENCLI_CODEX_CDP_ENDPOINT="http://127.0.0.1:9222"
20
- ```
21
-
22
- ## Commands
23
-
24
- ### Diagnostics
25
- - `opencli codex status`: Checks connection and reads the current active window URL/title.
26
- - `opencli codex dump`: Dumps the full UI DOM and Accessibility tree into `/tmp` (ideal for building AI automation tools on top of it).
27
-
28
- ### Agent Manipulation
29
- - `opencli codex new`: Simulates `Cmd+N` to start a completely fresh and isolated Git Worktree thread context.
30
- - `opencli codex send "message"`: Robustly finds the active Thread Composer and injects your text.
31
- - *Pro-tip*: You can trigger internal shortcuts by sending them, e.g., `opencli codex send "/review"` or `opencli codex send "$imagegen draw a cat"`.
32
- - `opencli codex read`: Extracts the entire current thread history and AI reasoning logs into readable text.
33
- - `opencli codex extract-diff`: Automatically scrapes any visual Patch chunks and Code Diffs the AI generated inside the review UI.
34
- - `opencli codex model`: Get the currently active AI model.
5
+ 📖 **Full documentation**: [docs/adapters/desktop/codex](../../../docs/adapters/desktop/codex.md)
@@ -1,33 +1,5 @@
1
- # Cursor Adapter for OpenCLI
1
+ # Cursor Adapter
2
2
 
3
- Control the **Cursor IDE** from the terminal via Chrome DevTools Protocol (CDP). Since Cursor is built on Electron (VS Code fork), OpenCLI can drive its internal UI, automate Composer interactions, and manipulate chat sessions.
3
+ Control the **Cursor IDE** from the terminal via Chrome DevTools Protocol (CDP).
4
4
 
5
- ## Prerequisites
6
-
7
- 1. Install [Cursor](https://cursor.sh/).
8
- 2. Launch it with the remote debugging port:
9
- ```bash
10
- /Applications/Cursor.app/Contents/MacOS/Cursor --remote-debugging-port=9226
11
- ```
12
-
13
- ## Setup
14
-
15
- ```bash
16
- export OPENCLI_CDP_ENDPOINT="http://127.0.0.1:9226"
17
- ```
18
-
19
- ## Commands
20
-
21
- ### Diagnostics
22
- - `opencli cursor status`: Check CDP connection status.
23
- - `opencli cursor dump`: Dump the full DOM and Accessibility snapshot to `/tmp/cursor-dom.html` and `/tmp/cursor-snapshot.json`.
24
-
25
- ### Chat Manipulation
26
- - `opencli cursor new`: Press `Cmd+N` to start a new file/tab.
27
- - `opencli cursor send "message"`: Inject text into the active Composer/Chat input and submit.
28
- - `opencli cursor read`: Extract the full conversation history from the active chat panel.
29
-
30
- ### AI Features
31
- - `opencli cursor composer "prompt"`: Open the Composer panel (`Cmd+I`) and send a prompt for inline AI editing.
32
- - `opencli cursor model`: Get the currently active AI model (e.g., `claude-4.5-sonnet`).
33
- - `opencli cursor extract-code`: Extract all code blocks from the current conversation.
5
+ 📖 **Full documentation**: [docs/adapters/desktop/cursor](../../../docs/adapters/desktop/cursor.md)
@@ -1,28 +1,5 @@
1
- # Discord Desktop Adapter
1
+ # Discord Adapter
2
2
 
3
3
  Control the **Discord Desktop App** from the terminal via Chrome DevTools Protocol (CDP).
4
4
 
5
- ## Prerequisites
6
-
7
- Launch with remote debugging port:
8
- ```bash
9
- /Applications/Discord.app/Contents/MacOS/Discord --remote-debugging-port=9232
10
- ```
11
-
12
- ## Setup
13
-
14
- ```bash
15
- export OPENCLI_CDP_ENDPOINT="http://127.0.0.1:9232"
16
- ```
17
-
18
- ## Commands
19
-
20
- | Command | Description |
21
- |---------|-------------|
22
- | `discord status` | Check CDP connection |
23
- | `discord send "message"` | Send a message in the active channel |
24
- | `discord read` | Read recent messages |
25
- | `discord channels` | List channels in the current server |
26
- | `discord servers` | List all joined servers |
27
- | `discord search "query"` | Search messages (Cmd+F) |
28
- | `discord members` | List online members |
5
+ 📖 **Full documentation**: [docs/adapters/desktop/discord](../../../docs/adapters/desktop/discord.md)
@@ -1,20 +1,5 @@
1
- # Feishu (飞书/Lark) Desktop Adapter
1
+ # Feishu (飞书/Lark) Adapter
2
2
 
3
3
  Control **Feishu/Lark Desktop** from the terminal via AppleScript.
4
4
 
5
- > **Note:** Feishu uses a custom `Lark Framework` (Chromium-based but NOT Electron). CDP is not available, so this adapter uses AppleScript + clipboard.
6
-
7
- ## Prerequisites
8
-
9
- 1. Feishu/Lark must be running and logged in
10
- 2. Terminal must have **Accessibility permission**
11
-
12
- ## Commands
13
-
14
- | Command | Description |
15
- |---------|-------------|
16
- | `feishu status` | Check if Feishu/Lark is running |
17
- | `feishu send "msg"` | Send message in active chat (paste + Enter) |
18
- | `feishu read` | Read current chat (Cmd+A → Cmd+C) |
19
- | `feishu search "query"` | Global search (Cmd+K) |
20
- | `feishu new` | New message/document (Cmd+N) |
5
+ 📖 **Full documentation**: [docs/adapters/desktop/feishu](../../../docs/adapters/desktop/feishu.md)
@@ -1,31 +1,5 @@
1
- # NeteaseMusic Desktop Adapter (网易云音乐)
1
+ # NeteaseMusic (网易云音乐) Adapter
2
2
 
3
- Control **NeteaseMusic** (网易云音乐) from the terminal via Chrome DevTools Protocol (CDP). The app uses Chromium Embedded Framework (CEF).
3
+ Control **NeteaseMusic** from the terminal via Chrome DevTools Protocol (CDP/CEF).
4
4
 
5
- ## Prerequisites
6
-
7
- Launch with remote debugging port:
8
- ```bash
9
- /Applications/NeteaseMusic.app/Contents/MacOS/NeteaseMusic --remote-debugging-port=9234
10
- ```
11
-
12
- ## Setup
13
-
14
- ```bash
15
- export OPENCLI_CDP_ENDPOINT="http://127.0.0.1:9234"
16
- ```
17
-
18
- ## Commands
19
-
20
- | Command | Description |
21
- |---------|-------------|
22
- | `neteasemusic status` | Check CDP connection |
23
- | `neteasemusic playing` | Current song info (title, artist, album) |
24
- | `neteasemusic play` | Play / Pause toggle |
25
- | `neteasemusic next` | Skip to next song |
26
- | `neteasemusic prev` | Go to previous song |
27
- | `neteasemusic search "query"` | Search songs, artists |
28
- | `neteasemusic playlist` | Show current playback queue |
29
- | `neteasemusic like` | Like / unlike current song |
30
- | `neteasemusic lyrics` | Get lyrics of current song |
31
- | `neteasemusic volume [0-100]` | Get or set volume |
5
+ 📖 **Full documentation**: [docs/adapters/desktop/neteasemusic](../../../docs/adapters/desktop/neteasemusic.md)
@@ -1,29 +1,5 @@
1
- # Notion Desktop Adapter
1
+ # Notion Adapter
2
2
 
3
3
  Control the **Notion Desktop App** from the terminal via Chrome DevTools Protocol (CDP).
4
4
 
5
- ## Prerequisites
6
-
7
- Launch with remote debugging port:
8
- ```bash
9
- /Applications/Notion.app/Contents/MacOS/Notion --remote-debugging-port=9230
10
- ```
11
-
12
- ## Setup
13
-
14
- ```bash
15
- export OPENCLI_CDP_ENDPOINT="http://127.0.0.1:9230"
16
- ```
17
-
18
- ## Commands
19
-
20
- | Command | Description |
21
- |---------|-------------|
22
- | `notion status` | Check CDP connection |
23
- | `notion search "query"` | Quick Find search (Cmd+P) |
24
- | `notion read` | Read the current page content |
25
- | `notion new "title"` | Create a new page (Cmd+N) |
26
- | `notion write "text"` | Append text to the current page |
27
- | `notion sidebar` | List pages from the sidebar |
28
- | `notion favorites` | List pages from the Favorites section |
29
- | `notion export` | Export page as Markdown |
5
+ 📖 **Full documentation**: [docs/adapters/desktop/notion](../../../docs/adapters/desktop/notion.md)
@@ -1,28 +1,5 @@
1
- # WeChat (微信) Desktop Adapter
1
+ # WeChat (微信) Adapter
2
2
 
3
3
  Control **WeChat Mac Desktop** from the terminal via AppleScript + Accessibility API.
4
4
 
5
- > **Note:** WeChat is a native macOS app (not Electron), so CDP is not available. This adapter uses AppleScript keyboard simulation and clipboard operations.
6
-
7
- ## Prerequisites
8
-
9
- 1. WeChat must be running and logged in
10
- 2. Terminal must have **Accessibility permission** (System Settings → Privacy & Security → Accessibility)
11
-
12
- ## Commands
13
-
14
- | Command | Description |
15
- |---------|-------------|
16
- | `wechat status` | Check if WeChat is running |
17
- | `wechat send "msg"` | Send message in the active chat (clipboard paste + Enter) |
18
- | `wechat read` | Read current chat content (Cmd+A → Cmd+C) |
19
- | `wechat search "keyword"` | Open search and type a query (Cmd+F) |
20
- | `wechat chats` | Switch to Chats tab (Cmd+1) |
21
- | `wechat contacts` | Switch to Contacts tab (Cmd+2) |
22
-
23
- ## Limitations
24
-
25
- - **No CDP support** — WeChat is native Cocoa, not Electron
26
- - `send` requires the correct conversation to be already open
27
- - `read` captures whatever is visible via select-all + copy
28
- - `search` types the query but cannot programmatically click results
5
+ 📖 **Full documentation**: [docs/adapters/desktop/wechat](../../../docs/adapters/desktop/wechat.md)
package/CDP.md DELETED
@@ -1,103 +0,0 @@
1
- # Connecting OpenCLI via CDP (Remote/Headless Servers)
2
-
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
-
5
- Because CDP binds to `localhost` by default for security reasons, accessing it from a remote server requires an additional networking tunnel.
6
-
7
- This guide is broken down into three phases:
8
- 1. **Preparation**: Start Chrome with CDP enabled locally.
9
- 2. **Network Tunnels**: Expose that CDP port to your remote server using either **SSH Tunnels** or **Reverse Proxies**.
10
- 3. **Execution**: Run OpenCLI on your server.
11
-
12
- ---
13
-
14
- ## Phase 1: Preparation (Local Machine)
15
-
16
- First, you need to start a Chrome browser on your local machine with remote debugging enabled.
17
-
18
- **macOS:**
19
- ```bash
20
- /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
21
- --remote-debugging-port=9222 \
22
- --user-data-dir="$HOME/chrome-debug-profile" \
23
- --remote-allow-origins="*"
24
- ```
25
-
26
- **Linux:**
27
- ```bash
28
- google-chrome \
29
- --remote-debugging-port=9222 \
30
- --user-data-dir="$HOME/chrome-debug-profile" \
31
- --remote-allow-origins="*"
32
- ```
33
-
34
- **Windows:**
35
- ```cmd
36
- "C:\Program Files\Google\Chrome\Application\chrome.exe" ^
37
- --remote-debugging-port=9222 ^
38
- --user-data-dir="%USERPROFILE%\chrome-debug-profile" ^
39
- --remote-allow-origins="*"
40
- ```
41
-
42
- > **Note**: The `--remote-allow-origins="*"` flag is often required for modern Chrome versions to accept cross-origin CDP WebSocket connections (e.g. from reverse proxies like ngrok).
43
-
44
- Once this browser instance opens, **log into the target websites you want to use** (e.g., bilibili.com, zhihu.com) so that the session contains the correct cookies.
45
-
46
- ---
47
-
48
- ## Phase 2: Remote Access Methods
49
-
50
- Once CDP is running locally on port `9222`, you must securely expose this port to your remote server. Choose one of the two methods below depending on your network conditions.
51
-
52
- ### Method A: SSH Tunnel (Recommended)
53
-
54
- If your local machine has SSH access to the remote server, this is the most secure and straightforward method.
55
-
56
- Run this command on your **Local Machine** to forward the remote server's port `9222` back to your local port `9222`:
57
-
58
- ```bash
59
- ssh -R 9222:localhost:9222 your-server-user@your-server-ip
60
- ```
61
-
62
- Leave this SSH session running in the background.
63
-
64
- ### Method B: Reverse Proxy (ngrok / frp / socat)
65
-
66
- If you cannot establish a direct SSH connection (e.g., due to NAT or firewalls), you can use an intranet penetration tool like `ngrok`.
67
-
68
- Run this command on your **Local Machine** to expose your local port `9222` to the public internet securely via ngrok:
69
-
70
- ```bash
71
- ngrok http 9222
72
- ```
73
-
74
- This will print a forwarding URL, such as `https://abcdef.ngrok.app`. **Copy this URL**.
75
-
76
- ---
77
-
78
- ## Phase 3: Execution (Remote Server)
79
-
80
- Now switch to your **Remote Server** where OpenCLI is installed.
81
-
82
- Depending on the network tunnel method you chose in Phase 2, set the `OPENCLI_CDP_ENDPOINT` environment variable and run your commands.
83
-
84
- ### If you used Method A (SSH Tunnel):
85
-
86
- ```bash
87
- export OPENCLI_CDP_ENDPOINT="http://localhost:9222"
88
- opencli doctor # Verify connection
89
- opencli bilibili hot --limit 5 # Test a command
90
- ```
91
-
92
- ### If you used Method B (Reverse Proxy like ngrok):
93
-
94
- ```bash
95
- # Use the URL you copied from ngrok earlier
96
- export OPENCLI_CDP_ENDPOINT="https://abcdef.ngrok.app"
97
- opencli doctor # Verify connection
98
- opencli bilibili hot --limit 5 # Test a command
99
- ```
100
-
101
- > *Tip: If you provide a standard HTTP/HTTPS CDP endpoint, OpenCLI requests the `/json` target list and picks the most likely inspectable app/page target automatically. If multiple app targets exist, you can further narrow selection with `OPENCLI_CDP_TARGET` (for example `antigravity` or `codex`).*
102
-
103
- If you plan to use this setup frequently, you can persist the environment variable by adding the `export` line to your `~/.bashrc` or `~/.zshrc` on the server.
package/CDP.zh-CN.md DELETED
@@ -1,103 +0,0 @@
1
- # 通过 CDP 远程连接 OpenCLI (服务器/无头环境)
2
-
3
- 如果你无法使用 opencli Browser Bridge 浏览器扩展(例如:在无界面的远程服务器上运行 OpenCLI 时),OpenCLI 提供了备选方案:通过连接 **CDP (Chrome DevTools Protocol,即 Chrome 开发者工具协议)** 来直接控制本地 Chrome。
4
-
5
- 出于安全考虑,CDP 默认仅绑定在 `localhost` 的本地端口。所以,若是想让**远程服务器**调用本地的 CDP 服务,我们需要依靠一层额外的网络隧道。
6
-
7
- 本指南将整个过程拆分为三个阶段:
8
- 1. **阶段一:准备工作**(在本地启动允许 CDP 调试的 Chrome)。
9
- 2. **阶段二:建立网络隧道**(通过 **SSH反向隧道** 或 **反向代理工具**,将本地的 CDP 端口暴露给服务器)。
10
- 3. **阶段三:执行命令**(在服务器端运行 OpenCLI)。
11
-
12
- ---
13
-
14
- ## 阶段一:准备工作 (本地电脑)
15
-
16
- 首先,你需要在你的本地电脑上,通过命令行参数启动一个开启了远程调试端口的 Chrome 实例。
17
-
18
- **macOS:**
19
- ```bash
20
- /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
21
- --remote-debugging-port=9222 \
22
- --user-data-dir="$HOME/chrome-debug-profile" \
23
- --remote-allow-origins="*"
24
- ```
25
-
26
- **Linux:**
27
- ```bash
28
- google-chrome \
29
- --remote-debugging-port=9222 \
30
- --user-data-dir="$HOME/chrome-debug-profile" \
31
- --remote-allow-origins="*"
32
- ```
33
-
34
- **Windows:**
35
- ```cmd
36
- "C:\Program Files\Google\Chrome\Application\chrome.exe" ^
37
- --remote-debugging-port=9222 ^
38
- --user-data-dir="%USERPROFILE%\chrome-debug-profile" ^
39
- --remote-allow-origins="*"
40
- ```
41
-
42
- > **注意**:此处增加的 `--remote-allow-origins="*"` 参数对于较新版本的 Chrome 来说通常是[必需的],以允许来自反向代理(如 ngrok)的跨域 WebSocket 连接请求。
43
-
44
- 待这个新的浏览器实例打开后,**手工登录那些你打算使用的网站**(如 bilibili.com、zhihu.com 等),这可以让该浏览器的运行资料(Profile)保留上这些网站登录用的 Cookie。
45
-
46
- ---
47
-
48
- ## 阶段二:建立网络隧道
49
-
50
- 现在你的本地已经有了一个监听在 `9222` 端口的 CDP 服务,接下来,选择以下任意一种方式将其实际暴露给你的远端服务器。
51
-
52
- ### 方法 A:SSH 反向端口转发 (推荐)
53
-
54
- 如果你的本地电脑可以直连远程服务器的 SSH,那么这是最简单且最安全的做法。
55
-
56
- 在你的 **本地电脑** 终端上直接运行这条 ssh 命令,将远程服务器的 `9222` 端口反向映射回本地的 `9222` 端口:
57
-
58
- ```bash
59
- ssh -R 9222:localhost:9222 your-server-user@your-server-ip
60
- ```
61
-
62
- 保持此 SSH 会话在后台运行即可。
63
-
64
- ### 方法 B:反向代理 / 内网穿透 (ngrok / frp / socat)
65
-
66
- 如果因为 NAT 或防火墙等因素导致无法直连 SSH 服务器,你可以使用 `ngrok` 等内网穿透工具。
67
-
68
- 在 **本地电脑** 运行 ngrok 将本地的 `9222` 端口暴露到公网:
69
-
70
- ```bash
71
- ngrok http 9222
72
- ```
73
-
74
- 此时终端里会打印出一段专属的转发 URL 地址(如:`https://abcdef.ngrok.app`)。**复制这一段 URL 地址备用**。
75
-
76
- ---
77
-
78
- ## 阶段三:执行命令 (远程服务器)
79
-
80
- 现在,所有的准备工作已结束。请切换到你已安装好 OpenCLI 的 **远程服务器** 终端上。
81
-
82
- 根据你在上方阶段二所选择的隧道方案,在终端中配置对应的 `OPENCLI_CDP_ENDPOINT` 环境变量:
83
-
84
- ### 若使用 方法 A (SSH 反向隧道):
85
-
86
- ```bash
87
- export OPENCLI_CDP_ENDPOINT="http://localhost:9222"
88
- opencli doctor # 查看并验证连接是否通畅
89
- opencli bilibili hot --limit 5 # 执行目标命令
90
- ```
91
-
92
- ### 若使用 方法 B (Ngrok 等反向代理):
93
-
94
- ```bash
95
- # 将刚刚使用 ngrok 得到的地址填入这里
96
- export OPENCLI_CDP_ENDPOINT="https://abcdef.ngrok.app"
97
- opencli doctor # 查看并验证连接是否通畅
98
- opencli bilibili hot --limit 5 # 执行目标命令
99
- ```
100
-
101
- > *Tip: 如果你填写的是一个普通 HTTP/HTTPS 的 CDP 地址,OpenCLI 会自动请求 `/json` target 列表,并挑选最可能的 app/page target;如果同一个端口下暴露了多个应用 target,还可以通过 `OPENCLI_CDP_TARGET`(例如 `antigravity`、`codex`)进一步缩小匹配范围。*
102
-
103
- 如果你想在此服务器上永久启用该配置,可以将对应的 `export` 语句追加进入你的 `~/.bashrc` 或 `~/.zshrc` 配置文件中。
package/CLI-ELECTRON.md DELETED
@@ -1,125 +0,0 @@
1
- ---
2
- description: How to CLI-ify and automate any Electron Desktop Application via CDP
3
- ---
4
-
5
- # CLI-ifying Electron Applications (Skill Guide)
6
-
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
-
9
- ## Core Concept
10
-
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
16
- ```bash
17
- /Applications/AppName.app/Contents/MacOS/AppName --remote-debugging-port=9222
18
- ```
19
-
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)
29
-
30
- Every new Electron adapter should implement these 5 commands in `src/clis/<app_name>/`:
31
-
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
- ```
49
-
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`:
52
- ```typescript
53
- const dom = await page.evaluate('document.body.innerHTML');
54
- fs.writeFileSync('/tmp/app-dom.html', dom);
55
- const snap = await page.snapshot({ interactive: false });
56
- fs.writeFileSync('/tmp/app-snapshot.json', JSON.stringify(snap, null, 2));
57
- ```
58
-
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:
63
- ```javascript
64
- const composer = document.querySelector('[contenteditable="true"]');
65
- composer.focus();
66
- document.execCommand('insertText', false, 'Hello');
67
- ```
68
- Then submit with `await page.pressKey('Enter')`.
69
-
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
74
-
75
- ### 5. `new.ts` — Keyboard Shortcuts
76
- Many GUI actions respond to native shortcuts rather than button clicks:
77
- ```typescript
78
- const isMac = process.platform === 'darwin';
79
- await page.pressKey(isMac ? 'Meta+N' : 'Control+N');
80
- await page.wait(1); // Wait for re-render
81
- ```
82
-
83
- ## Environment Variable
84
- ```bash
85
- export OPENCLI_CDP_ENDPOINT="http://127.0.0.1:9222"
86
- ```
87
-
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 |