chrome-cdp-cli 1.0.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +364 -37
- package/dist/cli/CLIApplication.js +13 -1
- package/dist/cli/CLIInterface.js +20 -0
- package/dist/cli/CommandRouter.js +20 -1
- package/dist/handlers/GetConsoleMessageHandler.js +91 -0
- package/dist/handlers/GetNetworkRequestHandler.js +50 -0
- package/dist/handlers/InstallClaudeSkillHandler.js +423 -0
- package/dist/handlers/InstallCursorCommandHandler.js +280 -0
- package/dist/handlers/ListConsoleMessagesHandler.js +114 -0
- package/dist/handlers/ListNetworkRequestsHandler.js +51 -0
- package/dist/handlers/index.js +6 -0
- package/dist/monitors/ConsoleMonitor.js +121 -0
- package/dist/monitors/NetworkMonitor.js +162 -0
- package/dist/monitors/index.js +18 -0
- package/package.json +3 -3
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.InstallCursorCommandHandler = void 0;
|
|
37
|
+
const fs = __importStar(require("fs/promises"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const logger_1 = require("../utils/logger");
|
|
40
|
+
class InstallCursorCommandHandler {
|
|
41
|
+
constructor() {
|
|
42
|
+
this.name = 'install_cursor_command';
|
|
43
|
+
}
|
|
44
|
+
async execute(_client, args) {
|
|
45
|
+
try {
|
|
46
|
+
const targetDir = args.targetDirectory || '.cursor/commands';
|
|
47
|
+
if (!args.targetDirectory && targetDir === '.cursor/commands' && !args.force) {
|
|
48
|
+
const cursorDirExists = await this.checkDirectoryExists('.cursor');
|
|
49
|
+
if (!cursorDirExists) {
|
|
50
|
+
return {
|
|
51
|
+
success: false,
|
|
52
|
+
error: `Warning: No .cursor directory found in current directory. This may not be a Cursor project root directory.
|
|
53
|
+
|
|
54
|
+
To install Cursor commands:
|
|
55
|
+
1. Navigate to your Cursor project root directory (where .cursor folder should be)
|
|
56
|
+
2. Run the command again, or
|
|
57
|
+
3. Use --target-directory to specify a custom location, or
|
|
58
|
+
4. Use --force to install anyway
|
|
59
|
+
|
|
60
|
+
Examples:
|
|
61
|
+
chrome-cdp-cli install-cursor-command --target-directory /path/to/.cursor/commands
|
|
62
|
+
chrome-cdp-cli install-cursor-command --force`
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
await this.ensureDirectory(targetDir);
|
|
67
|
+
const commands = this.generateCursorCommands();
|
|
68
|
+
const createdFiles = [];
|
|
69
|
+
for (const command of commands) {
|
|
70
|
+
const filePath = path.join(targetDir, `${command.name}.md`);
|
|
71
|
+
const content = this.generateCommandMarkdown(command);
|
|
72
|
+
await fs.writeFile(filePath, content, 'utf8');
|
|
73
|
+
createdFiles.push(filePath);
|
|
74
|
+
logger_1.logger.info(`Created Cursor command: ${filePath}`);
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
success: true,
|
|
78
|
+
data: {
|
|
79
|
+
installed: commands.length,
|
|
80
|
+
directory: targetDir,
|
|
81
|
+
commands: commands.map(c => c.name),
|
|
82
|
+
files: createdFiles
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
logger_1.logger.error('Failed to install Cursor commands:', error);
|
|
88
|
+
return {
|
|
89
|
+
success: false,
|
|
90
|
+
error: error instanceof Error ? error.message : 'Unknown error occurred'
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
async checkDirectoryExists(dirPath) {
|
|
95
|
+
try {
|
|
96
|
+
await fs.access(dirPath);
|
|
97
|
+
return true;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
async ensureDirectory(dirPath) {
|
|
104
|
+
try {
|
|
105
|
+
await fs.access(dirPath);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
await fs.mkdir(dirPath, { recursive: true });
|
|
109
|
+
logger_1.logger.info(`Created directory: ${dirPath}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
generateCursorCommands() {
|
|
113
|
+
return [
|
|
114
|
+
{
|
|
115
|
+
name: 'cdp-cli',
|
|
116
|
+
description: 'Chrome DevTools Protocol CLI 工具',
|
|
117
|
+
instructions: `通过 Chrome DevTools Protocol 控制 Chrome 浏览器,支持多种自动化操作。
|
|
118
|
+
|
|
119
|
+
## 功能列表
|
|
120
|
+
|
|
121
|
+
### 1. JavaScript 执行 (eval)
|
|
122
|
+
执行 JavaScript 代码并返回结果,支持异步代码和 Promise。
|
|
123
|
+
|
|
124
|
+
**用途:**
|
|
125
|
+
- 获取页面信息(标题、URL、元素等)
|
|
126
|
+
- 修改页面内容和样式
|
|
127
|
+
- 执行复杂的 JavaScript 逻辑
|
|
128
|
+
- 与页面元素交互
|
|
129
|
+
|
|
130
|
+
**示例:**
|
|
131
|
+
- \`chrome-cdp-cli eval "document.title"\`
|
|
132
|
+
- \`chrome-cdp-cli eval "window.location.href"\`
|
|
133
|
+
- \`chrome-cdp-cli eval "document.querySelector('#button').click()"\`
|
|
134
|
+
- \`chrome-cdp-cli eval "fetch('/api/data').then(r => r.json())"\`
|
|
135
|
+
|
|
136
|
+
### 2. 页面截图 (screenshot)
|
|
137
|
+
捕获当前页面的截图并保存到指定文件。
|
|
138
|
+
|
|
139
|
+
**功能:**
|
|
140
|
+
- 指定文件名和路径
|
|
141
|
+
- 全页面截图或视口截图
|
|
142
|
+
- 自定义图片质量和格式
|
|
143
|
+
- 输出 PNG 格式文件
|
|
144
|
+
|
|
145
|
+
**示例:**
|
|
146
|
+
- \`chrome-cdp-cli screenshot --filename screenshot.png\`
|
|
147
|
+
- \`chrome-cdp-cli screenshot --filename fullpage.png --full-page\`
|
|
148
|
+
- \`chrome-cdp-cli screenshot --filename reports/page-capture.png\`
|
|
149
|
+
|
|
150
|
+
### 3. DOM 快照 (snapshot)
|
|
151
|
+
捕获包含 DOM 结构、样式和布局信息的完整快照。
|
|
152
|
+
|
|
153
|
+
**包含内容:**
|
|
154
|
+
- 完整的 DOM 树结构
|
|
155
|
+
- 计算后的 CSS 样式
|
|
156
|
+
- 元素布局信息
|
|
157
|
+
- 元素属性和文本内容
|
|
158
|
+
|
|
159
|
+
**示例:**
|
|
160
|
+
- \`chrome-cdp-cli snapshot --filename dom-snapshot.json\`
|
|
161
|
+
- \`chrome-cdp-cli snapshot --filename page-structure.json\`
|
|
162
|
+
|
|
163
|
+
### 4. 控制台监控 (console)
|
|
164
|
+
获取浏览器控制台的消息,包括日志、警告和错误。
|
|
165
|
+
|
|
166
|
+
**功能:**
|
|
167
|
+
- 获取最新的控制台消息
|
|
168
|
+
- 列出所有控制台消息
|
|
169
|
+
- 按类型过滤消息(log、warn、error)
|
|
170
|
+
- 调试和监控页面运行状态
|
|
171
|
+
|
|
172
|
+
**示例:**
|
|
173
|
+
- \`chrome-cdp-cli get_console_message\`
|
|
174
|
+
- \`chrome-cdp-cli list_console_messages --type error\`
|
|
175
|
+
|
|
176
|
+
### 5. 网络请求监控 (network)
|
|
177
|
+
监控和获取页面的网络请求信息。
|
|
178
|
+
|
|
179
|
+
**功能:**
|
|
180
|
+
- 获取最新的网络请求
|
|
181
|
+
- 列出所有网络请求
|
|
182
|
+
- 按方法过滤请求(GET、POST 等)
|
|
183
|
+
- 查看请求和响应详情
|
|
184
|
+
- 分析页面的网络行为和 API 调用
|
|
185
|
+
|
|
186
|
+
**示例:**
|
|
187
|
+
- \`chrome-cdp-cli get_network_request\`
|
|
188
|
+
- \`chrome-cdp-cli list_network_requests --method POST\`
|
|
189
|
+
|
|
190
|
+
命令会自动连接到运行在 localhost:9222 的 Chrome 实例。`,
|
|
191
|
+
examples: [
|
|
192
|
+
'chrome-cdp-cli eval "document.title"',
|
|
193
|
+
'chrome-cdp-cli screenshot --filename page.png',
|
|
194
|
+
'chrome-cdp-cli snapshot --filename dom.json',
|
|
195
|
+
'chrome-cdp-cli get_console_message',
|
|
196
|
+
'chrome-cdp-cli list_network_requests'
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
];
|
|
200
|
+
}
|
|
201
|
+
generateCommandMarkdown(command) {
|
|
202
|
+
const examples = command.examples.map(example => `- ${example}`).join('\n');
|
|
203
|
+
return `# ${command.description}
|
|
204
|
+
|
|
205
|
+
${command.instructions}
|
|
206
|
+
|
|
207
|
+
## 使用示例
|
|
208
|
+
|
|
209
|
+
${examples}
|
|
210
|
+
|
|
211
|
+
## 前置条件
|
|
212
|
+
|
|
213
|
+
确保 Chrome 浏览器已启动并开启了远程调试:
|
|
214
|
+
|
|
215
|
+
\`\`\`bash
|
|
216
|
+
chrome --remote-debugging-port=9222
|
|
217
|
+
\`\`\`
|
|
218
|
+
|
|
219
|
+
或者在 macOS 上:
|
|
220
|
+
|
|
221
|
+
\`\`\`bash
|
|
222
|
+
/Applications/Google\\ Chrome.app/Contents/MacOS/Google\\ Chrome --remote-debugging-port=9222
|
|
223
|
+
\`\`\`
|
|
224
|
+
|
|
225
|
+
## 全局选项
|
|
226
|
+
|
|
227
|
+
所有命令都支持以下全局选项:
|
|
228
|
+
|
|
229
|
+
- \`--host <hostname>\`: Chrome DevTools 主机地址 (默认: localhost)
|
|
230
|
+
- \`--port <number>\`: Chrome DevTools 端口 (默认: 9222)
|
|
231
|
+
- \`--format <json|text>\`: 输出格式 (默认: json)
|
|
232
|
+
- \`--verbose\`: 启用详细日志
|
|
233
|
+
- \`--quiet\`: 静默模式
|
|
234
|
+
- \`--timeout <ms>\`: 命令超时时间
|
|
235
|
+
|
|
236
|
+
## 常用工作流程
|
|
237
|
+
|
|
238
|
+
### 网页自动化测试
|
|
239
|
+
\`\`\`bash
|
|
240
|
+
# 1. 导航到页面并截图
|
|
241
|
+
chrome-cdp-cli eval "window.location.href = 'https://example.com'"
|
|
242
|
+
chrome-cdp-cli screenshot --filename before.png
|
|
243
|
+
|
|
244
|
+
# 2. 填写表单
|
|
245
|
+
chrome-cdp-cli eval "document.querySelector('#email').value = 'test@example.com'"
|
|
246
|
+
chrome-cdp-cli eval "document.querySelector('#password').value = 'password123'"
|
|
247
|
+
|
|
248
|
+
# 3. 提交并检查结果
|
|
249
|
+
chrome-cdp-cli eval "document.querySelector('#submit').click()"
|
|
250
|
+
chrome-cdp-cli screenshot --filename after.png
|
|
251
|
+
chrome-cdp-cli list_console_messages --type error
|
|
252
|
+
\`\`\`
|
|
253
|
+
|
|
254
|
+
### API 调用监控
|
|
255
|
+
\`\`\`bash
|
|
256
|
+
# 1. 开始监控网络请求
|
|
257
|
+
chrome-cdp-cli eval "fetch('/api/users').then(r => r.json())"
|
|
258
|
+
|
|
259
|
+
# 2. 查看网络请求
|
|
260
|
+
chrome-cdp-cli list_network_requests --method POST
|
|
261
|
+
|
|
262
|
+
# 3. 获取最新请求详情
|
|
263
|
+
chrome-cdp-cli get_network_request
|
|
264
|
+
\`\`\`
|
|
265
|
+
|
|
266
|
+
### 页面分析
|
|
267
|
+
\`\`\`bash
|
|
268
|
+
# 1. 获取页面基本信息
|
|
269
|
+
chrome-cdp-cli eval "({title: document.title, url: location.href, links: document.querySelectorAll('a').length})"
|
|
270
|
+
|
|
271
|
+
# 2. 捕获完整页面结构
|
|
272
|
+
chrome-cdp-cli snapshot --filename page-analysis.json
|
|
273
|
+
|
|
274
|
+
# 3. 检查控制台错误
|
|
275
|
+
chrome-cdp-cli list_console_messages --type error
|
|
276
|
+
\`\`\`
|
|
277
|
+
`;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
exports.InstallCursorCommandHandler = InstallCursorCommandHandler;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ListConsoleMessagesHandler = void 0;
|
|
4
|
+
const ConsoleMonitor_1 = require("../monitors/ConsoleMonitor");
|
|
5
|
+
class ListConsoleMessagesHandler {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.name = 'list_console_messages';
|
|
8
|
+
this.consoleMonitor = null;
|
|
9
|
+
}
|
|
10
|
+
async execute(client, args) {
|
|
11
|
+
try {
|
|
12
|
+
const params = args;
|
|
13
|
+
if (!this.consoleMonitor) {
|
|
14
|
+
this.consoleMonitor = new ConsoleMonitor_1.ConsoleMonitor(client);
|
|
15
|
+
}
|
|
16
|
+
if (params.startMonitoring || !this.consoleMonitor.isActive()) {
|
|
17
|
+
await this.consoleMonitor.startMonitoring();
|
|
18
|
+
}
|
|
19
|
+
const filter = {};
|
|
20
|
+
if (params.types && params.types.length > 0) {
|
|
21
|
+
filter.types = params.types;
|
|
22
|
+
}
|
|
23
|
+
if (params.textPattern) {
|
|
24
|
+
filter.textPattern = params.textPattern;
|
|
25
|
+
}
|
|
26
|
+
if (params.maxMessages && params.maxMessages > 0) {
|
|
27
|
+
filter.maxMessages = params.maxMessages;
|
|
28
|
+
}
|
|
29
|
+
if (params.startTime) {
|
|
30
|
+
filter.startTime = params.startTime;
|
|
31
|
+
}
|
|
32
|
+
if (params.endTime) {
|
|
33
|
+
filter.endTime = params.endTime;
|
|
34
|
+
}
|
|
35
|
+
const messages = this.consoleMonitor.getMessages(filter);
|
|
36
|
+
return {
|
|
37
|
+
success: true,
|
|
38
|
+
data: {
|
|
39
|
+
messages: messages.map(msg => ({
|
|
40
|
+
type: msg.type,
|
|
41
|
+
text: msg.text,
|
|
42
|
+
args: msg.args,
|
|
43
|
+
timestamp: msg.timestamp,
|
|
44
|
+
stackTrace: msg.stackTrace
|
|
45
|
+
})),
|
|
46
|
+
totalCount: messages.length,
|
|
47
|
+
isMonitoring: this.consoleMonitor.isActive()
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
return {
|
|
53
|
+
success: false,
|
|
54
|
+
error: error instanceof Error ? error.message : 'Unknown error occurred'
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
validateArgs(args) {
|
|
59
|
+
if (!args || typeof args !== 'object') {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
const params = args;
|
|
63
|
+
if (params.types !== undefined) {
|
|
64
|
+
if (!Array.isArray(params.types)) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
const validTypes = ['log', 'info', 'warn', 'error', 'debug'];
|
|
68
|
+
for (const type of params.types) {
|
|
69
|
+
if (typeof type !== 'string' || !validTypes.includes(type)) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
if (params.textPattern !== undefined && typeof params.textPattern !== 'string') {
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
if (params.maxMessages !== undefined) {
|
|
78
|
+
if (typeof params.maxMessages !== 'number' || params.maxMessages <= 0) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (params.startTime !== undefined && typeof params.startTime !== 'number') {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
if (params.endTime !== undefined && typeof params.endTime !== 'number') {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
if (params.startMonitoring !== undefined && typeof params.startMonitoring !== 'boolean') {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
return true;
|
|
92
|
+
}
|
|
93
|
+
getHelp() {
|
|
94
|
+
return `list_console_messages - List all captured console messages
|
|
95
|
+
|
|
96
|
+
Usage:
|
|
97
|
+
list_console_messages [options]
|
|
98
|
+
|
|
99
|
+
Options:
|
|
100
|
+
--types <types> Filter by message types (comma-separated: log,info,warn,error,debug)
|
|
101
|
+
--textPattern <pattern> Filter by text pattern (regex)
|
|
102
|
+
--maxMessages <count> Maximum number of messages to return
|
|
103
|
+
--startTime <timestamp> Filter messages after this timestamp
|
|
104
|
+
--endTime <timestamp> Filter messages before this timestamp
|
|
105
|
+
--startMonitoring Start monitoring if not already active
|
|
106
|
+
|
|
107
|
+
Examples:
|
|
108
|
+
list_console_messages
|
|
109
|
+
list_console_messages --types error,warn
|
|
110
|
+
list_console_messages --textPattern "API" --maxMessages 10
|
|
111
|
+
list_console_messages --startTime 1640995200000`;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.ListConsoleMessagesHandler = ListConsoleMessagesHandler;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ListNetworkRequestsHandler = void 0;
|
|
4
|
+
const NetworkMonitor_1 = require("../monitors/NetworkMonitor");
|
|
5
|
+
class ListNetworkRequestsHandler {
|
|
6
|
+
constructor() {
|
|
7
|
+
this.name = 'list_network_requests';
|
|
8
|
+
this.networkMonitor = null;
|
|
9
|
+
}
|
|
10
|
+
async execute(client, args) {
|
|
11
|
+
try {
|
|
12
|
+
const params = args;
|
|
13
|
+
if (!this.networkMonitor) {
|
|
14
|
+
this.networkMonitor = new NetworkMonitor_1.NetworkMonitor(client);
|
|
15
|
+
}
|
|
16
|
+
if (!this.networkMonitor.isActive()) {
|
|
17
|
+
await this.networkMonitor.startMonitoring();
|
|
18
|
+
}
|
|
19
|
+
const filter = params.filter ? {
|
|
20
|
+
methods: params.filter.methods,
|
|
21
|
+
urlPattern: params.filter.urlPattern,
|
|
22
|
+
statusCodes: params.filter.statusCodes,
|
|
23
|
+
maxRequests: params.filter.maxRequests,
|
|
24
|
+
startTime: params.filter.startTime,
|
|
25
|
+
endTime: params.filter.endTime,
|
|
26
|
+
} : undefined;
|
|
27
|
+
const requests = this.networkMonitor.getRequests(filter);
|
|
28
|
+
return {
|
|
29
|
+
success: true,
|
|
30
|
+
data: {
|
|
31
|
+
requests,
|
|
32
|
+
count: requests.length,
|
|
33
|
+
isMonitoring: this.networkMonitor.isActive()
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
return {
|
|
39
|
+
success: false,
|
|
40
|
+
error: error instanceof Error ? error.message : 'Unknown error occurred'
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
getNetworkMonitor() {
|
|
45
|
+
return this.networkMonitor;
|
|
46
|
+
}
|
|
47
|
+
setNetworkMonitor(monitor) {
|
|
48
|
+
this.networkMonitor = monitor;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
exports.ListNetworkRequestsHandler = ListNetworkRequestsHandler;
|
package/dist/handlers/index.js
CHANGED
|
@@ -17,3 +17,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
17
17
|
__exportStar(require("./EvaluateScriptHandler"), exports);
|
|
18
18
|
__exportStar(require("./TakeScreenshotHandler"), exports);
|
|
19
19
|
__exportStar(require("./TakeSnapshotHandler"), exports);
|
|
20
|
+
__exportStar(require("./GetConsoleMessageHandler"), exports);
|
|
21
|
+
__exportStar(require("./ListConsoleMessagesHandler"), exports);
|
|
22
|
+
__exportStar(require("./GetNetworkRequestHandler"), exports);
|
|
23
|
+
__exportStar(require("./ListNetworkRequestsHandler"), exports);
|
|
24
|
+
__exportStar(require("./InstallCursorCommandHandler"), exports);
|
|
25
|
+
__exportStar(require("./InstallClaudeSkillHandler"), exports);
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConsoleMonitor = void 0;
|
|
4
|
+
class ConsoleMonitor {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.messages = [];
|
|
7
|
+
this.isMonitoring = false;
|
|
8
|
+
this.messageHandler = null;
|
|
9
|
+
this.client = client;
|
|
10
|
+
}
|
|
11
|
+
async startMonitoring() {
|
|
12
|
+
if (this.isMonitoring) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
await this.client.send('Runtime.enable');
|
|
16
|
+
this.messageHandler = (params) => {
|
|
17
|
+
this.handleConsoleMessage(params);
|
|
18
|
+
};
|
|
19
|
+
this.client.on('Runtime.consoleAPICalled', this.messageHandler);
|
|
20
|
+
this.isMonitoring = true;
|
|
21
|
+
}
|
|
22
|
+
async stopMonitoring() {
|
|
23
|
+
if (!this.isMonitoring || !this.messageHandler) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
this.client.off('Runtime.consoleAPICalled', this.messageHandler);
|
|
27
|
+
this.messageHandler = null;
|
|
28
|
+
this.isMonitoring = false;
|
|
29
|
+
}
|
|
30
|
+
getMessages(filter) {
|
|
31
|
+
let filteredMessages = [...this.messages];
|
|
32
|
+
if (filter) {
|
|
33
|
+
if (filter.types && filter.types.length > 0) {
|
|
34
|
+
filteredMessages = filteredMessages.filter(msg => filter.types.includes(msg.type));
|
|
35
|
+
}
|
|
36
|
+
if (filter.textPattern) {
|
|
37
|
+
const pattern = new RegExp(filter.textPattern, 'i');
|
|
38
|
+
filteredMessages = filteredMessages.filter(msg => pattern.test(msg.text));
|
|
39
|
+
}
|
|
40
|
+
if (filter.startTime) {
|
|
41
|
+
filteredMessages = filteredMessages.filter(msg => msg.timestamp >= filter.startTime);
|
|
42
|
+
}
|
|
43
|
+
if (filter.endTime) {
|
|
44
|
+
filteredMessages = filteredMessages.filter(msg => msg.timestamp <= filter.endTime);
|
|
45
|
+
}
|
|
46
|
+
if (filter.maxMessages && filter.maxMessages > 0) {
|
|
47
|
+
filteredMessages = filteredMessages.slice(-filter.maxMessages);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return filteredMessages;
|
|
51
|
+
}
|
|
52
|
+
getLatestMessage(filter) {
|
|
53
|
+
const messages = this.getMessages(filter);
|
|
54
|
+
return messages.length > 0 ? messages[messages.length - 1] : null;
|
|
55
|
+
}
|
|
56
|
+
clearMessages() {
|
|
57
|
+
this.messages = [];
|
|
58
|
+
}
|
|
59
|
+
getMessageCount(filter) {
|
|
60
|
+
return this.getMessages(filter).length;
|
|
61
|
+
}
|
|
62
|
+
isActive() {
|
|
63
|
+
return this.isMonitoring;
|
|
64
|
+
}
|
|
65
|
+
handleConsoleMessage(params) {
|
|
66
|
+
try {
|
|
67
|
+
const consoleParams = params;
|
|
68
|
+
const message = {
|
|
69
|
+
type: this.mapConsoleType(consoleParams.type),
|
|
70
|
+
text: this.formatConsoleArgs(consoleParams.args),
|
|
71
|
+
args: consoleParams.args.map(arg => arg.value || arg.description || ''),
|
|
72
|
+
timestamp: consoleParams.timestamp,
|
|
73
|
+
stackTrace: consoleParams.stackTrace ?
|
|
74
|
+
this.convertStackTrace(consoleParams.stackTrace.callFrames) : undefined
|
|
75
|
+
};
|
|
76
|
+
this.messages.push(message);
|
|
77
|
+
if (this.messages.length > 1000) {
|
|
78
|
+
this.messages = this.messages.slice(-1000);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch (error) {
|
|
82
|
+
console.error('Error handling console message:', error);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
mapConsoleType(cdpType) {
|
|
86
|
+
switch (cdpType) {
|
|
87
|
+
case 'log':
|
|
88
|
+
return 'log';
|
|
89
|
+
case 'info':
|
|
90
|
+
return 'info';
|
|
91
|
+
case 'warning':
|
|
92
|
+
return 'warn';
|
|
93
|
+
case 'error':
|
|
94
|
+
return 'error';
|
|
95
|
+
case 'debug':
|
|
96
|
+
return 'debug';
|
|
97
|
+
default:
|
|
98
|
+
return 'log';
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
formatConsoleArgs(args) {
|
|
102
|
+
return args.map(arg => {
|
|
103
|
+
if (arg.value !== undefined) {
|
|
104
|
+
if (typeof arg.value === 'string') {
|
|
105
|
+
return arg.value;
|
|
106
|
+
}
|
|
107
|
+
return JSON.stringify(arg.value);
|
|
108
|
+
}
|
|
109
|
+
return arg.description || '';
|
|
110
|
+
}).join(' ');
|
|
111
|
+
}
|
|
112
|
+
convertStackTrace(callFrames) {
|
|
113
|
+
return callFrames.map(frame => ({
|
|
114
|
+
functionName: frame.functionName || '<anonymous>',
|
|
115
|
+
url: frame.url,
|
|
116
|
+
lineNumber: frame.lineNumber,
|
|
117
|
+
columnNumber: frame.columnNumber
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
exports.ConsoleMonitor = ConsoleMonitor;
|