chrome-cdp-cli 1.5.0 → 1.7.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 CHANGED
@@ -390,6 +390,18 @@ chrome-cdp-cli list_console_messages
390
390
  chrome-cdp-cli list_console_messages --filter '{"types":["error","warn"]}'
391
391
  ```
392
392
 
393
+ **Note**: Console monitoring only captures messages generated *after* monitoring starts. For historical messages or immediate console operations, use the eval-first approach:
394
+
395
+ ```bash
396
+ # Generate and capture console messages in one command
397
+ chrome-cdp-cli eval "console.log('Test message'); console.warn('Warning'); 'Messages logged'"
398
+
399
+ # Check for existing console history (if page maintains it)
400
+ chrome-cdp-cli eval "window.consoleHistory || window._console_logs || 'No custom console history'"
401
+ ```
402
+
403
+ See [Console Monitoring Documentation](docs/CONSOLE_MONITORING.md) for detailed solutions and workarounds.
404
+
393
405
  #### Network Monitoring
394
406
  ```bash
395
407
  # Get latest network request
@@ -6,11 +6,13 @@ const ConnectionManager_1 = require("../connection/ConnectionManager");
6
6
  const handlers_1 = require("../handlers");
7
7
  const logger_1 = require("../utils/logger");
8
8
  const CommandRouter_1 = require("./CommandRouter");
