@dynamicu/chromedebug-mcp 2.5.14 → 2.5.15

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.
@@ -83,10 +83,10 @@ async function startHttpServer(chromeController = null, targetPort = null) {
83
83
  const contentType = req.get('content-type') || 'none';
84
84
  const contentLength = req.get('content-length') || '0';
85
85
 
86
- console.log(`[RAW-REQUEST] ${timestamp} - ${req.method} ${req.originalUrl}`);
87
- console.log(`[RAW-REQUEST] IP: ${ip} | UA: ${userAgent}`);
88
- console.log(`[RAW-REQUEST] Content-Type: ${contentType} | Length: ${contentLength}bytes`);
89
- console.log(`[RAW-REQUEST] Headers:`, Object.keys(req.headers).map(h => `${h}=${req.headers[h]}`).join(', '));
86
+ console.error(`[RAW-REQUEST] ${timestamp} - ${req.method} ${req.originalUrl}`);
87
+ console.error(`[RAW-REQUEST] IP: ${ip} | UA: ${userAgent}`);
88
+ console.error(`[RAW-REQUEST] Content-Type: ${contentType} | Length: ${contentLength}bytes`);
89
+ console.error(`[RAW-REQUEST] Headers:`, Object.keys(req.headers).map(h => `${h}=${req.headers[h]}`).join(', '));
90
90
 
91
91
  // Capture body parsing errors
92
92
  const originalJson = express.json();
@@ -96,8 +96,8 @@ async function startHttpServer(chromeController = null, targetPort = null) {
96
96
  const originalStatus = res.status;
97
97
  res.status = function(code) {
98
98
  if (code === 400) {
99
- console.log(`[RAW-REQUEST] HTTP 400 ERROR for ${req.method} ${req.originalUrl}`);
100
- console.log(`[RAW-REQUEST] This request will be rejected with 400`);
99
+ console.error(`[RAW-REQUEST] HTTP 400 ERROR for ${req.method} ${req.originalUrl}`);
100
+ console.error(`[RAW-REQUEST] This request will be rejected with 400`);
101
101
  }
102
102
  return originalStatus.call(this, code);
103
103
  };
@@ -108,10 +108,10 @@ async function startHttpServer(chromeController = null, targetPort = null) {
108
108
  // ENHANCED BODY PARSING - For debugging body parsing issues (only for screen-interactions)
109
109
  app.use('/chromedebug/screen-interactions/*', (req, res, next) => {
110
110
  if (req.method === 'POST') {
111
- console.log(`[BODY-DEBUG] Processing screen-interactions request for ${req.originalUrl}`);
112
- console.log(`[BODY-DEBUG] Content-Type: ${req.get('content-type')}`);
113
- console.log(`[BODY-DEBUG] Content-Length: ${req.get('content-length')}`);
114
- console.log(`[BODY-DEBUG] User-Agent: ${req.get('user-agent')}`);
111
+ console.error(`[BODY-DEBUG] Processing screen-interactions request for ${req.originalUrl}`);
112
+ console.error(`[BODY-DEBUG] Content-Type: ${req.get('content-type')}`);
113
+ console.error(`[BODY-DEBUG] Content-Length: ${req.get('content-length')}`);
114
+ console.error(`[BODY-DEBUG] User-Agent: ${req.get('user-agent')}`);
115
115
 
116
116
  // Store original data handler to capture raw body
117
117
  const originalData = req.on;
@@ -130,16 +130,16 @@ async function startHttpServer(chromeController = null, targetPort = null) {
130
130
  const wrappedHandler = () => {
131
131
  if (chunks.length > 0) {
132
132
  const rawBody = Buffer.concat(chunks).toString();
133
- console.log(`[BODY-DEBUG] Raw body captured (${rawBody.length} chars):`, rawBody);
133
+ console.error(`[BODY-DEBUG] Raw body captured (${rawBody.length} chars):`, rawBody);
134
134
  req.rawBody = rawBody;
135
135
 
136
136
  // Try to parse manually
137
137
  try {
138
138
  const parsedBody = JSON.parse(rawBody);
139
- console.log(`[BODY-DEBUG] Manual JSON parse successful`);
140
- console.log(`[BODY-DEBUG] Parsed data:`, JSON.stringify(parsedBody, null, 2));
139
+ console.error(`[BODY-DEBUG] Manual JSON parse successful`);
140
+ console.error(`[BODY-DEBUG] Parsed data:`, JSON.stringify(parsedBody, null, 2));
141
141
  } catch (parseError) {
142
- console.log(`[BODY-DEBUG] Manual JSON parse FAILED:`, parseError.message);
142
+ console.error(`[BODY-DEBUG] Manual JSON parse FAILED:`, parseError.message);
143
143
  }
144
144
  }
145
145
  return originalHandler();
@@ -155,9 +155,9 @@ async function startHttpServer(chromeController = null, targetPort = null) {
155
155
  // JSON PARSING ERROR HANDLER - Catch malformed JSON before it reaches our handlers
156
156
  app.use('/chromedebug/screen-interactions/*', (err, req, res, next) => {
157
157
  if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {
158
- console.log(`[JSON-PARSE-ERROR] Malformed JSON in screen-interactions request:`, err.message);
159
- console.log(`[JSON-PARSE-ERROR] Raw body:`, req.rawBody || 'not captured');
160
- console.log(`[JSON-PARSE-ERROR] Request body:`, req.body);
158
+ console.error(`[JSON-PARSE-ERROR] Malformed JSON in screen-interactions request:`, err.message);
159
+ console.error(`[JSON-PARSE-ERROR] Raw body:`, req.rawBody || 'not captured');
160
+ console.error(`[JSON-PARSE-ERROR] Request body:`, req.body);
161
161
  return res.status(400).json({
162
162
  error: 'Invalid JSON format',
163
163
  details: err.message
@@ -169,13 +169,13 @@ async function startHttpServer(chromeController = null, targetPort = null) {
169
169
  // ENHANCED VALIDATION ERROR HANDLER - Catch and log detailed validation errors
170
170
  app.use('/chromedebug/screen-interactions/*', (err, req, res, next) => {
171
171
  if (err && err.status === 400 && err.details) {
172
- console.log(`[VALIDATION-ERROR] Screen interactions validation failed:`);
173
- console.log(`[VALIDATION-ERROR] Request path:`, req.originalUrl);
174
- console.log(`[VALIDATION-ERROR] User agent:`, req.get('user-agent'));
175
- console.log(`[VALIDATION-ERROR] Content type:`, req.get('content-type'));
176
- console.log(`[VALIDATION-ERROR] Raw body:`, req.rawBody || 'not captured');
177
- console.log(`[VALIDATION-ERROR] Parsed body:`, JSON.stringify(req.body, null, 2));
178
- console.log(`[VALIDATION-ERROR] Validation errors:`, JSON.stringify(err.details, null, 2));
172
+ console.error(`[VALIDATION-ERROR] Screen interactions validation failed:`);
173
+ console.error(`[VALIDATION-ERROR] Request path:`, req.originalUrl);
174
+ console.error(`[VALIDATION-ERROR] User agent:`, req.get('user-agent'));
175
+ console.error(`[VALIDATION-ERROR] Content type:`, req.get('content-type'));
176
+ console.error(`[VALIDATION-ERROR] Raw body:`, req.rawBody || 'not captured');
177
+ console.error(`[VALIDATION-ERROR] Parsed body:`, JSON.stringify(req.body, null, 2));
178
+ console.error(`[VALIDATION-ERROR] Validation errors:`, JSON.stringify(err.details, null, 2));
179
179
  }
180
180
  next(err);
181
181
  });
@@ -288,8 +288,8 @@ async function startHttpServer(chromeController = null, targetPort = null) {
288
288
  createValidator(workflowRecordingSchema),
289
289
  async (req, res) => {
290
290
  const { sessionId, url, title, includeLogs, actions, logs, functionTraces, name, screenshotSettings } = req.body;
291
- console.log('[HTTP Server] Received workflow recording with name:', name);
292
- console.log('[HTTP Server] Function traces count:', functionTraces ? functionTraces.length : 0);
291
+ console.error('[HTTP Server] Received workflow recording with name:', name);
292
+ console.error('[HTTP Server] Function traces count:', functionTraces ? functionTraces.length : 0);
293
293
  if (!sessionId || !actions) {
294
294
  return res.status(400).json({ error: 'sessionId and actions are required' });
295
295
  }
@@ -360,18 +360,18 @@ async function startHttpServer(chromeController = null, targetPort = null) {
360
360
  return res.status(400).json({ error: 'No data provided' });
361
361
  }
362
362
 
363
- console.log(`[Upload] Received batch ${batchId} for recording ${recordingId} with ${events.length} events`);
363
+ console.error(`[Upload] Received batch ${batchId} for recording ${recordingId} with ${events.length} events`);
364
364
 
365
365
  // Ensure recording exists (auto-create if needed)
366
366
  try {
367
367
  const existingRecording = activeController.database.getRecording(recordingId);
368
368
  if (!existingRecording) {
369
- console.log(`[Upload] Auto-creating recording ${recordingId} for full data upload`);
369
+ console.error(`[Upload] Auto-creating recording ${recordingId} for full data upload`);
370
370
  activeController.database.storeRecording(recordingId, 'full_data_recording');
371
371
  }
372
372
  } catch (error) {
373
373
  // Recording doesn't exist, create it
374
- console.log(`[Upload] Auto-creating recording ${recordingId} for full data upload (error case)`);
374
+ console.error(`[Upload] Auto-creating recording ${recordingId} for full data upload (error case)`);
375
375
  activeController.database.storeRecording(recordingId, 'full_data_recording');
376
376
  }
377
377
 
@@ -394,7 +394,7 @@ async function startHttpServer(chromeController = null, targetPort = null) {
394
394
  await activeController.database.storePerformanceMetric(recordingId, event);
395
395
  break;
396
396
  default:
397
- console.warn(`[Upload] Unknown event type: ${event.type}`);
397
+ console.error(`[Upload] Unknown event type: ${event.type}`);
398
398
  }
399
399
  }
400
400
 
@@ -434,7 +434,7 @@ async function startHttpServer(chromeController = null, targetPort = null) {
434
434
  data = typeof req.body === 'string' ? JSON.parse(req.body) : req.body;
435
435
  }
436
436
 
437
- console.log(`[Upload] Received ${dataType} data for recording ${recordingId}`);
437
+ console.error(`[Upload] Received ${dataType} data for recording ${recordingId}`);
438
438
 
439
439
  // Store data based on type
440
440
  const storeMethod = `store${dataType.charAt(0).toUpperCase() + dataType.slice(1).replace(/-/g, '')}`;
@@ -461,23 +461,23 @@ async function startHttpServer(chromeController = null, targetPort = null) {
461
461
  authorize(PERMISSIONS.FRAME_WRITE),
462
462
  upload.none(),
463
463
  async (req, res) => {
464
- console.log('[FORMDATA-DEBUG] ==========================================');
465
- console.log('[FORMDATA-DEBUG] Frame batch request received');
466
- console.log('[FORMDATA-DEBUG] Content-Type:', req.headers['content-type']);
467
- console.log('[FORMDATA-DEBUG] Request method:', req.method);
468
- console.log('[FORMDATA-DEBUG] User:', req.user?.name || 'unknown');
469
- console.log('[FORMDATA-DEBUG] Raw body keys:', Object.keys(req.body || {}));
470
- console.log('[FORMDATA-DEBUG] Raw body:', req.body);
464
+ console.error('[FORMDATA-DEBUG] ==========================================');
465
+ console.error('[FORMDATA-DEBUG] Frame batch request received');
466
+ console.error('[FORMDATA-DEBUG] Content-Type:', req.headers['content-type']);
467
+ console.error('[FORMDATA-DEBUG] Request method:', req.method);
468
+ console.error('[FORMDATA-DEBUG] User:', req.user?.name || 'unknown');
469
+ console.error('[FORMDATA-DEBUG] Raw body keys:', Object.keys(req.body || {}));
470
+ console.error('[FORMDATA-DEBUG] Raw body:', req.body);
471
471
 
472
472
  // Handle both JSON and FormData
473
473
  let sessionId, frames, sessionName;
474
474
 
475
475
  if (req.headers['content-type']?.includes('application/json')) {
476
- console.log('[FORMDATA-DEBUG] Processing as JSON request');
476
+ console.error('[FORMDATA-DEBUG] Processing as JSON request');
477
477
  // JSON request - validate with schema
478
478
  const { error, value } = frameBatchSchema.validate(req.body);
479
479
  if (error) {
480
- console.log('[FORMDATA-DEBUG] JSON validation failed:', error.details);
480
+ console.error('[FORMDATA-DEBUG] JSON validation failed:', error.details);
481
481
  return res.status(400).json({
482
482
  error: 'Validation failed',
483
483
  details: error.details.map(detail => ({
@@ -490,37 +490,37 @@ async function startHttpServer(chromeController = null, targetPort = null) {
490
490
  frames = value.frames;
491
491
  sessionName = value.sessionName || null;
492
492
 
493
- console.log('[FORMDATA-DEBUG] JSON parsed successfully:', { sessionId, frameCount: frames?.length, sessionName });
493
+ console.error('[FORMDATA-DEBUG] JSON parsed successfully:', { sessionId, frameCount: frames?.length, sessionName });
494
494
  } else {
495
- console.log('[FORMDATA-DEBUG] Processing as FormData request');
495
+ console.error('[FORMDATA-DEBUG] Processing as FormData request');
496
496
 
497
497
  // FormData request - manual validation
498
498
  sessionId = req.body.sessionId;
499
499
  sessionName = req.body.sessionName || null;
500
500
 
501
- console.log('[FORMDATA-DEBUG] SessionId from FormData:', sessionId);
502
- console.log('[FORMDATA-DEBUG] SessionName from FormData:', sessionName);
503
- console.log('[FORMDATA-DEBUG] Frames field type:', typeof req.body.frames);
504
- console.log('[FORMDATA-DEBUG] Frames field length:', req.body.frames?.length);
505
- console.log('[FORMDATA-DEBUG] Frames field preview:', req.body.frames?.substring(0, 200));
501
+ console.error('[FORMDATA-DEBUG] SessionId from FormData:', sessionId);
502
+ console.error('[FORMDATA-DEBUG] SessionName from FormData:', sessionName);
503
+ console.error('[FORMDATA-DEBUG] Frames field type:', typeof req.body.frames);
504
+ console.error('[FORMDATA-DEBUG] Frames field length:', req.body.frames?.length);
505
+ console.error('[FORMDATA-DEBUG] Frames field preview:', req.body.frames?.substring(0, 200));
506
506
 
507
507
  try {
508
508
  if (!req.body.frames) {
509
- console.log('[FORMDATA-DEBUG] ❌ No frames field in FormData');
509
+ console.error('[FORMDATA-DEBUG] ❌ No frames field in FormData');
510
510
  frames = null;
511
511
  } else {
512
- console.log('[FORMDATA-DEBUG] 🔄 Attempting to parse frames JSON...');
512
+ console.error('[FORMDATA-DEBUG] 🔄 Attempting to parse frames JSON...');
513
513
  frames = JSON.parse(req.body.frames);
514
- console.log('[FORMDATA-DEBUG] ✅ Frames JSON parsed successfully');
515
- console.log('[FORMDATA-DEBUG] Parsed frames count:', frames?.length);
516
- console.log('[FORMDATA-DEBUG] First frame structure:', frames?.[0] ? Object.keys(frames[0]) : 'no frames');
514
+ console.error('[FORMDATA-DEBUG] ✅ Frames JSON parsed successfully');
515
+ console.error('[FORMDATA-DEBUG] Parsed frames count:', frames?.length);
516
+ console.error('[FORMDATA-DEBUG] First frame structure:', frames?.[0] ? Object.keys(frames[0]) : 'no frames');
517
517
  }
518
518
 
519
- console.log('[FORMDATA-DEBUG] 🔄 Validating parsed FormData...');
519
+ console.error('[FORMDATA-DEBUG] 🔄 Validating parsed FormData...');
520
520
  // Validate the parsed data
521
521
  const { error, value } = frameBatchSchema.validate({ sessionId, frames, sessionName });
522
522
  if (error) {
523
- console.log('[FORMDATA-DEBUG] ❌ FormData validation failed:', error.details);
523
+ console.error('[FORMDATA-DEBUG] ❌ FormData validation failed:', error.details);
524
524
  return res.status(400).json({
525
525
  error: 'Validation failed',
526
526
  details: error.details.map(detail => ({
@@ -533,7 +533,7 @@ async function startHttpServer(chromeController = null, targetPort = null) {
533
533
  frames = value.frames;
534
534
  sessionName = value.sessionName;
535
535
 
536
- console.log('[FORMDATA-DEBUG] ✅ FormData validation successful');
536
+ console.error('[FORMDATA-DEBUG] ✅ FormData validation successful');
537
537
  } catch (parseError) {
538
538
  console.error('[FORMDATA-DEBUG] ❌ Failed to parse frames JSON:', parseError);
539
539
  console.error('[FORMDATA-DEBUG] Raw frames data:', req.body.frames);
@@ -542,38 +542,38 @@ async function startHttpServer(chromeController = null, targetPort = null) {
542
542
  }
543
543
 
544
544
  if (!sessionId || !frames) {
545
- console.log('[FORMDATA-DEBUG] ❌ Missing required data');
546
- console.log('[FORMDATA-DEBUG] SessionId:', sessionId);
547
- console.log('[FORMDATA-DEBUG] Frames:', frames ? 'present' : 'null');
545
+ console.error('[FORMDATA-DEBUG] ❌ Missing required data');
546
+ console.error('[FORMDATA-DEBUG] SessionId:', sessionId);
547
+ console.error('[FORMDATA-DEBUG] Frames:', frames ? 'present' : 'null');
548
548
  return res.status(400).json({ error: 'sessionId and frames are required' });
549
549
  }
550
550
 
551
- console.log('[FORMDATA-DEBUG] ✅ All data validated, proceeding to storage');
552
- console.log('[FORMDATA-DEBUG] Session ID:', sessionId);
553
- console.log('[FORMDATA-DEBUG] Frame count:', frames?.length);
551
+ console.error('[FORMDATA-DEBUG] ✅ All data validated, proceeding to storage');
552
+ console.error('[FORMDATA-DEBUG] Session ID:', sessionId);
553
+ console.error('[FORMDATA-DEBUG] Frame count:', frames?.length);
554
554
 
555
555
  try {
556
- console.log('[FORMDATA-DEBUG] 🔄 Calling activeController.storeFrameBatch...');
556
+ console.error('[FORMDATA-DEBUG] 🔄 Calling activeController.storeFrameBatch...');
557
557
  if (frames && frames.length > 0) {
558
- console.log('[FORMDATA-DEBUG] First frame structure:', Object.keys(frames[0]));
559
- console.log('[FORMDATA-DEBUG] First frame has imageData:', !!frames[0].imageData);
560
- console.log('[FORMDATA-DEBUG] ImageData length:', frames[0].imageData ? frames[0].imageData.length : 'N/A');
558
+ console.error('[FORMDATA-DEBUG] First frame structure:', Object.keys(frames[0]));
559
+ console.error('[FORMDATA-DEBUG] First frame has imageData:', !!frames[0].imageData);
560
+ console.error('[FORMDATA-DEBUG] ImageData length:', frames[0].imageData ? frames[0].imageData.length : 'N/A');
561
561
  }
562
562
 
563
- console.log('[FORMDATA-DEBUG] Session name:', sessionName || 'none');
563
+ console.error('[FORMDATA-DEBUG] Session name:', sessionName || 'none');
564
564
 
565
565
  const result = await activeController.storeFrameBatch(sessionId, frames, sessionName);
566
- console.log('[FORMDATA-DEBUG] ✅ Frame batch storage result:', result);
566
+ console.error('[FORMDATA-DEBUG] ✅ Frame batch storage result:', result);
567
567
 
568
- console.log('[FORMDATA-DEBUG] Result recording ID:', result?.id);
569
- console.log('[FORMDATA-DEBUG] Result frame count:', result?.total_frames);
570
- console.log('[FORMDATA-DEBUG] ==========================================');
568
+ console.error('[FORMDATA-DEBUG] Result recording ID:', result?.id);
569
+ console.error('[FORMDATA-DEBUG] Result frame count:', result?.total_frames);
570
+ console.error('[FORMDATA-DEBUG] ==========================================');
571
571
 
572
572
  res.json(result);
573
573
  } catch (error) {
574
574
  console.error('[FORMDATA-DEBUG] ❌ Storage error:', error);
575
575
  console.error('[FORMDATA-DEBUG] Error stack:', error.stack);
576
- console.log('[FORMDATA-DEBUG] ==========================================');
576
+ console.error('[FORMDATA-DEBUG] ==========================================');
577
577
  res.status(500).json({ error: 'Failed to store frame batch', details: error.message });
578
578
  }
579
579
  });
@@ -592,7 +592,7 @@ async function startHttpServer(chromeController = null, targetPort = null) {
592
592
 
593
593
  // Debug: Verify logs are properly included and formatted
594
594
  if (result.frames?.length > 0 && result.frames[0]?.logs?.length > 0) {
595
- console.log(`[INFO] Frame session ${sessionId}: Loaded ${result.frames.length} frames with console logs`);
595
+ console.error(`[INFO] Frame session ${sessionId}: Loaded ${result.frames.length} frames with console logs`);
596
596
  }
597
597
 
598
598
  res.json(result);
@@ -655,7 +655,7 @@ async function startHttpServer(chromeController = null, targetPort = null) {
655
655
  if (req.body.logs) {
656
656
  const compliance = analyzeLogFieldCompliance(req.body.logs);
657
657
  if (!compliance.isCompliant) {
658
- console.log('[LogTransform] Applied field filtering:', {
658
+ console.error('[LogTransform] Applied field filtering:', {
659
659
  originalLogs: req.body.logs.length,
660
660
  nonSchemaFields: compliance.nonSchemaFields,
661
661
  missingFields: compliance.missingRequiredFields
@@ -690,7 +690,7 @@ async function startHttpServer(chromeController = null, targetPort = null) {
690
690
  if (logs) {
691
691
  const compliance = analyzeLogFieldCompliance(logs);
692
692
  if (!compliance.isCompliant) {
693
- console.log('[LogTransform] Applied field filtering (FormData):', {
693
+ console.error('[LogTransform] Applied field filtering (FormData):', {
694
694
  originalLogs: logs.length,
695
695
  nonSchemaFields: compliance.nonSchemaFields,
696
696
  missingFields: compliance.missingRequiredFields
@@ -1096,27 +1096,27 @@ async function startHttpServer(chromeController = null, targetPort = null) {
1096
1096
  const { interactions } = req.body;
1097
1097
 
1098
1098
  // Debug logging to identify validation issues
1099
- console.log('[SCREEN-INTERACTIONS-DEBUG] ==========================================');
1100
- console.log('[SCREEN-INTERACTIONS-DEBUG] Request received for session:', sessionId);
1101
- console.log('[SCREEN-INTERACTIONS-DEBUG] Content-Type:', req.get('content-type'));
1102
- console.log('[SCREEN-INTERACTIONS-DEBUG] User agent:', req.get('user-agent'));
1103
- console.log('[SCREEN-INTERACTIONS-DEBUG] Auth user:', req.user?.name || 'unknown');
1104
- console.log('[SCREEN-INTERACTIONS-DEBUG] Request body keys:', Object.keys(req.body || {}));
1105
- console.log('[SCREEN-INTERACTIONS-DEBUG] Interactions field present:', !!interactions);
1106
- console.log('[SCREEN-INTERACTIONS-DEBUG] Interactions type:', typeof interactions);
1107
- console.log('[SCREEN-INTERACTIONS-DEBUG] Interactions length:', Array.isArray(interactions) ? interactions.length : 'N/A');
1099
+ console.error('[SCREEN-INTERACTIONS-DEBUG] ==========================================');
1100
+ console.error('[SCREEN-INTERACTIONS-DEBUG] Request received for session:', sessionId);
1101
+ console.error('[SCREEN-INTERACTIONS-DEBUG] Content-Type:', req.get('content-type'));
1102
+ console.error('[SCREEN-INTERACTIONS-DEBUG] User agent:', req.get('user-agent'));
1103
+ console.error('[SCREEN-INTERACTIONS-DEBUG] Auth user:', req.user?.name || 'unknown');
1104
+ console.error('[SCREEN-INTERACTIONS-DEBUG] Request body keys:', Object.keys(req.body || {}));
1105
+ console.error('[SCREEN-INTERACTIONS-DEBUG] Interactions field present:', !!interactions);
1106
+ console.error('[SCREEN-INTERACTIONS-DEBUG] Interactions type:', typeof interactions);
1107
+ console.error('[SCREEN-INTERACTIONS-DEBUG] Interactions length:', Array.isArray(interactions) ? interactions.length : 'N/A');
1108
1108
  if (Array.isArray(interactions) && interactions.length > 0) {
1109
- console.log('[SCREEN-INTERACTIONS-DEBUG] First interaction:', JSON.stringify(interactions[0], null, 2));
1109
+ console.error('[SCREEN-INTERACTIONS-DEBUG] First interaction:', JSON.stringify(interactions[0], null, 2));
1110
1110
  }
1111
- console.log('[SCREEN-INTERACTIONS-DEBUG] Raw body:', JSON.stringify(req.body, null, 2));
1112
- console.log('[SCREEN-INTERACTIONS-DEBUG] ==========================================');
1111
+ console.error('[SCREEN-INTERACTIONS-DEBUG] Raw body:', JSON.stringify(req.body, null, 2));
1112
+ console.error('[SCREEN-INTERACTIONS-DEBUG] ==========================================');
1113
1113
 
1114
1114
  try {
1115
1115
  const { database } = await import('./database.js');
1116
1116
  const result = database.storeScreenInteractions(sessionId, interactions);
1117
1117
 
1118
1118
  if (result.success) {
1119
- console.log(`[HTTP] Stored ${result.count} screen interactions for recording ${sessionId}`);
1119
+ console.error(`[HTTP] Stored ${result.count} screen interactions for recording ${sessionId}`);
1120
1120
  res.json({ success: true, count: result.count });
1121
1121
  } else {
1122
1122
  res.status(500).json({ success: false, error: result.error });
@@ -1131,14 +1131,14 @@ async function startHttpServer(chromeController = null, targetPort = null) {
1131
1131
  app.post('/chromedebug/debug-interactions/:sessionId',
1132
1132
  authenticate,
1133
1133
  (req, res) => {
1134
- console.log('[DEBUG-ENDPOINT] ==========================================');
1135
- console.log('[DEBUG-ENDPOINT] Auth bypass test successful!');
1136
- console.log('[DEBUG-ENDPOINT] User:', JSON.stringify(req.user, null, 2));
1137
- console.log('[DEBUG-ENDPOINT] Session ID:', req.params.sessionId);
1138
- console.log('[DEBUG-ENDPOINT] Content-Type:', req.get('content-type'));
1139
- console.log('[DEBUG-ENDPOINT] Request headers:', Object.keys(req.headers));
1140
- console.log('[DEBUG-ENDPOINT] Request body:', JSON.stringify(req.body, null, 2));
1141
- console.log('[DEBUG-ENDPOINT] ==========================================');
1134
+ console.error('[DEBUG-ENDPOINT] ==========================================');
1135
+ console.error('[DEBUG-ENDPOINT] Auth bypass test successful!');
1136
+ console.error('[DEBUG-ENDPOINT] User:', JSON.stringify(req.user, null, 2));
1137
+ console.error('[DEBUG-ENDPOINT] Session ID:', req.params.sessionId);
1138
+ console.error('[DEBUG-ENDPOINT] Content-Type:', req.get('content-type'));
1139
+ console.error('[DEBUG-ENDPOINT] Request headers:', Object.keys(req.headers));
1140
+ console.error('[DEBUG-ENDPOINT] Request body:', JSON.stringify(req.body, null, 2));
1141
+ console.error('[DEBUG-ENDPOINT] ==========================================');
1142
1142
 
1143
1143
  res.json({
1144
1144
  debug: true,
@@ -1316,7 +1316,7 @@ async function startHttpServer(chromeController = null, targetPort = null) {
1316
1316
 
1317
1317
  // Add a catch-all route for debugging
1318
1318
  app.use('*', (req, res, next) => {
1319
- console.log(`[HTTP] ${req.method} ${req.originalUrl}`);
1319
+ console.error(`[HTTP] ${req.method} ${req.originalUrl}`);
1320
1320
  next();
1321
1321
  });
1322
1322
 
@@ -1325,7 +1325,7 @@ async function startHttpServer(chromeController = null, targetPort = null) {
1325
1325
 
1326
1326
  // 404 handler - must be last
1327
1327
  app.use((req, res) => {
1328
- console.log(`[HTTP] 404 - Route not found: ${req.method} ${req.originalUrl}`);
1328
+ console.error(`[HTTP] 404 - Route not found: ${req.method} ${req.originalUrl}`);
1329
1329
  res.status(404).json({
1330
1330
  success: false,
1331
1331
  error: 'Endpoint not found',
@@ -1353,7 +1353,7 @@ async function startHttpServer(chromeController = null, targetPort = null) {
1353
1353
  if (targetPort) {
1354
1354
  // Use the target port provided by session manager
1355
1355
  portsToTry = [targetPort];
1356
- console.log(`Attempting to start HTTP server on session manager allocated port: ${targetPort}`);
1356
+ console.error(`Attempting to start HTTP server on session manager allocated port: ${targetPort}`);
1357
1357
  } else {
1358
1358
  // Fall back to configured ports
1359
1359
  const configuredPorts = configLoader.getHttpServerPorts();
@@ -1364,7 +1364,7 @@ async function startHttpServer(chromeController = null, targetPort = null) {
1364
1364
  ? [startPort, ...configuredPorts.filter(p => p !== startPort)]
1365
1365
  : configuredPorts;
1366
1366
 
1367
- console.log('Attempting to start HTTP server on configured ports:', portsToTry);
1367
+ console.error('Attempting to start HTTP server on configured ports:', portsToTry);
1368
1368
  }
1369
1369
 
1370
1370
  // Try configured ports in order
@@ -1393,7 +1393,7 @@ async function startHttpServer(chromeController = null, targetPort = null) {
1393
1393
  throw new Error(`Could not find available port for HTTP server. All ports in use: ${portsToTry.join(', ')}`);
1394
1394
  }
1395
1395
 
1396
- console.log(`HTTP server started on port ${actualPort}`);
1396
+ console.error(`HTTP server started on port ${actualPort}`);
1397
1397
 
1398
1398
  // Write port file for discovery
1399
1399
  writePortFile(actualPort);
@@ -141,7 +141,7 @@ class ChromePilotApp {
141
141
  * Shows help information
142
142
  */
143
143
  showHelp() {
144
- console.log(`
144
+ console.error(`
145
145
  Chrome Debug MCP Server - Modular Architecture
146
146
 
147
147
  Usage: node src/index.js [options]
package/src/index.js CHANGED
@@ -201,7 +201,7 @@ class ChromePilotApp {
201
201
  * Shows help information
202
202
  */
203
203
  showHelp() {
204
- console.log(`
204
+ console.error(`
205
205
  Chrome Debug MCP Server - Modular Architecture with Session Isolation
206
206
 
207
207
  Usage: node src/index.js [options]
@@ -229,7 +229,7 @@ export class ChromeToolHandler {
229
229
 
230
230
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
231
231
  try {
232
- console.log(`[ChromeToolHandler] Attempt ${attempt}/${maxRetries} for ${name} (Session: ${this.chromeController.sessionId})`);
232
+ console.error(`[ChromeToolHandler] Attempt ${attempt}/${maxRetries} for ${name} (Session: ${this.chromeController.sessionId})`);
233
233
 
234
234
  // Execute the operation based on name
235
235
  switch (name) {
@@ -254,7 +254,7 @@ export class ChromeToolHandler {
254
254
  const isSessionConflict = this.isSessionConflictError(error);
255
255
 
256
256
  if (isSessionConflict && attempt < maxRetries) {
257
- console.log(`[ChromeToolHandler] Detected session conflict, attempting recovery...`);
257
+ console.error(`[ChromeToolHandler] Detected session conflict, attempting recovery...`);
258
258
 
259
259
  try {
260
260
  // Force cleanup current session and create new one
@@ -263,7 +263,7 @@ export class ChromeToolHandler {
263
263
  // Wait a bit before retrying to let system stabilize
264
264
  await new Promise(resolve => setTimeout(resolve, 1000 + (attempt * 500)));
265
265
 
266
- console.log(`[ChromeToolHandler] Session recovery completed, retrying...`);
266
+ console.error(`[ChromeToolHandler] Session recovery completed, retrying...`);
267
267
  } catch (recoveryError) {
268
268
  console.error(`[ChromeToolHandler] Session recovery failed:`, recoveryError.message);
269
269
  }
@@ -96,7 +96,7 @@ export class FrameToolHandler {
96
96
  }
97
97
  } catch (error) {
98
98
  // Fall back to direct database access if HTTP client fails
99
- console.warn('[FrameToolHandler] HTTP client failed, falling back to direct access:', error.message);
99
+ console.error('[FrameToolHandler] HTTP client failed, falling back to direct access:', error.message);
100
100
  sessionInfo = await this.chromeController.getFrameSessionInfo(args.sessionId);
101
101
  if (!sessionInfo) {
102
102
  availableSessions = await this.chromeController.listFrameSessions();
@@ -167,7 +167,7 @@ export class FrameToolHandler {
167
167
  result.note = 'No frame data or interactions found. This may indicate the recording was started but stopped immediately.';
168
168
  }
169
169
  } catch (error) {
170
- console.warn('[FrameToolHandler] Failed to check interactions:', error.message);
170
+ console.error('[FrameToolHandler] Failed to check interactions:', error.message);
171
171
  result.note = 'No frame data found. Unable to check for interactions.';
172
172
  }
173
173
 
@@ -285,7 +285,7 @@ export class FrameToolHandler {
285
285
  frameData.interactionMetadata = { totalFound: 0, displayed: 0, timeWindow: 500 };
286
286
  }
287
287
  } catch (error) {
288
- console.warn('[FrameToolHandler] Failed to get frame interactions:', error.message);
288
+ console.error('[FrameToolHandler] Failed to get frame interactions:', error.message);
289
289
  frameData.interactions = [];
290
290
  frameData.associatedInteractions = [];
291
291
  frameData.interactionMetadata = { totalFound: 0, displayed: 0, timeWindow: 500 };
@@ -329,7 +329,7 @@ export class FrameToolHandler {
329
329
  }
330
330
  }
331
331
  } catch (error) {
332
- console.warn('[FrameToolHandler] HTTP client failed, falling back to direct access:', error.message);
332
+ console.error('[FrameToolHandler] HTTP client failed, falling back to direct access:', error.message);
333
333
  info = await this.chromeController.getFrameSessionInfo(args.sessionId);
334
334
  if (!info) {
335
335
  availableSessions = await this.chromeController.listFrameSessions();
@@ -386,7 +386,7 @@ export class FrameToolHandler {
386
386
  interactionSummary.interactionTypes = Object.entries(typeCount).map(([type, count]) => `${type}: ${count}`);
387
387
  }
388
388
  } catch (error) {
389
- console.warn('[FrameToolHandler] Failed to get interaction summary:', error.message);
389
+ console.error('[FrameToolHandler] Failed to get interaction summary:', error.message);
390
390
  // Keep default empty summary
391
391
  }
392
392
 
@@ -424,7 +424,7 @@ export class FrameToolHandler {
424
424
  frame = await this.chromeController.getFrame(args.sessionId, args.frameIndex);
425
425
  }
426
426
  } catch (error) {
427
- console.warn('[FrameToolHandler] HTTP client failed, falling back to direct access:', error.message);
427
+ console.error('[FrameToolHandler] HTTP client failed, falling back to direct access:', error.message);
428
428
  frame = await this.chromeController.getFrame(args.sessionId, args.frameIndex);
429
429
  }
430
430
 
@@ -534,7 +534,7 @@ export class FrameToolHandler {
534
534
  results = await this.chromeController.searchFrameLogs(args.sessionId, args.searchText, logLevel, maxResults);
535
535
  }
536
536
  } catch (error) {
537
- console.warn('[FrameToolHandler] HTTP client failed, falling back to direct access:', error.message);
537
+ console.error('[FrameToolHandler] HTTP client failed, falling back to direct access:', error.message);
538
538
  results = await this.chromeController.searchFrameLogs(args.sessionId, args.searchText, logLevel, maxResults);
539
539
  }
540
540
 
@@ -577,7 +577,7 @@ export class FrameToolHandler {
577
577
  results = await this.chromeController.getFrameLogsPaginated(args.sessionId, args.frameIndex, offset, limit, logLevel, searchText);
578
578
  }
579
579
  } catch (error) {
580
- console.warn('[FrameToolHandler] HTTP client failed, falling back to direct access:', error.message);
580
+ console.error('[FrameToolHandler] HTTP client failed, falling back to direct access:', error.message);
581
581
  results = await this.chromeController.getFrameLogsPaginated(args.sessionId, args.frameIndex, offset, limit, logLevel, searchText);
582
582
  }
583
583
 
@@ -698,7 +698,7 @@ export class FrameToolHandler {
698
698
  }
699
699
  }
700
700
  } catch (error) {
701
- console.warn('[FrameToolHandler] HTTP client failed, falling back to direct access:', error.message);
701
+ console.error('[FrameToolHandler] HTTP client failed, falling back to direct access:', error.message);
702
702
  if (args.frameIndex !== undefined) {
703
703
  interactions = await this.chromeController.getFrameInteractions(args.sessionId, args.frameIndex);
704
704
  } else {
@@ -936,7 +936,7 @@ export class FrameToolHandler {
936
936
  }
937
937
  }
938
938
  } catch (error) {
939
- console.warn(`Error processing snapshot ${snapshot.id}:`, error.message);
939
+ console.error(`Error processing snapshot ${snapshot.id}:`, error.message);
940
940
  }
941
941
  }
942
942
 
@@ -77,7 +77,7 @@ export class WorkflowToolHandler {
77
77
  recording = await this.chromeController.getWorkflowRecording(args.sessionId);
78
78
  }
79
79
  } catch (error) {
80
- console.warn('[WorkflowToolHandler] HTTP client failed, falling back to direct access:', error.message);
80
+ console.error('[WorkflowToolHandler] HTTP client failed, falling back to direct access:', error.message);
81
81
  recording = await this.chromeController.getWorkflowRecording(args.sessionId);
82
82
  }
83
83
 
@@ -112,7 +112,7 @@ export class WorkflowToolHandler {
112
112
  result = await this.chromeController.listWorkflowRecordings();
113
113
  }
114
114
  } catch (error) {
115
- console.warn('[WorkflowToolHandler] HTTP client failed, falling back to direct access:', error.message);
115
+ console.error('[WorkflowToolHandler] HTTP client failed, falling back to direct access:', error.message);
116
116
  result = await this.chromeController.listWorkflowRecordings();
117
117
  }
118
118
 
@@ -38,7 +38,7 @@ export const corsOptions = {
38
38
  if (isAllowed) {
39
39
  callback(null, true);
40
40
  } else {
41
- console.warn(`CORS: Blocked origin ${origin}`);
41
+ console.error(`CORS: Blocked origin ${origin}`);
42
42
  callback(new Error('Not allowed by CORS policy'));
43
43
  }
44
44
  },
@@ -165,14 +165,14 @@ export function securityLogger(req, res, next) {
165
165
  );
166
166
 
167
167
  if (isSensitive) {
168
- console.log(`[Security] ${req.method} ${req.path} - User: ${req.user?.name || 'unauthenticated'} - IP: ${req.ip}`);
168
+ console.error(`[Security] ${req.method} ${req.path} - User: ${req.user?.name || 'unauthenticated'} - IP: ${req.ip}`);
169
169
  }
170
170
 
171
171
  // Track response time for monitoring
172
172
  res.on('finish', () => {
173
173
  const duration = Date.now() - start;
174
174
  if (duration > 5000) { // Log slow requests
175
- console.warn(`[Performance] Slow request: ${req.method} ${req.path} - ${duration}ms`);
175
+ console.error(`[Performance] Slow request: ${req.method} ${req.path} - ${duration}ms`);
176
176
  }
177
177
  });
178
178
 
@@ -245,7 +245,7 @@ export function createIPWhitelist(allowedIPs = []) {
245
245
  const clientIP = req.ip || req.connection.remoteAddress;
246
246
 
247
247
  if (!allowedIPs.includes(clientIP)) {
248
- console.warn(`[Security] Blocked IP: ${clientIP}`);
248
+ console.error(`[Security] Blocked IP: ${clientIP}`);
249
249
  return res.status(403).json({
250
250
  error: 'IP not whitelisted'
251
251
  });