@jackwener/opencli 0.9.4 → 0.9.5

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/README.md CHANGED
@@ -143,25 +143,20 @@ npm install -g @jackwener/opencli@latest
143
143
 
144
144
  ## Built-in Commands
145
145
 
146
- **19 sites · 80+ commands** — run `opencli list` for the live registry.
146
+ **26 sites · 119 commands** — run `opencli list` for the live registry.
147
147
 
148
148
  | Site | Commands | Count | Mode |
149
149
  |------|----------|:-----:|------|
150
150
  | **twitter** | `trending` `bookmarks` `profile` `search` `timeline` `thread` `following` `followers` `notifications` `post` `reply` `delete` `like` `article` `follow` `unfollow` `bookmark` `unbookmark` | 18 | 🔐 Browser |
151
151
  | **reddit** | `hot` `frontpage` `popular` `search` `subreddit` `read` `user` `user-posts` `user-comments` `upvote` `save` `comment` `subscribe` `saved` `upvoted` | 15 | 🔐 Browser |
152
- | **antigravity** | `status` `send` `read` `new` `evaluate` | 5 | 🖥️ Desktop |
153
- | **bbc** | `news` | 1 | 🌐 Public |
154
152
  | **bilibili** | `hot` `search` `me` `favorite` `history` `feed` `subtitle` `dynamic` `ranking` `following` `user-videos` | 11 | 🔐 Browser |
155
- | **boss** | `search` `detail` | 2 | 🔐 Browser |
153
+ | **cursor** | `status` `send` `read` `new` `dump` `composer` `model` `extract-code` | 8 | 🖥️ Desktop |
156
154
  | **codex** | `status` `send` `read` `new` `extract-diff` `model` | 6 | 🖥️ Desktop |
157
- | **coupang** | `search` `add-to-cart` | 2 | 🔐 Browser |
158
- | **ctrip** | `search` | 1 | 🔐 Browser |
159
- | **cursor** | `status` `send` `read` `new` `dump` `composer` `model` | 7 | 🖥️ Desktop |
160
- | **github** | `search` | 1 | 🌐 Public |
161
- | **hackernews** | `top` | 1 | 🌐 Public |
162
155
  | **v2ex** | `hot` `latest` `topic` `daily` `me` `notifications` | 6 | 🌐 / 🔐 |
163
156
  | **xueqiu** | `feed` `hot-stock` `hot` `search` `stock` `watchlist` | 6 | 🔐 Browser |
157
+ | **antigravity** | `status` `send` `read` `new` `evaluate` | 5 | 🖥️ Desktop |
164
158
  | **xiaohongshu** | `search` `notifications` `feed` `me` `user` | 5 | 🔐 Browser |
159
+ | **chatgpt** | `status` `new` `send` `read` | 4 | 🖥️ Desktop |
165
160
  | **xiaoyuzhou** | `podcast` `podcast-episodes` `episode` | 3 | 🌐 Public |
166
161
  | **youtube** | `search` `video` `transcript` | 3 | 🔐 Browser |
167
162
  | **zhihu** | `hot` `search` `question` | 3 | 🔐 Browser |
package/README.zh-CN.md CHANGED
@@ -144,15 +144,16 @@ npm install -g @jackwener/opencli@latest
144
144
 
145
145
  ## 内置命令
146
146
 
147
- **19 个站点 · 80+ 命令** — 运行 `opencli list` 查看完整注册表。
147
+ **26 个站点 · 119 命令** — 运行 `opencli list` 查看完整注册表。
148
148
 
149
149
  | 站点 | 命令 | 数量 | 模式 |
150
150
  |------|------|:----:|------|
151
151
  | **twitter** | `trending` `bookmarks` `profile` `search` `timeline` `thread` `following` `followers` `notifications` `post` `reply` `delete` `like` `article` `follow` `unfollow` `bookmark` `unbookmark` | 18 | 🔐 浏览器 |