9
+ const ProxyManager_1 = require("../proxy/ProxyManager");
9
10
  class CLIApplication {
10
11
  constructor() {
11
12
  this.cli = new CLIInterface_1.CLIInterface();
12
13
  this.connectionManager = new ConnectionManager_1.ConnectionManager();
13
14
  this.logger = new logger_1.Logger();
15
+ this.proxyManager = ProxyManager_1.ProxyManager.getInstance();
14
16
  this.setupHandlers();
15
17
  }
16
18
  setupHandlers() {
@@ -35,20 +37,40 @@ class CLIApplication {
35
37
  }
36
38
  async run(argv) {
37
39
  try {
40
+ console.log('[DEBUG] CLIApplication.run called with argv:', argv);
38
41
  const command = this.cli.parseArgs(argv);
42
+ console.log('[DEBUG] Parsed command:', command);
43
+ if (command.config.verbose) {
44
+ this.proxyManager.setLogging(true);
45
+ }
46
+ console.log('[DEBUG] Ensuring proxy is ready...');
47
+ await this.ensureProxyReady();
39
48
  if (this.needsConnection(command.name)) {
49
+ console.log('[DEBUG] Command needs connection, ensuring connection...');
40
50
  await this.ensureConnection(command);
41
51
  }
52
+ console.log('[DEBUG] Executing command via CLI interface...');
42
53
  const result = await this.cli.execute(command);
54
+ console.log('[DEBUG] Command execution result:', result);
43
55
  this.outputResult(result, command);
44
56
  return result.exitCode || (result.success ? CommandRouter_1.ExitCode.SUCCESS : CommandRouter_1.ExitCode.GENERAL_ERROR);
45
57
  }
46
58
  catch (error) {
59
+ console.log('[DEBUG] Error in CLIApplication.run:', error);
47
60
  const errorMessage = error instanceof Error ? error.message : String(error);
48
61
  console.error(`Error: ${errorMessage}`);
49
62
  return CommandRouter_1.ExitCode.GENERAL_ERROR;
50
63
  }
51
64
  }
65
+ async ensureProxyReady() {
66
+ try {
67
+ const isReady = await this.proxyManager.ensureProxyReady();
68
+ if (!isReady) {
69
+ }
70
+ }
71
+ catch (error) {
72
+ }
73
+ }
52
74
  needsConnection(commandName) {
53
75
  const noConnectionCommands = [
54
76
  'help',
@@ -104,6 +126,12 @@ class CLIApplication {
104
126
  this.logger.error('Error during shutdown:', error);
105
127
  }
106
128
  }
129
+ try {
130
+ await this.proxyManager.shutdown();
131
+ }
132
+ catch (error) {
133
+ this.logger.error('Error shutting down proxy manager:', error);
134
+ }
107
135
  }
108
136
  getCLI() {
109
137
  return this.cli;
@@ -39,6 +39,7 @@ const path = __importStar(require("path"));
39
39
  const CLIInterface_1 = require("../interfaces/CLIInterface");
40
40
  const CommandRegistry_1 = require("./CommandRegistry");
41
41
  const CommandRouter_1 = require("./CommandRouter");
42
+ const packageJson = require('../../package.json');
42
43
  class CLIInterface {
43
44
  constructor() {
44
45
  this.program = new commander_1.Command();
@@ -50,7 +51,7 @@ class CLIInterface {
50
51
  this.program
51
52
  .name('chrome-cdp-cli')
52
53
  .description('Command-line tool for controlling Chrome browser via DevTools Protocol')
53
- .version('1.0.0')
54
+ .version(packageJson.version)
54
55
  .allowUnknownOption(true)
55
56
  .allowExcessArguments(true);
56
57
  this.program
@@ -65,6 +66,10 @@ class CLIInterface {
65
66
  parseArgs(argv) {
66
67
  try {
67
68
  const args = argv.slice(2);
69
+ if (args.includes('--version') || args.includes('-V')) {
70
+ console.log(packageJson.version);
71
+ process.exit(0);
72
+ }
68
73
  const options = {};
69
74
  const commandArgs = [];
70
75
  let i = 0;
@@ -341,6 +346,65 @@ class CLIInterface {
341
346
  if (result.data === undefined || result.data === null) {
342
347
  return 'Success';
343
348
  }
349
+ let output = '';
350
+ let dataSourceInfo = '';
351
+ if (result.dataSource === 'proxy' && result.hasHistoricalData) {
352
+ dataSourceInfo = '📊 Data from proxy server (includes historical data)\n';
353
+ }
354
+ else if (result.dataSource === 'direct' && result.hasHistoricalData === false) {
355
+ dataSourceInfo = '⚠️ Data from direct connection (new messages only, no historical data)\n';
356
+ }
357
+ if (result.data && typeof result.data === 'object') {
358
+ const data = result.data;
359
+ if (data.messages && Array.isArray(data.messages)) {
360
+ output += dataSourceInfo;
361
+ if (data.messages.length === 0) {
362
+ output += 'No console messages found.';
363
+ }
364
+ else {
365
+ output += `Found ${data.messages.length} console message(s):\n\n`;
366
+ data.messages.forEach((msg, index) => {
367
+ const timestamp = new Date(msg.timestamp).toISOString();
368
+ output += `[${index + 1}] ${timestamp} [${msg.type.toUpperCase()}] ${msg.text}\n`;
369
+ if (msg.args && msg.args.length > 0) {
370
+ output += ` Args: ${JSON.stringify(msg.args)}\n`;
371
+ }
372
+ });
373
+ }
374
+ return output.trim();
375
+ }
376
+ if (data.requests && Array.isArray(data.requests)) {
377
+ output += dataSourceInfo;
378
+ if (data.requests.length === 0) {
379
+ output += 'No network requests found.';
380
+ }
381
+ else {
382
+ output += `Found ${data.requests.length} network request(s):\n\n`;
383
+ data.requests.forEach((req, index) => {
384
+ const timestamp = new Date(req.timestamp).toISOString();
385
+ const status = req.status ? ` [${req.status}]` : ' [pending]';
386
+ output += `[${index + 1}] ${timestamp} ${req.method} ${req.url}${status}\n`;
387
+ });
388
+ }
389
+ return output.trim();
390
+ }
391
+ if (data.type && data.text !== undefined && data.timestamp) {
392
+ output += dataSourceInfo;
393
+ const timestamp = new Date(data.timestamp).toISOString();
394
+ output += `${timestamp} [${data.type.toUpperCase()}] ${data.text}`;
395
+ if (data.args && data.args.length > 0) {
396
+ output += `\nArgs: ${JSON.stringify(data.args)}`;
397
+ }
398
+ return output;
399
+ }
400
+ if (data.requestId && data.url && data.method) {
401
+ output += dataSourceInfo;
402
+ const timestamp = new Date(data.timestamp).toISOString();
403
+ const status = data.status ? ` [${data.status}]` : ' [pending]';
404
+ output += `${timestamp} ${data.method} ${data.url}${status}`;
405
+ return output;
406
+ }
407
+ }
344
408
  if (typeof result.data === 'string') {
345
409
  return result.data;
346
410
  }
@@ -169,14 +169,18 @@ class CommandRouter {
169
169
  }
170
170
  async executeWithTimeout(handler, command) {
171
171
  const timeout = command.config.timeout;
172
+ console.log(`[DEBUG] CommandRouter.executeWithTimeout called for command: ${command.name}, timeout: ${timeout}ms`);
172
173
  const timeoutPromise = new Promise((_, reject) => {
173
174
  setTimeout(() => {
175
+ console.log(`[DEBUG] Command timeout reached for: ${command.name} after ${timeout}ms`);
174
176
  reject(new Error(`Command timeout after ${timeout}ms`));
175
177
  }, timeout);
176
178
  });
179
+ console.log(`[DEBUG] Starting handler execution for: ${command.name}`);
177
180
  const executionPromise = handler.execute(this.client, command.args);
178
181
  try {
179
182
  const result = await Promise.race([executionPromise, timeoutPromise]);
183
+ console.log(`[DEBUG] Command completed successfully for: ${command.name}`);
180
184
  if (!result || typeof result !== 'object') {
181
185
  return {
182
186
  success: false,
@@ -190,6 +194,7 @@ class CommandRouter {
190
194
  return result;
191
195
  }
192
196
  catch (error) {
197
+ console.log(`[DEBUG] Command execution error for: ${command.name}:`, error);
193
198
  if (error instanceof Error && error.message.includes('timeout')) {
194
199
  return {
195
200
  success: false,
@@ -214,6 +219,7 @@ Global Options:
214
219
  -q, --quiet Enable quiet mode
215
220
  -t, --timeout <ms> Command timeout in milliseconds (default: 30000)
216
221
  -c, --config <path> Configuration file path
222
+ -V, --version Show version number
217
223
 
218
224
  Available Commands:
219
225
  ${commands.map(cmd => ` ${cmd.padEnd(20)} - ${this.getCommandDescription(cmd)}`).join('\n')}
@@ -0,0 +1,278 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ProxyClient = void 0;
7
+ const ws_1 = require("ws");
8
+ const node_fetch_1 = __importDefault(require("node-fetch"));
9
+ const ProxyManager_1 = require("../proxy/ProxyManager");
10
+ class ProxyClient {
11
+ constructor(config) {
12
+ this.config = {
13
+ proxyUrl: 'http://localhost:9223',
14
+ fallbackToDirect: true,
15
+ startProxyIfNeeded: true,
16
+ ...config
17
+ };
18
+ this.proxyManager = ProxyManager_1.ProxyManager.getInstance();
19
+ }
20
+ async ensureProxyRunning() {
21
+ if (this.config.startProxyIfNeeded) {
22
+ return await this.proxyManager.ensureProxyReady();
23
+ }
24
+ return await this.isProxyRunning();
25
+ }
26
+ async isProxyAvailable() {
27
+ return await this.isProxyRunning();
28
+ }
29
+ async isProxyRunning() {
30
+ try {
31
+ const controller = new AbortController();
32
+ const timeout = setTimeout(() => controller.abort(), 2000);
33
+ const response = await (0, node_fetch_1.default)(`${this.config.proxyUrl}/api/health`, {
34
+ method: 'GET',
35
+ signal: controller.signal
36
+ });
37
+ clearTimeout(timeout);
38
+ return response.ok;
39
+ }
40
+ catch (error) {
41
+ return false;
42
+ }
43
+ }
44
+ async connect(host, port, targetId) {
45
+ const request = {
46
+ host,
47
+ port,
48
+ targetId
49
+ };
50
+ try {
51
+ const controller = new AbortController();
52
+ const timeout = setTimeout(() => controller.abort(), 30000);
53
+ const response = await (0, node_fetch_1.default)(`${this.config.proxyUrl}/api/connect`, {
54
+ method: 'POST',
55
+ headers: {
56
+ 'Content-Type': 'application/json'
57
+ },
58
+ body: JSON.stringify(request),
59
+ signal: controller.signal
60
+ });
61
+ clearTimeout(timeout);
62
+ if (!response.ok) {
63
+ throw new Error(`Proxy connect failed: ${response.status} ${response.statusText}`);
64
+ }
65
+ const result = await response.json();
66
+ if (!result.success) {
67
+ throw new Error(`Proxy connect failed: ${result.error}`);
68
+ }
69
+ this.connectionId = result.data.connectionId;
70
+ return this.connectionId;
71
+ }
72
+ catch (error) {
73
+ throw new Error(`Failed to connect through proxy: ${error instanceof Error ? error.message : error}`);
74
+ }
75
+ }
76
+ async getConsoleMessages(filter) {
77
+ if (!this.connectionId) {
78
+ throw new Error('No active connection. Call connect() first.');
79
+ }
80
+ try {
81
+ const url = new URL(`${this.config.proxyUrl}/api/console/${this.connectionId}`);
82
+ if (filter) {
83
+ if (filter.types) {
84
+ url.searchParams.set('types', filter.types.join(','));
85
+ }
86
+ if (filter.textPattern) {
87
+ url.searchParams.set('textPattern', filter.textPattern);
88
+ }
89
+ if (filter.maxMessages) {
90
+ url.searchParams.set('maxMessages', filter.maxMessages.toString());
91
+ }
92
+ if (filter.startTime) {
93
+ url.searchParams.set('startTime', filter.startTime.toString());
94
+ }
95
+ if (filter.endTime) {
96
+ url.searchParams.set('endTime', filter.endTime.toString());
97
+ }
98
+ if (filter.source) {
99
+ url.searchParams.set('source', filter.source);
100
+ }
101
+ }
102
+ const controller = new AbortController();
103
+ const timeout = setTimeout(() => controller.abort(), 5000);
104
+ const response = await (0, node_fetch_1.default)(url.toString(), {
105
+ method: 'GET',
106
+ signal: controller.signal
107
+ });
108
+ clearTimeout(timeout);
109
+ if (!response.ok) {
110
+ throw new Error(`Failed to get console messages: ${response.status} ${response.statusText}`);
111
+ }
112
+ const result = await response.json();
113
+ if (!result.success) {
114
+ throw new Error(`Failed to get console messages: ${result.error}`);
115
+ }
116
+ return result.data?.messages || [];
117
+ }
118
+ catch (error) {
119
+ throw new Error(`Failed to get console messages: ${error instanceof Error ? error.message : error}`);
120
+ }
121
+ }
122
+ async getNetworkRequests(filter) {
123
+ if (!this.connectionId) {
124
+ throw new Error('No active connection. Call connect() first.');
125
+ }
126
+ try {
127
+ const url = new URL(`${this.config.proxyUrl}/api/network/${this.connectionId}`);
128
+ if (filter) {
129
+ if (filter.methods) {
130
+ url.searchParams.set('methods', filter.methods.join(','));
131
+ }
132
+ if (filter.statusCodes) {
133
+ url.searchParams.set('statusCodes', filter.statusCodes.join(','));
134
+ }
135
+ if (filter.urlPattern) {
136
+ url.searchParams.set('urlPattern', filter.urlPattern);
137
+ }
138
+ if (filter.maxRequests) {
139
+ url.searchParams.set('maxRequests', filter.maxRequests.toString());
140
+ }
141
+ if (filter.startTime) {
142
+ url.searchParams.set('startTime', filter.startTime.toString());
143
+ }
144
+ if (filter.endTime) {
145
+ url.searchParams.set('endTime', filter.endTime.toString());
146
+ }
147
+ if (filter.includeResponseBody !== undefined) {
148
+ url.searchParams.set('includeResponseBody', filter.includeResponseBody.toString());
149
+ }
150
+ }
151
+ const controller = new AbortController();
152
+ const timeout = setTimeout(() => controller.abort(), 5000);
153
+ const response = await (0, node_fetch_1.default)(url.toString(), {
154
+ method: 'GET',
155
+ signal: controller.signal
156
+ });
157
+ clearTimeout(timeout);
158
+ if (!response.ok) {
159
+ throw new Error(`Failed to get network requests: ${response.status} ${response.statusText}`);
160
+ }
161
+ const result = await response.json();
162
+ if (!result.success) {
163
+ throw new Error(`Failed to get network requests: ${result.error}`);
164
+ }
165
+ return result.data?.requests || [];
166
+ }
167
+ catch (error) {
168
+ throw new Error(`Failed to get network requests: ${error instanceof Error ? error.message : error}`);
169
+ }
170
+ }
171
+ async createWebSocketProxy() {
172
+ if (!this.connectionId) {
173
+ throw new Error('No active connection. Call connect() first.');
174
+ }
175
+ console.log(`[DEBUG] Creating WebSocket proxy for connection: ${this.connectionId}`);
176
+ try {
177
+ const wsUrl = this.config.proxyUrl.replace('http://', 'ws://').replace('https://', 'wss://');
178
+ const fullWsUrl = `${wsUrl}/ws/${this.connectionId}`;
179
+ console.log(`[DEBUG] WebSocket URL: ${fullWsUrl}`);
180
+ const ws = new ws_1.WebSocket(fullWsUrl);
181
+ return new Promise((resolve, reject) => {
182
+ const timeout = setTimeout(() => {
183
+ console.log(`[DEBUG] WebSocket connection timeout for ${this.connectionId}`);
184
+ reject(new Error('WebSocket connection timeout'));
185
+ }, 10000);
186
+ ws.on('open', () => {
187
+ console.log(`[DEBUG] WebSocket connection opened for ${this.connectionId}`);
188
+ clearTimeout(timeout);
189
+ this.wsConnection = ws;
190
+ resolve(ws);
191
+ });
192
+ ws.on('error', (error) => {
193
+ console.log(`[DEBUG] WebSocket connection error for ${this.connectionId}:`, error);
194
+ clearTimeout(timeout);
195
+ reject(error);
196
+ });
197
+ });
198
+ }
199
+ catch (error) {
200
+ console.log(`[DEBUG] Failed to create WebSocket proxy for ${this.connectionId}:`, error);
201
+ throw new Error(`Failed to create WebSocket proxy: ${error instanceof Error ? error.message : error}`);
202
+ }
203
+ }
204
+ async healthCheck() {
205
+ if (!this.connectionId) {
206
+ return null;
207
+ }
208
+ try {
209
+ const controller = new AbortController();
210
+ const timeout = setTimeout(() => controller.abort(), 5000);
211
+ const response = await (0, node_fetch_1.default)(`${this.config.proxyUrl}/api/health/${this.connectionId}`, {
212
+ method: 'GET',
213
+ signal: controller.signal
214
+ });
215
+ clearTimeout(timeout);
216
+ if (!response.ok) {
217
+ throw new Error(`Health check failed: ${response.status} ${response.statusText}`);
218
+ }
219
+ const result = await response.json();
220
+ if (!result.success) {
221
+ throw new Error(`Health check failed: ${result.error}`);
222
+ }
223
+ return result.data || null;
224
+ }
225
+ catch (error) {
226
+ console.warn('Health check failed:', error instanceof Error ? error.message : error);
227
+ return null;
228
+ }
229
+ }
230
+ async disconnect() {
231
+ try {
232
+ if (this.connectionId) {
233
+ try {
234
+ const controller = new AbortController();
235
+ const timeout = setTimeout(() => controller.abort(), 5000);
236
+ await (0, node_fetch_1.default)(`${this.config.proxyUrl}/api/client/release`, {
237
+ method: 'POST',
238
+ headers: {
239
+ 'Content-Type': 'application/json',
240
+ 'x-client-id': `proxy_client_${Date.now()}`
241
+ },
242
+ signal: controller.signal
243
+ });
244
+ clearTimeout(timeout);
245
+ }
246
+ catch (error) {
247
+ }
248
+ }
249
+ if (this.wsConnection) {
250
+ this.wsConnection.close();
251
+ this.wsConnection = undefined;
252
+ }
253
+ if (this.connectionId) {
254
+ try {
255
+ const controller = new AbortController();
256
+ const timeout = setTimeout(() => controller.abort(), 5000);
257
+ await (0, node_fetch_1.default)(`${this.config.proxyUrl}/api/connection/${this.connectionId}`, {
258
+ method: 'DELETE',
259
+ signal: controller.signal
260
+ });
261
+ clearTimeout(timeout);
262
+ }
263
+ catch (error) {
264
+ }
265
+ this.connectionId = undefined;
266
+ }
267
+ }
268
+ catch (error) {
269
+ }
270
+ }
271
+ getConnectionId() {
272
+ return this.connectionId;
273
+ }
274
+ getConfig() {
275
+ return { ...this.config };
276
+ }
277
+ }
278
+ exports.ProxyClient = ProxyClient;
@@ -15,3 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./CDPClient"), exports);
18
+ __exportStar(require("./ProxyClient"), exports);
@@ -1,12 +1,20 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
3
6
  exports.EvaluateScriptHandler = void 0;
7
+ const ProxyClient_1 = require("../client/ProxyClient");
4
8
  const fs_1 = require("fs");
9
+ const node_fetch_1 = __importDefault(require("node-fetch"));
5
10
  class EvaluateScriptHandler {
6
- constructor() {
11
+ constructor(useProxy = false) {
7
12
  this.name = 'eval';
13
+ this.proxyClient = new ProxyClient_1.ProxyClient();
14
+ this.useProxy = useProxy;
8
15
  }
9
16
  async execute(client, args) {
17
+ console.log('[DEBUG] EvaluateScriptHandler.execute called with args:', args);
10
18
  const scriptArgs = args;
11
19
  if (!scriptArgs.expression && !scriptArgs.file) {
12
20
  return {
@@ -20,6 +28,140 @@ class EvaluateScriptHandler {
20
28
  error: 'Cannot specify both "expression" and "file" arguments'
21
29
  };
22
30
  }
31
+ console.log('[DEBUG] Arguments validated, useProxy:', this.useProxy);
32
+ try {
33
+ if (this.useProxy) {
34
+ console.log('[DEBUG] Checking proxy availability...');
35
+ const proxyAvailable = await this.proxyClient.isProxyAvailable();
36
+ console.log('[DEBUG] Proxy available:', proxyAvailable);
37
+ if (proxyAvailable) {
38
+ console.log('[INFO] Using proxy connection for script evaluation');
39
+ console.log('[DEBUG] About to call executeWithProxy...');
40
+ const result = await this.executeWithProxy(scriptArgs);
41
+ console.log('[DEBUG] executeWithProxy returned:', result);
42
+ return result;
43
+ }
44
+ else {
45
+ console.warn('[WARN] Proxy not available, falling back to direct CDP connection');
46
+ }
47
+ }
48
+ }
49
+ catch (error) {
50
+ console.warn('[WARN] Proxy execution failed, falling back to direct CDP:', error instanceof Error ? error.message : error);
51
+ }
52
+ console.log('[DEBUG] Falling back to direct CDP');
53
+ return await this.executeWithDirectCDP(client, scriptArgs);
54
+ }
55
+ async executeWithProxy(scriptArgs) {
56
+ try {
57
+ console.log('[DEBUG] Starting executeWithProxy');
58
+ let expression;
59
+ if (scriptArgs.file) {
60
+ expression = await this.readScriptFile(scriptArgs.file);
61
+ }
62
+ else {
63
+ expression = scriptArgs.expression;
64
+ }
65
+ console.log('[DEBUG] Expression to execute:', expression.substring(0, 100));
66
+ console.log('[DEBUG] Creating new proxy connection...');
67
+ const connectionId = await this.proxyClient.connect('localhost', 9222);
68
+ console.log(`[DEBUG] Created new proxy connection: ${connectionId}`);
69
+ try {
70
+ const result = await this.executeScriptThroughHTTP(connectionId, expression, scriptArgs);
71
+ return {
72
+ success: true,
73
+ data: result
74
+ };
75
+ }
76
+ finally {
77
+ await this.proxyClient.disconnect();
78
+ }
79
+ }
80
+ catch (error) {
81
+ console.log('[DEBUG] Error in executeWithProxy:', error);
82
+ return {
83
+ success: false,
84
+ error: error instanceof Error ? error.message : String(error)
85
+ };
86
+ }
87
+ }
88
+ async executeScriptThroughHTTP(connectionId, expression, args) {
89
+ const timeout = args.timeout || 30000;
90
+ const awaitPromise = args.awaitPromise ?? true;
91
+ const returnByValue = args.returnByValue ?? true;
92
+ console.log(`[DEBUG] Starting HTTP script execution, timeout: ${timeout}ms`);
93
+ console.log(`[DEBUG] Expression: ${expression.substring(0, 100)}${expression.length > 100 ? '...' : ''}`);
94
+ try {
95
+ const proxyUrl = this.proxyClient.getConfig().proxyUrl;
96
+ const commandId = Date.now() + Math.floor(Math.random() * 10000);
97
+ const command = {
98
+ id: commandId,
99
+ method: 'Runtime.evaluate',
100
+ params: {
101
+ expression: expression,
102
+ awaitPromise: awaitPromise,
103
+ returnByValue: returnByValue,
104
+ userGesture: true,
105
+ generatePreview: false
106
+ }
107
+ };
108
+ console.log(`[DEBUG] Sending HTTP command to ${proxyUrl}/api/execute/${connectionId}`);
109
+ const controller = new AbortController();
110
+ const timeoutHandle = setTimeout(() => controller.abort(), timeout);
111
+ try {
112
+ const response = await (0, node_fetch_1.default)(`${proxyUrl}/api/execute/${connectionId}`, {
113
+ method: 'POST',
114
+ headers: {
115
+ 'Content-Type': 'application/json',
116
+ 'x-client-id': `eval_handler_${Date.now()}`
117
+ },
118
+ body: JSON.stringify({
119
+ command,
120
+ timeout
121
+ }),
122
+ signal: controller.signal
123
+ });
124
+ clearTimeout(timeoutHandle);
125
+ if (!response.ok) {
126
+ const errorData = await response.json().catch(() => ({}));
127
+ throw new Error(`HTTP ${response.status}: ${errorData.error || response.statusText}`);
128
+ }
129
+ const result = await response.json();
130
+ console.log(`[DEBUG] HTTP command response:`, result);
131
+ if (!result.success) {
132
+ throw new Error(`Command execution failed: ${result.error || 'Unknown error'}`);
133
+ }
134
+ const commandResult = result.data.result;
135
+ if (result.data.error) {
136
+ throw new Error(`CDP Error: ${result.data.error.message}`);
137
+ }
138
+ if (commandResult.exceptionDetails) {
139
+ console.log(`[DEBUG] Exception details:`, commandResult.exceptionDetails);
140
+ const error = new Error(commandResult.result?.description || 'Script execution failed');
141
+ error.exceptionDetails = commandResult.exceptionDetails;
142
+ throw error;
143
+ }
144
+ let value = commandResult.result?.value;
145
+ if (commandResult.result?.type === 'undefined') {
146
+ value = undefined;
147
+ }
148
+ else if (commandResult.result?.unserializableValue) {
149
+ value = commandResult.result.unserializableValue;
150
+ }
151
+ console.log(`[DEBUG] Successful HTTP result:`, value);
152
+ return value;
153
+ }
154
+ catch (error) {
155
+ clearTimeout(timeoutHandle);
156
+ throw error;
157
+ }
158
+ }
159
+ catch (error) {
160
+ console.log(`[DEBUG] Error in HTTP script execution:`, error);
161
+ throw error;
162
+ }
163
+ }
164
+ async executeWithDirectCDP(client, scriptArgs) {
23
165
  try {
24
166
  let expression;
25
167
  if (scriptArgs.file) {