chrome-cdp-cli 2.0.4 → 2.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.
- package/dist/cli/ArgumentParser.js +172 -91
- package/dist/cli/CLIApplication.js +181 -57
- package/dist/cli/CommandRouter.js +98 -74
- package/dist/cli/CommandSchemaRegistry.js +506 -398
- package/dist/cli/EnhancedCLIInterface.js +2 -1
- package/dist/cli/HelpSystem.js +286 -256
- package/dist/handlers/ClickHandler.js +91 -27
- package/dist/handlers/InstallClaudeSkillHandler.js +220 -220
- package/dist/handlers/InstallCursorCommandHandler.js +60 -60
- package/dist/handlers/ListConsoleMessagesHandler.js +126 -178
- package/dist/handlers/ListNetworkRequestsHandler.js +128 -108
- package/dist/handlers/RestartProxyHandler.js +4 -4
- package/dist/handlers/TakeScreenshotHandler.js +70 -59
- package/dist/handlers/TakeSnapshotHandler.js +223 -165
- package/dist/handlers/index.js +0 -1
- package/dist/monitors/ConsoleMonitor.js +29 -0
- package/dist/monitors/NetworkMonitor.js +43 -19
- package/dist/proxy/server/CDPProxyServer.js +5 -1
- package/dist/proxy/server/CommandExecutionService.js +1 -1
- package/dist/proxy/server/ProxyAPIServer.js +11 -6
- package/package.json +3 -2
package/dist/handlers/index.js
CHANGED
|
@@ -30,4 +30,3 @@ __exportStar(require("./PressKeyHandler"), exports);
|
|
|
30
30
|
__exportStar(require("./UploadFileHandler"), exports);
|
|
31
31
|
__exportStar(require("./WaitForHandler"), exports);
|
|
32
32
|
__exportStar(require("./HandleDialogHandler"), exports);
|
|
33
|
-
__exportStar(require("./RestartProxyHandler"), exports);
|
|
@@ -6,6 +6,7 @@ class ConsoleMonitor {
|
|
|
6
6
|
this.messages = [];
|
|
7
7
|
this.isMonitoring = false;
|
|
8
8
|
this.messageHandler = null;
|
|
9
|
+
this.messageCallbacks = [];
|
|
9
10
|
this.client = client;
|
|
10
11
|
}
|
|
11
12
|
async startMonitoring() {
|
|
@@ -71,6 +72,18 @@ class ConsoleMonitor {
|
|
|
71
72
|
isActive() {
|
|
72
73
|
return this.isMonitoring;
|
|
73
74
|
}
|
|
75
|
+
onMessage(callback) {
|
|
76
|
+
this.messageCallbacks.push(callback);
|
|
77
|
+
}
|
|
78
|
+
offMessage(callback) {
|
|
79
|
+
const index = this.messageCallbacks.indexOf(callback);
|
|
80
|
+
if (index > -1) {
|
|
81
|
+
this.messageCallbacks.splice(index, 1);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
clearCallbacks() {
|
|
85
|
+
this.messageCallbacks = [];
|
|
86
|
+
}
|
|
74
87
|
handleConsoleMessage(params) {
|
|
75
88
|
try {
|
|
76
89
|
const consoleParams = params;
|
|
@@ -86,6 +99,14 @@ class ConsoleMonitor {
|
|
|
86
99
|
if (this.messages.length > 1000) {
|
|
87
100
|
this.messages = this.messages.slice(-1000);
|
|
88
101
|
}
|
|
102
|
+
this.messageCallbacks.forEach(callback => {
|
|
103
|
+
try {
|
|
104
|
+
callback(message);
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
console.error('Error in message callback:', error);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
89
110
|
}
|
|
90
111
|
catch (error) {
|
|
91
112
|
console.error('Error handling console message:', error);
|
|
@@ -111,6 +132,14 @@ class ConsoleMonitor {
|
|
|
111
132
|
if (this.messages.length > 1000) {
|
|
112
133
|
this.messages = this.messages.slice(-1000);
|
|
113
134
|
}
|
|
135
|
+
this.messageCallbacks.forEach(callback => {
|
|
136
|
+
try {
|
|
137
|
+
callback(message);
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
console.error('Error in message callback:', error);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
114
143
|
}
|
|
115
144
|
catch (error) {
|
|
116
145
|
console.error('Error handling log entry:', error);
|
|
@@ -10,13 +10,14 @@ class NetworkMonitor {
|
|
|
10
10
|
this.responseReceivedHandler = null;
|
|
11
11
|
this.loadingFinishedHandler = null;
|
|
12
12
|
this.loadingFailedHandler = null;
|
|
13
|
+
this.requestCallbacks = [];
|
|
13
14
|
this.client = client;
|
|
14
15
|
}
|
|
15
16
|
async startMonitoring() {
|
|
16
17
|
if (this.isMonitoring) {
|
|
17
18
|
return;
|
|
18
19
|
}
|
|
19
|
-
await this.client.send(
|
|
20
|
+
await this.client.send("Network.enable");
|
|
20
21
|
this.requestWillBeSentHandler = (params) => {
|
|
21
22
|
this.handleRequestWillBeSent(params);
|
|
22
23
|
};
|
|
@@ -29,10 +30,10 @@ class NetworkMonitor {
|
|
|
29
30
|
this.loadingFailedHandler = (params) => {
|
|
30
31
|
this.handleLoadingFailed(params);
|
|
31
32
|
};
|
|
32
|
-
this.client.on(
|
|
33
|
-
this.client.on(
|
|
34
|
-
this.client.on(
|
|
35
|
-
this.client.on(
|
|
33
|
+
this.client.on("Network.requestWillBeSent", this.requestWillBeSentHandler);
|
|
34
|
+
this.client.on("Network.responseReceived", this.responseReceivedHandler);
|
|
35
|
+
this.client.on("Network.loadingFinished", this.loadingFinishedHandler);
|
|
36
|
+
this.client.on("Network.loadingFailed", this.loadingFailedHandler);
|
|
36
37
|
this.isMonitoring = true;
|
|
37
38
|
}
|
|
38
39
|
async stopMonitoring() {
|
|
@@ -40,19 +41,19 @@ class NetworkMonitor {
|
|
|
40
41
|
return;
|
|
41
42
|
}
|
|
42
43
|
if (this.requestWillBeSentHandler) {
|
|
43
|
-
this.client.off(
|
|
44
|
+
this.client.off("Network.requestWillBeSent", this.requestWillBeSentHandler);
|
|
44
45
|
this.requestWillBeSentHandler = null;
|
|
45
46
|
}
|
|
46
47
|
if (this.responseReceivedHandler) {
|
|
47
|
-
this.client.off(
|
|
48
|
+
this.client.off("Network.responseReceived", this.responseReceivedHandler);
|
|
48
49
|
this.responseReceivedHandler = null;
|
|
49
50
|
}
|
|
50
51
|
if (this.loadingFinishedHandler) {
|
|
51
|
-
this.client.off(
|
|
52
|
+
this.client.off("Network.loadingFinished", this.loadingFinishedHandler);
|
|
52
53
|
this.loadingFinishedHandler = null;
|
|
53
54
|
}
|
|
54
55
|
if (this.loadingFailedHandler) {
|
|
55
|
-
this.client.off(
|
|
56
|
+
this.client.off("Network.loadingFailed", this.loadingFailedHandler);
|
|
56
57
|
this.loadingFailedHandler = null;
|
|
57
58
|
}
|
|
58
59
|
this.isMonitoring = false;
|
|
@@ -61,20 +62,20 @@ class NetworkMonitor {
|
|
|
61
62
|
let filteredRequests = [...this.completedRequests];
|
|
62
63
|
if (filter) {
|
|
63
64
|
if (filter.methods && filter.methods.length > 0) {
|
|
64
|
-
filteredRequests = filteredRequests.filter(req => filter.methods.includes(req.method.toUpperCase()));
|
|
65
|
+
filteredRequests = filteredRequests.filter((req) => filter.methods.includes(req.method.toUpperCase()));
|
|
65
66
|
}
|
|
66
67
|
if (filter.urlPattern) {
|
|
67
|
-
const pattern = new RegExp(filter.urlPattern,
|
|
68
|
-
filteredRequests = filteredRequests.filter(req => pattern.test(req.url));
|
|
68
|
+
const pattern = new RegExp(filter.urlPattern, "i");
|
|
69
|
+
filteredRequests = filteredRequests.filter((req) => pattern.test(req.url));
|
|
69
70
|
}
|
|
70
71
|
if (filter.statusCodes && filter.statusCodes.length > 0) {
|
|
71
|
-
filteredRequests = filteredRequests.filter(req => req.status && filter.statusCodes.includes(req.status));
|
|
72
|
+
filteredRequests = filteredRequests.filter((req) => req.status && filter.statusCodes.includes(req.status));
|
|
72
73
|
}
|
|
73
74
|
if (filter.startTime) {
|
|
74
|
-
filteredRequests = filteredRequests.filter(req => req.timestamp >= filter.startTime);
|
|
75
|
+
filteredRequests = filteredRequests.filter((req) => req.timestamp >= filter.startTime);
|
|
75
76
|
}
|
|
76
77
|
if (filter.endTime) {
|
|
77
|
-
filteredRequests = filteredRequests.filter(req => req.timestamp <= filter.endTime);
|
|
78
|
+
filteredRequests = filteredRequests.filter((req) => req.timestamp <= filter.endTime);
|
|
78
79
|
}
|
|
79
80
|
if (filter.maxRequests && filter.maxRequests > 0) {
|
|
80
81
|
filteredRequests = filteredRequests.slice(-filter.maxRequests);
|
|
@@ -96,6 +97,15 @@ class NetworkMonitor {
|
|
|
96
97
|
isActive() {
|
|
97
98
|
return this.isMonitoring;
|
|
98
99
|
}
|
|
100
|
+
onRequest(callback) {
|
|
101
|
+
this.requestCallbacks.push(callback);
|
|
102
|
+
}
|
|
103
|
+
offRequest(callback) {
|
|
104
|
+
const index = this.requestCallbacks.indexOf(callback);
|
|
105
|
+
if (index > -1) {
|
|
106
|
+
this.requestCallbacks.splice(index, 1);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
99
109
|
handleRequestWillBeSent(params) {
|
|
100
110
|
try {
|
|
101
111
|
const requestParams = params;
|
|
@@ -109,7 +119,7 @@ class NetworkMonitor {
|
|
|
109
119
|
this.requests.set(requestParams.requestId, networkRequest);
|
|
110
120
|
}
|
|
111
121
|
catch (error) {
|
|
112
|
-
console.error(
|
|
122
|
+
console.error("Error handling requestWillBeSent:", error);
|
|
113
123
|
}
|
|
114
124
|
}
|
|
115
125
|
handleResponseReceived(params) {
|
|
@@ -122,7 +132,7 @@ class NetworkMonitor {
|
|
|
122
132
|
}
|
|
123
133
|
}
|
|
124
134
|
catch (error) {
|
|
125
|
-
console.error(
|
|
135
|
+
console.error("Error handling responseReceived:", error);
|
|
126
136
|
}
|
|
127
137
|
}
|
|
128
138
|
handleLoadingFinished(params) {
|
|
@@ -135,10 +145,17 @@ class NetworkMonitor {
|
|
|
135
145
|
if (this.completedRequests.length > 1000) {
|
|
136
146
|
this.completedRequests = this.completedRequests.slice(-1000);
|
|
137
147
|
}
|
|
148
|
+
this.requestCallbacks.forEach((cb) => {
|
|
149
|
+
try {
|
|
150
|
+
cb(request);
|
|
151
|
+
}
|
|
152
|
+
catch (e) {
|
|
153
|
+
}
|
|
154
|
+
});
|
|
138
155
|
}
|
|
139
156
|
}
|
|
140
157
|
catch (error) {
|
|
141
|
-
console.error(
|
|
158
|
+
console.error("Error handling loadingFinished:", error);
|
|
142
159
|
}
|
|
143
160
|
}
|
|
144
161
|
handleLoadingFailed(params) {
|
|
@@ -152,10 +169,17 @@ class NetworkMonitor {
|
|
|
152
169
|
if (this.completedRequests.length > 1000) {
|
|
153
170
|
this.completedRequests = this.completedRequests.slice(-1000);
|
|
154
171
|
}
|
|
172
|
+
this.requestCallbacks.forEach((cb) => {
|
|
173
|
+
try {
|
|
174
|
+
cb(request);
|
|
175
|
+
}
|
|
176
|
+
catch (e) {
|
|
177
|
+
}
|
|
178
|
+
});
|
|
155
179
|
}
|
|
156
180
|
}
|
|
157
181
|
catch (error) {
|
|
158
|
-
console.error(
|
|
182
|
+
console.error("Error handling loadingFailed:", error);
|
|
159
183
|
}
|
|
160
184
|
}
|
|
161
185
|
}
|
|
@@ -108,6 +108,7 @@ class CDPProxyServer {
|
|
|
108
108
|
this.apiServer = new ProxyAPIServer_1.ProxyAPIServer(this.connectionPool, this.messageStore, this.healthMonitor, this.performanceMonitor, this.securityManager);
|
|
109
109
|
this.setupMiddleware();
|
|
110
110
|
this.apiServer.setupRoutes(this.app);
|
|
111
|
+
this.setupErrorHandling();
|
|
111
112
|
this.wsServer = new ws_1.WebSocketServer({ server: this.httpServer });
|
|
112
113
|
this.wsProxy.start(this.wsServer);
|
|
113
114
|
this.healthMonitor.start(this.config.healthCheckInterval);
|
|
@@ -300,6 +301,8 @@ class CDPProxyServer {
|
|
|
300
301
|
this.resetAutoShutdownTimer();
|
|
301
302
|
next();
|
|
302
303
|
});
|
|
304
|
+
}
|
|
305
|
+
setupErrorHandling() {
|
|
303
306
|
this.app.use((error, req, res, _next) => {
|
|
304
307
|
this.logger.logAPIEvent(req.method, req.path, 500, 0, req.ip, error);
|
|
305
308
|
this.logger.logSecurityEvent('api_error', 'API error occurred', {
|
|
@@ -418,7 +421,8 @@ class CDPProxyServer {
|
|
|
418
421
|
return config;
|
|
419
422
|
}
|
|
420
423
|
catch (error) {
|
|
421
|
-
|
|
424
|
+
const err = error;
|
|
425
|
+
if (err.code === 'ENOENT') {
|
|
422
426
|
this.logger.info('No configuration file found, using defaults', {
|
|
423
427
|
configPath: configPath.replace(os.homedir(), '~')
|
|
424
428
|
});
|
|
@@ -74,7 +74,7 @@ class CommandExecutionService {
|
|
|
74
74
|
error: error instanceof Error ? error.message : String(error)
|
|
75
75
|
});
|
|
76
76
|
let errorCode = 500;
|
|
77
|
-
|
|
77
|
+
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
|
|
78
78
|
if (errorMessage.includes('Another CLI client')) {
|
|
79
79
|
errorCode = 409;
|
|
80
80
|
}
|
|
@@ -389,12 +389,17 @@ class ProxyAPIServer {
|
|
|
389
389
|
});
|
|
390
390
|
}
|
|
391
391
|
}
|
|
392
|
-
async handleServerHealth(_req, res) {
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
392
|
+
async handleServerHealth(_req, res, next) {
|
|
393
|
+
try {
|
|
394
|
+
res.json({
|
|
395
|
+
success: true,
|
|
396
|
+
data: { status: 'healthy' },
|
|
397
|
+
timestamp: Date.now()
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
catch (error) {
|
|
401
|
+
next(error);
|
|
402
|
+
}
|
|
398
403
|
}
|
|
399
404
|
async handleDetailedHealthCheck(_req, res) {
|
|
400
405
|
try {
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chrome-cdp-cli",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "Browser automation CLI via Chrome DevTools Protocol. Designed for developers and AI assistants - combines dedicated commands for common tasks with flexible JavaScript execution for complex scenarios. Features: element interaction, screenshots, DOM snapshots, console/network monitoring. Built-in IDE integration for Cursor and Claude.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"bin": {
|
|
8
|
-
"chrome-cdp-cli": "dist/index.js"
|
|
8
|
+
"chrome-cdp-cli": "dist/index.js",
|
|
9
|
+
"cdp": "dist/index.js"
|
|
9
10
|
},
|
|
10
11
|
"files": [
|
|
11
12
|
"dist/**/*",
|