152
152
  | **reddit** | `hot` `frontpage` `popular` `search` `subreddit` `read` `user` `user-posts` `user-comments` `upvote` `save` `comment` `subscribe` `saved` `upvoted` | 15 | 🔐 浏览器 |
153
153
  | **antigravity** | `status` `send` `read` `new` `evaluate` | 5 | 🖥️ 桌面端 |
154
+ | **chatgpt** | `status` `new` `send` `read` | 4 | 🖥️ 桌面端 |
154
155
  | **codex** | `status` `send` `read` `new` `extract-diff` `model` | 6 | 🖥️ 桌面端 |
155
- | **cursor** | `status` `send` `read` `new` `dump` `composer` `model` | 7 | 🖥️ 桌面端 |
156
+ | **cursor** | `status` `send` `read` `new` `dump` `composer` `model` `extract-code` | 8 | 🖥️ 桌面端 |
156
157
  | **bilibili** | `hot` `search` `me` `favorite` `history` `feed` `subtitle` `dynamic` `ranking` `following` `user-videos` | 11 | 🔐 浏览器 |
157
158
  | **v2ex** | `hot` `latest` `topic` `daily` `me` `notifications` | 6 | 🌐 / 🔐 |
158
159
  | **xueqiu** | `feed` `hot-stock` `hot` `search` `stock` `watchlist` | 6 | 🔐 浏览器 |
@@ -810,6 +810,71 @@
810
810
  "url"
811
811
  ]
812
812
  },
