@dynamicu/chromedebug-mcp 2.7.0 → 2.7.2

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.
@@ -5,7 +5,7 @@
5
5
 
6
6
  // Check if already loaded
7
7
  if (window.chromePilotContentScriptLoaded) {
8
- console.log('[ChromeDebug MCP v2.0] Content script already loaded, skipping re-injection');
8
+ // console.log('[ChromeDebug MCP v2.0] Content script already loaded, skipping re-injection');
9
9
  return;
10
10
  }
11
11
 
@@ -60,7 +60,7 @@
60
60
  }
61
61
 
62
62
  if (shouldBlock) {
63
- console.log(`[ChromeDebug MCP] Skipping restricted site (${mode} mode):`, hostname);
63
+ // console.log(`[ChromeDebug MCP] Skipping restricted site (${mode} mode):`, hostname);
64
64
  return;
65
65
  }
66
66
 
@@ -72,7 +72,7 @@
72
72
  window.chromePilotContentScriptLoaded = true;
73
73
 
74
74
  const CHROME_PILOT_VERSION = '2.0.4-BUILD-20250119';
75
- console.log(`[content.js] Loaded version: ${CHROME_PILOT_VERSION}`);
75
+ // console.log(`[content.js] Loaded version: ${CHROME_PILOT_VERSION}`);
76
76
 
77
77
  let frameFlashIndicator = null;
78
78
 
@@ -88,7 +88,7 @@ function isExtensionValid() {
88
88
 
89
89
  // Initialize ChromeDebug MCP content script
90
90
  setTimeout(() => {
91
- console.log('[ChromeDebug MCP] 🚀 Content script initializing...');
91
+ // console.log('[ChromeDebug MCP] 🚀 Content script initializing...');
92
92
  }, 100);
93
93
 
94
94
  /*
@@ -119,7 +119,7 @@ let consoleMonitorInjected = false;
119
119
 
120
120
  function injectConsoleMonitor() {
121
121
  if (consoleMonitorInjected) {
122
- console.log('[ChromeDebug] Console monitor already injected');
122
+ // console.log('[ChromeDebug] Console monitor already injected');
123
123
  return Promise.resolve(true);
124
124
  }
125
125
 
@@ -128,7 +128,7 @@ function injectConsoleMonitor() {
128
128
  script.src = chrome.runtime.getURL('console-monitor.js');
129
129
 
130
130
  script.onload = function() {
131
- console.log('[ChromeDebug] Console monitor loaded successfully');
131
+ // console.log('[ChromeDebug] Console monitor loaded successfully');
132
132
  consoleMonitorInjected = true;
133
133
  this.remove();
134
134
  resolve(true);
@@ -154,7 +154,7 @@ window.addEventListener('message', (event) => {
154
154
  }
155
155
  });
156
156
 
157
- console.log('[ChromeDebug] Console monitoring ready (will inject on demand)');
157
+ // console.log('[ChromeDebug] Console monitoring ready (will inject on demand)');
158
158
  */
159
159
 
160
160
  function getAngularComponentInfo(element) {
@@ -190,7 +190,7 @@ function getAngularComponentInfo(element) {
190
190
  };
191
191
  }
192
192
  } catch (e) {
193
- console.log('Error detecting Angular component:', e);
193
+ // console.log('Error detecting Angular component:', e);
194
194
  }
195
195
 
196
196
  return null;
