@dynamicu/chromedebug-mcp 2.3.0 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/database.js CHANGED
@@ -4,6 +4,7 @@ import path from 'path';
4
4
  import { fileURLToPath } from 'url';
5
5
  import fs from 'fs';
6
6
  import { ProjectManager } from './services/project-manager.js';
7
+ import logger from './utils/logger.js';
7
8
 
8
9
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
10
 
@@ -24,7 +25,7 @@ function getDatabasePath() {
24
25
  fs.mkdirSync(dbDir, { recursive: true });
25
26
  }
26
27
 
27
- console.log(`[Database] Using global database: ${globalDbPath}`);
28
+ logger.debug(`[Database] Using global database: ${globalDbPath}`);
28
29
  return globalDbPath;
29
30
  }
30
31
 
@@ -52,7 +53,7 @@ class ChromePilotDatabase {
52
53
  // Create tables
53
54
  this.createTables();
54
55
  this.initialized = true;
55
- console.log(`ChromeDebug MCP database initialized at: ${DB_PATH}`);
56
+ logger.debug(`ChromeDebug MCP database initialized at: ${DB_PATH}`);
56
57
  }
57
58
 
58
59
  createTables() {
@@ -89,11 +90,11 @@ class ChromePilotDatabase {
89
90
  // Add interactions column to existing frames table if it doesn't exist
90
91
  try {
91
92
  this.db.exec(`ALTER TABLE frames ADD COLUMN interactions TEXT DEFAULT '[]'`);
92
- console.log('[Database] Added interactions column to frames table');
93
+ logger.debug('[Database] Added interactions column to frames table');
93
94
  } catch (error) {
94
95
  // Column already exists, ignore error
95
96
  if (!error.message.includes('duplicate column name')) {
96
- console.warn('[Database] Unexpected error adding interactions column:', error.message);
97
+ logger.warn('[Database] Unexpected error adding interactions column:', error.message);
97
98
  }
98
99
  }
99
100
 
@@ -214,41 +215,41 @@ class ChromePilotDatabase {
214
215
 
215
216
  if (!hasComponent) {
216
217
  this.db.exec('ALTER TABLE workflow_actions ADD COLUMN component TEXT');
217
- console.log('[Database] Added component column to workflow_actions');
218
+ logger.debug('[Database] Added component column to workflow_actions');
218
219
  }
219
220
  if (!hasArgs) {
220
221
  this.db.exec('ALTER TABLE workflow_actions ADD COLUMN args TEXT');
221
- console.log('[Database] Added args column to workflow_actions');
222
+ logger.debug('[Database] Added args column to workflow_actions');
222
223
  }
223
224
  if (!hasStack) {
224
225
  this.db.exec('ALTER TABLE workflow_actions ADD COLUMN stack TEXT');
225
- console.log('[Database] Added stack column to workflow_actions');
226
+ logger.debug('[Database] Added stack column to workflow_actions');
226
227
  }
227
228
 
228
229
  // Add enhanced click tracking columns
229
230
  if (!hasElementHtml) {
230
231
  this.db.exec('ALTER TABLE workflow_actions ADD COLUMN element_html TEXT');
231
- console.log('[Database] Added element_html column to workflow_actions');
232
+ logger.debug('[Database] Added element_html column to workflow_actions');
232
233
  }
233
234
  if (!hasComponentData) {
234
235
  this.db.exec('ALTER TABLE workflow_actions ADD COLUMN component_data TEXT');
235
- console.log('[Database] Added component_data column to workflow_actions');
236
+ logger.debug('[Database] Added component_data column to workflow_actions');
236
237
  }
237
238
  if (!hasEventHandlers) {
238
239
  this.db.exec('ALTER TABLE workflow_actions ADD COLUMN event_handlers TEXT');
239
- console.log('[Database] Added event_handlers column to workflow_actions');
240
+ logger.debug('[Database] Added event_handlers column to workflow_actions');
240
241
  }
241
242
  if (!hasElementState) {
242
243
  this.db.exec('ALTER TABLE workflow_actions ADD COLUMN element_state TEXT');
243
- console.log('[Database] Added element_state column to workflow_actions');
244
+ logger.debug('[Database] Added element_state column to workflow_actions');
244
245
  }
245
246
  if (!hasPerformanceMetrics) {
246
247
  this.db.exec('ALTER TABLE workflow_actions ADD COLUMN performance_metrics TEXT');
247
- console.log('[Database] Added performance_metrics column to workflow_actions');
248
+ logger.debug('[Database] Added performance_metrics column to workflow_actions');
248
249
  }
249
250
  } catch (error) {
250
251
  // Columns might already exist, that's ok
251
- console.log('[Database] Function trace columns already exist or migration failed:', error.message);
252
+ logger.debug('[Database] Function trace columns already exist or migration failed:', error.message);
252
253
  }
253
254
 
254
255
  // Add enhanced columns to screen_interactions table
@@ -263,27 +264,27 @@ class ChromePilotDatabase {
263
264
  // Add enhanced click tracking columns to screen_interactions
264
265
  if (!hasScreenElementHtml) {
265
266
  this.db.exec('ALTER TABLE screen_interactions ADD COLUMN element_html TEXT');
266
- console.log('[Database] Added element_html column to screen_interactions');
267
+ logger.debug('[Database] Added element_html column to screen_interactions');
267
268
  }
268
269
  if (!hasScreenComponentData) {
269
270
  this.db.exec('ALTER TABLE screen_interactions ADD COLUMN component_data TEXT');
270
- console.log('[Database] Added component_data column to screen_interactions');
271
+ logger.debug('[Database] Added component_data column to screen_interactions');
271
272
  }
272
273
  if (!hasScreenEventHandlers) {
273
274
  this.db.exec('ALTER TABLE screen_interactions ADD COLUMN event_handlers TEXT');
274
- console.log('[Database] Added event_handlers column to screen_interactions');
275
+ logger.debug('[Database] Added event_handlers column to screen_interactions');
275
276
  }
276
277
  if (!hasScreenElementState) {
277
278
  this.db.exec('ALTER TABLE screen_interactions ADD COLUMN element_state TEXT');
278
- console.log('[Database] Added element_state column to screen_interactions');
279
+ logger.debug('[Database] Added element_state column to screen_interactions');
279
280
  }
280
281
  if (!hasScreenPerformanceMetrics) {
281
282
  this.db.exec('ALTER TABLE screen_interactions ADD COLUMN performance_metrics TEXT');
282
- console.log('[Database] Added performance_metrics column to screen_interactions');
283
+ logger.debug('[Database] Added performance_metrics column to screen_interactions');
283
284
  }
284
285
  } catch (error) {
285
286
  // Columns might already exist, that's ok
286
- console.log('[Database] Screen interactions enhanced columns already exist or migration failed:', error.message);
287
+ logger.debug('[Database] Screen interactions enhanced columns already exist or migration failed:', error.message);
287
288
  }
288
289
 
289
290
  // Restore points table
@@ -461,12 +462,12 @@ class ChromePilotDatabase {
461
462
  const hasScreenshotSettings = columns.some(col => col.name === 'screenshot_settings');
462
463
 
463
464
  if (!hasNameColumn) {
464
- console.log('[Database] Migrating workflow_recordings table to add name column');
465
+ logger.debug('[Database] Migrating workflow_recordings table to add name column');
465
466
  this.db.exec(`ALTER TABLE workflow_recordings ADD COLUMN name TEXT`);
466
467
  }
467
468
 
468
469
  if (!hasScreenshotSettings) {
469
- console.log('[Database] Migrating workflow_recordings table to add screenshot_settings column');
470
+ logger.debug('[Database] Migrating workflow_recordings table to add screenshot_settings column');
470
471
  this.db.exec(`ALTER TABLE workflow_recordings ADD COLUMN screenshot_settings TEXT`);
471
472
  }
472
473
 
@@ -475,7 +476,7 @@ class ChromePilotDatabase {
475
476
  const hasScreenshotData = actionColumns.some(col => col.name === 'screenshot_data');
476
477
 
477
478
  if (!hasScreenshotData) {
478
- console.log('[Database] Migrating workflow_actions table to add screenshot_data column');
479
+ logger.debug('[Database] Migrating workflow_actions table to add screenshot_data column');
479
480
  this.db.exec(`ALTER TABLE workflow_actions ADD COLUMN screenshot_data TEXT`);
480
481
  }
481
482
 
@@ -484,7 +485,7 @@ class ChromePilotDatabase {
484
485
  const hasSequenceNumber = logColumns.some(col => col.name === 'sequence_number');
485
486
 
486
487
  if (!hasSequenceNumber) {
487
- console.log('[Database] Migrating console_logs table to add sequence_number column');
488
+ logger.debug('[Database] Migrating console_logs table to add sequence_number column');
488
489
  this.db.exec(`ALTER TABLE console_logs ADD COLUMN sequence_number INTEGER DEFAULT 0`);
489
490
  }
490
491
 
@@ -495,17 +496,17 @@ class ChromePilotDatabase {
495
496
  const hasName = recordingsColumns.some(col => col.name === 'name');
496
497
 
497
498
  if (!hasRecordingType) {
498
- console.log('[Database] Migrating recordings table to add recording_type column');
499
+ logger.debug('[Database] Migrating recordings table to add recording_type column');
499
500
  this.db.exec(`ALTER TABLE recordings ADD COLUMN recording_type TEXT DEFAULT 'continuous'`);
500
501
  }
501
502
 
502
503
  if (!hasUserNote) {
503
- console.log('[Database] Migrating recordings table to add user_note column');
504
+ logger.debug('[Database] Migrating recordings table to add user_note column');
504
505
  this.db.exec(`ALTER TABLE recordings ADD COLUMN user_note TEXT`);
505
506
  }
506
507
 
507
508
  if (!hasName) {
508
- console.log('[Database] Migrating recordings table to add name column');
509
+ logger.debug('[Database] Migrating recordings table to add name column');
509
510
  this.db.exec(`ALTER TABLE recordings ADD COLUMN name TEXT`);
510
511
  }
511
512
  }
@@ -523,9 +524,9 @@ class ChromePilotDatabase {
523
524
  const recordingId = sessionId;
524
525
  const timestamp = Date.now();
525
526
 
526
- console.log(`[Database] Storing recording: ${recordingId} for session: ${sessionId}, type: ${recordingType}, name: ${name || 'none'}`);
527
+ logger.debug(`[Database] Storing recording: ${recordingId} for session: ${sessionId}, type: ${recordingType}, name: ${name || 'none'}`);
527
528
  const result = stmt.run(recordingId, sessionId, type, timestamp, recordingType, userNote, name);
528
- console.log(`[Database] Recording stored with changes: ${result.changes}, lastInsertRowid: ${result.lastInsertRowid}`);
529
+ logger.debug(`[Database] Recording stored with changes: ${result.changes}, lastInsertRowid: ${result.lastInsertRowid}`);
529
530
 
530
531
  return recordingId;
531
532
  }
@@ -562,7 +563,7 @@ class ChromePilotDatabase {
562
563
  this.storeFrameBatch(sessionId, [frameData]);
563
564
  }
564
565
 
565
- console.log(`[Database] Snapshot stored: ${recordingId} with note: ${userNote || 'none'}`);
566
+ logger.debug(`[Database] Snapshot stored: ${recordingId} with note: ${userNote || 'none'}`);
566
567
  return recordingId;
567
568
  }
568
569
 
@@ -590,26 +591,26 @@ class ChromePilotDatabase {
590
591
  // Use base ID instead of prefixed ID
591
592
  const recordingId = sessionId;
592
593
 
593
- console.log(`[storeFrameBatch] DEATH SPIRAL FIX: Processing ${frames.length} frames for session ${sessionId}`);
594
+ logger.debug(`[storeFrameBatch] DEATH SPIRAL FIX: Processing ${frames.length} frames for session ${sessionId}`);
594
595
 
595
596
  // Ensure recording exists (but don't overwrite existing)
596
597
  const existingRecording = this.getRecording(sessionId);
597
598
  if (!existingRecording) {
598
599
  this.storeRecording(sessionId, 'frame_capture', 'continuous', null, name);
599
600
  } else {
600
- console.log(`[storeFrameBatch] Using existing recording: ${existingRecording.id}`);
601
+ logger.debug(`[storeFrameBatch] Using existing recording: ${existingRecording.id}`);
601
602
  // Update name if provided and different
602
603
  if (name && name !== existingRecording.name) {
603
604
  const updateStmt = this.db.prepare(`UPDATE recordings SET name = ? WHERE id = ?`);
604
605
  updateStmt.run(name, sessionId);
605
- console.log(`[storeFrameBatch] Updated recording name to: ${name}`);
606
+ logger.debug(`[storeFrameBatch] Updated recording name to: ${name}`);
606
607
  }
607
608
  }
608
609
 
609
610
  // Check existing frame count BEFORE insertion
610
611
  const preCountStmt = this.db.prepare(`SELECT COUNT(*) as count FROM frames WHERE recording_id = ?`);
611
612
  const preCount = preCountStmt.get(recordingId).count;
612
- console.log(`[storeFrameBatch] PRE-INSERT: ${preCount} existing frames in database`);
613
+ logger.debug(`[storeFrameBatch] PRE-INSERT: ${preCount} existing frames in database`);
613
614
 
614
615
  // Use INSERT OR REPLACE instead of INSERT OR IGNORE to handle updates
615
616
  const frameStmt = this.db.prepare(`
@@ -626,7 +627,7 @@ class ChromePilotDatabase {
626
627
  // Use frame.index from extension (properly tracked per session), fallback to i for backward compatibility
627
628
  const frameIndex = frame.index !== undefined ? frame.index : i;
628
629
 
629
- console.log(`[storeFrameBatch] Inserting frame ${frameIndex}: timestamp=${frame.timestamp}, absoluteTimestamp=${frame.absoluteTimestamp}`);
630
+ logger.debug(`[storeFrameBatch] Inserting frame ${frameIndex}: timestamp=${frame.timestamp}, absoluteTimestamp=${frame.absoluteTimestamp}`);
630
631
 
631
632
  try {
632
633
  // Serialize interactions as JSON
@@ -643,18 +644,18 @@ class ChromePilotDatabase {
643
644
 
644
645
  if (result.changes > 0) {
645
646
  insertedCount++;
646
- console.log(`[storeFrameBatch] SUCCESS: Frame ${frameIndex} inserted/updated`);
647
+ logger.debug(`[storeFrameBatch] SUCCESS: Frame ${frameIndex} inserted/updated`);
647
648
  } else {
648
649
  skippedCount++;
649
- console.log(`[storeFrameBatch] WARNING: Frame ${frameIndex} not changed`);
650
+ logger.debug(`[storeFrameBatch] WARNING: Frame ${frameIndex} not changed`);
650
651
  }
651
652
  } catch (error) {
652
- console.error(`[storeFrameBatch] ERROR inserting frame ${frameIndex}:`, error.message);
653
+ logger.error(`[storeFrameBatch] ERROR inserting frame ${frameIndex}:`, error.message);
653
654
  throw error; // Fail fast on SQL errors
654
655
  }
655
656
  }
656
657
 
657
- console.log(`[storeFrameBatch] Transaction complete: ${insertedCount} inserted, ${skippedCount} skipped`);
658
+ logger.debug(`[storeFrameBatch] Transaction complete: ${insertedCount} inserted, ${skippedCount} skipped`);
658
659
 
659
660
  // Update total frames count
660
661
  const updateStmt = this.db.prepare(`
@@ -668,13 +669,13 @@ class ChromePilotDatabase {
668
669
  // Debug: Check the actual count after update
669
670
  const finalCountStmt = this.db.prepare(`SELECT COUNT(*) as count FROM frames WHERE recording_id = ?`);
670
671
  const finalCount = finalCountStmt.get(recordingId).count;
671
- console.log(`[storeFrameBatch] FINAL: ${finalCount} frames in database (was ${preCount})`);
672
+ logger.debug(`[storeFrameBatch] FINAL: ${finalCount} frames in database (was ${preCount})`);
672
673
 
673
674
  return { insertedCount, skippedCount, finalCount };
674
675
  });
675
676
 
676
677
  const result = transaction(frames);
677
- console.log(`[storeFrameBatch] DEATH SPIRAL RESOLVED: ${result.insertedCount}/${frames.length} frames stored successfully`);
678
+ logger.debug(`[storeFrameBatch] DEATH SPIRAL RESOLVED: ${result.insertedCount}/${frames.length} frames stored successfully`);
678
679
 
679
680
  // Verify what was actually stored
680
681
  const verifyStmt = this.db.prepare(`
@@ -683,10 +684,10 @@ class ChromePilotDatabase {
683
684
  ORDER BY frame_index ASC
684
685
  `);
685
686
  const storedFrames = verifyStmt.all(recordingId);
686
- console.log(`[storeFrameBatch] VERIFICATION: ${storedFrames.length} frames with indices: [${storedFrames.map(f => f.frame_index).join(', ')}]`);
687
+ logger.debug(`[storeFrameBatch] VERIFICATION: ${storedFrames.length} frames with indices: [${storedFrames.map(f => f.frame_index).join(', ')}]`);
687
688
 
688
689
  if (storedFrames.length === 0) {
689
- console.error(`[storeFrameBatch] DEATH SPIRAL DETECTED: NO FRAMES STORED! Check SQL constraints and frame data.`);
690
+ logger.error(`[storeFrameBatch] DEATH SPIRAL DETECTED: NO FRAMES STORED! Check SQL constraints and frame data.`);
690
691
  throw new Error(`Frame storage failed: 0 frames stored for session ${sessionId}`);
691
692
  }
692
693
 
@@ -716,13 +717,13 @@ class ChromePilotDatabase {
716
717
  `);
717
718
  const frames = framesStmt.all(recordingId);
718
719
 
719
- console.log(`[associateLogsWithFrames] Found ${frames.length} frames for log association`);
720
- console.log(`[associateLogsWithFrames] Frame indices found: [${frames.map(f => f.frame_index).join(', ')}]`);
720
+ logger.debug(`[associateLogsWithFrames] Found ${frames.length} frames for log association`);
721
+ logger.debug(`[associateLogsWithFrames] Frame indices found: [${frames.map(f => f.frame_index).join(', ')}]`);
721
722
 
722
723
  // Debug: Check total frames before processing
723
724
  const countStmt = this.db.prepare(`SELECT COUNT(*) as count FROM frames WHERE recording_id = ?`);
724
725
  const frameCount = countStmt.get(recordingId).count;
725
- console.log(`[associateLogsWithFrames] Total frames in database before log association: ${frameCount}`);
726
+ logger.debug(`[associateLogsWithFrames] Total frames in database before log association: ${frameCount}`);
726
727
 
727
728
  if (frames.length === 0) {
728
729
  return { success: false, message: 'No frames found for session' };
@@ -775,11 +776,11 @@ class ChromePilotDatabase {
775
776
 
776
777
  const associatedCount = transaction(logs, frames);
777
778
 
778
- console.log(`Associated ${associatedCount} of ${logs.length} logs with frames`);
779
+ logger.debug(`Associated ${associatedCount} of ${logs.length} logs with frames`);
779
780
 
780
781
  // Debug: Check total frames after processing
781
782
  const finalFrameCount = countStmt.get(recordingId).count;
782
- console.log(`[associateLogsWithFrames] Total frames in database after log association: ${finalFrameCount}`);
783
+ logger.debug(`[associateLogsWithFrames] Total frames in database after log association: ${finalFrameCount}`);
783
784
 
784
785
  return {
785
786
  success: true,
@@ -796,7 +797,7 @@ class ChromePilotDatabase {
796
797
  // Use base ID instead of prefixed ID
797
798
  const recordingId = sessionId;
798
799
 
799
- console.log(`[streamLogsToFrames] Processing ${logs.length} logs for session: ${sessionId}`);
800
+ logger.debug(`[streamLogsToFrames] Processing ${logs.length} logs for session: ${sessionId}`);
800
801
 
801
802
  // Get all frames sorted by timestamp for efficient association
802
803
  const framesStmt = this.db.prepare(`
@@ -808,7 +809,7 @@ class ChromePilotDatabase {
808
809
  const frames = framesStmt.all(recordingId);
809
810
 
810
811
  if (frames.length === 0) {
811
- console.log(`[streamLogsToFrames] No frames found for session: ${sessionId}, storing ${logs.length} logs as deferred`);
812
+ logger.debug(`[streamLogsToFrames] No frames found for session: ${sessionId}, storing ${logs.length} logs as deferred`);
812
813
  return this.storeDeferredLogs(sessionId, logs);
813
814
  }
814
815
 
@@ -882,7 +883,7 @@ class ChromePilotDatabase {
882
883
 
883
884
  const associatedCount = transaction(logs, frames);
884
885
 
885
- console.log(`[streamLogsToFrames] Streamed ${associatedCount} of ${logs.length} logs to frames`);
886
+ logger.debug(`[streamLogsToFrames] Streamed ${associatedCount} of ${logs.length} logs to frames`);
886
887
 
887
888
  return {
888
889
  success: true,
@@ -897,7 +898,7 @@ class ChromePilotDatabase {
897
898
  storeDeferredLogs(sessionId, logs) {
898
899
  this.init();
899
900
 
900
- console.log(`[storeDeferredLogs] Storing ${logs.length} deferred logs for session: ${sessionId}`);
901
+ logger.debug(`[storeDeferredLogs] Storing ${logs.length} deferred logs for session: ${sessionId}`);
901
902
 
902
903
  const deferredLogStmt = this.db.prepare(`
903
904
  INSERT INTO deferred_logs (session_id, level, message, timestamp, sequence_number, args)
@@ -918,7 +919,7 @@ class ChromePilotDatabase {
918
919
  );
919
920
  stored++;
920
921
  } catch (error) {
921
- console.error(`[storeDeferredLogs] Failed to store deferred log:`, error, log);
922
+ logger.error(`[storeDeferredLogs] Failed to store deferred log:`, error, log);
922
923
  }
923
924
  }
924
925
  return stored;
@@ -926,7 +927,7 @@ class ChromePilotDatabase {
926
927
 
927
928
  const storedCount = transaction(logs);
928
929
 
929
- console.log(`[storeDeferredLogs] Stored ${storedCount} of ${logs.length} deferred logs`);
930
+ logger.debug(`[storeDeferredLogs] Stored ${storedCount} of ${logs.length} deferred logs`);
930
931
 
931
932
  return {
932
933
  success: true,
@@ -941,7 +942,7 @@ class ChromePilotDatabase {
941
942
  associateDeferredLogs(sessionId) {
942
943
  this.init();
943
944
 
944
- console.log(`[associateDeferredLogs] Checking for deferred logs for session: ${sessionId}`);
945
+ logger.debug(`[associateDeferredLogs] Checking for deferred logs for session: ${sessionId}`);
945
946
 
946
947
  // Get deferred logs for this session
947
948
  const deferredLogsStmt = this.db.prepare(`
@@ -953,11 +954,11 @@ class ChromePilotDatabase {
953
954
  const deferredLogs = deferredLogsStmt.all(sessionId);
954
955
 
955
956
  if (deferredLogs.length === 0) {
956
- console.log(`[associateDeferredLogs] No deferred logs found for session: ${sessionId}`);
957
+ logger.debug(`[associateDeferredLogs] No deferred logs found for session: ${sessionId}`);
957
958
  return { success: true, logsAssociated: 0 };
958
959
  }
959
960
 
960
- console.log(`[associateDeferredLogs] Found ${deferredLogs.length} deferred logs, attempting to associate with frames`);
961
+ logger.debug(`[associateDeferredLogs] Found ${deferredLogs.length} deferred logs, attempting to associate with frames`);
961
962
 
962
963
  // Convert deferred logs back to the format expected by streamLogsToFrames
963
964
  const logs = deferredLogs.map(log => ({
@@ -975,7 +976,7 @@ class ChromePilotDatabase {
975
976
  // Successfully associated - clean up deferred logs
976
977
  const cleanupStmt = this.db.prepare(`DELETE FROM deferred_logs WHERE session_id = ?`);
977
978
  cleanupStmt.run(sessionId);
978
- console.log(`[associateDeferredLogs] Successfully associated ${result.logsStreamed} logs and cleaned up deferred storage`);
979
+ logger.debug(`[associateDeferredLogs] Successfully associated ${result.logsStreamed} logs and cleaned up deferred storage`);
979
980
 
980
981
  return {
981
982
  success: true,
@@ -984,7 +985,7 @@ class ChromePilotDatabase {
984
985
  };
985
986
  }
986
987
 
987
- console.log(`[associateDeferredLogs] Frames still not available for session: ${sessionId}`);
988
+ logger.debug(`[associateDeferredLogs] Frames still not available for session: ${sessionId}`);
988
989
  return { success: false, message: 'Frames still not available' };
989
990
  }
990
991
 
@@ -992,13 +993,13 @@ class ChromePilotDatabase {
992
993
  getRecording(recordingId) {
993
994
  this.init();
994
995
 
995
- console.log(`[getRecording] Looking for recording with ID: ${recordingId}`);
996
+ logger.debug(`[getRecording] Looking for recording with ID: ${recordingId}`);
996
997
 
997
998
  // Handle both old format (frame_<id>) and new format (base id)
998
999
  let baseId = recordingId;
999
1000
  if (recordingId.startsWith('frame_')) {
1000
1001
  baseId = recordingId.substring(6); // Remove 'frame_' prefix
1001
- console.log(`[getRecording] Converting old format ID ${recordingId} to base ID: ${baseId}`);
1002
+ logger.debug(`[getRecording] Converting old format ID ${recordingId} to base ID: ${baseId}`);
1002
1003
  }
1003
1004
 
1004
1005
  // Priority order: exact id match, then session_id match with frames, then any session_id match
@@ -1020,11 +1021,11 @@ class ChromePilotDatabase {
1020
1021
  const recording = stmt.get(recordingId, baseId, recordingId, baseId, recordingId, baseId, recordingId);
1021
1022
 
1022
1023
  if (recording) {
1023
- console.log(`[getRecording] Found recording with ID: ${recording.id}, total_frames: ${recording.total_frames}`);
1024
+ logger.debug(`[getRecording] Found recording with ID: ${recording.id}, total_frames: ${recording.total_frames}`);
1024
1025
  return recording;
1025
1026
  }
1026
1027
 
1027
- console.log(`[getRecording] No recording found for: ${recordingId} or base ID: ${baseId}`);
1028
+ logger.debug(`[getRecording] No recording found for: ${recordingId} or base ID: ${baseId}`);
1028
1029
  return null;
1029
1030
  }
1030
1031
 
@@ -1086,7 +1087,7 @@ class ChromePilotDatabase {
1086
1087
  try {
1087
1088
  embeddedInteractions = JSON.parse(frame.interactions || '[]');
1088
1089
  } catch (error) {
1089
- console.warn(`[getFrame] Failed to parse embedded interactions for frame ${frameIndex}:`, error);
1090
+ logger.warn(`[getFrame] Failed to parse embedded interactions for frame ${frameIndex}:`, error);
1090
1091
  embeddedInteractions = [];
1091
1092
  }
1092
1093
 
@@ -1122,7 +1123,7 @@ class ChromePilotDatabase {
1122
1123
  WHERE recording_id = ?
1123
1124
  `);
1124
1125
  const frameStats = allFramesStmt.get(recording.id);
1125
- console.log(`[getFrameSession] Database stats for ${recording.id}: ${frameStats.count} frames, indices ${frameStats.min_index} to ${frameStats.max_index}`);
1126
+ logger.debug(`[getFrameSession] Database stats for ${recording.id}: ${frameStats.count} frames, indices ${frameStats.min_index} to ${frameStats.max_index}`);
1126
1127
 
1127
1128
  const framesStmt = this.db.prepare(`
1128
1129
  SELECT frame_index, timestamp, absolute_timestamp, image_data, interactions
@@ -1132,8 +1133,8 @@ class ChromePilotDatabase {
1132
1133
  `);
1133
1134
  const frames = framesStmt.all(recording.id);
1134
1135
 
1135
- console.log(`[getFrameSession] Found ${frames.length} frames in database for session ${sessionId}`);
1136
- console.log(`[getFrameSession] Frame indices: [${frames.map(f => f.frame_index).join(', ')}]`);
1136
+ logger.debug(`[getFrameSession] Found ${frames.length} frames in database for session ${sessionId}`);
1137
+ logger.debug(`[getFrameSession] Frame indices: [${frames.map(f => f.frame_index).join(', ')}]`);
1137
1138
 
1138
1139
  // Get logs and interactions for all frames
1139
1140
  for (const frame of frames) {
@@ -1172,7 +1173,7 @@ class ChromePilotDatabase {
1172
1173
  try {
1173
1174
  embeddedInteractions = JSON.parse(frame.interactions || '[]');
1174
1175
  } catch (error) {
1175
- console.warn(`[getFrameSession] Failed to parse embedded interactions for frame ${frame.frame_index}:`, error);
1176
+ logger.warn(`[getFrameSession] Failed to parse embedded interactions for frame ${frame.frame_index}:`, error);
1176
1177
  embeddedInteractions = [];
1177
1178
  }
1178
1179
 
@@ -1316,7 +1317,7 @@ class ChromePilotDatabase {
1316
1317
  storeWorkflowRecording(sessionId, url, title, includeLogs = false, name = null, screenshotSettings = null) {
1317
1318
  this.init();
1318
1319
 
1319
- console.log('[Database] Storing workflow recording with name:', name, 'sessionId:', sessionId);
1320
+ logger.debug('[Database] Storing workflow recording with name:', name, 'sessionId:', sessionId);
1320
1321
 
1321
1322
  const stmt = this.db.prepare(`
1322
1323
  INSERT OR REPLACE INTO workflow_recordings (id, session_id, name, url, title, timestamp, include_logs, screenshot_settings, updated_at)
@@ -1360,7 +1361,7 @@ class ChromePilotDatabase {
1360
1361
  if (!data) return null;
1361
1362
  let jsonStr = typeof data === 'string' ? data : JSON.stringify(data);
1362
1363
  if (jsonStr.length > maxSize) {
1363
- console.warn(`[Database] Truncating data field from ${jsonStr.length} to ${maxSize} bytes`);
1364
+ logger.warn(`[Database] Truncating data field from ${jsonStr.length} to ${maxSize} bytes`);
1364
1365
  jsonStr = jsonStr.substring(0, maxSize - 50) + '...[TRUNCATED]';
1365
1366
  }
1366
1367
  return jsonStr;
@@ -1676,7 +1677,7 @@ class ChromePilotDatabase {
1676
1677
  const deleteRecordingsStmt = this.db.prepare(`DELETE FROM workflow_recordings`);
1677
1678
  const result = deleteRecordingsStmt.run();
1678
1679
 
1679
- console.log(`[Database] Cleared workflow recordings: ${result.changes} recordings deleted`);
1680
+ logger.debug(`[Database] Cleared workflow recordings: ${result.changes} recordings deleted`);
1680
1681
  return result.changes;
1681
1682
  });
1682
1683
 
@@ -1715,7 +1716,7 @@ class ChromePilotDatabase {
1715
1716
 
1716
1717
  return { success: true, restorePointId };
1717
1718
  } catch (error) {
1718
- console.error('Error storing restore point:', error);
1719
+ logger.error('Error storing restore point:', error);
1719
1720
  return { success: false, error: error.message };
1720
1721
  }
1721
1722
  }
@@ -1785,7 +1786,7 @@ class ChromePilotDatabase {
1785
1786
  `);
1786
1787
 
1787
1788
  stmt.run(pid, mode);
1788
- console.log(`Registered server instance: PID ${pid}, mode: ${mode}`);
1789
+ logger.debug(`Registered server instance: PID ${pid}, mode: ${mode}`);
1789
1790
  }
1790
1791
 
1791
1792
  async getSingleServerInstance() {
@@ -1824,7 +1825,7 @@ class ChromePilotDatabase {
1824
1825
  // Process is dead, remove it
1825
1826
  const deleteStmt = this.db.prepare(`DELETE FROM server_instances WHERE pid = ?`);
1826
1827
  deleteStmt.run(instance.pid);
1827
- console.log(`Cleaned up dead server instance: PID ${instance.pid}`);
1828
+ logger.debug(`Cleaned up dead server instance: PID ${instance.pid}`);
1828
1829
  }
1829
1830
  }
1830
1831
  }
@@ -1836,7 +1837,7 @@ class ChromePilotDatabase {
1836
1837
  const result = stmt.run(pid);
1837
1838
 
1838
1839
  if (result.changes > 0) {
1839
- console.log(`Unregistered server instance: PID ${pid}`);
1840
+ logger.debug(`Unregistered server instance: PID ${pid}`);
1840
1841
  }
1841
1842
  }
1842
1843
 
@@ -1893,7 +1894,7 @@ class ChromePilotDatabase {
1893
1894
  transaction();
1894
1895
  return { success: true, count: interactions.length };
1895
1896
  } catch (error) {
1896
- console.error('Error storing screen interactions:', error);
1897
+ logger.error('Error storing screen interactions:', error);
1897
1898
  return { success: false, error: error.message };
1898
1899
  }
1899
1900
  }
@@ -1907,7 +1908,7 @@ class ChromePilotDatabase {
1907
1908
  let baseId = recordingId;
1908
1909
  if (recordingId.startsWith('frame_')) {
1909
1910
  baseId = recordingId.substring(6); // Remove 'frame_' prefix
1910
- console.log(`[getScreenInteractions] Converting old format ID ${recordingId} to base ID: ${baseId}`);
1911
+ logger.debug(`[getScreenInteractions] Converting old format ID ${recordingId} to base ID: ${baseId}`);
1911
1912
  }
1912
1913
 
1913
1914
  // Priority order: exact recording_id match, then baseId match
@@ -1972,11 +1973,11 @@ class ChromePilotDatabase {
1972
1973
  const interactions = stmt.all(frameTimestamp, recordingId, lowerBound, upperBound);
1973
1974
 
1974
1975
  // Diagnostic logging for interaction association debugging
1975
- console.log(`[getInteractionsForFrame] DEBUGGING - recordingId: ${recordingId}, frameTimestamp: ${frameTimestamp}, window: ±${windowMs}ms`);
1976
- console.log(`[getInteractionsForFrame] Search range: ${lowerBound} to ${upperBound}`);
1977
- console.log(`[getInteractionsForFrame] Found ${interactions.length} interactions`);
1976
+ logger.debug(`[getInteractionsForFrame] DEBUGGING - recordingId: ${recordingId}, frameTimestamp: ${frameTimestamp}, window: ±${windowMs}ms`);
1977
+ logger.debug(`[getInteractionsForFrame] Search range: ${lowerBound} to ${upperBound}`);
1978
+ logger.debug(`[getInteractionsForFrame] Found ${interactions.length} interactions`);
1978
1979
  if (interactions.length > 0) {
1979
- console.log(`[getInteractionsForFrame] First interaction:`, interactions[0]);
1980
+ logger.debug(`[getInteractionsForFrame] First interaction:`, interactions[0]);
1980
1981
  }
1981
1982
 
1982
1983
  // Convert to InteractionData format with metadata