@jackwener/opencli 1.0.5 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/README.md +36 -10
  3. package/README.zh-CN.md +3 -0
  4. package/SKILL.md +7 -2
  5. package/dist/bilibili.js +4 -2
  6. package/dist/cli-manifest.json +506 -6
  7. package/dist/cli.js +51 -1
  8. package/dist/clis/antigravity/serve.js +296 -47
  9. package/dist/clis/arxiv/paper.d.ts +1 -0
  10. package/dist/clis/arxiv/paper.js +21 -0
  11. package/dist/clis/arxiv/search.d.ts +1 -0
  12. package/dist/clis/arxiv/search.js +24 -0
  13. package/dist/clis/arxiv/utils.d.ts +18 -0
  14. package/dist/clis/arxiv/utils.js +49 -0
  15. package/dist/clis/boss/batchgreet.d.ts +1 -0
  16. package/dist/clis/boss/batchgreet.js +147 -0
  17. package/dist/clis/boss/exchange.d.ts +1 -0
  18. package/dist/clis/boss/exchange.js +111 -0
  19. package/dist/clis/boss/greet.d.ts +1 -0
  20. package/dist/clis/boss/greet.js +175 -0
  21. package/dist/clis/boss/invite.d.ts +1 -0
  22. package/dist/clis/boss/invite.js +158 -0
  23. package/dist/clis/boss/joblist.d.ts +1 -0
  24. package/dist/clis/boss/joblist.js +55 -0
  25. package/dist/clis/boss/mark.d.ts +1 -0
  26. package/dist/clis/boss/mark.js +141 -0
  27. package/dist/clis/boss/recommend.d.ts +1 -0
  28. package/dist/clis/boss/recommend.js +83 -0
  29. package/dist/clis/boss/stats.d.ts +1 -0
  30. package/dist/clis/boss/stats.js +116 -0
  31. package/dist/clis/sinafinance/news.d.ts +7 -0
  32. package/dist/clis/sinafinance/news.js +61 -0
  33. package/dist/clis/wikipedia/search.d.ts +1 -0
  34. package/dist/clis/wikipedia/search.js +30 -0
  35. package/dist/clis/wikipedia/summary.d.ts +1 -0
  36. package/dist/clis/wikipedia/summary.js +28 -0
  37. package/dist/clis/wikipedia/utils.d.ts +8 -0
  38. package/dist/clis/wikipedia/utils.js +18 -0
  39. package/dist/clis/xiaohongshu/creator-note-detail.d.ts +64 -5
  40. package/dist/clis/xiaohongshu/creator-note-detail.js +258 -69
  41. package/dist/clis/xiaohongshu/creator-note-detail.test.d.ts +1 -0
  42. package/dist/clis/xiaohongshu/creator-note-detail.test.js +211 -0
  43. package/dist/clis/xiaohongshu/creator-notes-summary.d.ts +28 -0
  44. package/dist/clis/xiaohongshu/creator-notes-summary.js +92 -0
  45. package/dist/clis/xiaohongshu/creator-notes-summary.test.d.ts +1 -0
  46. package/dist/clis/xiaohongshu/creator-notes-summary.test.js +49 -0
  47. package/dist/clis/xiaohongshu/creator-notes.d.ts +18 -5
  48. package/dist/clis/xiaohongshu/creator-notes.js +159 -71
  49. package/dist/clis/xiaohongshu/creator-notes.test.d.ts +1 -0
  50. package/dist/clis/xiaohongshu/creator-notes.test.js +162 -0
  51. package/dist/external.d.ts +20 -0
  52. package/dist/external.js +159 -0
  53. package/docs/.vitepress/config.mts +1 -0
  54. package/docs/public/CNAME +1 -0
  55. package/package.json +1 -1
  56. package/src/bilibili.ts +4 -2
  57. package/src/browser/cdp.ts +3 -3
  58. package/src/cli.ts +56 -1
  59. package/src/clis/antigravity/README.md +3 -46
  60. package/src/clis/antigravity/serve.ts +323 -50
  61. package/src/clis/arxiv/paper.ts +21 -0
  62. package/src/clis/arxiv/search.ts +24 -0
  63. package/src/clis/arxiv/utils.ts +63 -0
  64. package/src/clis/boss/batchgreet.ts +167 -0
  65. package/src/clis/boss/exchange.ts +126 -0
  66. package/src/clis/boss/greet.ts +198 -0
  67. package/src/clis/boss/invite.ts +177 -0
  68. package/src/clis/boss/joblist.ts +63 -0
  69. package/src/clis/boss/mark.ts +155 -0
  70. package/src/clis/boss/recommend.ts +94 -0
  71. package/src/clis/boss/stats.ts +130 -0
  72. package/src/clis/chaoxing/README.md +2 -24
  73. package/src/clis/chatgpt/README.md +3 -42
  74. package/src/clis/chatwise/README.md +3 -36
  75. package/src/clis/codex/README.md +3 -32
  76. package/src/clis/cursor/README.md +3 -31
  77. package/src/clis/discord-app/README.md +2 -25
  78. package/src/clis/feishu/README.md +2 -17
  79. package/src/clis/neteasemusic/README.md +3 -29
  80. package/src/clis/notion/README.md +2 -26
  81. package/src/clis/sinafinance/news.ts +76 -0
  82. package/src/clis/wechat/README.md +2 -25
  83. package/src/clis/wikipedia/search.ts +32 -0
  84. package/src/clis/wikipedia/summary.ts +28 -0
  85. package/src/clis/wikipedia/utils.ts +20 -0
  86. package/src/clis/xiaohongshu/creator-note-detail.test.ts +223 -0
  87. package/src/clis/xiaohongshu/creator-note-detail.ts +340 -72
  88. package/src/clis/xiaohongshu/creator-notes-summary.test.ts +54 -0
  89. package/src/clis/xiaohongshu/creator-notes-summary.ts +120 -0
  90. package/src/clis/xiaohongshu/creator-notes.test.ts +178 -0
  91. package/src/clis/xiaohongshu/creator-notes.ts +215 -75
  92. package/src/daemon.ts +3 -3
  93. package/src/external-clis.yaml +39 -0
  94. package/src/external.ts +182 -0
  95. package/CDP.md +0 -103
  96. package/CDP.zh-CN.md +0 -103
  97. package/CLI-ELECTRON.md +0 -125