@@ -218,8 +218,8 @@ function getReactComponentInfo(element) {
218
218
 
219
219
  // Debug: Log the first fiber to see what properties are available
220
220
  if (fiber) {
221
- console.log('React Fiber found:', fiber);
222
- console.log('Fiber properties:', Object.keys(fiber));
221
+ // console.log('React Fiber found:', fiber);
222
+ // console.log('Fiber properties:', Object.keys(fiber));
223
223
  }
224
224
 
225
225
  while (currentFiber) {
@@ -239,7 +239,7 @@ function getReactComponentInfo(element) {
239
239
  lineNumber: currentFiber._debugSource.lineNumber,
240
240
  columnNumber: currentFiber._debugSource.columnNumber
241
241
  };
242
- console.log('Found _debugSource:', sourceInfo);
242
+ // console.log('Found _debugSource:', sourceInfo);
243
243
  }
244
244
 
245
245
  // Method 2: _owner and _source
@@ -350,8 +350,8 @@ function getComponentInfo(element) {
350
350
  while (currentElement && depth < maxDepth) {
351
351
  // Log for debugging
352
352
  if (depth === 0) {
353
- console.log(`Checking element:`, currentElement);
354
- console.log(`Element keys:`, Object.keys(currentElement).filter(k => k.includes('react')));
353
+ // console.log(`Checking element:`, currentElement);
354
+ // console.log(`Element keys:`, Object.keys(currentElement).filter(k => k.includes('react')));
355
355
  }
356
356
 
357
357
  // Try to find React info on current element
@@ -388,7 +388,7 @@ function getComponentInfo(element) {
388
388
  return angularInfo;
389
389
  }
390
390
 
391
- console.log('No component info found');
391
+ // console.log('No component info found');
392
392
  return null;
393
393
  }
394
394
 
@@ -401,12 +401,12 @@ let cleanupExecuted = false;
401
401
  async function cleanup() {
402
402
  // Idempotent protection - only run cleanup once
403
403
  if (cleanupExecuted) {
404
- console.log('[ChromeDebug MCP] Cleanup already executed, skipping');
404
+ // console.log('[ChromeDebug MCP] Cleanup already executed, skipping');
405
405
  return;
406
406
  }
407
407
 
408
408
  cleanupExecuted = true;
409
- console.log('[ChromeDebug MCP] Executing cleanup...');
409
+ // console.log('[ChromeDebug MCP] Executing cleanup...');
410
410
 
411
411
  // Clean up recording indicators and event listeners
412
412
  try {
@@ -414,7 +414,7 @@ async function cleanup() {
414
414
 
415
415
  // Stop workflow recording if active
416
416
  if (typeof isWorkflowRecording !== 'undefined' && isWorkflowRecording) {
417
- console.log('[ChromeDebug MCP] Stopping workflow recording during cleanup');
417
+ // console.log('[ChromeDebug MCP] Stopping workflow recording during cleanup');
418
418
  if (typeof stopWorkflowRecording === 'function') {
419
419
  await stopWorkflowRecording();
420
420
  }
@@ -422,13 +422,13 @@ async function cleanup() {
422
422
 
423
423
  // Stop screen interaction tracking if active
424
424
  if (typeof isScreenRecording !== 'undefined' && isScreenRecording) {
425
- console.log('[ChromeDebug MCP] Stopping screen recording during cleanup');
425
+ // console.log('[ChromeDebug MCP] Stopping screen recording during cleanup');
426
426
  if (typeof stopScreenInteractionTracking === 'function') {
427
427
  stopScreenInteractionTracking();
428
428
  }
429
429
  }
430
430
 
431
- console.log('[ChromeDebug MCP] Cleanup completed successfully');
431
+ // console.log('[ChromeDebug MCP] Cleanup completed successfully');
432
432
  } catch (error) {
433
433
  console.warn('[ChromeDebug MCP] Error during cleanup:', error);
434
434
  }
@@ -449,7 +449,7 @@ if (isExtensionValid()) {
449
449
  });
450
450
  return true; // Keep channel open for async response
451
451
  } else if (request.action === 'showRecordingUI') {
452
- console.log('Received showRecordingUI message');
452
+ // console.log('Received showRecordingUI message');
453
453
  showRecordingInterface();
454
454
  sendResponse({ success: true });
455
455
  return true; // Keep channel open for async response
@@ -458,7 +458,7 @@ if (isExtensionValid()) {
458
458
  sendResponse({ success: true });
459
459
  } else if (request.action === 'recordingComplete') {
460
460
  // Show the recording ID in the floating UI
461
- console.log('Recording complete with ID:', request.recordingId);
461
+ // console.log('Recording complete with ID:', request.recordingId);
462
462
  if (recordingOverlay) {
463
463
  const statusDiv = document.getElementById('chrome-debug-recording-status');
464
464
  if (statusDiv && request.recordingId) {
@@ -476,24 +476,24 @@ if (isExtensionValid()) {
476
476
  sendResponse({ success: true });
477
477
  } else if (request.action === 'recordingStarted') {
478
478
  // Recording indicator now handled by ScreenCaptureVisualFeedback
479
- console.log('[ChromeDebug MCP] Received recordingStarted message with scheduled start time:', request.scheduledStartTime);
479
+ // console.log('[ChromeDebug MCP] Received recordingStarted message with scheduled start time:', request.scheduledStartTime);
480
480
  // Start tracking screen interactions with scheduled timing
481
481
  startScreenInteractionTracking(request.scheduledStartTime, request.sessionId);
482
482
  sendResponse({ success: true });
483
483
  } else if (request.action === 'recordingStopped') {
484
484
  // Recording indicator cleanup now handled by ScreenCaptureVisualFeedback
485
- console.log('[ChromeDebug MCP] Received recordingStopped message');
485
+ // console.log('[ChromeDebug MCP] Received recordingStopped message');
486
486
  // Stop tracking screen interactions
487
487
  stopScreenInteractionTracking();
488
488
  sendResponse({ success: true });
489
489
  } else if (request.action === 'recordingSessionComplete') {
490
490
  // Recording indicator cleanup now handled by ScreenCaptureVisualFeedback
491
- console.log('[ChromeDebug MCP] Received recordingSessionComplete message');
491
+ // console.log('[ChromeDebug MCP] Received recordingSessionComplete message');
492
492
  // Stop tracking screen interactions
493
493
  stopScreenInteractionTracking();
494
494
  sendResponse({ success: true });
495
495
  } else if (request.action === 'startWorkflowRecording') {
496
- console.log('[ChromeDebug MCP] Starting workflow recording with settings:', request.screenshotSettings);
496
+ // console.log('[ChromeDebug MCP] Starting workflow recording with settings:', request.screenshotSettings);
497
497
  // Store tabId for use when stopping recording from mini-menu
498
498
  workflowTabId = request.tabId;
499
499
  startWorkflowRecording(request.screenshotSettings);
@@ -501,7 +501,7 @@ if (isExtensionValid()) {
501
501
  } else if (request.action === 'getWorkflowData') {
502
502
  // Called by background script to retrieve workflow data
503
503
  // This happens when popup stops the recording (not mini-menu)
504
- console.log('[ChromeDebug MCP] Getting workflow data');
504
+ // console.log('[ChromeDebug MCP] Getting workflow data');
505
505
  stopWorkflowRecording().then(async workflow => {
506
506
  sendResponse({ success: true, workflow: workflow });
507
507
 
@@ -512,10 +512,10 @@ if (isExtensionValid()) {
512
512
  const storedData = await chrome.storage.local.get(['currentWorkflowId']);
513
513
  const workflowId = storedData.currentWorkflowId || 'Recording saved';
514
514
  const actionCount = workflow.actions?.length || 0;
515
- console.log('[ChromeDebug MCP] Showing completion UI with workflowId:', workflowId, 'actionCount:', actionCount);
515
+ // console.log('[ChromeDebug MCP] Showing completion UI with workflowId:', workflowId, 'actionCount:', actionCount);
516
516
  showWorkflowRecordingComplete(workflowId, actionCount);
517
517
  } catch (e) {
518
- console.log('[ChromeDebug MCP] Could not show completion UI:', e);
518
+ // console.log('[ChromeDebug MCP] Could not show completion UI:', e);
519
519
  }
520
520
  }).catch(error => {
521
521
  console.error('[ChromeDebug MCP] Error getting workflow data:', error);
@@ -548,7 +548,7 @@ if (isExtensionValid()) {
548
548
  return true; // Keep channel open for async response
549
549
  } else if (request.action === 'startFullDataRecording') {
550
550
  // Start full data recording with user configuration
551
- console.log('[ChromeDebug MCP] Starting full data recording with config:', request.config);
551
+ // console.log('[ChromeDebug MCP] Starting full data recording with config:', request.config);
552
552
  startFullDataRecording(request.config).then(() => {
553
553
  sendResponse({ success: true });
554
554
  }).catch(error => {
@@ -557,7 +557,7 @@ if (isExtensionValid()) {
557
557
  return true; // Keep channel open for async response
558
558
  } else if (request.action === 'stopFullDataRecording') {
559
559
  // Stop full data recording
560
- console.log('[ChromeDebug MCP] Stopping full data recording');
560
+ // console.log('[ChromeDebug MCP] Stopping full data recording');
561
561
  stopFullDataRecording().then(() => {
562
562
  sendResponse({ success: true });
563
563
  }).catch(error => {
@@ -623,7 +623,7 @@ async function waitForPageLoad(timeout = 10000) {
623
623
  // Set up timeout
624
624
  timeoutId = setTimeout(() => {
625
625
  cleanup();
626
- console.log('[ChromePilot] Page load timeout reached, continuing...');
626
+ // console.log('[ChromePilot] Page load timeout reached, continuing...');
627
627
  resolve();
628
628
  }, timeout);
629
629
  });
@@ -646,7 +646,7 @@ async function waitForElement(selector, timeout = 5000) {
646
646
 
647
647
  // Function to play a workflow recording
648
648
  async function playWorkflowRecording(workflow, actions) {
649
- console.log('[ChromePilot] Starting workflow playback with', actions.length, 'actions');
649
+ // console.log('[ChromePilot] Starting workflow playback with', actions.length, 'actions');
650
650
 
651
651
  try {
652
652
  // Show playback indicator
@@ -700,7 +700,7 @@ async function playWorkflowRecording(workflow, actions) {
700
700
  actionCounter.textContent = i + 1;
701
701
 
702
702
  try {
703
- console.log(`[ChromePilot] Executing action ${i + 1}/${actions.length}:`, action.type, 'selector:', action.selector);
703
+ // console.log(`[ChromePilot] Executing action ${i + 1}/${actions.length}:`, action.type, 'selector:', action.selector);
704
704
 
705
705
  // Calculate delay based on timestamps
706
706
  let delay = 500; // Default delay
@@ -709,7 +709,7 @@ async function playWorkflowRecording(workflow, actions) {
709
709
  // Apply reasonable limits
710
710
  delay = Math.min(delay, 10000); // Cap at 10 seconds
711
711
  delay = Math.max(delay, 100); // Minimum 100ms
712
- console.log(`[ChromePilot] Calculated delay: ${delay}ms`);
712
+ // console.log(`[ChromePilot] Calculated delay: ${delay}ms`);
713
713
  }
714
714
 
715
715
  // Wait between actions
@@ -727,13 +727,13 @@ async function playWorkflowRecording(workflow, actions) {
727
727
  let element = document.querySelector(fixedSelector);
728
728
  if (!element && action.xpath) {
729
729
  // Try XPath as fallback
730
- console.log('[ChromePilot] Trying XPath fallback:', action.xpath);
730
+ // console.log('[ChromePilot] Trying XPath fallback:', action.xpath);
731
731
  const xpathResult = document.evaluate(action.xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
732
732
  element = xpathResult.singleNodeValue;
733
733
  }
734
734
 
735
735
  if (!element) {
736
- console.log('[ChromePilot] Element not found immediately, waiting...');
736
+ // console.log('[ChromePilot] Element not found immediately, waiting...');
737
737
  element = await waitForElement(fixedSelector, 3000);
738
738
  }
739
739
 
@@ -745,7 +745,7 @@ async function playWorkflowRecording(workflow, actions) {
745
745
  clickableElement = element.closest('button, a') || element;
746
746
  }
747
747
 
748
- console.log('[ChromePilot] Found element:', clickableElement.tagName, 'for selector:', fixedSelector);
748
+ // console.log('[ChromePilot] Found element:', clickableElement.tagName, 'for selector:', fixedSelector);
749
749
  clickableElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
750
750
  await new Promise(resolve => setTimeout(resolve, 200)); // Wait for scroll
751
751
 
@@ -758,7 +758,7 @@ async function playWorkflowRecording(workflow, actions) {
758
758
  // Try to click
759
759
  try {
760
760
  clickableElement.click();
761
- console.log('[ChromePilot] Clicked element successfully');
761
+ // console.log('[ChromePilot] Clicked element successfully');
762
762
  } catch (e) {
763
763
  console.error('[ChromePilot] Error clicking element:', e);
764
764
  // Try alternative click method
@@ -771,7 +771,7 @@ async function playWorkflowRecording(workflow, actions) {
771
771
 
772
772
  // If URL changed, wait for page load
773
773
  if (window.location.href !== currentUrl) {
774
- console.log('[ChromePilot] Navigation detected after click, waiting for page load...');
774
+ // console.log('[ChromePilot] Navigation detected after click, waiting for page load...');
775
775
  await waitForPageLoad();
776
776
  }
777
777
  } else {
@@ -791,12 +791,12 @@ async function playWorkflowRecording(workflow, actions) {
791
791
  // Wait for element to appear if it's not immediately available
792
792
  let element = document.querySelector(action.selector);
793
793
  if (!element) {
794
- console.log('[ChromePilot] Input element not found immediately, waiting...');
794
+ // console.log('[ChromePilot] Input element not found immediately, waiting...');
795
795
  element = await waitForElement(action.selector, 3000);
796
796
  }
797
797
 
798
798
  if (element) {
799
- console.log('[ChromePilot] Found input element:', element.tagName, 'type:', element.type, 'for selector:', action.selector);
799
+ // console.log('[ChromePilot] Found input element:', element.tagName, 'type:', element.type, 'for selector:', action.selector);
800
800
  element.scrollIntoView({ behavior: 'smooth', block: 'center' });
801
801
  await new Promise(resolve => setTimeout(resolve, 200)); // Wait for scroll
802
802
 
@@ -808,7 +808,7 @@ async function playWorkflowRecording(workflow, actions) {
808
808
 
809
809
  // Set new value
810
810
  element.value = action.value || '';
811
- console.log('[ChromePilot] Set input value to:', action.value);
811
+ // console.log('[ChromePilot] Set input value to:', action.value);
812
812
 
813
813
  // Trigger events in the right order
814
814
  element.dispatchEvent(new Event('focus', { bubbles: true }));
@@ -836,7 +836,7 @@ async function playWorkflowRecording(workflow, actions) {
836
836
 
837
837
  case 'navigation':
838
838
  // Navigation will be handled by the browser
839
- console.log('[ChromePilot] Navigation detected');
839
+ // console.log('[ChromePilot] Navigation detected');
840
840
  break;
841
841
 
842
842
  default:
@@ -861,7 +861,7 @@ async function playWorkflowRecording(workflow, actions) {
861
861
  style.remove();
862
862
  }, 3000);
863
863
 
864
- console.log('[ChromePilot] Workflow playback completed');
864
+ // console.log('[ChromePilot] Workflow playback completed');
865
865
 
866
866
  } catch (error) {
867
867
  console.error('[ChromePilot] Error during workflow playback:', error);
@@ -1072,10 +1072,10 @@ function createWorkflowRecordingIndicator() {
1072
1072
  }
1073
1073
 
1074
1074
  if (response && response.success) {
1075
- console.log('[WorkflowRecording] Stop response:', response);
1075
+ // console.log('[WorkflowRecording] Stop response:', response);
1076
1076
  const workflowId = response.workflow?.sessionId || 'unknown';
1077
1077
  const actionCount = response.workflow?.actions?.length || 0;
1078
- console.log('[WorkflowRecording] Extracted workflowId:', workflowId, 'actionCount:', actionCount);
1078
+ // console.log('[WorkflowRecording] Extracted workflowId:', workflowId, 'actionCount:', actionCount);
1079
1079
  // Show completion with action buttons
1080
1080
  showWorkflowRecordingComplete(workflowId, actionCount);
1081
1081
  } else {
@@ -1226,9 +1226,9 @@ let getPerformanceMetrics = null;
1226
1226
  captureElementState = module.captureElementState;
1227
1227
  getEnhancedComponentInfo = module.getEnhancedComponentInfo;
1228
1228
  getPerformanceMetrics = module.getPerformanceMetrics;
1229
- console.log('[ChromePilot Pro] Enhanced capture module loaded');
1229
+ // console.log('[ChromePilot Pro] Enhanced capture module loaded');
1230
1230
  } catch (e) {
1231
- console.log('[ChromePilot Free] Enhanced capture not available - using basic mode');
1231
+ // console.log('[ChromePilot Free] Enhanced capture not available - using basic mode');
1232
1232
  // Create stub functions that return empty data for free version
1233
1233
  captureElementHTML = () => '';
1234
1234
  extractEventHandlers = () => ({});
@@ -1259,7 +1259,7 @@ function recordClick(event) {
1259
1259
  if (element.tagName === 'svg' || element.tagName === 'path' || element.tagName === 'g' || element.tagName === 'circle' || element.tagName === 'rect') {
1260
1260
  const clickableParent = element.closest('button, a, [role="button"], [onclick]');
1261
1261
  if (clickableParent) {
1262
- console.log('[ChromePilot] Adjusted click target from', element.tagName, 'to', clickableParent.tagName);
1262
+ // console.log('[ChromePilot] Adjusted click target from', element.tagName, 'to', clickableParent.tagName);
1263
1263
  element = clickableParent;
1264
1264
  }
1265
1265
  }
@@ -1471,12 +1471,12 @@ function startWorkflowRecording(screenshotSettings) {
1471
1471
  pendingScreenshots = []; // Clear any pending screenshots from previous recording
1472
1472
  createWorkflowRecordingIndicator();
1473
1473
 
1474
- console.log('[ChromePilot] Workflow recording started with settings:', screenshotSettings);
1474
+ // console.log('[ChromePilot] Workflow recording started with settings:', screenshotSettings);
1475
1475
 
1476
1476
  // Start runtime bridge recording for function traces
1477
1477
  if (window.__chromePilot && window.__chromePilot.startRecording) {
1478
1478
  window.__chromePilot.startRecording();
1479
- console.log('[ChromePilot] Started runtime bridge recording for function traces');
1479
+ // console.log('[ChromePilot] Started runtime bridge recording for function traces');
1480
1480
  }
1481
1481
 
1482
1482
  // Connect to the existing FunctionTracker for workflow recording
@@ -1511,7 +1511,7 @@ function startWorkflowRecording(screenshotSettings) {
1511
1511
 
1512
1512
  // Enable function tracking via ChromePilotTracker
1513
1513
  window.ChromePilotTracker._setRecordingStatus(true);
1514
- console.log('[ChromePilot] Connected workflow recording to FunctionTracker');
1514
+ // console.log('[ChromePilot] Connected workflow recording to FunctionTracker');
1515
1515
  } else {
1516
1516
  // FunctionTracker is a PRO feature - use debug level to avoid confusing FREE users
1517
1517
  console.debug('[ChromePilot] FunctionTracker not available (PRO feature)');
@@ -1547,15 +1547,15 @@ async function stopWorkflowRecording() {
1547
1547
  // DON'T remove indicator here - let the completion screen handle it
1548
1548
  // removeWorkflowRecordingIndicator();
1549
1549
 
1550
- console.log(`[ChromePilot] Stopping recording. Captured ${workflowActions.length} actions`);
1550
+ // console.log(`[ChromePilot] Stopping recording. Captured ${workflowActions.length} actions`);
1551
1551
 
1552
1552
  // Wait for all pending screenshots to complete
1553
1553
  if (pendingScreenshots.length > 0) {
1554
- console.log(`[SCREENSHOT-DEBUG] Waiting for ${pendingScreenshots.length} pending screenshots to complete...`);
1554
+ // console.log(`[SCREENSHOT-DEBUG] Waiting for ${pendingScreenshots.length} pending screenshots to complete...`);
1555
1555
  await Promise.all(pendingScreenshots);
1556
- console.log('[SCREENSHOT-DEBUG] All pending screenshots completed!');
1556
+ // console.log('[SCREENSHOT-DEBUG] All pending screenshots completed!');
1557
1557
  } else {
1558
- console.log('[SCREENSHOT-DEBUG] No pending screenshots to wait for');
1558
+ // console.log('[SCREENSHOT-DEBUG] No pending screenshots to wait for');
1559
1559
  }
1560
1560
 
1561
1561
  // Disconnect from FunctionTracker and disable recording
@@ -1565,7 +1565,7 @@ async function stopWorkflowRecording() {
1565
1565
 
1566
1566
  // Count function traces captured during workflow recording
1567
1567
  const functionTraces = workflowActions.filter(action => action.type === 'function-trace');
1568
- console.log(`[ChromePilot] Function tracking stopped. Captured ${functionTraces.length} function traces`);
1568
+ // console.log(`[ChromePilot] Function tracking stopped. Captured ${functionTraces.length} function traces`);
1569
1569
  }
1570
1570
 
1571
1571
  // Remove event listeners
@@ -1584,7 +1584,7 @@ async function stopWorkflowRecording() {
1584
1584
 
1585
1585
  // First, get any function traces from the runtime bridge
1586
1586
  if (window.__chromePilot && window.__chromePilot.stopRecording) {
1587
- console.log('[ChromeDebug MCP] Stopping runtime bridge recording...');
1587
+ // console.log('[ChromeDebug MCP] Stopping runtime bridge recording...');
1588
1588
  const bridgeTraces = window.__chromePilot.stopRecording();
1589
1589
  if (Array.isArray(bridgeTraces)) {
1590
1590
  // Convert bridge traces to workflow action format
@@ -1602,31 +1602,31 @@ async function stopWorkflowRecording() {
1602
1602
  placeholder: null,
1603
1603
  screenshot_data: null
1604
1604
  }));
1605
- console.log(`[Chrome Debug] Retrieved ${functionTraces.length} function traces from runtime bridge`);
1605
+ // console.log(`[Chrome Debug] Retrieved ${functionTraces.length} function traces from runtime bridge`);
1606
1606
  }
1607
1607
  }
1608
1608
 
1609
1609
  // Also include any function traces that were added to workflowActions
1610
1610
  const embeddedTraces = workflowActions.filter(action => action.type === 'function-trace');
1611
1611
  if (embeddedTraces.length > 0) {
1612
- console.log(`[Chrome Debug] Found ${embeddedTraces.length} embedded function traces`);
1612
+ // console.log(`[Chrome Debug] Found ${embeddedTraces.length} embedded function traces`);
1613
1613
  functionTraces = [...functionTraces, ...embeddedTraces];
1614
1614
  }
1615
1615
 
1616
1616
  // Log screenshot data before returning
1617
- console.log('[SCREENSHOT-DEBUG] stopWorkflowRecording - Preparing to return workflow');
1618
- console.log('[SCREENSHOT-DEBUG] stopWorkflowRecording - Total actions:', workflowActions.length);
1617
+ // console.log('[SCREENSHOT-DEBUG] stopWorkflowRecording - Preparing to return workflow');
1618
+ // console.log('[SCREENSHOT-DEBUG] stopWorkflowRecording - Total actions:', workflowActions.length);
1619
1619
 
1620
1620
  const actionsWithScreenshots = workflowActions.filter(a => a.screenshot_data);
1621
- console.log('[SCREENSHOT-DEBUG] stopWorkflowRecording - Actions WITH screenshot_data:', actionsWithScreenshots.length);
1621
+ // console.log('[SCREENSHOT-DEBUG] stopWorkflowRecording - Actions WITH screenshot_data:', actionsWithScreenshots.length);
1622
1622
 
1623
1623
  workflowActions.forEach((action, index) => {
1624
- console.log(`[SCREENSHOT-DEBUG] stopWorkflowRecording - Action ${index}:`, {
1625
- type: action.type,
1626
- hasScreenshotData: !!action.screenshot_data,
1627
- screenshotDataLength: action.screenshot_data?.length,
1628
- screenshotPreview: action.screenshot_data?.substring(0, 50)
1629
- });
1624
+ // console.log(`[SCREENSHOT-DEBUG] stopWorkflowRecording - Action ${index}:`, {
1625
+ // type: action.type,
1626
+ // hasScreenshotData: !!action.screenshot_data,
1627
+ // screenshotDataLength: action.screenshot_data?.length,
1628
+ // screenshotPreview: action.screenshot_data?.substring(0, 50)
1629
+ // });
1630
1630
  });
1631
1631
 
1632
1632
  // Return the recorded workflow with proper functionTraces field
@@ -1773,7 +1773,7 @@ function captureConsoleLogs() {
1773
1773
 
1774
1774
  // Create restore point
1775
1775
  async function createRestorePoint(actionIndex) {
1776
- console.log('[ChromePilot] Creating restore point at action index:', actionIndex);
1776
+ // console.log('[ChromePilot] Creating restore point at action index:', actionIndex);
1777
1777
 
1778
1778
  try {
1779
1779
  // Capture all data
@@ -1802,7 +1802,7 @@ async function createRestorePoint(actionIndex) {
1802
1802
  });
1803
1803
 
1804
1804
  if (response && response.success) {
1805
- console.log('[ChromePilot] Restore point saved:', response.restorePointId);
1805
+ // console.log('[ChromePilot] Restore point saved:', response.restorePointId);
1806
1806
  // Visual feedback
1807
1807
  showRestorePointNotification('Restore point saved!');
1808
1808
  return response.restorePointId;
@@ -1818,7 +1818,7 @@ async function createRestorePoint(actionIndex) {
1818
1818
 
1819
1819
  // Restore from a restore point
1820
1820
  async function restoreFromPoint(restorePointData) {
1821
- console.log('[ChromePilot] Restoring from restore point');
1821
+ // console.log('[ChromePilot] Restoring from restore point');
1822
1822
 
1823
1823
  try {
1824
1824
  // First check if we need to navigate
@@ -2169,7 +2169,7 @@ function startScreenInteractionTracking(scheduledStartTime, sessionId) {
2169
2169
  recordingScheduledStartTime = scheduledStartTime;
2170
2170
  recordingSessionId = sessionId;
2171
2171
 
2172
- console.log('[ChromePilot] Screen interaction tracking scheduled to start at:', new Date(scheduledStartTime));
2172
+ // console.log('[ChromePilot] Screen interaction tracking scheduled to start at:', new Date(scheduledStartTime));
2173
2173
 
2174
2174
  // Trigger visual feedback start
2175
2175
  if (window.screenCaptureVisualFeedback) {
@@ -2190,7 +2190,7 @@ function startScreenInteractionTracking(scheduledStartTime, sessionId) {
2190
2190
  document.addEventListener('mousedown', recordScreenMouseDown, true);
2191
2191
  document.addEventListener('mouseup', recordScreenMouseUp, true);
2192
2192
 
2193
- console.log('[ChromePilot] Screen interaction tracking started at scheduled time');
2193
+ // console.log('[ChromePilot] Screen interaction tracking started at scheduled time');
2194
2194
  }, waitTime);
2195
2195
  }
2196
2196
 
@@ -2223,7 +2223,7 @@ function stopScreenInteractionTracking() {
2223
2223
  screenRecordingDragStartX = 0; // CRITICAL: This was missing
2224
2224
  screenRecordingDragStartY = 0; // CRITICAL: This was missing
2225
2225
 
2226
- console.log('[ChromePilot] Screen interaction tracking stopped');
2226
+ // console.log('[ChromePilot] Screen interaction tracking stopped');
2227
2227
 
2228
2228
  // Visual feedback stop with error isolation
2229
2229
  try {
@@ -2317,7 +2317,7 @@ let isFullDataRecordingActive = false;
2317
2317
 
2318
2318
  // Create floating recording interface
2319
2319
  function showRecordingInterface() {
2320
- console.log('showRecordingInterface called');
2320
+ // console.log('showRecordingInterface called');
2321
2321
 
2322
2322
  // Remove any existing recording overlay
2323
2323
  if (recordingOverlay) {
@@ -2419,7 +2419,7 @@ function startRecording() {
2419
2419
  // Start performance monitoring when recording begins
2420
2420
  if (performanceMonitor) {
2421
2421
  performanceMonitor.startMonitoring();
2422
- console.log('[ChromeDebug MCP] Performance monitoring started with recording');
2422
+ // console.log('[ChromeDebug MCP] Performance monitoring started with recording');
2423
2423
  }
2424
2424
 
2425
2425
  // Start timer display
@@ -2480,7 +2480,7 @@ function stopRecording() {
2480
2480
  // Stop performance monitoring when recording ends
2481
2481
  if (performanceMonitor) {
2482
2482
  performanceMonitor.stopMonitoring();
2483
- console.log('[ChromeDebug MCP] Performance monitoring stopped with recording');
2483
+ // console.log('[ChromeDebug MCP] Performance monitoring stopped with recording');
2484
2484
  }
2485
2485
  });
2486
2486
  }
@@ -2519,7 +2519,7 @@ function showFrameFlash() {
2519
2519
  /*
2520
2520
  async function initializeFullDataRecordingSystem() {
2521
2521
  try {
2522
- console.log('[ChromeDebug MCP] Initializing full data recording system...');
2522
+ // console.log('[ChromeDebug MCP] Initializing full data recording system...');
2523
2523
 
2524
2524
  // Initialize core components
2525
2525
  if (typeof DataBuffer !== 'undefined') {
@@ -2566,7 +2566,7 @@ async function initializeFullDataRecordingSystem() {
2566
2566
  if (dataBuffer) {
2567
2567
  try {
2568
2568
  await dataBuffer.addBatch(events);
2569
- console.log(`[Chrome Debug] Persisted ${events.length} function traces`);
2569
+ // console.log(`[Chrome Debug] Persisted ${events.length} function traces`);
2570
2570
  } catch (error) {
2571
2571
  console.error('[ChromeDebug MCP] Failed to persist function traces:', error);
2572
2572
  }
@@ -2646,10 +2646,10 @@ async function initializeFullDataRecordingSystem() {
2646
2646
  }
2647
2647
  };
2648
2648
 
2649
- console.log('[ChromeDebug MCP] ChromePilotTracker API exposed for manual instrumentation');
2649
+ // console.log('[ChromeDebug MCP] ChromePilotTracker API exposed for manual instrumentation');
2650
2650
  }
2651
2651
 
2652
- console.log('[ChromeDebug MCP] Full data recording system initialized successfully');
2652
+ // console.log('[ChromeDebug MCP] Full data recording system initialized successfully');
2653
2653
  return true;
2654
2654
 
2655
2655
  } catch (error) {
@@ -2666,7 +2666,7 @@ async function startFullDataRecording(config) {
2666
2666
  return;
2667
2667
  }
2668
2668
 
2669
- console.log('[ChromeDebug MCP] Starting full data recording with config:', config);
2669
+ // console.log('[ChromeDebug MCP] Starting full data recording with config:', config);
2670
2670
 
2671
2671
  // Initialize system if not already done
2672
2672
  if (!dataBuffer) {
@@ -2696,7 +2696,7 @@ async function startFullDataRecording(config) {
2696
2696
  // Start performance monitoring (lazy loading - only when recording)
2697
2697
  if (performanceMonitor) {
2698
2698
  performanceMonitor.startMonitoring();
2699
- console.log('[ChromeDebug MCP] Performance monitoring started');
2699
+ // console.log('[ChromeDebug MCP] Performance monitoring started');
2700
2700
  }
2701
2701
 
2702
2702
  // Configure and start DOM tracking
@@ -2709,7 +2709,7 @@ async function startFullDataRecording(config) {
2709
2709
  mutationThrottle: config.instrumentationLevel <= 2 ? 20 : 50 // Throttle for lower levels
2710
2710
  });
2711
2711
  domTracker.startTracking();
2712
- console.log('[ChromeDebug MCP] DOM tracking started');
2712
+ // console.log('[ChromeDebug MCP] DOM tracking started');
2713
2713
  }
2714
2714
 
2715
2715
  // Configure and start network tracking
@@ -2724,7 +2724,7 @@ async function startFullDataRecording(config) {
2724
2724
  maxBodySize: config.instrumentationLevel >= 4 ? 50 * 1024 : 10 * 1024
2725
2725
  });
2726
2726
  networkTracker.startTracking();
2727
- console.log('[ChromeDebug MCP] Network tracking started');
2727
+ // console.log('[ChromeDebug MCP] Network tracking started');
2728
2728
  }
2729
2729
 
2730
2730
  // Configure and start function tracking
@@ -2741,7 +2741,7 @@ async function startFullDataRecording(config) {
2741
2741
  if (chrome.runtime.lastError) {
2742
2742
  console.error('[ChromeDebug MCP] Failed to send function traces to background:', chrome.runtime.lastError);
2743
2743
  } else {
2744
- console.log(`[Chrome Debug] Sent ${data.length} function traces to background for upload`);
2744
+ // console.log(`[Chrome Debug] Sent ${data.length} function traces to background for upload`);
2745
2745
  }
2746
2746
  });
2747
2747
  }
@@ -2770,7 +2770,7 @@ async function startFullDataRecording(config) {
2770
2770
  window.ChromePilotTracker._functionTracker = functionTracker;
2771
2771
  }
2772
2772
 
2773
- console.log('[ChromeDebug MCP] Function tracking started');
2773
+ // console.log('[ChromeDebug MCP] Function tracking started');
2774
2774
  }
2775
2775
 
2776
2776
  // Start upload manager via background script
@@ -2780,7 +2780,7 @@ async function startFullDataRecording(config) {
2780
2780
  if (chrome.runtime.lastError) {
2781
2781
  console.error('[ChromeDebug MCP] Error starting upload manager:', chrome.runtime.lastError.message);
2782
2782
  } else {
2783
- console.log('[ChromeDebug MCP] Upload manager started via background script');
2783
+ // console.log('[ChromeDebug MCP] Upload manager started via background script');
2784
2784
  }
2785
2785
  });
2786
2786
 
@@ -2788,7 +2788,7 @@ async function startFullDataRecording(config) {
2788
2788
 
2789
2789
  // Full data recording indicator removed - functionality disabled
2790
2790
 
2791
- console.log('[ChromeDebug MCP] Full data recording started successfully:', recordingId);
2791
+ // console.log('[ChromeDebug MCP] Full data recording started successfully:', recordingId);
2792
2792
 
2793
2793
  } catch (error) {
2794
2794
  console.error('[ChromeDebug MCP] Failed to start full data recording:', error);
@@ -2804,17 +2804,17 @@ async function stopFullDataRecording() {
2804
2804
  return;
2805
2805
  }
2806
2806
 
2807
- console.log('[ChromeDebug MCP] Stopping full data recording...');
2807
+ // console.log('[ChromeDebug MCP] Stopping full data recording...');
2808
2808
 
2809
2809
  // Stop all trackers
2810
2810
  if (domTracker) {
2811
2811
  domTracker.stopTracking();
2812
- console.log('[ChromeDebug MCP] DOM tracking stopped');
2812
+ // console.log('[ChromeDebug MCP] DOM tracking stopped');
2813
2813
  }
2814
2814
 
2815
2815
  if (networkTracker) {
2816
2816
  networkTracker.stopTracking();
2817
- console.log('[ChromeDebug MCP] Network tracking stopped');
2817
+ // console.log('[ChromeDebug MCP] Network tracking stopped');
2818
2818
  }
2819
2819
 
2820
2820
  if (functionTracker) {
@@ -2825,13 +2825,13 @@ async function stopFullDataRecording() {
2825
2825
  window.ChromePilotTracker._setRecordingStatus(false);
2826
2826
  }
2827
2827
 
2828
- console.log('[ChromeDebug MCP] Function tracking stopped');
2828
+ // console.log('[ChromeDebug MCP] Function tracking stopped');
2829
2829
  }
2830
2830
 
2831
2831
  // Stop performance monitoring
2832
2832
  if (performanceMonitor) {
2833
2833
  performanceMonitor.stopMonitoring();
2834
- console.log('[ChromeDebug MCP] Performance monitoring stopped');
2834
+ // console.log('[ChromeDebug MCP] Performance monitoring stopped');
2835
2835
  }
2836
2836
 
2837
2837
  // Create final batch for any remaining events
@@ -2842,7 +2842,7 @@ async function stopFullDataRecording() {
2842
2842
  if (result.currentRecordingId) {
2843
2843
  // Create a batch with any remaining events
2844
2844
  await dataBuffer.createBatch(result.currentRecordingId);
2845
- console.log('[ChromeDebug MCP] Final batch created for remaining events');
2845
+ // console.log('[ChromeDebug MCP] Final batch created for remaining events');
2846
2846
  }
2847
2847
  } catch (error) {
2848
2848
  console.warn('[ChromeDebug MCP] Could not create final batch:', error);
@@ -2858,7 +2858,7 @@ async function stopFullDataRecording() {
2858
2858
  if (chrome.runtime.lastError) {
2859
2859
  console.error('[ChromeDebug MCP] Error finalizing uploads:', chrome.runtime.lastError.message);
2860
2860
  } else {
2861
- console.log('[ChromeDebug MCP] Upload manager stopped via background script');
2861
+ // console.log('[ChromeDebug MCP] Upload manager stopped via background script');
2862
2862
  }
2863
2863
  resolve();
2864
2864
  });
@@ -2869,7 +2869,7 @@ async function stopFullDataRecording() {
2869
2869
 
2870
2870
  // Full data recording indicator removed - functionality disabled
2871
2871
 
2872
- console.log('[ChromeDebug MCP] Full data recording stopped successfully');
2872
+ // console.log('[ChromeDebug MCP] Full data recording stopped successfully');
2873
2873
 
2874
2874
  } catch (error) {
2875
2875
  console.error('[ChromeDebug MCP] Failed to stop full data recording:', error);
@@ -2903,7 +2903,7 @@ class ScreenCaptureVisualFeedback {
2903
2903
  init() {
2904
2904
  // Listen for screen capture events
2905
2905
  chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
2906
- console.log('[ScreenCapture] Received message:', message.type, message);
2906
+ // console.log('[ScreenCapture] Received message:', message.type, message);
2907
2907
  switch (message.type) {
2908
2908
  case 'start-screen-capture-tracking':
2909
2909
  this.handleStartScreenCapture(message);
@@ -2919,25 +2919,25 @@ class ScreenCaptureVisualFeedback {
2919
2919
  break;
2920
2920
  case 'recording-complete-show-ui':
2921
2921
  // Show completion UI when stopped from popup (not from mini menu button)
2922
- console.log('[ScreenCapture] Processing recording-complete-show-ui, sessionId:', message.sessionId, 'actionCount:', this.actionCount);
2922
+ // console.log('[ScreenCapture] Processing recording-complete-show-ui, sessionId:', message.sessionId, 'actionCount:', this.actionCount);
2923
2923
  if (message.sessionId) {
2924
- console.log('[ScreenCapture] Calling showScreenRecordingComplete with sessionId:', message.sessionId);
2924
+ // console.log('[ScreenCapture] Calling showScreenRecordingComplete with sessionId:', message.sessionId);
2925
2925
  this.showScreenRecordingComplete(message.sessionId, this.actionCount);
2926
2926
  } else {
2927
- console.log('[ScreenCapture] ERROR: No sessionId in recording-complete-show-ui message!');
2927
+ // console.log('[ScreenCapture] ERROR: No sessionId in recording-complete-show-ui message!');
2928
2928
  }
2929
2929
  break;
2930
2930
  default:
2931
2931
  // Log unknown message types for debugging
2932
2932
  if (message.type && message.type.includes('screen-capture') || message.type && message.type.includes('recording')) {
2933
- console.log('[ScreenCapture] Unknown screen capture message type:', message.type);
2933
+ // console.log('[ScreenCapture] Unknown screen capture message type:', message.type);
2934
2934
  }
2935
2935
  }
2936
2936
  });
2937
2937
  }
2938
2938
 
2939
2939
  handleStartScreenCapture(message) {
2940
- console.log('[ScreenCapture] Starting new recording, current indicator exists:', !!this.recordingIndicatorElement);
2940
+ // console.log('[ScreenCapture] Starting new recording, current indicator exists:', !!this.recordingIndicatorElement);
2941
2941
  this.isRecording = true;
2942
2942
  this.actionCount = 0;
2943
2943
  this.showRecordingIndicator();
@@ -3026,7 +3026,7 @@ class ScreenCaptureVisualFeedback {
3026
3026
  showRecordingIndicator() {
3027
3027
  // CRITICAL FIX: Clear any existing countdown interval FIRST
3028
3028
  if (this.countdownInterval) {
3029
- console.log('[ScreenCapture] Clearing existing countdown interval');
3029
+ // console.log('[ScreenCapture] Clearing existing countdown interval');
3030
3030
  clearInterval(this.countdownInterval);
3031
3031
  this.countdownInterval = null;
3032
3032
  }
@@ -3034,12 +3034,12 @@ class ScreenCaptureVisualFeedback {
3034
3034
  // CRITICAL FIX: If old indicator exists (showing completion), remove it completely
3035
3035
  // This ensures the old popup closes immediately before showing the new countdown
3036
3036
  if (this.recordingIndicatorElement && this.recordingIndicatorElement.parentNode) {
3037
- console.log('[ScreenCapture] Removing old indicator element from DOM');
3037
+ // console.log('[ScreenCapture] Removing old indicator element from DOM');
3038
3038
  this.recordingIndicatorElement.parentNode.removeChild(this.recordingIndicatorElement);
3039
3039
  this.recordingIndicatorElement = null;
3040
- console.log('[ScreenCapture] Old indicator removed successfully');
3040
+ // console.log('[ScreenCapture] Old indicator removed successfully');
3041
3041
  } else {
3042
- console.log('[ScreenCapture] No old indicator to remove, creating fresh');
3042
+ // console.log('[ScreenCapture] No old indicator to remove, creating fresh');
3043
3043
  }
3044
3044
 
3045
3045
  // Add required CSS styles if not already added
@@ -3136,17 +3136,33 @@ class ScreenCaptureVisualFeedback {
3136
3136
  <span class="action-count-badge" style="background: rgba(255,255,255,0.2); padding: 2px 8px; border-radius: 12px; font-size: 12px;">0 actions</span>
3137
3137
  `;
3138
3138
  } else {
3139
- // Switch to recording display with stop button
3139
+ // Countdown complete! Notify background to start inactivity monitoring NOW
3140
+ if (isExtensionValid()) {
3141
+ chrome.runtime.sendMessage({ action: 'countdownComplete' }).catch(err => {
3142
+ console.warn('[ScreenCapture] Could not send countdownComplete:', err);
3143
+ });
3144
+ }
3145
+
3146
+ // Switch to recording display with two-row layout
3140
3147
  this.recordingIndicatorElement.style.pointerEvents = 'auto'; // Enable clicking
3141
3148
  this.recordingIndicatorElement.innerHTML = `
3142
- <div style="display: flex; align-items: center; gap: 12px;">
3143
- <div style="display: flex; align-items: center; gap: 8px; flex: 1;">
3144
- <span style="color: #4CAF50; font-size: 20px; animation: pulse 1.5s infinite;">●</span>
3145
- <span>Recording Screen Capture...</span>
3146
- <span class="action-count-badge" style="background: rgba(255,255,255,0.2); padding: 2px 8px; border-radius: 12px; font-size: 12px;">0 actions</span>
3149
+ <div style="display: flex; flex-direction: column; gap: 8px;">
3150
+ <!-- Row 1: Status and primary actions -->
3151
+ <div style="display: flex; align-items: center; gap: 8px;">
3152
+ <span style="color: #4CAF50; font-size: 18px; animation: pulse 1.5s infinite;">●</span>
3153
+ <span style="font-size: 13px; font-weight: 500;">Recording Screen Capture...</span>
3154
+ <span class="action-count-badge" style="background: rgba(255,255,255,0.2); padding: 2px 8px; border-radius: 10px; font-size: 11px;">0 actions</span>
3155
+ <div style="flex: 1;"></div>
3156
+ <button id="screen-stop-btn" style="background: #f44336; color: white; border: none; padding: 6px 14px; border-radius: 15px; font-size: 12px; font-weight: 500; cursor: pointer; font-family: inherit;">Stop</button>
3157
+ <button id="screen-close-btn" style="background: transparent; color: white; border: none; padding: 4px 8px; font-size: 16px; cursor: pointer; font-family: inherit; opacity: 0.7;" title="Close notification">×</button>
3158
+ </div>
3159
+ <!-- Row 2: Frame count, countdown, and disable button -->
3160
+ <div style="display: flex; align-items: center; gap: 10px; font-size: 11px; color: rgba(255,255,255,0.8); padding-left: 26px;">
3161
+ <span class="frame-count-badge">0 frames</span>
3162
+ <span style="opacity: 0.5;">|</span>
3163
+ <span class="inactivity-countdown-badge" style="color: rgba(255,152,0,0.9);">⏱ --</span>
3164
+ <button id="disable-inactivity-btn" style="background: rgba(255,152,0,0.4); color: white; border: none; padding: 4px 10px; border-radius: 10px; font-size: 11px; cursor: pointer; font-family: inherit;" title="Disable auto-stop timeout">Disable</button>
3147
3165
  </div>
3148
- <button id="screen-stop-btn" style="background: #f44336; color: white; border: none; padding: 6px 16px; border-radius: 15px; font-size: 12px; font-weight: 500; cursor: pointer; font-family: inherit;">Stop</button>
3149
- <button id="screen-close-btn" style="background: transparent; color: white; border: none; padding: 4px 8px; font-size: 16px; cursor: pointer; font-family: inherit; opacity: 0.7;" title="Close notification">×</button>
3150
3166
  </div>
3151
3167
  `;
3152
3168
  clearInterval(this.countdownInterval);
@@ -3183,6 +3199,40 @@ class ScreenCaptureVisualFeedback {
3183
3199
  this.hideRecordingIndicator();
3184
3200
  });
3185
3201
  }
3202
+
3203
+ // Add disable inactivity timeout button handler
3204
+ const disableBtn = document.getElementById('disable-inactivity-btn');
3205
+ if (disableBtn) {
3206
+ disableBtn.addEventListener('click', async (e) => {
3207
+ e.stopPropagation();
3208
+ try {
3209
+ const response = await chrome.runtime.sendMessage({ action: 'toggleInactivityTimeout' });
3210
+ if (response && response.success) {
3211
+ const countdownBadge = this.recordingIndicatorElement?.querySelector('.inactivity-countdown-badge');
3212
+ if (response.disabled) {
3213
+ // Timeout disabled - show Enable button (green)
3214
+ disableBtn.textContent = 'Enable';
3215
+ disableBtn.title = 'Enable auto-stop timeout';
3216
+ disableBtn.style.background = 'rgba(76, 175, 80, 0.5)';
3217
+ if (countdownBadge) {
3218
+ countdownBadge.textContent = '⏱ OFF';
3219
+ countdownBadge.style.color = 'rgba(76, 175, 80, 0.9)';
3220
+ }
3221
+ } else {
3222
+ // Timeout enabled - show Disable button (orange)
3223
+ disableBtn.textContent = 'Disable';
3224
+ disableBtn.title = 'Disable auto-stop timeout';
3225
+ disableBtn.style.background = 'rgba(255,152,0,0.4)';
3226
+ if (countdownBadge) {
3227
+ countdownBadge.style.color = 'rgba(255,152,0,0.9)';
3228
+ }
3229
+ }
3230
+ }
3231
+ } catch (err) {
3232
+ console.warn('[ScreenCapture] Could not toggle inactivity timeout:', err);
3233
+ }
3234
+ });
3235
+ }
3186
3236
  }
3187
3237
  }, 1000);
3188
3238
  }
@@ -3257,13 +3307,40 @@ class ScreenCaptureVisualFeedback {
3257
3307
  if (deleteBtn) {
3258
3308
  deleteBtn.addEventListener('click', async () => {
3259
3309
  if (confirm('Delete this screen recording?')) {
3310
+ // Hide immediately for better UX
3311
+ this.hideRecordingIndicator();
3312
+
3313
+ // Show brief "Deleting..." toast
3314
+ const toast = document.createElement('div');
3315
+ Object.assign(toast.style, {
3316
+ position: 'fixed',
3317
+ bottom: '80px',
3318
+ left: '20px',
3319
+ background: 'rgba(0, 0, 0, 0.9)',
3320
+ color: 'white',
3321
+ padding: '12px 20px',
3322
+ borderRadius: '20px',
3323
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif',
3324
+ fontSize: '13px',
3325
+ zIndex: '2147483646'
3326
+ });
3327
+ toast.textContent = 'Deleting...';
3328
+ document.body.appendChild(toast);
3329
+
3260
3330
  chrome.runtime.sendMessage({
3261
3331
  action: 'deleteScreenRecording',
3262
3332
  sessionId: sessionId
3263
3333
  }, (response) => {
3334
+ // Update toast with result
3264
3335
  if (response && response.success) {
3265
- this.hideRecordingIndicator();
3336
+ toast.textContent = '✓ Recording deleted';
3337
+ toast.style.background = 'rgba(76, 175, 80, 0.9)';
3338
+ } else {
3339
+ toast.textContent = '✗ Delete failed';
3340
+ toast.style.background = 'rgba(244, 67, 54, 0.9)';
3266
3341
  }
3342
+ // Remove toast after 2 seconds
3343
+ setTimeout(() => toast.remove(), 2000);
3267
3344
  });
3268
3345
  }
3269
3346
  });
@@ -3409,16 +3486,125 @@ setTimeout(() => {
3409
3486
  }
3410
3487
  };
3411
3488
 
3412
- console.log('[ChromeDebug MCP] ChromePilotTracker initialized for workflow recording');
3489
+ // console.log('[ChromeDebug MCP] ChromePilotTracker initialized for workflow recording');
3413
3490
  }
3414
3491
 
3415
3492
  // Initialize minimal workflow recording support
3416
- console.log('[ChromeDebug MCP] Basic workflow recording ready (lightweight mode)');
3493
+ // console.log('[ChromeDebug MCP] Basic workflow recording ready (lightweight mode)');
3417
3494
  }
3418
3495
  }, 500);
3419
3496
 
3420
3497
  // Full data recording system will be initialized on-demand when recording begins
3421
3498
  // This prevents unnecessary resource usage on every page load
3422
3499
 
3500
+ // =============================================================================
3501
+ // INACTIVITY TRACKER - Auto-stop recording if user is inactive
3502
+ // =============================================================================
3503
+ (function initInactivityTracker() {
3504
+ let lastActivityTime = Date.now();
3505
+ let isTrackingActivity = false;
3506
+ let inactivityCheckInterval = null;
3507
+
3508
+ // Debounce activity updates to avoid flooding background script
3509
+ let activityDebounceTimer = null;
3510
+ const ACTIVITY_DEBOUNCE_MS = 1000; // Report activity at most once per second
3511
+
3512
+ function reportActivity() {
3513
+ if (!isTrackingActivity) return;
3514
+
3515
+ lastActivityTime = Date.now();
3516
+
3517
+ // Debounced report to background
3518
+ if (activityDebounceTimer) return;
3519
+ activityDebounceTimer = setTimeout(() => {
3520
+ activityDebounceTimer = null;
3521
+ if (isExtensionValid()) {
3522
+ chrome.runtime.sendMessage({
3523
+ action: 'userActivity',
3524
+ timestamp: lastActivityTime
3525
+ }).catch(() => {});
3526
+ }
3527
+ }, ACTIVITY_DEBOUNCE_MS);
3528
+ }
3529
+
3530
+ // Activity event listeners (passive for performance)
3531
+ const activityEvents = ['mousedown', 'mousemove', 'keydown', 'scroll', 'touchstart', 'click'];
3532
+
3533
+ function startTracking() {
3534
+ if (isTrackingActivity) return;
3535
+ isTrackingActivity = true;
3536
+ lastActivityTime = Date.now();
3537
+
3538
+ activityEvents.forEach(event => {
3539
+ document.addEventListener(event, reportActivity, { passive: true, capture: true });
3540
+ });
3541
+
3542
+ // Send IMMEDIATE activity report on start to sync with background timer
3543
+ // This prevents premature auto-stop due to setup delay
3544
+ if (isExtensionValid()) {
3545
+ chrome.runtime.sendMessage({
3546
+ action: 'userActivity',
3547
+ timestamp: lastActivityTime
3548
+ }).catch(() => {});
3549
+ }
3550
+ }
3551
+
3552
+ function stopTracking() {
3553
+ if (!isTrackingActivity) return;
3554
+ isTrackingActivity = false;
3555
+
3556
+ activityEvents.forEach(event => {
3557
+ document.removeEventListener(event, reportActivity, { capture: true });
3558
+ });
3559
+
3560
+ if (activityDebounceTimer) {
3561
+ clearTimeout(activityDebounceTimer);
3562
+ activityDebounceTimer = null;
3563
+ }
3564
+ }
3565
+
3566
+ // Listen for start/stop tracking messages from background
3567
+ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
3568
+ if (message.action === 'startActivityTracking') {
3569
+ startTracking();
3570
+ sendResponse({ success: true });
3571
+ } else if (message.action === 'stopActivityTracking') {
3572
+ stopTracking();
3573
+ sendResponse({ success: true });
3574
+ } else if (message.action === 'updateInactivityCountdown') {
3575
+ // Update countdown badge in recording indicator
3576
+ const countdownBadge = document.querySelector('.inactivity-countdown-badge');
3577
+ if (countdownBadge) {
3578
+ if (message.disabled) {
3579
+ countdownBadge.textContent = '⏱ OFF';
3580
+ countdownBadge.style.background = 'rgba(76, 175, 80, 0.3)';
3581
+ countdownBadge.style.color = 'rgba(255,255,255,0.9)';
3582
+ } else {
3583
+ countdownBadge.textContent = `⏱ ${message.timeRemaining}s`;
3584
+ // Warning colors
3585
+ if (message.timeRemaining <= 3) {
3586
+ countdownBadge.style.background = 'rgba(244, 67, 54, 0.5)';
3587
+ countdownBadge.style.color = '#fff';
3588
+ } else if (message.timeRemaining <= 5) {
3589
+ countdownBadge.style.background = 'rgba(255, 152, 0, 0.5)';
3590
+ countdownBadge.style.color = '#fff';
3591
+ } else {
3592
+ countdownBadge.style.background = 'rgba(255, 152, 0, 0.3)';
3593
+ countdownBadge.style.color = 'rgba(255,255,255,0.9)';
3594
+ }
3595
+ }
3596
+ }
3597
+ sendResponse({ success: true });
3598
+ } else if (message.action === 'updateFrameCount') {
3599
+ // Update frame count badge in recording indicator
3600
+ const frameBadge = document.querySelector('.frame-count-badge');
3601
+ if (frameBadge) {
3602
+ frameBadge.textContent = `${message.frameCount} frames`;
3603
+ }
3604
+ sendResponse({ success: true });
3605
+ }
3606
+ });
3607
+ })();
3608
+
3423
3609
  } // End of initializeChromePilot function
3424
3610
  })(); // End of IIFE wrapper