@jackwener/opencli 1.0.0 → 1.0.1
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 +20 -1
- package/README.zh-CN.md +20 -1
- package/dist/browser/daemon-client.d.ts +1 -1
- package/dist/browser/index.d.ts +1 -2
- package/dist/browser/index.js +1 -5
- package/dist/browser/mcp.d.ts +5 -8
- package/dist/browser/mcp.js +9 -10
- package/dist/browser/page.d.ts +8 -1
- package/dist/browser/page.js +23 -17
- package/dist/browser.test.js +6 -6
- package/dist/cli-manifest.json +394 -14
- package/dist/clis/apple-podcasts/episodes.d.ts +1 -0
- package/dist/clis/apple-podcasts/episodes.js +28 -0
- package/dist/clis/apple-podcasts/search.d.ts +1 -0
- package/dist/clis/apple-podcasts/search.js +29 -0
- package/dist/clis/apple-podcasts/top.d.ts +1 -0
- package/dist/clis/apple-podcasts/top.js +34 -0
- package/dist/clis/apple-podcasts/utils.d.ts +11 -0
- package/dist/clis/apple-podcasts/utils.js +30 -0
- package/dist/clis/apple-podcasts/utils.test.d.ts +1 -0
- package/dist/clis/apple-podcasts/utils.test.js +57 -0
- package/dist/clis/chatwise/history.js +18 -1
- package/dist/clis/discord-app/channels.js +33 -21
- package/dist/clis/twitter/accept.d.ts +1 -0
- package/dist/clis/twitter/accept.js +202 -0
- package/dist/clis/twitter/followers.js +30 -22
- package/dist/clis/twitter/following.js +19 -14
- package/dist/clis/twitter/notifications.js +29 -22
- package/dist/clis/twitter/reply-dm.d.ts +1 -0
- package/dist/clis/twitter/reply-dm.js +181 -0
- package/dist/clis/twitter/search.js +50 -12
- package/dist/clis/weread/book.d.ts +1 -0
- package/dist/clis/weread/book.js +26 -0
- package/dist/clis/weread/highlights.d.ts +1 -0
- package/dist/clis/weread/highlights.js +23 -0
- package/dist/clis/weread/notebooks.d.ts +1 -0
- package/dist/clis/weread/notebooks.js +21 -0
- package/dist/clis/weread/notes.d.ts +1 -0
- package/dist/clis/weread/notes.js +29 -0
- package/dist/clis/weread/ranking.d.ts +1 -0
- package/dist/clis/weread/ranking.js +28 -0
- package/dist/clis/weread/search.d.ts +1 -0
- package/dist/clis/weread/search.js +25 -0
- package/dist/clis/weread/shelf.d.ts +1 -0
- package/dist/clis/weread/shelf.js +24 -0
- package/dist/clis/weread/utils.d.ts +20 -0
- package/dist/clis/weread/utils.js +72 -0
- package/dist/clis/weread/utils.test.d.ts +1 -0
- package/dist/clis/weread/utils.test.js +85 -0
- package/dist/daemon.js +2 -2
- package/dist/doctor.d.ts +0 -21
- package/dist/doctor.js +2 -24
- package/dist/main.js +6 -16
- package/dist/runtime.d.ts +1 -4
- package/dist/runtime.js +1 -4
- package/dist/setup.js +2 -2
- package/extension/dist/background.js +484 -0
- package/extension/manifest.json +1 -1
- package/extension/package.json +1 -1
- package/extension/src/background.ts +99 -22
- package/extension/src/protocol.ts +1 -1
- package/package.json +1 -1
- package/src/browser/daemon-client.ts +1 -1
- package/src/browser/index.ts +1 -6
- package/src/browser/mcp.ts +14 -15
- package/src/browser/page.ts +23 -17
- package/src/browser.test.ts +6 -6
- package/src/clis/apple-podcasts/episodes.ts +28 -0
- package/src/clis/apple-podcasts/search.ts +29 -0
- package/src/clis/apple-podcasts/top.ts +34 -0
- package/src/clis/apple-podcasts/utils.test.ts +72 -0
- package/src/clis/apple-podcasts/utils.ts +37 -0
- package/src/clis/chatwise/history.ts +15 -1
- package/src/clis/discord-app/channels.ts +33 -21
- package/src/clis/twitter/accept.ts +213 -0
- package/src/clis/twitter/followers.ts +36 -29
- package/src/clis/twitter/following.ts +25 -20
- package/src/clis/twitter/notifications.ts +34 -27
- package/src/clis/twitter/reply-dm.ts +193 -0
- package/src/clis/twitter/search.ts +53 -13
- package/src/clis/weread/book.ts +28 -0
- package/src/clis/weread/highlights.ts +25 -0
- package/src/clis/weread/notebooks.ts +23 -0
- package/src/clis/weread/notes.ts +31 -0
- package/src/clis/weread/ranking.ts +29 -0
- package/src/clis/weread/search.ts +26 -0
- package/src/clis/weread/shelf.ts +26 -0
- package/src/clis/weread/utils.test.ts +104 -0
- package/src/clis/weread/utils.ts +74 -0
- package/src/daemon.ts +2 -2
- package/src/doctor.ts +2 -19
- package/src/main.ts +5 -11
- package/src/runtime.ts +2 -6
- package/src/setup.ts +2 -2
- package/tests/e2e/public-commands.test.ts +68 -1
- package/dist/clis/grok/debug.d.ts +0 -1
- package/dist/clis/grok/debug.js +0 -45
- package/src/clis/grok/debug.ts +0 -49
package/README.md
CHANGED
|
@@ -22,6 +22,7 @@ Turn ANY Electron application into a CLI tool! Recombine, script, and extend app
|
|
|
22
22
|
- [Prerequisites](#prerequisites)
|
|
23
23
|
- [Quick Start](#quick-start)
|
|
24
24
|
- [Built-in Commands](#built-in-commands)
|
|
25
|
+
- [Desktop App Adapters](#desktop-app-adapters)
|
|
25
26
|
- [Download Support](#download-support)
|
|
26
27
|
- [Output Formats](#output-formats)
|
|
27
28
|
- [For AI Agents (Developer Guide)](#for-ai-agents-developer-guide)
|
|
@@ -106,7 +107,7 @@ Run `opencli list` for the live registry.
|
|
|
106
107
|
|
|
107
108
|
| Site | Commands | Mode |
|
|
108
109
|
|------|----------|------|
|
|
109
|
-
| **twitter** | `trending` `bookmarks` `profile` `search` `timeline` `thread` `following` `followers` `notifications` `post` `reply` `delete` `like` `article` `follow` `unfollow` `bookmark` `unbookmark` `download` | 🔐 Browser |
|
|
110
|
+
| **twitter** | `trending` `bookmarks` `profile` `search` `timeline` `thread` `following` `followers` `notifications` `post` `reply` `delete` `like` `article` `follow` `unfollow` `bookmark` `unbookmark` `download` `accept` `reply-dm` | 🔐 Browser |
|
|
110
111
|
| **reddit** | `hot` `frontpage` `popular` `search` `subreddit` `read` `user` `user-posts` `user-comments` `upvote` `save` `comment` `subscribe` `saved` `upvoted` | 🔐 Browser |
|
|
111
112
|
| **cursor** | `status` `send` `read` `new` `dump` `composer` `model` `extract-code` `ask` `screenshot` `history` `export` | 🖥️ Desktop |
|
|
112
113
|
| **bilibili** | `hot` `search` `me` `favorite` `history` `feed` `subtitle` `dynamic` `ranking` `following` `user-videos` `download` | 🔐 Browser |
|
|
@@ -119,6 +120,7 @@ Run `opencli list` for the live registry.
|
|
|
119
120
|
| **antigravity** | `status` `send` `read` `new` `evaluate` | 🖥️ Desktop |
|
|
120
121
|
| **chatgpt** | `status` `new` `send` `read` `ask` | 🖥️ Desktop |
|
|
121
122
|
| **xiaohongshu** | `search` `notifications` `feed` `me` `user` `download` | 🔐 Browser |
|
|
123
|
+
| **apple-podcasts** | `search` `episodes` `top` | 🌐 Public |
|
|
122
124
|
| **xiaoyuzhou** | `podcast` `podcast-episodes` `episode` | 🌐 Public |
|
|
123
125
|
| **zhihu** | `hot` `search` `question` `download` | 🔐 Browser |
|
|
124
126
|
| **youtube** | `search` `video` `transcript` | 🔐 Browser |
|
|
@@ -134,6 +136,23 @@ Run `opencli list` for the live registry.
|
|
|
134
136
|
| **weibo** | `hot` | 🔐 Browser |
|
|
135
137
|
| **yahoo-finance** | `quote` | 🔐 Browser |
|
|
136
138
|
|
|
139
|
+
### Desktop App Adapters
|
|
140
|
+
|
|
141
|
+
Each desktop adapter has its own detailed documentation with commands reference, setup guide, and examples:
|
|
142
|
+
|
|
143
|
+
| App | Description | Doc |
|
|
144
|
+
|-----|-------------|-----|
|
|
145
|
+
| **Cursor** | Control Cursor IDE — Composer, chat, code extraction | [README](./src/clis/cursor/README.md) |
|
|
146
|
+
| **Codex** | Drive OpenAI Codex CLI agent headlessly | [README](./src/clis/codex/README.md) |
|
|
147
|
+
| **Antigravity** | Control Antigravity Ultra from terminal | [README](./src/clis/antigravity/README.md) |
|
|
148
|
+
| **ChatGPT** | Automate ChatGPT macOS desktop app | [README](./src/clis/chatgpt/README.md) |
|
|
149
|
+
| **ChatWise** | Multi-LLM client (GPT-4, Claude, Gemini) | [README](./src/clis/chatwise/README.md) |
|
|
150
|
+
| **Notion** | Search, read, write Notion pages | [README](./src/clis/notion/README.md) |
|
|
151
|
+
| **Discord** | Discord Desktop — messages, channels, servers | [README](./src/clis/discord-app/README.md) |
|
|
152
|
+
| **Feishu** | 飞书/Lark Desktop via AppleScript | [README](./src/clis/feishu/README.md) |
|
|
153
|
+
| **WeChat** | 微信 Desktop via AppleScript + Accessibility | [README](./src/clis/wechat/README.md) |
|
|
154
|
+
| **NeteaseMusic** | 网易云音乐 Desktop via CEF/CDP | [README](./src/clis/neteasemusic/README.md) |
|
|
155
|
+
|
|
137
156
|
## Download Support
|
|
138
157
|
|
|
139
158
|
OpenCLI supports downloading images, videos, and articles from supported platforms.
|
package/README.zh-CN.md
CHANGED
|
@@ -24,6 +24,7 @@ CLI all electron!现在支持把所有 electron 应用 CLI 化,从而组合
|
|
|
24
24
|
- [前置要求](#前置要求)
|
|
25
25
|
- [快速开始](#快速开始)
|
|
26
26
|
- [内置命令](#内置命令)
|
|
27
|
+
- [桌面应用适配器](#桌面应用适配器)
|
|
27
28
|
- [下载支持](#下载支持)
|
|
28
29
|
- [输出格式](#输出格式)
|
|
29
30
|
- [致 AI Agent(开发者指南)](#致-ai-agent开发者指南)
|
|
@@ -107,7 +108,7 @@ npm install -g @jackwener/opencli@latest
|
|
|
107
108
|
|
|
108
109
|
| 站点 | 命令 | 模式 |
|
|
109
110
|
|------|------|------|
|
|
110
|
-
| **twitter** | `trending` `bookmarks` `profile` `search` `timeline` `thread` `following` `followers` `notifications` `post` `reply` `delete` `like` `article` `follow` `unfollow` `bookmark` `unbookmark` `download` | 🔐 浏览器 |
|
|
111
|
+
| **twitter** | `trending` `bookmarks` `profile` `search` `timeline` `thread` `following` `followers` `notifications` `post` `reply` `delete` `like` `article` `follow` `unfollow` `bookmark` `unbookmark` `download` `accept` `reply-dm` | 🔐 浏览器 |
|
|
111
112
|
| **reddit** | `hot` `frontpage` `popular` `search` `subreddit` `read` `user` `user-posts` `user-comments` `upvote` `save` `comment` `subscribe` `saved` `upvoted` | 🔐 浏览器 |
|
|
112
113
|
| **cursor** | `status` `send` `read` `new` `dump` `composer` `model` `extract-code` `ask` `screenshot` `history` `export` | 🖥️ 桌面端 |
|
|
113
114
|
| **bilibili** | `hot` `search` `me` `favorite` `history` `feed` `subtitle` `dynamic` `ranking` `following` `user-videos` `download` | 🔐 浏览器 |
|
|
@@ -120,6 +121,7 @@ npm install -g @jackwener/opencli@latest
|
|
|
120
121
|
| **antigravity** | `status` `send` `read` `new` `evaluate` | 🖥️ 桌面端 |
|
|
121
122
|
| **chatgpt** | `status` `new` `send` `read` `ask` | 🖥️ 桌面端 |
|
|
122
123
|
| **xiaohongshu** | `search` `notifications` `feed` `me` `user` `download` | 🔐 浏览器 |
|
|
124
|
+
| **apple-podcasts** | `search` `episodes` `top` | 🌐 公开 |
|
|
123
125
|
| **xiaoyuzhou** | `podcast` `podcast-episodes` `episode` | 🌐 公开 |
|
|
124
126
|
| **zhihu** | `hot` `search` `question` `download` | 🔐 浏览器 |
|
|
125
127
|
| **youtube** | `search` `video` `transcript` | 🔐 浏览器 |
|
|
@@ -135,6 +137,23 @@ npm install -g @jackwener/opencli@latest
|
|
|
135
137
|
| **weibo** | `hot` | 🔐 浏览器 |
|
|
136
138
|
| **yahoo-finance** | `quote` | 🔐 浏览器 |
|
|
137
139
|
|
|
140
|
+
### 桌面应用适配器
|
|
141
|
+
|
|
142
|
+
每个桌面适配器都有自己详细的文档说明,包括命令参考、启动配置与使用示例:
|
|
143
|
+
|
|
144
|
+
| 应用 | 描述 | 文档 |
|
|
145
|
+
|-----|-------------|-----|
|
|
146
|
+
| **Cursor** | 控制 Cursor IDE — Composer、对话、代码提取等 | [README](./src/clis/cursor/README.md) |
|
|
147
|
+
| **Codex** | 在后台(无头)驱动 OpenAI Codex CLI Agent | [README](./src/clis/codex/README.md) |
|
|
148
|
+
| **Antigravity** | 在终端直接控制 Antigravity Ultra | [README](./src/clis/antigravity/README.md) |
|
|
149
|
+
| **ChatGPT** | 自动化操作 ChatGPT macOS 桌面客户端 | [README](./src/clis/chatgpt/README.md) |
|
|
150
|
+
| **ChatWise** | 多 LLM 客户端(GPT-4、Claude、Gemini) | [README](./src/clis/chatwise/README.md) |
|
|
151
|
+
| **Notion** | 搜索、读取、写入 Notion 页面 | [README](./src/clis/notion/README.md) |
|
|
152
|
+
| **Discord** | Discord 桌面版 — 消息、频道、服务器 | [README](./src/clis/discord-app/README.md) |
|
|
153
|
+
| **Feishu** | 飞书/Lark 桌面版 (AppleScript 驱动) | [README](./src/clis/feishu/README.md) |
|
|
154
|
+
| **WeChat** | 微信 Mac 桌面端 (AppleScript + 无障碍接口) | [README](./src/clis/wechat/README.md) |
|
|
155
|
+
| **NeteaseMusic** | 网易云音乐 (CEF/CDP 驱动) | [README](./src/clis/neteasemusic/README.md) |
|
|
156
|
+
|
|
138
157
|
## 下载支持
|
|
139
158
|
|
|
140
159
|
OpenCLI 支持从各平台下载图片、视频和文章。
|
package/dist/browser/index.d.ts
CHANGED
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
* External code should import from './browser/index.js' (or './browser.js' via Node resolution).
|
|
6
6
|
*/
|
|
7
7
|
export { Page } from './page.js';
|
|
8
|
-
export { PlaywrightMCP } from './mcp.js';
|
|
8
|
+
export { BrowserBridge, BrowserBridge as PlaywrightMCP } from './mcp.js';
|
|
9
9
|
export { isDaemonRunning } from './daemon-client.js';
|
|
10
|
-
export declare function getTokenFingerprint(_token: string | undefined): string | null;
|
|
11
10
|
import { extractTabEntries, diffTabIndexes, appendLimited } from './tabs.js';
|
|
12
11
|
import { withTimeoutMs } from '../runtime.js';
|
|
13
12
|
export declare const __test__: {
|
package/dist/browser/index.js
CHANGED
|
@@ -5,12 +5,8 @@
|
|
|
5
5
|
* External code should import from './browser/index.js' (or './browser.js' via Node resolution).
|
|
6
6
|
*/
|
|
7
7
|
export { Page } from './page.js';
|
|
8
|
-
export { PlaywrightMCP } from './mcp.js';
|
|
8
|
+
export { BrowserBridge, BrowserBridge as PlaywrightMCP } from './mcp.js';
|
|
9
9
|
export { isDaemonRunning } from './daemon-client.js';
|
|
10
|
-
// Backward compatibility: getTokenFingerprint is no longer needed but kept as no-op export
|
|
11
|
-
export function getTokenFingerprint(_token) {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
10
|
import { extractTabEntries, diffTabIndexes, appendLimited } from './tabs.js';
|
|
15
11
|
import { withTimeoutMs } from '../runtime.js';
|
|
16
12
|
export const __test__ = {
|
package/dist/browser/mcp.d.ts
CHANGED
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Browser session manager — auto-spawns daemon and provides IPage.
|
|
3
|
-
*
|
|
4
|
-
* Replaces the old PlaywrightMCP class. Still exports as PlaywrightMCP
|
|
5
|
-
* for backward compatibility with main.ts and other consumers.
|
|
6
3
|
*/
|
|
7
4
|
import type { IPage } from '../types.js';
|
|
8
|
-
export type
|
|
5
|
+
export type BrowserBridgeState = 'idle' | 'connecting' | 'connected' | 'closing' | 'closed';
|
|
9
6
|
/**
|
|
10
7
|
* Browser factory: manages daemon lifecycle and provides IPage instances.
|
|
11
|
-
*
|
|
12
|
-
* Kept as `PlaywrightMCP` class name for backward compatibility.
|
|
13
8
|
*/
|
|
14
|
-
export declare class
|
|
9
|
+
export declare class BrowserBridge {
|
|
15
10
|
private _state;
|
|
16
11
|
private _page;
|
|
17
12
|
private _daemonProc;
|
|
18
|
-
get state():
|
|
13
|
+
get state(): BrowserBridgeState;
|
|
19
14
|
connect(opts?: {
|
|
20
15
|
timeout?: number;
|
|
21
16
|
}): Promise<IPage>;
|
|
22
17
|
close(): Promise<void>;
|
|
23
18
|
private _ensureDaemon;
|
|
24
19
|
}
|
|
20
|
+
/** @deprecated Use BrowserBridge instead */
|
|
21
|
+
export declare const PlaywrightMCP: typeof BrowserBridge;
|
package/dist/browser/mcp.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Browser session manager — auto-spawns daemon and provides IPage.
|
|
3
|
-
*
|
|
4
|
-
* Replaces the old PlaywrightMCP class. Still exports as PlaywrightMCP
|
|
5
|
-
* for backward compatibility with main.ts and other consumers.
|
|
6
3
|
*/
|
|
7
4
|
import { spawn } from 'node:child_process';
|
|
8
5
|
import { fileURLToPath } from 'node:url';
|
|
@@ -13,10 +10,8 @@ import { isDaemonRunning, isExtensionConnected } from './daemon-client.js';
|
|
|
13
10
|
const DAEMON_SPAWN_TIMEOUT = 10000; // 10s to wait for daemon + extension
|
|
14
11
|
/**
|
|
15
12
|
* Browser factory: manages daemon lifecycle and provides IPage instances.
|
|
16
|
-
*
|
|
17
|
-
* Kept as `PlaywrightMCP` class name for backward compatibility.
|
|
18
13
|
*/
|
|
19
|
-
export class
|
|
14
|
+
export class BrowserBridge {
|
|
20
15
|
_state = 'idle';
|
|
21
16
|
_page = null;
|
|
22
17
|
_daemonProc = null;
|
|
@@ -68,10 +63,12 @@ export class PlaywrightMCP {
|
|
|
68
63
|
if (process.env.OPENCLI_VERBOSE) {
|
|
69
64
|
console.error(`[opencli] Starting daemon (${isTs ? 'ts' : 'js'})...`);
|
|
70
65
|
}
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
66
|
+
// For compiled .js, use the current node binary directly (fast).
|
|
67
|
+
// For .ts dev mode, node can't run .ts files — use tsx via --import.
|
|
68
|
+
const spawnArgs = isTs
|
|
69
|
+
? [process.execPath, '--import', 'tsx/esm', daemonPath]
|
|
70
|
+
: [process.execPath, daemonPath];
|
|
71
|
+
this._daemonProc = spawn(spawnArgs[0], spawnArgs.slice(1), {
|
|
75
72
|
detached: true,
|
|
76
73
|
stdio: 'ignore',
|
|
77
74
|
env: { ...process.env },
|
|
@@ -94,3 +91,5 @@ export class PlaywrightMCP {
|
|
|
94
91
|
'Make sure port 19825 is available.');
|
|
95
92
|
}
|
|
96
93
|
}
|
|
94
|
+
/** @deprecated Use BrowserBridge instead */
|
|
95
|
+
export const PlaywrightMCP = BrowserBridge;
|
package/dist/browser/page.d.ts
CHANGED
|
@@ -19,6 +19,8 @@ export declare class Page implements IPage {
|
|
|
19
19
|
/** Helper: spread tabId into command params if we have one */
|
|
20
20
|
private _tabOpt;
|
|
21
21
|
goto(url: string): Promise<void>;
|
|
22
|
+
/** Close the automation window in the extension */
|
|
23
|
+
closeWindow(): Promise<void>;
|
|
22
24
|
evaluate(js: string): Promise<any>;
|
|
23
25
|
snapshot(opts?: {
|
|
24
26
|
interactive?: boolean;
|
|
@@ -39,7 +41,12 @@ export declare class Page implements IPage {
|
|
|
39
41
|
newTab(): Promise<void>;
|
|
40
42
|
selectTab(index: number): Promise<void>;
|
|
41
43
|
networkRequests(includeStatic?: boolean): Promise<any>;
|
|
42
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Console messages are not available in lightweight daemon mode.
|
|
46
|
+
* Would require CDP Runtime.consoleAPICalled event listener.
|
|
47
|
+
* @returns Always returns empty array.
|
|
48
|
+
*/
|
|
49
|
+
consoleMessages(_level?: string): Promise<any>;
|
|
43
50
|
/**
|
|
44
51
|
* Capture a screenshot via CDP Page.captureScreenshot.
|
|
45
52
|
* @param options.format - 'png' (default) or 'jpeg'
|
package/dist/browser/page.js
CHANGED
|
@@ -31,6 +31,15 @@ export class Page {
|
|
|
31
31
|
this._tabId = result.tabId;
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
|
+
/** Close the automation window in the extension */
|
|
35
|
+
async closeWindow() {
|
|
36
|
+
try {
|
|
37
|
+
await sendCommand('close-window', {});
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// Window may already be closed or daemon may be down
|
|
41
|
+
}
|
|
42
|
+
}
|
|
34
43
|
async evaluate(js) {
|
|
35
44
|
const code = wrapForEval(js);
|
|
36
45
|
return sendCommand('exec', { code, ...this._tabOpt() });
|
|
@@ -168,12 +177,12 @@ export class Page {
|
|
|
168
177
|
`;
|
|
169
178
|
return sendCommand('exec', { code, ...this._tabOpt() });
|
|
170
179
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
180
|
+
/**
|
|
181
|
+
* Console messages are not available in lightweight daemon mode.
|
|
182
|
+
* Would require CDP Runtime.consoleAPICalled event listener.
|
|
183
|
+
* @returns Always returns empty array.
|
|
184
|
+
*/
|
|
185
|
+
async consoleMessages(_level = 'info') {
|
|
177
186
|
return [];
|
|
178
187
|
}
|
|
179
188
|
/**
|
|
@@ -234,20 +243,17 @@ export class Page {
|
|
|
234
243
|
}
|
|
235
244
|
async installInterceptor(pattern) {
|
|
236
245
|
const { generateInterceptorJs } = await import('../interceptor.js');
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
});
|
|
246
|
+
// Must use evaluate() so wrapForEval() converts the arrow function into an IIFE;
|
|
247
|
+
// sendCommand('exec') sends the code as-is, and CDP never executes a bare arrow.
|
|
248
|
+
await this.evaluate(generateInterceptorJs(JSON.stringify(pattern), {
|
|
249
|
+
arrayName: '__opencli_xhr',
|
|
250
|
+
patchGuard: '__opencli_interceptor_patched',
|
|
251
|
+
}));
|
|
244
252
|
}
|
|
245
253
|
async getInterceptedRequests() {
|
|
246
254
|
const { generateReadInterceptedJs } = await import('../interceptor.js');
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
...this._tabOpt(),
|
|
250
|
-
});
|
|
255
|
+
// Same as installInterceptor: must go through evaluate() for IIFE wrapping
|
|
256
|
+
const result = await this.evaluate(generateReadInterceptedJs('__opencli_xhr'));
|
|
251
257
|
return result || [];
|
|
252
258
|
}
|
|
253
259
|
}
|
package/dist/browser.test.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import {
|
|
2
|
+
import { BrowserBridge, __test__ } from './browser/index.js';
|
|
3
3
|
describe('browser helpers', () => {
|
|
4
4
|
it('extracts tab entries from string snapshots', () => {
|
|
5
5
|
const entries = __test__.extractTabEntries('Tab 0 https://example.com\nTab 1 Chrome Extension');
|
|
@@ -31,25 +31,25 @@ describe('browser helpers', () => {
|
|
|
31
31
|
await expect(__test__.withTimeoutMs(new Promise(() => { }), 10, 'timeout')).rejects.toThrow('timeout');
|
|
32
32
|
});
|
|
33
33
|
});
|
|
34
|
-
describe('
|
|
34
|
+
describe('BrowserBridge state', () => {
|
|
35
35
|
it('transitions to closed after close()', async () => {
|
|
36
|
-
const mcp = new
|
|
36
|
+
const mcp = new BrowserBridge();
|
|
37
37
|
expect(mcp.state).toBe('idle');
|
|
38
38
|
await mcp.close();
|
|
39
39
|
expect(mcp.state).toBe('closed');
|
|
40
40
|
});
|
|
41
41
|
it('rejects connect() after the session has been closed', async () => {
|
|
42
|
-
const mcp = new
|
|
42
|
+
const mcp = new BrowserBridge();
|
|
43
43
|
await mcp.close();
|
|
44
44
|
await expect(mcp.connect()).rejects.toThrow('Session is closed');
|
|
45
45
|
});
|
|
46
46
|
it('rejects connect() while already connecting', async () => {
|
|
47
|
-
const mcp = new
|
|
47
|
+
const mcp = new BrowserBridge();
|
|
48
48
|
mcp._state = 'connecting';
|
|
49
49
|
await expect(mcp.connect()).rejects.toThrow('Already connecting');
|
|
50
50
|
});
|
|
51
51
|
it('rejects connect() while closing', async () => {
|
|
52
|
-
const mcp = new
|
|
52
|
+
const mcp = new BrowserBridge();
|
|
53
53
|
mcp._state = 'closing';
|
|
54
54
|
await expect(mcp.connect()).rejects.toThrow('Session is closing');
|
|
55
55
|
});
|