@@ -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)
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Sina Finance 7x24 live news feed.
3
+ *
4
+ * Uses the public CJ API — no key or browser required.
5
+ * https://app.cj.sina.com.cn/api/news/pc
6
+ */
7
+
8
+ import { cli, Strategy } from '../../registry.js';
9
+ import { CliError } from '../../errors.js';
10
+
11
+ // User-facing type (0-9) → Sina API tag ID
12
+ const TYPE_MAP = [
13
+ 0, // 0: 全部
14
+ 10, // 1: A股
15
+ 1, // 2: 宏观
16
+ 3, // 3: 公司
17
+ 4, // 4: 数据
18
+ 5, // 5: 市场
19
+ 102, // 6: 国际
20
+ 6, // 7: 观点
21
+ 6, // 8: 央行
22
+ 8, // 9: 其它
23
+ ] as const;
24
+
25
+ interface SinaNewsItem {
26
+ id?: string;
27
+ create_time?: string;
28
+ rich_text?: string;
29
+ view_num?: number;
30
+ }
31
+
32
+ function stripHtml(html: string): string {
33
+ return html.replace(/<[^>]+>/g, '').trim();
34
+ }
35
+
36
+ cli({
37
+ site: 'sinafinance',
38
+ name: 'news',
39
+ description: '新浪财经 7x24 小时实时快讯',
40
+ domain: 'app.cj.sina.com.cn',
41
+ strategy: Strategy.PUBLIC,
42
+ browser: false,
43
+ args: [
44
+ { name: 'limit', type: 'int', default: 20, help: 'Max results (max 50)' },
45
+ { name: 'type', type: 'int', default: 0, help: 'News type: 0=全部 1=A股 2=宏观 3=公司 4=数据 5=市场 6=国际 7=观点 8=央行 9=其它' },
46
+ ],
47
+ columns: ['id', 'time', 'content', 'views'],
48
+ func: async (_page, args) => {
49
+ const limit = Math.max(1, Math.min(Number(args.limit), 50));
50
+ const apiTag = TYPE_MAP[args.type as number] ?? 0;
51
+
52
+ const params = new URLSearchParams({
53
+ page: '1',
54
+ size: String(limit),
55
+ tag: String(apiTag),
56
+ });
57
+
58
+ const res = await fetch(`https://app.cj.sina.com.cn/api/news/pc?${params}`);
59
+ if (!res.ok) {
60
+ throw new CliError('FETCH_ERROR', `Sina Finance API HTTP ${res.status}`, 'Check your network connection');
61
+ }
62
+ const json = await res.json() as { result?: { data?: { feed?: { list?: SinaNewsItem[] } } } };
63
+ const list = json?.result?.data?.feed?.list ?? [];
64
+
65
+ if (!list.length) {
66
+ throw new CliError('NOT_FOUND', 'No news found', 'Try a different type or increase limit');
67
+ }
68
+
69
+ return list.map((item) => ({
70
+ id: item.id ?? '',
71
+ time: item.create_time ?? '',
72
+ content: stripHtml(item.rich_text ?? ''),
73
+ views: item.view_num ?? 0,
74
+ }));
75
+ },
76
+ });
@@ -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)
@@ -0,0 +1,32 @@
1
+ import { cli, Strategy } from '../../registry.js';
2
+ import { CliError } from '../../errors.js';
3
+ import { wikiFetch } from './utils.js';
4
+
5
+ interface WikiSearchResult { title: string; snippet: string; }
6
+
7
+ cli({
8
+ site: 'wikipedia',
9
+ name: 'search',
10
+ description: 'Search Wikipedia articles',
11
+ strategy: Strategy.PUBLIC,
12
+ browser: false,
13
+ args: [
14
+ { name: 'keyword', positional: true, required: true, help: 'Search keyword' },
15
+ { name: 'limit', type: 'int', default: 10, help: 'Max results' },
16
+ { name: 'lang', default: 'en', help: 'Language code (e.g. en, zh, ja)' },
17
+ ],
18
+ columns: ['title', 'snippet', 'url'],
19
+ func: async (_page, args) => {
20
+ const limit = Math.max(1, Math.min(Number(args.limit), 50));
21
+ const lang = args.lang || 'en';
22
+ const q = encodeURIComponent(args.keyword);
23
+ const data = await wikiFetch(lang, `/w/api.php?action=query&list=search&srsearch=${q}&srlimit=${limit}&format=json&utf8=1`) as { query?: { search?: WikiSearchResult[] } };
24
+ const results = data?.query?.search;
25
+ if (!results?.length) throw new CliError('NOT_FOUND', 'No articles found', 'Try a different keyword');
26
+ return results.map((r) => ({
27
+ title: r.title,
28
+ snippet: r.snippet.replace(/<[^>]+>/g, '').slice(0, 120),
29
+ url: `https://${lang}.wikipedia.org/wiki/${encodeURIComponent(r.title.replace(/ /g, '_'))}`,
30
+ }));
31
+ },
32
+ });
@@ -0,0 +1,28 @@
1
+ import { cli, Strategy } from '../../registry.js';
2
+ import { CliError } from '../../errors.js';
3
+ import { wikiFetch } from './utils.js';
4
+
5
+ cli({
6
+ site: 'wikipedia',
7
+ name: 'summary',
8
+ description: 'Get Wikipedia article summary',
9
+ strategy: Strategy.PUBLIC,
10
+ browser: false,
11
+ args: [
12
+ { name: 'title', positional: true, required: true, help: 'Article title (e.g. "Transformer (machine learning model)")' },
13
+ { name: 'lang', default: 'en', help: 'Language code (e.g. en, zh, ja)' },
14
+ ],
15
+ columns: ['title', 'description', 'extract', 'url'],
16
+ func: async (_page, args) => {
17
+ const lang = args.lang || 'en';
18
+ const title = encodeURIComponent(args.title.replace(/ /g, '_'));
19
+ const data = await wikiFetch(lang, `/api/rest_v1/page/summary/${title}`) as { title?: string; description?: string; extract?: string; content_urls?: { desktop?: { page?: string } } };
20
+ if (!data?.title) throw new CliError('NOT_FOUND', `Article "${args.title}" not found`, 'Try searching first: opencli wikipedia search <keyword>');
21
+ return [{
22
+ title: data.title,
23
+ description: data.description ?? '-',
24
+ extract: (data.extract ?? '').slice(0, 300),
25
+ url: data.content_urls?.desktop?.page ?? `https://${lang}.wikipedia.org/wiki/${title}`,
26
+ }];
27
+ },
28
+ });
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Wikipedia adapter utilities.
3
+ *
4
+ * Uses the public MediaWiki REST API and Action API — no key required.
5
+ * REST API: https://en.wikipedia.org/api/rest_v1/
6
+ * Action API: https://en.wikipedia.org/w/api.php
7
+ */
8
+
9
+ import { CliError } from '../../errors.js';
10
+
11
+ export async function wikiFetch(lang: string, path: string): Promise<unknown> {
12
+ const url = `https://${lang}.wikipedia.org${path}`;
13
+ const resp = await fetch(url, {
14
+ headers: { 'User-Agent': 'opencli/1.0 (https://github.com/jackwener/opencli)' },
15
+ });
16
+ if (!resp.ok) {
17
+ throw new CliError('FETCH_ERROR', `Wikipedia API HTTP ${resp.status}`, `Check your title or search term`);
18
+ }
19
+ return resp.json();
20
+ }