813
+ {
814
+ "site": "chatgpt",
815
+ "name": "new",
816
+ "description": "Open a new chat in ChatGPT Desktop App",
817
+ "strategy": "public",
818
+ "browser": false,
819
+ "args": [],
820
+ "type": "ts",
821
+ "modulePath": "chatgpt/new.js",
822
+ "domain": "localhost",
823
+ "columns": [
824
+ "Status"
825
+ ]
826
+ },
827
+ {
828
+ "site": "chatgpt",
829
+ "name": "read",
830
+ "description": "Copy the most recent ChatGPT Desktop App response to clipboard and read it",
831
+ "strategy": "public",
832
+ "browser": false,
833
+ "args": [],
834
+ "type": "ts",
835
+ "modulePath": "chatgpt/read.js",
836
+ "domain": "localhost",
837
+ "columns": [
838
+ "Role",
839
+ "Text"
840
+ ]
841
+ },
842
+ {
843
+ "site": "chatgpt",
844
+ "name": "send",
845
+ "description": "Send a message to the active ChatGPT Desktop App window",
846
+ "strategy": "public",
847
+ "browser": false,
848
+ "args": [
849
+ {
850
+ "name": "text",
851
+ "type": "str",
852
+ "required": true,
853
+ "positional": true,
854
+ "help": "Message to send"
855
+ }
856
+ ],
857
+ "type": "ts",
858
+ "modulePath": "chatgpt/send.js",
859
+ "domain": "localhost",
860
+ "columns": [
861
+ "Status"
862
+ ]
863
+ },
864
+ {
865
+ "site": "chatgpt",
866
+ "name": "status",
867
+ "description": "Check if ChatGPT Desktop App is running natively on macOS",
868
+ "strategy": "public",
869
+ "browser": false,
870
+ "args": [],
871
+ "type": "ts",
872
+ "modulePath": "chatgpt/status.js",
873
+ "domain": "localhost",
874
+ "columns": [
875
+ "Status"
876
+ ]
877
+ },
813
878
  {
814
879
  "site": "codex",
815
880
  "name": "dump",
@@ -0,0 +1 @@
1
+ export declare const newCommand: import("../../registry.js").CliCommand;
@@ -0,0 +1,23 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { cli, Strategy } from '../../registry.js';
3
+ export const newCommand = cli({
4
+ site: 'chatgpt',
5
+ name: 'new',
6
+ description: 'Open a new chat in ChatGPT Desktop App',
7
+ domain: 'localhost',
8
+ strategy: Strategy.PUBLIC,
9
+ browser: false,
10
+ args: [],
11
+ columns: ['Status'],
12
+ func: async (page) => {
13
+ try {
14
+ execSync("osascript -e 'tell application \"ChatGPT\" to activate'");
15
+ execSync("osascript -e 'delay 0.5'");
16
+ execSync("osascript -e 'tell application \"System Events\" to keystroke \"n\" using command down'");
17
+ return [{ Status: 'Success' }];
18
+ }
19
+ catch (err) {
20
+ return [{ Status: "Error: " + err.message }];
21
+ }
22
+ },
23
+ });
@@ -0,0 +1 @@
1
+ export declare const readCommand: import("../../registry.js").CliCommand;
@@ -0,0 +1,28 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { cli, Strategy } from '../../registry.js';
3
+ export const readCommand = cli({
4
+ site: 'chatgpt',
5
+ name: 'read',
6
+ description: 'Copy the most recent ChatGPT Desktop App response to clipboard and read it',
7
+ domain: 'localhost',
8
+ strategy: Strategy.PUBLIC,
9
+ browser: false,
10
+ args: [],
11
+ columns: ['Role', 'Text'],
12
+ func: async (page) => {
13
+ try {
14
+ execSync("osascript -e 'tell application \"ChatGPT\" to activate'");
15
+ execSync("osascript -e 'delay 0.5'");
16
+ execSync("osascript -e 'tell application \"System Events\" to keystroke \"c\" using {command down, shift down}'");
17
+ execSync("osascript -e 'delay 0.3'");
18
+ const result = execSync('pbpaste', { encoding: 'utf-8' }).trim();
19
+ if (!result) {
20
+ return [{ Role: 'System', Text: 'No text was copied. Is there a response in the chat?' }];
21
+ }
22
+ return [{ Role: 'Assistant', Text: result }];
23
+ }
24
+ catch (err) {
25
+ throw new Error("Failed to read from ChatGPT: " + err.message);
26
+ }
27
+ },
28
+ });
@@ -0,0 +1 @@
1
+ export declare const sendCommand: import("../../registry.js").CliCommand;
@@ -0,0 +1,31 @@
1
+ import { execSync, spawnSync } from 'node:child_process';
2
+ import { cli, Strategy } from '../../registry.js';
3
+ export const sendCommand = cli({
4
+ site: 'chatgpt',
5
+ name: 'send',
6
+ description: 'Send a message to the active ChatGPT Desktop App window',
7
+ domain: 'localhost',
8
+ strategy: Strategy.PUBLIC,
9
+ browser: false,
10
+ args: [{ name: 'text', required: true, positional: true, help: 'Message to send' }],
11
+ columns: ['Status'],
12
+ func: async (page, kwargs) => {
13
+ const text = kwargs.text;
14
+ try {
15
+ spawnSync('pbcopy', { input: text });
16
+ execSync("osascript -e 'tell application \"ChatGPT\" to activate'");
17
+ execSync("osascript -e 'delay 0.5'");
18
+ const cmd = "osascript " +
19
+ "-e 'tell application \"System Events\"' " +
20
+ "-e 'keystroke \"v\" using command down' " +
21
+ "-e 'delay 0.2' " +
22
+ "-e 'keystroke return' " +
23
+ "-e 'end tell'";
24
+ execSync(cmd);
25
+ return [{ Status: 'Success' }];
26
+ }
27
+ catch (err) {
28
+ return [{ Status: "Error: " + err.message }];
29
+ }
30
+ },
31
+ });
@@ -0,0 +1 @@
1
+ export declare const statusCommand: import("../../registry.js").CliCommand;
@@ -0,0 +1,21 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { cli, Strategy } from '../../registry.js';
3
+ export const statusCommand = cli({
4
+ site: 'chatgpt',
5
+ name: 'status',
6
+ description: 'Check if ChatGPT Desktop App is running natively on macOS',
7
+ domain: 'localhost',
8
+ strategy: Strategy.PUBLIC,
9
+ browser: false,
10
+ args: [],
11
+ columns: ['Status'],
12
+ func: async (page) => {
13
+ try {
14
+ const output = execSync("osascript -e 'application \"ChatGPT\" is running'", { encoding: 'utf-8' }).trim();
15
+ return [{ Status: output === 'true' ? 'Running' : 'Stopped' }];
16
+ }
17
+ catch {
18
+ return [{ Status: 'Error querying application state' }];
19
+ }
20
+ },
21
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jackwener/opencli",
3
- "version": "0.9.4",
3
+ "version": "0.9.5",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -0,0 +1,35 @@
1
+ # ChatGPT Desktop Adapter for OpenCLI
2
+
3
+ Control the **ChatGPT macOS Desktop App** directly from the terminal via native AppleScript automation. Unlike Electron-based apps (Antigravity, Codex, Cursor), ChatGPT Desktop is a native macOS application — OpenCLI drives it using `osascript` and System Events.
4
+
5
+ ## Prerequisites
6
+
7
+ 1. Install the official [ChatGPT Desktop App](https://openai.com/chatgpt/mac/) from OpenAI.
8
+ 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.
9
+
10
+ ## Setup
11
+
12
+ No extra environment variables needed — the adapter uses `osascript` directly.
13
+
14
+ ## Commands
15
+
16
+ ### Diagnostics
17
+ - `opencli chatgpt status`: Check if the ChatGPT app is currently running.
18
+
19
+ ### Chat Manipulation
20
+ - `opencli chatgpt new`: Activate ChatGPT and press `Cmd+N` to start a new conversation.
21
+ - `opencli chatgpt send "message"`: Copy your message to clipboard, activate ChatGPT, paste, and submit.
22
+ - `opencli chatgpt read`: Copy the last AI response via `Cmd+Shift+C` and return it as text.
23
+
24
+ ## How It Works
25
+
26
+ Unlike CDP-based adapters, this adapter:
27
+ - Uses `osascript` to send AppleScript commands to System Events
28
+ - Leverages `pbcopy`/`pbpaste` for clipboard-based text transfer
29
+ - Requires no remote debugging port — works with the stock app
30
+
31
+ ## Limitations
32
+
33
+ - macOS only (AppleScript dependency)
34
+ - Requires Accessibility permissions for keystroke simulation
35
+ - `read` command copies the last response — earlier messages need manual scroll
@@ -0,0 +1,35 @@
1
+ # ChatGPT 桌面端适配器
2
+
3
+ 通过原生 AppleScript 自动化,在终端中直接控制 **ChatGPT macOS 桌面应用**。与基于 Electron 的应用(Antigravity、Codex、Cursor)不同,ChatGPT Desktop 是原生 macOS 应用 — OpenCLI 使用 `osascript` 和 System Events 来驱动它。
4
+
5
+ ## 前置条件
6
+
7
+ 1. 安装官方 [ChatGPT Desktop App](https://openai.com/chatgpt/mac/)。
8
+ 2. 在 **系统设置 → 隐私与安全性 → 辅助功能** 中为终端应用(Terminal / iTerm / Warp)授予 **辅助功能权限**。这是 System Events 按键模拟所必需的。
9
+
10
+ ## 配置
11
+
12
+ 无需额外环境变量 — 适配器直接使用 `osascript`。
13
+
14
+ ## 命令
15
+
16
+ ### 诊断
17
+ - `opencli chatgpt status`:检查 ChatGPT 应用是否在运行。
18
+
19
+ ### 对话操作
20
+ - `opencli chatgpt new`:激活 ChatGPT 并按 `Cmd+N` 开始新对话。
21
+ - `opencli chatgpt send "消息"`:将消息复制到剪贴板,激活 ChatGPT,粘贴并提交。
22
+ - `opencli chatgpt read`:通过 `Cmd+Shift+C` 复制最后一条 AI 回复并返回文本。
23
+
24
+ ## 工作原理
25
+
26
+ 与基于 CDP 的适配器不同,此适配器:
27
+ - 使用 `osascript` 向 System Events 发送 AppleScript 命令
28
+ - 利用 `pbcopy`/`pbpaste` 进行基于剪贴板的文本传输
29
+ - 无需远程调试端口 — 直接与原生应用交互
30
+
31
+ ## 限制
32
+
33
+ - 仅支持 macOS(AppleScript 依赖)
34
+ - 需要辅助功能权限以模拟按键
35
+ - `read` 命令复制最后一条回复 — 更早的消息需要手动滚动
@@ -0,0 +1,24 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { cli, Strategy } from '../../registry.js';
3
+ import type { IPage } from '../../types.js';
4
+
5
+ export const newCommand = cli({
6
+ site: 'chatgpt',
7
+ name: 'new',
8
+ description: 'Open a new chat in ChatGPT Desktop App',
9
+ domain: 'localhost',
10
+ strategy: Strategy.PUBLIC,
11
+ browser: false,
12
+ args: [],
13
+ columns: ['Status'],
14
+ func: async (page: IPage | null) => {
15
+ try {
16
+ execSync("osascript -e 'tell application \"ChatGPT\" to activate'");
17
+ execSync("osascript -e 'delay 0.5'");
18
+ execSync("osascript -e 'tell application \"System Events\" to keystroke \"n\" using command down'");
19
+ return [{ Status: 'Success' }];
20
+ } catch (err: any) {
21
+ return [{ Status: "Error: " + err.message }];
22
+ }
23
+ },
24
+ });
@@ -0,0 +1,32 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { cli, Strategy } from '../../registry.js';
3
+ import type { IPage } from '../../types.js';
4
+
5
+ export const readCommand = cli({
6
+ site: 'chatgpt',
7
+ name: 'read',
8
+ description: 'Copy the most recent ChatGPT Desktop App response to clipboard and read it',
9
+ domain: 'localhost',
10
+ strategy: Strategy.PUBLIC,
11
+ browser: false,
12
+ args: [],
13
+ columns: ['Role', 'Text'],
14
+ func: async (page: IPage | null) => {
15
+ try {
16
+ execSync("osascript -e 'tell application \"ChatGPT\" to activate'");
17
+ execSync("osascript -e 'delay 0.5'");
18
+ execSync("osascript -e 'tell application \"System Events\" to keystroke \"c\" using {command down, shift down}'");
19
+ execSync("osascript -e 'delay 0.3'");
20
+
21
+ const result = execSync('pbpaste', { encoding: 'utf-8' }).trim();
22
+
23
+ if (!result) {
24
+ return [{ Role: 'System', Text: 'No text was copied. Is there a response in the chat?' }];
25
+ }
26
+
27
+ return [{ Role: 'Assistant', Text: result }];
28
+ } catch (err: any) {
29
+ throw new Error("Failed to read from ChatGPT: " + err.message);
30
+ }
31
+ },
32
+ });
@@ -0,0 +1,36 @@
1
+ import { execSync, spawnSync } from 'node:child_process';
2
+ import { cli, Strategy } from '../../registry.js';
3
+ import type { IPage } from '../../types.js';
4
+
5
+ export const sendCommand = cli({
6
+ site: 'chatgpt',
7
+ name: 'send',
8
+ description: 'Send a message to the active ChatGPT Desktop App window',
9
+ domain: 'localhost',
10
+ strategy: Strategy.PUBLIC,
11
+ browser: false,
12
+ args: [{ name: 'text', required: true, positional: true, help: 'Message to send' }],
13
+ columns: ['Status'],
14
+ func: async (page: IPage | null, kwargs: any) => {
15
+ const text = kwargs.text as string;
16
+ try {
17
+ spawnSync('pbcopy', { input: text });
18
+
19
+ execSync("osascript -e 'tell application \"ChatGPT\" to activate'");
20
+ execSync("osascript -e 'delay 0.5'");
21
+
22
+ const cmd = "osascript " +
23
+ "-e 'tell application \"System Events\"' " +
24
+ "-e 'keystroke \"v\" using command down' " +
25
+ "-e 'delay 0.2' " +
26
+ "-e 'keystroke return' " +
27
+ "-e 'end tell'";
28
+
29
+ execSync(cmd);
30
+
31
+ return [{ Status: 'Success' }];
32
+ } catch (err: any) {
33
+ return [{ Status: "Error: " + err.message }];
34
+ }
35
+ },
36
+ });
@@ -0,0 +1,22 @@
1
+ import { execSync } from 'node:child_process';
2
+ import { cli, Strategy } from '../../registry.js';
3
+ import type { IPage } from '../../types.js';
4
+
5
+ export const statusCommand = cli({
6
+ site: 'chatgpt',
7
+ name: 'status',
8
+ description: 'Check if ChatGPT Desktop App is running natively on macOS',
9
+ domain: 'localhost',
10
+ strategy: Strategy.PUBLIC,
11
+ browser: false,
12
+ args: [],
13
+ columns: ['Status'],
14
+ func: async (page: IPage | null) => {
15
+ try {
16
+ const output = execSync("osascript -e 'application \"ChatGPT\" is running'", { encoding: 'utf-8' }).trim();
17
+ return [{ Status: output === 'true' ? 'Running' : 'Stopped' }];
18
+ } catch {
19
+ return [{ Status: 'Error querying application state' }];
20
+ }
21
+ },
22
+ });
@@ -31,3 +31,4 @@ export OPENCLI_CODEX_CDP_ENDPOINT="http://127.0.0.1:9222"
31
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
32
  - `opencli codex read`: Extracts the entire current thread history and AI reasoning logs into readable text.
33
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.
@@ -0,0 +1,33 @@
1
+ # Cursor Adapter for OpenCLI
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.
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.
@@ -0,0 +1,33 @@
1
+ # Cursor 适配器
2
+
3
+ 通过 Chrome DevTools Protocol (CDP) 在终端中控制 **Cursor IDE**。由于 Cursor 基于 Electron(VS Code 分支),OpenCLI 可以驱动其内部 UI,自动化 Composer 交互,操控聊天会话。
4
+
5
+ ## 前置条件
6
+
7
+ 1. 安装 [Cursor](https://cursor.sh/)。
8
+ 2. 通过远程调试端口启动:
9
+ ```bash
10
+ /Applications/Cursor.app/Contents/MacOS/Cursor --remote-debugging-port=9226
11
+ ```
12
+
13
+ ## 配置
14
+
15
+ ```bash
16
+ export OPENCLI_CDP_ENDPOINT="http://127.0.0.1:9226"
17
+ ```
18
+
19
+ ## 命令
20
+
21
+ ### 诊断
22
+ - `opencli cursor status`:检查 CDP 连接状态。
23
+ - `opencli cursor dump`:导出完整 DOM 和 Accessibility 快照到 `/tmp/cursor-dom.html` 和 `/tmp/cursor-snapshot.json`。
24
+
25
+ ### 对话操作
26
+ - `opencli cursor new`:按 `Cmd+N` 创建新文件/标签。
27
+ - `opencli cursor send "消息"`:将文本注入活跃的 Composer/Chat 输入框并提交。
28
+ - `opencli cursor read`:提取当前聊天面板的完整对话历史。
29
+
30
+ ### AI 功能
31
+ - `opencli cursor composer "提示词"`:打开 Composer 面板(`Cmd+I`)并发送提示词进行内联 AI 编辑。
32
+ - `opencli cursor model`:获取当前活跃的 AI 模型(如 `claude-4.5-sonnet`)。
33
+ - `opencli cursor extract-code`:从当前对话中提取所有代码块。