@dynamicu/chromedebug-mcp 2.7.0 → 2.7.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/CLAUDE.md +16 -0
- package/chrome-extension/activation-manager.js +10 -10
- package/chrome-extension/background.js +455 -252
- package/chrome-extension/chrome-session-manager.js +5 -5
- package/chrome-extension/content.js +305 -119
- package/chrome-extension/data-buffer.js +5 -5
- package/chrome-extension/dom-tracker.js +9 -9
- package/chrome-extension/firebase-client.js +13 -13
- package/chrome-extension/frame-capture.js +20 -38
- package/chrome-extension/license-helper.js +9 -9
- package/chrome-extension/manifest.free.json +3 -3
- package/chrome-extension/network-tracker.js +9 -9
- package/chrome-extension/options.html +10 -0
- package/chrome-extension/options.js +20 -7
- package/chrome-extension/performance-monitor.js +17 -17
- package/chrome-extension/popup.html +8 -1
- package/chrome-extension/popup.js +71 -92
- package/chrome-extension/pro/frame-editor.html +23 -0
- package/chrome-extension/pro/frame-editor.js +101 -30
- package/chrome-extension/pro/function-tracker.js +10 -10
- package/chrome-extension/upload-manager.js +7 -7
- package/dist/chromedebug-extension-free.zip +0 -0
- package/package.json +1 -1
- package/src/validation/schemas.js +10 -9
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Background script to handle server communication and recording
|
|
2
2
|
const EXTENSION_VERSION = '2.0.4-BUILD-20250119';
|
|
3
|
-
console.log(`[background.js] Loaded version: ${EXTENSION_VERSION}`);
|
|
3
|
+
// console.log(`[background.js] Loaded version: ${EXTENSION_VERSION}`);
|
|
4
4
|
|
|
5
5
|
// Import configuration and libraries
|
|
6
6
|
importScripts('extension-config.js');
|
|
@@ -93,7 +93,7 @@ async function checkUsageBeforeRecording() {
|
|
|
93
93
|
async function incrementUsageAfterRecording() {
|
|
94
94
|
// PRO version: skip tracking
|
|
95
95
|
if (isProVersion()) {
|
|
96
|
-
console.log('[Usage] PRO version - skipping usage tracking');
|
|
96
|
+
// console.log('[Usage] PRO version - skipping usage tracking');
|
|
97
97
|
return { success: true, count: 0, limit: Infinity, isPro: true };
|
|
98
98
|
}
|
|
99
99
|
|
|
@@ -108,7 +108,7 @@ async function incrementUsageAfterRecording() {
|
|
|
108
108
|
[USAGE_STORAGE_KEY]: { count: newCount, date: today }
|
|
109
109
|
});
|
|
110
110
|
|
|
111
|
-
console.log(`[Usage] Recording tracked: ${newCount}/${FREE_TIER_DAILY_LIMIT} today`);
|
|
111
|
+
// console.log(`[Usage] Recording tracked: ${newCount}/${FREE_TIER_DAILY_LIMIT} today`);
|
|
112
112
|
|
|
113
113
|
return { success: true, count: newCount, limit: FREE_TIER_DAILY_LIMIT };
|
|
114
114
|
}
|
|
@@ -154,7 +154,7 @@ class LogStreamer {
|
|
|
154
154
|
async init() {
|
|
155
155
|
// Skip initialization in browser-only mode
|
|
156
156
|
if (serverMode === 'browser-only') {
|
|
157
|
-
console.log('[LogStreamer] Skipping initialization - browser-only mode');
|
|
157
|
+
// console.log('[LogStreamer] Skipping initialization - browser-only mode');
|
|
158
158
|
return;
|
|
159
159
|
}
|
|
160
160
|
|
|
@@ -164,7 +164,7 @@ class LogStreamer {
|
|
|
164
164
|
// Start periodic streaming
|
|
165
165
|
this.startPeriodicStreaming();
|
|
166
166
|
|
|
167
|
-
console.log('[LogStreamer] Initialized with server availability:', this.serverAvailable);
|
|
167
|
+
// console.log('[LogStreamer] Initialized with server availability:', this.serverAvailable);
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
async checkServerAvailability() {
|
|
@@ -176,7 +176,7 @@ class LogStreamer {
|
|
|
176
176
|
});
|
|
177
177
|
if (response.ok) {
|
|
178
178
|
this.serverAvailable = true;
|
|
179
|
-
console.log(`[LogStreamer] Server available on port ${port}`);
|
|
179
|
+
// console.log(`[LogStreamer] Server available on port ${port}`);
|
|
180
180
|
return;
|
|
181
181
|
}
|
|
182
182
|
} catch (error) {
|
|
@@ -184,7 +184,7 @@ class LogStreamer {
|
|
|
184
184
|
}
|
|
185
185
|
}
|
|
186
186
|
this.serverAvailable = false;
|
|
187
|
-
console.log('[LogStreamer] No server available');
|
|
187
|
+
// console.log('[LogStreamer] No server available');
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
startPeriodicStreaming() {
|
|
@@ -227,7 +227,7 @@ class LogStreamer {
|
|
|
227
227
|
// This gives frames time to be processed before logs are associated
|
|
228
228
|
const timeSinceLastFrame = Date.now() - this.lastFrameCapture;
|
|
229
229
|
if (this.lastFrameCapture > 0 && timeSinceLastFrame < 100) {
|
|
230
|
-
console.log('[LogStreamer] Waiting for frame processing before streaming logs');
|
|
230
|
+
// console.log('[LogStreamer] Waiting for frame processing before streaming logs');
|
|
231
231
|
return; // Wait for next cycle
|
|
232
232
|
}
|
|
233
233
|
|
|
@@ -256,7 +256,7 @@ class LogStreamer {
|
|
|
256
256
|
// Method to notify LogStreamer when frame is captured
|
|
257
257
|
notifyFrameCapture() {
|
|
258
258
|
this.lastFrameCapture = Date.now();
|
|
259
|
-
console.log('[LogStreamer] Frame capture notification received');
|
|
259
|
+
// console.log('[LogStreamer] Frame capture notification received');
|
|
260
260
|
}
|
|
261
261
|
|
|
262
262
|
async sendToServer(batch) {
|
|
@@ -280,7 +280,7 @@ class LogStreamer {
|
|
|
280
280
|
const result = await response.json();
|
|
281
281
|
// Only log if we had to try multiple ports (first port failed)
|
|
282
282
|
if (port !== this.serverPorts[0]) {
|
|
283
|
-
console.log(`[LogStreamer] Connected to server on port ${port}`);
|
|
283
|
+
// console.log(`[LogStreamer] Connected to server on port ${port}`);
|
|
284
284
|
}
|
|
285
285
|
return result;
|
|
286
286
|
}
|
|
@@ -331,7 +331,7 @@ class LogStreamer {
|
|
|
331
331
|
if (now >= item.nextRetry && item.attempts < 3) {
|
|
332
332
|
try {
|
|
333
333
|
await this.sendToServer(item.batch);
|
|
334
|
-
console.log(`[LogStreamer] Retry successful for batch with ${item.batch.length} logs`);
|
|
334
|
+
// console.log(`[LogStreamer] Retry successful for batch with ${item.batch.length} logs`);
|
|
335
335
|
} catch (error) {
|
|
336
336
|
item.attempts++;
|
|
337
337
|
item.nextRetry = now + (1000 * Math.pow(2, item.attempts)); // Exponential backoff
|
|
@@ -389,7 +389,7 @@ class LogBuffer {
|
|
|
389
389
|
// Flush all buffers to Chrome storage
|
|
390
390
|
async flushAll() {
|
|
391
391
|
if (this.flushInProgress) {
|
|
392
|
-
console.log('[LogBuffer] Flush already in progress, waiting for completion...');
|
|
392
|
+
// console.log('[LogBuffer] Flush already in progress, waiting for completion...');
|
|
393
393
|
// Wait for current flush to complete instead of skipping
|
|
394
394
|
while (this.flushInProgress) {
|
|
395
395
|
await new Promise(resolve => setTimeout(resolve, 10));
|
|
@@ -402,7 +402,7 @@ class LogBuffer {
|
|
|
402
402
|
const startTime = Date.now();
|
|
403
403
|
|
|
404
404
|
try {
|
|
405
|
-
console.log(`[LogBuffer] Starting flushAll for ${this.tabBuffers.size} tabs`);
|
|
405
|
+
// console.log(`[LogBuffer] Starting flushAll for ${this.tabBuffers.size} tabs`);
|
|
406
406
|
|
|
407
407
|
for (const [tabId, tabBuffer] of this.tabBuffers) {
|
|
408
408
|
flushPromises.push(tabBuffer.flush());
|
|
@@ -410,7 +410,7 @@ class LogBuffer {
|
|
|
410
410
|
|
|
411
411
|
await Promise.all(flushPromises);
|
|
412
412
|
const duration = Date.now() - startTime;
|
|
413
|
-
console.log(`[LogBuffer] Successfully flushed all buffers for ${this.tabBuffers.size} tabs in ${duration}ms`);
|
|
413
|
+
// console.log(`[LogBuffer] Successfully flushed all buffers for ${this.tabBuffers.size} tabs in ${duration}ms`);
|
|
414
414
|
} catch (error) {
|
|
415
415
|
console.error('[LogBuffer] Error during flush operation:', error);
|
|
416
416
|
throw error; // Re-throw to ensure proper error handling upstream
|
|
@@ -431,7 +431,7 @@ class LogBuffer {
|
|
|
431
431
|
clearTab(tabId) {
|
|
432
432
|
if (this.tabBuffers.has(tabId)) {
|
|
433
433
|
this.tabBuffers.delete(tabId);
|
|
434
|
-
console.log(`[LogBuffer] Cleared buffer for tab ${tabId}`);
|
|
434
|
+
// console.log(`[LogBuffer] Cleared buffer for tab ${tabId}`);
|
|
435
435
|
}
|
|
436
436
|
}
|
|
437
437
|
|
|
@@ -457,7 +457,7 @@ class LogBuffer {
|
|
|
457
457
|
// Debug method to log current buffer state
|
|
458
458
|
logStats() {
|
|
459
459
|
const stats = this.getStats();
|
|
460
|
-
console.log('[LogBuffer] Current statistics:', stats);
|
|
460
|
+
// console.log('[LogBuffer] Current statistics:', stats);
|
|
461
461
|
return stats;
|
|
462
462
|
}
|
|
463
463
|
}
|
|
@@ -572,7 +572,7 @@ class LogTabBuffer {
|
|
|
572
572
|
}
|
|
573
573
|
|
|
574
574
|
this.totalLogsFlushed += this.buffer.length;
|
|
575
|
-
console.log(`[LogBuffer] Flushed ${this.buffer.length} logs for tab ${this.tabId} (total: ${this.totalLogsFlushed})`);
|
|
575
|
+
// console.log(`[LogBuffer] Flushed ${this.buffer.length} logs for tab ${this.tabId} (total: ${this.totalLogsFlushed})`);
|
|
576
576
|
|
|
577
577
|
// Clear the buffer
|
|
578
578
|
this.buffer = [];
|
|
@@ -715,7 +715,7 @@ class WorkflowLogBuffer {
|
|
|
715
715
|
}
|
|
716
716
|
|
|
717
717
|
this.totalLogsFlushed += this.buffer.length;
|
|
718
|
-
console.log(`[WorkflowLogBuffer] Flushed ${this.buffer.length} logs for tab ${this.tabId} (total: ${this.totalLogsFlushed})`);
|
|
718
|
+
// console.log(`[WorkflowLogBuffer] Flushed ${this.buffer.length} logs for tab ${this.tabId} (total: ${this.totalLogsFlushed})`);
|
|
719
719
|
|
|
720
720
|
// Clear the buffer
|
|
721
721
|
this.buffer = [];
|
|
@@ -746,7 +746,7 @@ class WorkflowLogBuffer {
|
|
|
746
746
|
if (this.buffer.length > 0) {
|
|
747
747
|
await this.performFlush();
|
|
748
748
|
}
|
|
749
|
-
console.log(`[WorkflowLogBuffer] Cleaned up buffer for tab ${this.tabId}`);
|
|
749
|
+
// console.log(`[WorkflowLogBuffer] Cleaned up buffer for tab ${this.tabId}`);
|
|
750
750
|
} catch (error) {
|
|
751
751
|
console.error(`[WorkflowLogBuffer] Error during cleanup for tab ${this.tabId}:`, error);
|
|
752
752
|
}
|
|
@@ -809,10 +809,10 @@ const DATA_PROTECTION_TIERS = {
|
|
|
809
809
|
async function initializeServices() {
|
|
810
810
|
try {
|
|
811
811
|
// FIRST: Initialize comprehensive error handling system
|
|
812
|
-
console.log('[Background] Initializing comprehensive error handling...');
|
|
812
|
+
// console.log('[Background] Initializing comprehensive error handling...');
|
|
813
813
|
const errorHandlingSuccess = await initializeErrorHandling();
|
|
814
814
|
if (errorHandlingSuccess) {
|
|
815
|
-
console.log('[Background] Comprehensive error handling initialized successfully');
|
|
815
|
+
// console.log('[Background] Comprehensive error handling initialized successfully');
|
|
816
816
|
} else {
|
|
817
817
|
console.warn('[Background] Error handling initialization failed - continuing with basic functionality');
|
|
818
818
|
}
|
|
@@ -820,16 +820,16 @@ async function initializeServices() {
|
|
|
820
820
|
// Initialize the data buffer
|
|
821
821
|
dataBuffer = new DataBuffer();
|
|
822
822
|
await dataBuffer.init();
|
|
823
|
-
console.log('[Background] Data buffer initialized');
|
|
823
|
+
// console.log('[Background] Data buffer initialized');
|
|
824
824
|
|
|
825
825
|
// Only create upload manager if data buffer initialized successfully
|
|
826
826
|
try {
|
|
827
827
|
uploadManager = new UploadManager(dataBuffer);
|
|
828
828
|
const serverAvailable = await uploadManager.init();
|
|
829
829
|
if (serverAvailable) {
|
|
830
|
-
console.log('[Background] Upload manager initialized with server');
|
|
830
|
+
// console.log('[Background] Upload manager initialized with server');
|
|
831
831
|
} else {
|
|
832
|
-
console.log('[Background] Upload manager initialized but no server available yet');
|
|
832
|
+
// console.log('[Background] Upload manager initialized but no server available yet');
|
|
833
833
|
}
|
|
834
834
|
} catch (uploadErr) {
|
|
835
835
|
console.error('[Background] Failed to initialize upload manager:', uploadErr);
|
|
@@ -841,7 +841,7 @@ async function initializeServices() {
|
|
|
841
841
|
try {
|
|
842
842
|
logStreamer = new LogStreamer();
|
|
843
843
|
await logStreamer.init();
|
|
844
|
-
console.log('[Background] Log streamer initialized');
|
|
844
|
+
// console.log('[Background] Log streamer initialized');
|
|
845
845
|
} catch (streamErr) {
|
|
846
846
|
console.error('[Background] Failed to initialize log streamer:', streamErr);
|
|
847
847
|
logStreamer = null;
|
|
@@ -850,7 +850,7 @@ async function initializeServices() {
|
|
|
850
850
|
// Initialize log buffer for race-condition-free storage
|
|
851
851
|
try {
|
|
852
852
|
logBuffer = new LogBuffer();
|
|
853
|
-
console.log('[Background] Log buffer initialized');
|
|
853
|
+
// console.log('[Background] Log buffer initialized');
|
|
854
854
|
} catch (bufferErr) {
|
|
855
855
|
console.error('[Background] Failed to initialize log buffer:', bufferErr);
|
|
856
856
|
logBuffer = null;
|
|
@@ -859,7 +859,7 @@ async function initializeServices() {
|
|
|
859
859
|
// Initialize browser recording manager for browser-only mode
|
|
860
860
|
try {
|
|
861
861
|
browserRecordingManager = new BrowserRecordingManager(dataBuffer);
|
|
862
|
-
console.log('[Background] Browser recording manager initialized');
|
|
862
|
+
// console.log('[Background] Browser recording manager initialized');
|
|
863
863
|
} catch (recordingErr) {
|
|
864
864
|
console.error('[Background] Failed to initialize browser recording manager:', recordingErr);
|
|
865
865
|
browserRecordingManager = null;
|
|
@@ -869,12 +869,12 @@ async function initializeServices() {
|
|
|
869
869
|
try {
|
|
870
870
|
if (!sessionManager) {
|
|
871
871
|
sessionManager = new ChromeExtensionSessionManager();
|
|
872
|
-
console.log('[Background] Session manager initialized');
|
|
872
|
+
// console.log('[Background] Session manager initialized');
|
|
873
873
|
}
|
|
874
874
|
|
|
875
875
|
// Recover any stuck sessions on startup
|
|
876
876
|
await sessionManager.recoverSessions();
|
|
877
|
-
console.log('[Background] Session recovery completed');
|
|
877
|
+
// console.log('[Background] Session recovery completed');
|
|
878
878
|
} catch (sessionErr) {
|
|
879
879
|
console.error('[Background] Failed to initialize session manager:', sessionErr);
|
|
880
880
|
// Session manager critical for recording - but don't fail completely
|
|
@@ -1012,12 +1012,12 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1012
1012
|
}));
|
|
1013
1013
|
|
|
1014
1014
|
dataBuffer.addBatch(eventsWithRecordingId).then(() => {
|
|
1015
|
-
console.log(`[Background] Added ${eventsWithRecordingId.length} events to buffer for recording ${message.recordingId}`);
|
|
1015
|
+
// console.log(`[Background] Added ${eventsWithRecordingId.length} events to buffer for recording ${message.recordingId}`);
|
|
1016
1016
|
// Create a batch if we have enough events
|
|
1017
1017
|
return dataBuffer.createBatch(message.recordingId);
|
|
1018
1018
|
}).then(batch => {
|
|
1019
1019
|
if (batch) {
|
|
1020
|
-
console.log(`[Background] Created batch ${batch.id} with ${batch.events.length} events`);
|
|
1020
|
+
// console.log(`[Background] Created batch ${batch.id} with ${batch.events.length} events`);
|
|
1021
1021
|
// Process upload queue if upload manager is available
|
|
1022
1022
|
if (uploadManager) {
|
|
1023
1023
|
uploadManager.processUploadQueue();
|
|
@@ -1086,7 +1086,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1086
1086
|
sessionId: message.sessionId
|
|
1087
1087
|
}).catch(() => {
|
|
1088
1088
|
// Content script might not be available
|
|
1089
|
-
console.log('[Background] Could not forward start-screen-capture-tracking to content script');
|
|
1089
|
+
// console.log('[Background] Could not forward start-screen-capture-tracking to content script');
|
|
1090
1090
|
});
|
|
1091
1091
|
}
|
|
1092
1092
|
sendResponse({ success: true });
|
|
@@ -1098,7 +1098,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1098
1098
|
chrome.tabs.sendMessage(sender.tab.id, {
|
|
1099
1099
|
type: 'stop-screen-capture-tracking'
|
|
1100
1100
|
}).catch(() => {
|
|
1101
|
-
console.log('[Background] Could not forward stop-screen-capture-tracking to content script');
|
|
1101
|
+
// console.log('[Background] Could not forward stop-screen-capture-tracking to content script');
|
|
1102
1102
|
});
|
|
1103
1103
|
}
|
|
1104
1104
|
sendResponse({ success: true });
|
|
@@ -1128,7 +1128,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1128
1128
|
frameIndex: frameIndex
|
|
1129
1129
|
};
|
|
1130
1130
|
screenInteractions.push(interaction);
|
|
1131
|
-
console.log('[Background] Visual feedback interaction recorded:', interaction.type, 'Total:', screenInteractions.length);
|
|
1131
|
+
// console.log('[Background] Visual feedback interaction recorded:', interaction.type, 'Total:', screenInteractions.length);
|
|
1132
1132
|
}
|
|
1133
1133
|
}).catch(error => {
|
|
1134
1134
|
console.error('Error validating recording state for interaction:', error);
|
|
@@ -1141,7 +1141,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1141
1141
|
frameIndex: frameCounter.get(currentRecordingSessionId) || 0
|
|
1142
1142
|
};
|
|
1143
1143
|
screenInteractions.push(interaction);
|
|
1144
|
-
console.log('[Background] Visual feedback interaction recorded:', interaction.type, 'Total:', screenInteractions.length);
|
|
1144
|
+
// console.log('[Background] Visual feedback interaction recorded:', interaction.type, 'Total:', screenInteractions.length);
|
|
1145
1145
|
}
|
|
1146
1146
|
}
|
|
1147
1147
|
}
|
|
@@ -1154,7 +1154,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1154
1154
|
chrome.tabs.sendMessage(sender.tab.id, {
|
|
1155
1155
|
type: 'screen-capture-frame-captured'
|
|
1156
1156
|
}).catch(() => {
|
|
1157
|
-
console.log('[Background] Could not forward frame flash to content script');
|
|
1157
|
+
// console.log('[Background] Could not forward frame flash to content script');
|
|
1158
1158
|
});
|
|
1159
1159
|
}
|
|
1160
1160
|
// Don't send response to avoid warnings
|
|
@@ -1165,7 +1165,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1165
1165
|
if (logBuffer && sender.tab) {
|
|
1166
1166
|
const tabId = sender.tab.id;
|
|
1167
1167
|
const testLogsCount = message.count || 1000;
|
|
1168
|
-
console.log(`[Background] Starting LogBuffer race condition test with ${testLogsCount} logs for tab ${tabId}`);
|
|
1168
|
+
// console.log(`[Background] Starting LogBuffer race condition test with ${testLogsCount} logs for tab ${tabId}`);
|
|
1169
1169
|
|
|
1170
1170
|
// Simulate rapid log generation like a real high-volume scenario
|
|
1171
1171
|
const startTime = Date.now();
|
|
@@ -1188,8 +1188,8 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1188
1188
|
Promise.all(logPromises).then(() => {
|
|
1189
1189
|
const endTime = Date.now();
|
|
1190
1190
|
const stats = logBuffer.getStats();
|
|
1191
|
-
console.log(`[Background] LogBuffer test completed in ${endTime - startTime}ms`);
|
|
1192
|
-
console.log(`[Background] Test results:`, stats);
|
|
1191
|
+
// console.log(`[Background] LogBuffer test completed in ${endTime - startTime}ms`);
|
|
1192
|
+
// console.log(`[Background] Test results:`, stats);
|
|
1193
1193
|
|
|
1194
1194
|
sendResponse({
|
|
1195
1195
|
success: true,
|
|
@@ -1219,7 +1219,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1219
1219
|
// DEBUG: Get current LogBuffer statistics
|
|
1220
1220
|
if (logBuffer) {
|
|
1221
1221
|
const stats = logBuffer.getStats();
|
|
1222
|
-
console.log('[Background] LogBuffer stats requested:', stats);
|
|
1222
|
+
// console.log('[Background] LogBuffer stats requested:', stats);
|
|
1223
1223
|
sendResponse({
|
|
1224
1224
|
success: true,
|
|
1225
1225
|
stats: stats
|
|
@@ -1234,10 +1234,10 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1234
1234
|
|
|
1235
1235
|
case 'getBrowserRecordings':
|
|
1236
1236
|
// Get all browser-only recordings from IndexedDB
|
|
1237
|
-
console.log('[Background] getBrowserRecordings - Manager exists:', !!browserRecordingManager);
|
|
1237
|
+
// console.log('[Background] getBrowserRecordings - Manager exists:', !!browserRecordingManager);
|
|
1238
1238
|
if (browserRecordingManager) {
|
|
1239
1239
|
browserRecordingManager.listRecordings().then(recordings => {
|
|
1240
|
-
console.log('[Background] Recordings retrieved from manager:', recordings);
|
|
1240
|
+
// console.log('[Background] Recordings retrieved from manager:', recordings);
|
|
1241
1241
|
sendResponse(recordings);
|
|
1242
1242
|
}).catch(error => {
|
|
1243
1243
|
console.error('[Background] Failed to get browser recordings:', error);
|
|
@@ -1284,7 +1284,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1284
1284
|
// Get frames for a browser-only recording
|
|
1285
1285
|
if (dataBuffer && message.sessionId) {
|
|
1286
1286
|
dataBuffer.getBrowserFrames(message.sessionId).then(frames => {
|
|
1287
|
-
console.log(`[DEBUG] getBrowserRecordingFrames: Retrieved ${frames.length} frames from IndexedDB`);
|
|
1287
|
+
// console.log(`[DEBUG] getBrowserRecordingFrames: Retrieved ${frames.length} frames from IndexedDB`);
|
|
1288
1288
|
|
|
1289
1289
|
// Debug first frame to see structure
|
|
1290
1290
|
if (frames.length > 0) {
|
|
@@ -1298,7 +1298,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1298
1298
|
frameIndex: firstFrame.frameIndex,
|
|
1299
1299
|
allKeys: Object.keys(firstFrame)
|
|
1300
1300
|
};
|
|
1301
|
-
console.log('[DEBUG] First frame structure:', JSON.stringify(debugInfo, null, 2));
|
|
1301
|
+
// console.log('[DEBUG] First frame structure:', JSON.stringify(debugInfo, null, 2));
|
|
1302
1302
|
}
|
|
1303
1303
|
|
|
1304
1304
|
// Transform frames to match frame editor's expected structure
|
|
@@ -1315,7 +1315,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1315
1315
|
logsCount: transformedFrames[0].logs ? transformedFrames[0].logs.length : 0,
|
|
1316
1316
|
allKeys: Object.keys(transformedFrames[0])
|
|
1317
1317
|
} : 'No frames';
|
|
1318
|
-
console.log('[DEBUG] Transformed first frame:', JSON.stringify(transformDebug, null, 2));
|
|
1318
|
+
// console.log('[DEBUG] Transformed first frame:', JSON.stringify(transformDebug, null, 2));
|
|
1319
1319
|
|
|
1320
1320
|
sendResponse({ success: true, frames: transformedFrames });
|
|
1321
1321
|
}).catch(error => {
|
|
@@ -1341,7 +1341,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1341
1341
|
default:
|
|
1342
1342
|
// Don't warn or respond for messages that should be handled by other listener (v2.0.6)
|
|
1343
1343
|
// This prevents intercepting workflow recording messages
|
|
1344
|
-
console.log('[Background v2.0.6] Message not handled by this listener:', messageType);
|
|
1344
|
+
// console.log('[Background v2.0.6] Message not handled by this listener:', messageType);
|
|
1345
1345
|
// Don't send response - let other listener handle it
|
|
1346
1346
|
return;
|
|
1347
1347
|
}
|
|
@@ -1351,13 +1351,13 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
|
|
1351
1351
|
|
|
1352
1352
|
// Session recovery on startup - handle any stuck recordings from previous session
|
|
1353
1353
|
chrome.runtime.onStartup.addListener(async () => {
|
|
1354
|
-
console.log('[Background] Extension startup detected - checking for stuck sessions');
|
|
1354
|
+
// console.log('[Background] Extension startup detected - checking for stuck sessions');
|
|
1355
1355
|
|
|
1356
1356
|
if (sessionManager) {
|
|
1357
1357
|
try {
|
|
1358
1358
|
// Use existing recovery method from session manager
|
|
1359
1359
|
await sessionManager.recoverSessions();
|
|
1360
|
-
console.log('[Background] Startup session recovery completed');
|
|
1360
|
+
// console.log('[Background] Startup session recovery completed');
|
|
1361
1361
|
} catch (error) {
|
|
1362
1362
|
console.error('[Background] Failed to recover sessions on startup:', error);
|
|
1363
1363
|
}
|
|
@@ -1368,7 +1368,7 @@ chrome.runtime.onStartup.addListener(async () => {
|
|
|
1368
1368
|
|
|
1369
1369
|
// Extension install/update
|
|
1370
1370
|
chrome.runtime.onInstalled.addListener(async (details) => {
|
|
1371
|
-
console.log('[Background] Extension installed/updated:', details.reason);
|
|
1371
|
+
// console.log('[Background] Extension installed/updated:', details.reason);
|
|
1372
1372
|
});
|
|
1373
1373
|
|
|
1374
1374
|
// Listen for tab updates to handle restore points
|
|
@@ -1380,7 +1380,7 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
|
|
1380
1380
|
isCurrentlyRecordingAsync().then(async (recording) => {
|
|
1381
1381
|
const currentTabId = await getCurrentTabIdAsync();
|
|
1382
1382
|
if (recording && tabId === currentTabId && tab.url && !tab.url.startsWith('chrome://') && !tab.url.startsWith('chrome-extension://')) {
|
|
1383
|
-
console.log('Re-injecting console logging for navigation during recording');
|
|
1383
|
+
// console.log('Re-injecting console logging for navigation during recording');
|
|
1384
1384
|
startCapturingLogs(tabId).catch(err => {
|
|
1385
1385
|
console.error('Failed to re-inject console logging:', err);
|
|
1386
1386
|
});
|
|
@@ -1391,7 +1391,7 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
|
|
1391
1391
|
} else {
|
|
1392
1392
|
// Legacy fallback
|
|
1393
1393
|
if (tabId === recordingTabId && isCurrentlyRecording && tab.url && !tab.url.startsWith('chrome://') && !tab.url.startsWith('chrome-extension://')) {
|
|
1394
|
-
console.log('Re-injecting console logging for navigation during recording');
|
|
1394
|
+
// console.log('Re-injecting console logging for navigation during recording');
|
|
1395
1395
|
startCapturingLogs(tabId).catch(err => {
|
|
1396
1396
|
console.error('Failed to re-inject console logging:', err);
|
|
1397
1397
|
});
|
|
@@ -1470,7 +1470,7 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
|
|
|
1470
1470
|
chrome.tabs.onRemoved.addListener((tabId, removeInfo) => {
|
|
1471
1471
|
// Clean up any workflow recording state for closed tabs
|
|
1472
1472
|
if (workflowRecordingTabs.has(tabId)) {
|
|
1473
|
-
console.log(`[Workflow] Tab ${tabId} closed during recording, cleaning up`);
|
|
1473
|
+
// console.log(`[Workflow] Tab ${tabId} closed during recording, cleaning up`);
|
|
1474
1474
|
workflowRecordingTabs.delete(tabId);
|
|
1475
1475
|
workflowIncludeLogs.delete(tabId);
|
|
1476
1476
|
workflowScreenshotSettings.delete(tabId);
|
|
@@ -1481,7 +1481,7 @@ chrome.tabs.onRemoved.addListener((tabId, removeInfo) => {
|
|
|
1481
1481
|
if (buffer) {
|
|
1482
1482
|
buffer.cleanup().then(() => {
|
|
1483
1483
|
workflowLogBuffers.delete(tabId);
|
|
1484
|
-
console.log(`[Workflow] Cleaned up WorkflowLogBuffer for closed tab ${tabId}`);
|
|
1484
|
+
// console.log(`[Workflow] Cleaned up WorkflowLogBuffer for closed tab ${tabId}`);
|
|
1485
1485
|
}).catch(err => {
|
|
1486
1486
|
console.error(`[Workflow] Error cleaning up buffer for closed tab ${tabId}:`, err);
|
|
1487
1487
|
workflowLogBuffers.delete(tabId);
|
|
@@ -1519,11 +1519,148 @@ let isCurrentlyRecording = false; // DEPRECATED: Use isCurrentlyRecordingAsync()
|
|
|
1519
1519
|
let currentRecordingSessionId = null; // DEPRECATED: Use getCurrentSessionIdAsync() instead
|
|
1520
1520
|
let frameCounter = new Map(); // DEPRECATED: Session manager handles frame counting
|
|
1521
1521
|
|
|
1522
|
+
// =============================================================================
|
|
1523
|
+
// INACTIVITY AUTO-STOP - Stop recording if user is inactive
|
|
1524
|
+
// =============================================================================
|
|
1525
|
+
const DEFAULT_INACTIVITY_TIMEOUT_MS = 10 * 1000; // 10 seconds default
|
|
1526
|
+
let lastUserActivityTime = Date.now();
|
|
1527
|
+
let inactivityCheckInterval = null;
|
|
1528
|
+
let currentInactivityTimeout = DEFAULT_INACTIVITY_TIMEOUT_MS;
|
|
1529
|
+
let inactivityMonitoringStarted = false; // Track if monitoring has started
|
|
1530
|
+
let inactivityFallbackTimer = null; // Fallback timer if countdownComplete not received
|
|
1531
|
+
let inactivityDisabled = false; // User can disable for current session
|
|
1532
|
+
|
|
1533
|
+
/**
|
|
1534
|
+
* Start inactivity monitoring for a recording
|
|
1535
|
+
* @param {number} tabId - Tab ID to monitor
|
|
1536
|
+
*/
|
|
1537
|
+
async function startInactivityMonitoring(tabId) {
|
|
1538
|
+
// Mark as started (for fallback timer check)
|
|
1539
|
+
inactivityMonitoringStarted = true;
|
|
1540
|
+
|
|
1541
|
+
// Clear fallback timer since we're starting properly
|
|
1542
|
+
if (inactivityFallbackTimer) {
|
|
1543
|
+
clearTimeout(inactivityFallbackTimer);
|
|
1544
|
+
inactivityFallbackTimer = null;
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
// Load user's configured timeout from storage
|
|
1548
|
+
const settings = await chrome.storage.sync.get(['inactivityTimeout']);
|
|
1549
|
+
currentInactivityTimeout = (settings.inactivityTimeout || 10) * 1000; // Convert seconds to ms (default 10s)
|
|
1550
|
+
|
|
1551
|
+
lastUserActivityTime = Date.now();
|
|
1552
|
+
|
|
1553
|
+
// Tell content script to start tracking activity AND send config for countdown display
|
|
1554
|
+
try {
|
|
1555
|
+
await chrome.tabs.sendMessage(tabId, {
|
|
1556
|
+
action: 'startActivityTracking',
|
|
1557
|
+
inactivityTimeoutMs: currentInactivityTimeout,
|
|
1558
|
+
disabled: inactivityDisabled
|
|
1559
|
+
});
|
|
1560
|
+
} catch (error) {
|
|
1561
|
+
console.warn('[Inactivity] Could not start activity tracking in content script:', error.message);
|
|
1562
|
+
}
|
|
1563
|
+
|
|
1564
|
+
// Clear any existing interval
|
|
1565
|
+
if (inactivityCheckInterval) {
|
|
1566
|
+
clearInterval(inactivityCheckInterval);
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
// If disabled, don't start the check interval
|
|
1570
|
+
if (inactivityDisabled) {
|
|
1571
|
+
return;
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
// Check for inactivity every 2 seconds
|
|
1575
|
+
inactivityCheckInterval = setInterval(async () => {
|
|
1576
|
+
// Skip if disabled
|
|
1577
|
+
if (inactivityDisabled) return;
|
|
1578
|
+
|
|
1579
|
+
const timeSinceActivity = Date.now() - lastUserActivityTime;
|
|
1580
|
+
const timeRemaining = Math.max(0, currentInactivityTimeout - timeSinceActivity);
|
|
1581
|
+
|
|
1582
|
+
// Send countdown update to content script
|
|
1583
|
+
try {
|
|
1584
|
+
await chrome.tabs.sendMessage(tabId, {
|
|
1585
|
+
action: 'updateInactivityCountdown',
|
|
1586
|
+
timeRemaining: Math.ceil(timeRemaining / 1000),
|
|
1587
|
+
disabled: inactivityDisabled
|
|
1588
|
+
});
|
|
1589
|
+
} catch (e) {
|
|
1590
|
+
// Tab might be closed, ignore
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
if (timeSinceActivity >= currentInactivityTimeout) {
|
|
1594
|
+
// Stop the recording first
|
|
1595
|
+
await stopRecording();
|
|
1596
|
+
|
|
1597
|
+
// Show notification with link to settings
|
|
1598
|
+
try {
|
|
1599
|
+
await chrome.notifications.create('inactivity-stop', {
|
|
1600
|
+
type: 'basic',
|
|
1601
|
+
iconUrl: 'icon128.png',
|
|
1602
|
+
title: 'Recording Auto-Stopped',
|
|
1603
|
+
message: `Recording stopped after ${Math.round(currentInactivityTimeout / 1000)}s of inactivity. Click to adjust timeout in Settings.`,
|
|
1604
|
+
priority: 2
|
|
1605
|
+
});
|
|
1606
|
+
} catch (e) {
|
|
1607
|
+
console.warn('[Inactivity] Could not show notification:', e.message);
|
|
1608
|
+
}
|
|
1609
|
+
}
|
|
1610
|
+
}, 2000); // Check every 2 seconds
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
/**
|
|
1614
|
+
* Stop inactivity monitoring
|
|
1615
|
+
* @param {number} tabId - Tab ID that was being monitored
|
|
1616
|
+
*/
|
|
1617
|
+
async function stopInactivityMonitoring(tabId) {
|
|
1618
|
+
if (inactivityCheckInterval) {
|
|
1619
|
+
clearInterval(inactivityCheckInterval);
|
|
1620
|
+
inactivityCheckInterval = null;
|
|
1621
|
+
}
|
|
1622
|
+
|
|
1623
|
+
// Clear fallback timer
|
|
1624
|
+
if (inactivityFallbackTimer) {
|
|
1625
|
+
clearTimeout(inactivityFallbackTimer);
|
|
1626
|
+
inactivityFallbackTimer = null;
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
// Reset state for next recording
|
|
1630
|
+
inactivityMonitoringStarted = false;
|
|
1631
|
+
inactivityDisabled = false; // Reset disabled state for next session
|
|
1632
|
+
|
|
1633
|
+
// Tell content script to stop tracking
|
|
1634
|
+
if (tabId) {
|
|
1635
|
+
try {
|
|
1636
|
+
await chrome.tabs.sendMessage(tabId, { action: 'stopActivityTracking' });
|
|
1637
|
+
} catch (error) {
|
|
1638
|
+
// Tab might be closed, that's ok
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
/**
|
|
1644
|
+
* Handle user activity report from content script
|
|
1645
|
+
* @param {number} timestamp - Activity timestamp
|
|
1646
|
+
*/
|
|
1647
|
+
function handleUserActivity(timestamp) {
|
|
1648
|
+
lastUserActivityTime = timestamp || Date.now();
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
// Handle notification clicks - open settings page when inactivity notification is clicked
|
|
1652
|
+
chrome.notifications.onClicked.addListener((notificationId) => {
|
|
1653
|
+
if (notificationId === 'inactivity-stop') {
|
|
1654
|
+
chrome.runtime.openOptionsPage();
|
|
1655
|
+
chrome.notifications.clear(notificationId);
|
|
1656
|
+
}
|
|
1657
|
+
});
|
|
1658
|
+
|
|
1522
1659
|
// Initialize session manager
|
|
1523
1660
|
(async function initializeSessionManager() {
|
|
1524
1661
|
try {
|
|
1525
1662
|
sessionManager = new ChromeExtensionSessionManager();
|
|
1526
|
-
console.log('[ChromeSessionManager] Initialized successfully');
|
|
1663
|
+
// console.log('[ChromeSessionManager] Initialized successfully');
|
|
1527
1664
|
} catch (error) {
|
|
1528
1665
|
console.error('[ChromeSessionManager] Failed to initialize:', error);
|
|
1529
1666
|
}
|
|
@@ -1659,7 +1796,7 @@ let workflowLogBuffers = new Map(); // Map of tabId to WorkflowLogBuffer instanc
|
|
|
1659
1796
|
*/
|
|
1660
1797
|
async function initializeErrorHandling() {
|
|
1661
1798
|
try {
|
|
1662
|
-
console.log('[ErrorHandling] Initializing comprehensive error handling system...');
|
|
1799
|
+
// console.log('[ErrorHandling] Initializing comprehensive error handling system...');
|
|
1663
1800
|
|
|
1664
1801
|
// Generate session ID if not exists
|
|
1665
1802
|
if (!errorHandlingState.sessionId) {
|
|
@@ -1682,11 +1819,11 @@ async function initializeErrorHandling() {
|
|
|
1682
1819
|
errorHandlingState.isInitialized = true;
|
|
1683
1820
|
errorHandlingState.currentState = 'NORMAL_OPERATION';
|
|
1684
1821
|
|
|
1685
|
-
console.log('[ErrorHandling] System initialization complete:', {
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
});
|
|
1822
|
+
// console.log('[ErrorHandling] System initialization complete:', {
|
|
1823
|
+
// sessionId: errorHandlingState.sessionId,
|
|
1824
|
+
// state: errorHandlingState.currentState,
|
|
1825
|
+
// circuitBreaker: errorHandlingState.circuitBreakerState
|
|
1826
|
+
// });
|
|
1690
1827
|
|
|
1691
1828
|
return true;
|
|
1692
1829
|
} catch (error) {
|
|
@@ -1711,7 +1848,7 @@ async function initializeBackupStorage() {
|
|
|
1711
1848
|
};
|
|
1712
1849
|
|
|
1713
1850
|
request.onsuccess = () => {
|
|
1714
|
-
console.log('[ErrorHandling] IndexedDB initialized successfully');
|
|
1851
|
+
// console.log('[ErrorHandling] IndexedDB initialized successfully');
|
|
1715
1852
|
resolve(request.result);
|
|
1716
1853
|
};
|
|
1717
1854
|
|
|
@@ -1741,7 +1878,7 @@ async function initializeBackupStorage() {
|
|
|
1741
1878
|
errorStore.createIndex('timestamp', 'timestamp', { unique: false });
|
|
1742
1879
|
}
|
|
1743
1880
|
|
|
1744
|
-
console.log('[ErrorHandling] IndexedDB schema created');
|
|
1881
|
+
// console.log('[ErrorHandling] IndexedDB schema created');
|
|
1745
1882
|
};
|
|
1746
1883
|
});
|
|
1747
1884
|
}
|
|
@@ -1752,7 +1889,7 @@ async function initializeBackupStorage() {
|
|
|
1752
1889
|
function initializeCircuitBreaker() {
|
|
1753
1890
|
errorHandlingState.circuitBreakerState = 'CLOSED';
|
|
1754
1891
|
errorHandlingState.failedSaveCount = 0;
|
|
1755
|
-
console.log('[ErrorHandling] Circuit breaker initialized in CLOSED state');
|
|
1892
|
+
// console.log('[ErrorHandling] Circuit breaker initialized in CLOSED state');
|
|
1756
1893
|
}
|
|
1757
1894
|
|
|
1758
1895
|
/**
|
|
@@ -1765,7 +1902,7 @@ async function setupNotificationSystem() {
|
|
|
1765
1902
|
await chrome.notifications.clear(notificationId);
|
|
1766
1903
|
}
|
|
1767
1904
|
|
|
1768
|
-
console.log('[ErrorHandling] Notification system ready');
|
|
1905
|
+
// console.log('[ErrorHandling] Notification system ready');
|
|
1769
1906
|
}
|
|
1770
1907
|
|
|
1771
1908
|
/**
|
|
@@ -1804,7 +1941,7 @@ async function cleanupOldBackups() {
|
|
|
1804
1941
|
}
|
|
1805
1942
|
};
|
|
1806
1943
|
|
|
1807
|
-
console.log('[ErrorHandling] Cleanup completed for data older than', ERROR_HANDLING_CONFIG.backupRetentionDays, 'days');
|
|
1944
|
+
// console.log('[ErrorHandling] Cleanup completed for data older than', ERROR_HANDLING_CONFIG.backupRetentionDays, 'days');
|
|
1808
1945
|
};
|
|
1809
1946
|
} catch (error) {
|
|
1810
1947
|
console.error('[ErrorHandling] Failed to cleanup old backups:', error);
|
|
@@ -1831,13 +1968,13 @@ async function handleSaveAttempt(saveFunction, data, context = {}) {
|
|
|
1831
1968
|
if (errorHandlingState.circuitBreakerState === 'OPEN') {
|
|
1832
1969
|
const timeSinceLastFailure = Date.now() - (errorHandlingState.lastError?.timestamp || 0);
|
|
1833
1970
|
if (timeSinceLastFailure < ERROR_HANDLING_CONFIG.resetTimeout) {
|
|
1834
|
-
console.log('[ErrorHandling] Circuit breaker OPEN, attempting backup instead');
|
|
1971
|
+
// console.log('[ErrorHandling] Circuit breaker OPEN, attempting backup instead');
|
|
1835
1972
|
await backupFailedData(data, context);
|
|
1836
1973
|
return { success: false, circuitBreakerOpen: true };
|
|
1837
1974
|
} else {
|
|
1838
1975
|
// Try half-open
|
|
1839
1976
|
errorHandlingState.circuitBreakerState = 'HALF_OPEN';
|
|
1840
|
-
console.log('[ErrorHandling] Circuit breaker moving to HALF_OPEN state');
|
|
1977
|
+
// console.log('[ErrorHandling] Circuit breaker moving to HALF_OPEN state');
|
|
1841
1978
|
}
|
|
1842
1979
|
}
|
|
1843
1980
|
|
|
@@ -1848,7 +1985,7 @@ async function handleSaveAttempt(saveFunction, data, context = {}) {
|
|
|
1848
1985
|
if (result && result.success !== false) {
|
|
1849
1986
|
errorHandlingState.circuitBreakerState = 'CLOSED';
|
|
1850
1987
|
errorHandlingState.failedSaveCount = 0;
|
|
1851
|
-
console.log('[ErrorHandling] Save successful, circuit breaker CLOSED');
|
|
1988
|
+
// console.log('[ErrorHandling] Save successful, circuit breaker CLOSED');
|
|
1852
1989
|
return { success: true, result };
|
|
1853
1990
|
} else {
|
|
1854
1991
|
throw new Error('Save function returned failure');
|
|
@@ -1888,7 +2025,7 @@ async function handleSaveFailure(error, data, context, attempt) {
|
|
|
1888
2025
|
// Attempt backup
|
|
1889
2026
|
try {
|
|
1890
2027
|
await backupFailedData(data, context);
|
|
1891
|
-
console.log('[ErrorHandling] Data backed up successfully');
|
|
2028
|
+
// console.log('[ErrorHandling] Data backed up successfully');
|
|
1892
2029
|
} catch (backupError) {
|
|
1893
2030
|
console.error('[ErrorHandling] CRITICAL: Backup also failed:', backupError);
|
|
1894
2031
|
await createUserNotification('CRITICAL', 'Data loss imminent - manual intervention required');
|
|
@@ -1984,7 +2121,7 @@ async function backupFailedData(data, context) {
|
|
|
1984
2121
|
const store = transaction.objectStore('sessionBackups');
|
|
1985
2122
|
|
|
1986
2123
|
store.add(backupData);
|
|
1987
|
-
console.log('[ErrorHandling] Data backed up with session ID:', errorHandlingState.sessionId);
|
|
2124
|
+
// console.log('[ErrorHandling] Data backed up with session ID:', errorHandlingState.sessionId);
|
|
1988
2125
|
};
|
|
1989
2126
|
|
|
1990
2127
|
// Also add to retained interactions if relevant
|
|
@@ -2025,7 +2162,7 @@ async function createUserNotification(priority, message) {
|
|
|
2025
2162
|
}
|
|
2026
2163
|
|
|
2027
2164
|
await chrome.notifications.create(notificationId, notificationOptions);
|
|
2028
|
-
console.log('[ErrorHandling] User notification created:', notificationId);
|
|
2165
|
+
// console.log('[ErrorHandling] User notification created:', notificationId);
|
|
2029
2166
|
|
|
2030
2167
|
// Set up notification click handlers
|
|
2031
2168
|
chrome.notifications.onButtonClicked.addListener((notifId, buttonIndex) => {
|
|
@@ -2045,16 +2182,16 @@ async function createUserNotification(priority, message) {
|
|
|
2045
2182
|
async function handleNotificationAction(buttonIndex, priority) {
|
|
2046
2183
|
switch (buttonIndex) {
|
|
2047
2184
|
case 0: // Retry Save
|
|
2048
|
-
console.log('[ErrorHandling] User requested retry');
|
|
2185
|
+
// console.log('[ErrorHandling] User requested retry');
|
|
2049
2186
|
await attemptRecovery();
|
|
2050
2187
|
break;
|
|
2051
2188
|
case 1: // View Details
|
|
2052
|
-
console.log('[ErrorHandling] User requested error details');
|
|
2189
|
+
// console.log('[ErrorHandling] User requested error details');
|
|
2053
2190
|
// Could open an options page or log details
|
|
2054
2191
|
break;
|
|
2055
2192
|
case 2: // Download Backup (for critical errors)
|
|
2056
2193
|
if (priority === 'CRITICAL') {
|
|
2057
|
-
console.log('[ErrorHandling] User requested backup download');
|
|
2194
|
+
// console.log('[ErrorHandling] User requested backup download');
|
|
2058
2195
|
await downloadBackupData();
|
|
2059
2196
|
}
|
|
2060
2197
|
break;
|
|
@@ -2074,14 +2211,14 @@ async function attemptRecovery() {
|
|
|
2074
2211
|
|
|
2075
2212
|
store.getAll().onsuccess = (event) => {
|
|
2076
2213
|
const backups = event.target.result;
|
|
2077
|
-
console.log('[ErrorHandling] Found', backups.length, 'backup records for recovery');
|
|
2214
|
+
// console.log('[ErrorHandling] Found', backups.length, 'backup records for recovery');
|
|
2078
2215
|
|
|
2079
2216
|
// Process each backup
|
|
2080
2217
|
backups.forEach(async (backup) => {
|
|
2081
2218
|
try {
|
|
2082
2219
|
// Attempt to save the backed up data
|
|
2083
2220
|
// This would call the original save function with the backed up data
|
|
2084
|
-
console.log('[ErrorHandling] Attempting recovery for session:', backup.sessionId);
|
|
2221
|
+
// console.log('[ErrorHandling] Attempting recovery for session:', backup.sessionId);
|
|
2085
2222
|
} catch (error) {
|
|
2086
2223
|
console.error('[ErrorHandling] Recovery failed for session:', backup.sessionId, error);
|
|
2087
2224
|
}
|
|
@@ -2124,7 +2261,7 @@ async function downloadBackupData() {
|
|
|
2124
2261
|
filename: `chrome-debug-backup-${Date.now()}.json`
|
|
2125
2262
|
});
|
|
2126
2263
|
|
|
2127
|
-
console.log('[ErrorHandling] Backup data download initiated');
|
|
2264
|
+
// console.log('[ErrorHandling] Backup data download initiated');
|
|
2128
2265
|
};
|
|
2129
2266
|
};
|
|
2130
2267
|
};
|
|
@@ -2140,7 +2277,7 @@ async function createOffscreenDocument() {
|
|
|
2140
2277
|
const hasDocument = await chrome.offscreen.hasDocument();
|
|
2141
2278
|
if (hasDocument) {
|
|
2142
2279
|
hasOffscreenDocument = true;
|
|
2143
|
-
console.log('Offscreen document already exists');
|
|
2280
|
+
// console.log('Offscreen document already exists');
|
|
2144
2281
|
return;
|
|
2145
2282
|
}
|
|
2146
2283
|
|
|
@@ -2151,12 +2288,12 @@ async function createOffscreenDocument() {
|
|
|
2151
2288
|
justification: 'Recording tab frames for Chrome Debug'
|
|
2152
2289
|
});
|
|
2153
2290
|
hasOffscreenDocument = true;
|
|
2154
|
-
console.log('Created new offscreen document');
|
|
2291
|
+
// console.log('Created new offscreen document');
|
|
2155
2292
|
} catch (error) {
|
|
2156
2293
|
if (error.message.includes('Only a single offscreen document may be created')) {
|
|
2157
2294
|
// Document already exists, just mark it as available
|
|
2158
2295
|
hasOffscreenDocument = true;
|
|
2159
|
-
console.log('Offscreen document already exists (caught error)');
|
|
2296
|
+
// console.log('Offscreen document already exists (caught error)');
|
|
2160
2297
|
} else {
|
|
2161
2298
|
throw error;
|
|
2162
2299
|
}
|
|
@@ -2174,7 +2311,7 @@ async function closeOffscreenDocument() {
|
|
|
2174
2311
|
}
|
|
2175
2312
|
|
|
2176
2313
|
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
2177
|
-
console.log('Received message:', request.action || request.type || 'unknown');
|
|
2314
|
+
// console.log('Received message:', request.action || request.type || 'unknown');
|
|
2178
2315
|
|
|
2179
2316
|
if (request.action === 'sendToServer') {
|
|
2180
2317
|
// Primary port is 3028 - try it first, then fallback to others if needed
|
|
@@ -2182,11 +2319,11 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
|
2182
2319
|
|
|
2183
2320
|
async function tryPorts() {
|
|
2184
2321
|
let lastError = null;
|
|
2185
|
-
console.log('Trying to connect to server...');
|
|
2322
|
+
// console.log('Trying to connect to server...');
|
|
2186
2323
|
|
|
2187
2324
|
for (const port of ports) {
|
|
2188
2325
|
try {
|
|
2189
|
-
console.log(`Trying port ${port}...`);
|
|
2326
|
+
// console.log(`Trying port ${port}...`);
|
|
2190
2327
|
const controller = new AbortController();
|
|
2191
2328
|
const timeoutId = setTimeout(() => controller.abort(), DISCOVERY_TIMEOUT);
|
|
2192
2329
|
|
|
@@ -2203,7 +2340,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
|
2203
2340
|
|
|
2204
2341
|
if (response.ok) {
|
|
2205
2342
|
const result = await response.json();
|
|
2206
|
-
console.log(`Success on port ${port}:`, result);
|
|
2343
|
+
// console.log(`Success on port ${port}:`, result);
|
|
2207
2344
|
sendResponse({ success: true, result, port });
|
|
2208
2345
|
return;
|
|
2209
2346
|
} else {
|
|
@@ -2211,7 +2348,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
|
2211
2348
|
try {
|
|
2212
2349
|
const errorData = await response.json();
|
|
2213
2350
|
if (errorData.message || errorData.error) {
|
|
2214
|
-
console.log(`Port ${port} error:`, errorData);
|
|
2351
|
+
// console.log(`Port ${port} error:`, errorData);
|
|
2215
2352
|
sendResponse({
|
|
2216
2353
|
success: false,
|
|
2217
2354
|
result: errorData,
|
|
@@ -2223,11 +2360,11 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
|
2223
2360
|
// Response wasn't JSON
|
|
2224
2361
|
}
|
|
2225
2362
|
lastError = `Port ${port}: HTTP ${response.status}`;
|
|
2226
|
-
console.log(lastError);
|
|
2363
|
+
// console.log(lastError);
|
|
2227
2364
|
}
|
|
2228
2365
|
} catch (e) {
|
|
2229
2366
|
lastError = `Port ${port}: ${e.message}`;
|
|
2230
|
-
console.log(lastError);
|
|
2367
|
+
// console.log(lastError);
|
|
2231
2368
|
}
|
|
2232
2369
|
}
|
|
2233
2370
|
|
|
@@ -2305,7 +2442,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
|
2305
2442
|
|
|
2306
2443
|
// Session manager lease renewal handler
|
|
2307
2444
|
if (request.action === 'renewLease') {
|
|
2308
|
-
console.log('[Background] RENEW LEASE - Session:', request.sessionId, 'Manager exists:', !!sessionManager);
|
|
2445
|
+
// console.log('[Background] RENEW LEASE - Session:', request.sessionId, 'Manager exists:', !!sessionManager);
|
|
2309
2446
|
|
|
2310
2447
|
if (!sessionManager) {
|
|
2311
2448
|
console.error('[Background] Session manager not available');
|
|
@@ -2321,7 +2458,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
|
2321
2458
|
};
|
|
2322
2459
|
|
|
2323
2460
|
sessionManager.renewLease(leaseRequest).then((result) => {
|
|
2324
|
-
console.log('[Background] Lease renewed - Success:', result.success);
|
|
2461
|
+
// console.log('[Background] Lease renewed - Success:', result.success);
|
|
2325
2462
|
sendResponse(result);
|
|
2326
2463
|
}).catch((error) => {
|
|
2327
2464
|
console.error('[Background] Error renewing lease:', error);
|
|
@@ -2355,6 +2492,45 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
|
2355
2492
|
return true;
|
|
2356
2493
|
}
|
|
2357
2494
|
|
|
2495
|
+
// User activity handler for inactivity tracking
|
|
2496
|
+
if (request.action === 'userActivity') {
|
|
2497
|
+
handleUserActivity(request.timestamp);
|
|
2498
|
+
sendResponse({ success: true });
|
|
2499
|
+
return false; // Synchronous response
|
|
2500
|
+
}
|
|
2501
|
+
|
|
2502
|
+
// Countdown complete handler - content script finished 3-2-1 countdown
|
|
2503
|
+
if (request.action === 'countdownComplete') {
|
|
2504
|
+
// Start inactivity monitoring now that countdown is done
|
|
2505
|
+
// Use isCurrentlyRecording (the actual state variable)
|
|
2506
|
+
if (isCurrentlyRecording && recordingTabId && !inactivityMonitoringStarted) {
|
|
2507
|
+
startInactivityMonitoring(recordingTabId);
|
|
2508
|
+
}
|
|
2509
|
+
sendResponse({ success: true });
|
|
2510
|
+
return false;
|
|
2511
|
+
}
|
|
2512
|
+
|
|
2513
|
+
// Toggle inactivity timeout (user clicked disable/enable button)
|
|
2514
|
+
if (request.action === 'toggleInactivityTimeout') {
|
|
2515
|
+
inactivityDisabled = !inactivityDisabled;
|
|
2516
|
+
|
|
2517
|
+
if (inactivityDisabled) {
|
|
2518
|
+
// Stop the check interval but keep tracking activity
|
|
2519
|
+
if (inactivityCheckInterval) {
|
|
2520
|
+
clearInterval(inactivityCheckInterval);
|
|
2521
|
+
inactivityCheckInterval = null;
|
|
2522
|
+
}
|
|
2523
|
+
} else {
|
|
2524
|
+
// Restart monitoring
|
|
2525
|
+
if (recordingTabId && !inactivityCheckInterval) {
|
|
2526
|
+
startInactivityMonitoring(recordingTabId);
|
|
2527
|
+
}
|
|
2528
|
+
}
|
|
2529
|
+
|
|
2530
|
+
sendResponse({ success: true, disabled: inactivityDisabled });
|
|
2531
|
+
return false;
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2358
2534
|
// Force stop session handler (emergency)
|
|
2359
2535
|
if (request.action === 'forceStopSession') {
|
|
2360
2536
|
if (!sessionManager) {
|
|
@@ -2408,7 +2584,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
|
2408
2584
|
*/
|
|
2409
2585
|
/*
|
|
2410
2586
|
if (request.action === 'takeStandaloneSnapshot') {
|
|
2411
|
-
console.log('Taking standalone snapshot for tab:', request.tabId);
|
|
2587
|
+
// console.log('Taking standalone snapshot for tab:', request.tabId);
|
|
2412
2588
|
takeStandaloneSnapshot(request.tabId, request.note).then((result) => {
|
|
2413
2589
|
sendResponse({ success: true, sessionId: result.sessionId });
|
|
2414
2590
|
}).catch((error) => {
|
|
@@ -2456,7 +2632,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
|
2456
2632
|
}
|
|
2457
2633
|
|
|
2458
2634
|
if (request.action === 'startRecordingFromContent') {
|
|
2459
|
-
console.log('Starting recording from content script');
|
|
2635
|
+
// console.log('Starting recording from content script');
|
|
2460
2636
|
const tabId = sender.tab.id;
|
|
2461
2637
|
|
|
2462
2638
|
// Store recording state and show notification
|
|
@@ -2480,14 +2656,14 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
|
2480
2656
|
}
|
|
2481
2657
|
|
|
2482
2658
|
if (request.action === 'deleteRecording') {
|
|
2483
|
-
console.log('Deleting recording:', request.recordingId);
|
|
2659
|
+
// console.log('Deleting recording:', request.recordingId);
|
|
2484
2660
|
deleteRecordingFromServer(request.recordingId, sendResponse);
|
|
2485
2661
|
return true;
|
|
2486
2662
|
}
|
|
2487
2663
|
|
|
2488
2664
|
// Workflow recording handlers
|
|
2489
2665
|
if (request.action === 'startWorkflowRecording') {
|
|
2490
|
-
console.log('Starting workflow recording for tab:', request.tabId);
|
|
2666
|
+
// console.log('Starting workflow recording for tab:', request.tabId);
|
|
2491
2667
|
startWorkflowRecording(
|
|
2492
2668
|
request.tabId,
|
|
2493
2669
|
request.includeLogsInExport,
|
|
@@ -2504,7 +2680,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
|
2504
2680
|
|
|
2505
2681
|
if (request.action === 'stopWorkflowRecording') {
|
|
2506
2682
|
const tabId = request.tabId || sender.tab?.id;
|
|
2507
|
-
console.log('Stopping workflow recording for tab:', tabId);
|
|
2683
|
+
// console.log('Stopping workflow recording for tab:', tabId);
|
|
2508
2684
|
// stopWorkflowRecording already returns { success: true, workflow: {...}, savedToServer: bool }
|
|
2509
2685
|
// so we pass it through directly - don't double-wrap!
|
|
2510
2686
|
stopWorkflowRecording(tabId).then(async (result) => {
|
|
@@ -2600,7 +2776,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
|
2600
2776
|
frameIndex: frameIndex
|
|
2601
2777
|
};
|
|
2602
2778
|
screenInteractions.push(interaction);
|
|
2603
|
-
console.log('Screen interaction recorded:', interaction.type, 'Total:', screenInteractions.length);
|
|
2779
|
+
// console.log('Screen interaction recorded:', interaction.type, 'Total:', screenInteractions.length);
|
|
2604
2780
|
}
|
|
2605
2781
|
}).catch(error => {
|
|
2606
2782
|
console.error('Error validating recording state for screen interaction:', error);
|
|
@@ -2613,7 +2789,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
|
2613
2789
|
frameIndex: frameCounter.get(currentRecordingSessionId) || 0
|
|
2614
2790
|
};
|
|
2615
2791
|
screenInteractions.push(interaction);
|
|
2616
|
-
console.log('Screen interaction recorded:', interaction.type, 'Total:', screenInteractions.length);
|
|
2792
|
+
// console.log('Screen interaction recorded:', interaction.type, 'Total:', screenInteractions.length);
|
|
2617
2793
|
}
|
|
2618
2794
|
}
|
|
2619
2795
|
}
|
|
@@ -2729,18 +2905,18 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
|
2729
2905
|
|
|
2730
2906
|
// Handle workflow screenshot capture
|
|
2731
2907
|
if (request.action === 'captureWorkflowScreenshot' && sender.tab) {
|
|
2732
|
-
console.log('[SCREENSHOT-DEBUG] background.js - Received captureWorkflowScreenshot message');
|
|
2908
|
+
// console.log('[SCREENSHOT-DEBUG] background.js - Received captureWorkflowScreenshot message');
|
|
2733
2909
|
const tabId = sender.tab.id;
|
|
2734
2910
|
const settings = request.settings || {};
|
|
2735
|
-
console.log('[SCREENSHOT-DEBUG] background.js - tabId:', tabId);
|
|
2736
|
-
console.log('[SCREENSHOT-DEBUG] background.js - settings:', JSON.stringify(settings));
|
|
2911
|
+
// console.log('[SCREENSHOT-DEBUG] background.js - tabId:', tabId);
|
|
2912
|
+
// console.log('[SCREENSHOT-DEBUG] background.js - settings:', JSON.stringify(settings));
|
|
2737
2913
|
|
|
2738
2914
|
captureTabScreenshot(tabId, settings).then((screenshotData) => {
|
|
2739
|
-
console.log('[SCREENSHOT-DEBUG] background.js - captureTabScreenshot succeeded');
|
|
2740
|
-
console.log('[SCREENSHOT-DEBUG] background.js - screenshotData type:', typeof screenshotData);
|
|
2741
|
-
console.log('[SCREENSHOT-DEBUG] background.js - screenshotData length:', screenshotData?.length);
|
|
2742
|
-
console.log('[SCREENSHOT-DEBUG] background.js - screenshotData preview:', screenshotData?.substring(0, 100));
|
|
2743
|
-
console.log('[SCREENSHOT-DEBUG] background.js - Sending response with success: true');
|
|
2915
|
+
// console.log('[SCREENSHOT-DEBUG] background.js - captureTabScreenshot succeeded');
|
|
2916
|
+
// console.log('[SCREENSHOT-DEBUG] background.js - screenshotData type:', typeof screenshotData);
|
|
2917
|
+
// console.log('[SCREENSHOT-DEBUG] background.js - screenshotData length:', screenshotData?.length);
|
|
2918
|
+
// console.log('[SCREENSHOT-DEBUG] background.js - screenshotData preview:', screenshotData?.substring(0, 100));
|
|
2919
|
+
// console.log('[SCREENSHOT-DEBUG] background.js - Sending response with success: true');
|
|
2744
2920
|
sendResponse({ success: true, screenshotData });
|
|
2745
2921
|
}).catch((error) => {
|
|
2746
2922
|
console.error('[SCREENSHOT-DEBUG] background.js - captureTabScreenshot FAILED');
|
|
@@ -2774,7 +2950,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
|
2774
2950
|
/*
|
|
2775
2951
|
async function takeStandaloneSnapshot(tabId, note = '') {
|
|
2776
2952
|
try {
|
|
2777
|
-
console.log('Taking standalone snapshot for tab:', tabId);
|
|
2953
|
+
// console.log('Taking standalone snapshot for tab:', tabId);
|
|
2778
2954
|
|
|
2779
2955
|
// Create a unique session ID for the snapshot
|
|
2780
2956
|
const sessionId = `snapshot_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
@@ -2850,7 +3026,7 @@ async function takeStandaloneSnapshot(tabId, note = '') {
|
|
|
2850
3026
|
|
|
2851
3027
|
if (response.ok) {
|
|
2852
3028
|
const result = await response.json();
|
|
2853
|
-
console.log('Snapshot uploaded successfully:', sessionId);
|
|
3029
|
+
// console.log('Snapshot uploaded successfully:', sessionId);
|
|
2854
3030
|
uploadSuccess = true;
|
|
2855
3031
|
break;
|
|
2856
3032
|
}
|
|
@@ -2874,34 +3050,34 @@ async function takeStandaloneSnapshot(tabId, note = '') {
|
|
|
2874
3050
|
|
|
2875
3051
|
// Capture screenshot for workflow recording
|
|
2876
3052
|
async function captureTabScreenshot(tabId, settings) {
|
|
2877
|
-
console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - ENTRY');
|
|
2878
|
-
console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - tabId:', tabId);
|
|
2879
|
-
console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - settings:', JSON.stringify(settings));
|
|
3053
|
+
// console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - ENTRY');
|
|
3054
|
+
// console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - tabId:', tabId);
|
|
3055
|
+
// console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - settings:', JSON.stringify(settings));
|
|
2880
3056
|
|
|
2881
3057
|
try {
|
|
2882
3058
|
// Get the tab to find its window
|
|
2883
|
-
console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - Getting tab info...');
|
|
3059
|
+
// console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - Getting tab info...');
|
|
2884
3060
|
const tab = await chrome.tabs.get(tabId);
|
|
2885
3061
|
const windowId = tab.windowId;
|
|
2886
|
-
console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - windowId:', windowId);
|
|
2887
|
-
console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - tab.url:', tab.url);
|
|
3062
|
+
// console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - windowId:', windowId);
|
|
3063
|
+
// console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - tab.url:', tab.url);
|
|
2888
3064
|
|
|
2889
3065
|
const captureOptions = {
|
|
2890
3066
|
format: settings.format || 'jpeg',
|
|
2891
3067
|
quality: settings.quality || 30
|
|
2892
3068
|
};
|
|
2893
|
-
console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - captureOptions:', JSON.stringify(captureOptions));
|
|
2894
|
-
console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - Calling chrome.tabs.captureVisibleTab...');
|
|
3069
|
+
// console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - captureOptions:', JSON.stringify(captureOptions));
|
|
3070
|
+
// console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - Calling chrome.tabs.captureVisibleTab...');
|
|
2895
3071
|
|
|
2896
3072
|
const dataUrl = await chrome.tabs.captureVisibleTab(windowId, captureOptions);
|
|
2897
3073
|
|
|
2898
|
-
console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - captureVisibleTab SUCCESS');
|
|
2899
|
-
console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - dataUrl length:', dataUrl?.length);
|
|
2900
|
-
console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - dataUrl prefix:', dataUrl?.substring(0, 100));
|
|
3074
|
+
// console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - captureVisibleTab SUCCESS');
|
|
3075
|
+
// console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - dataUrl length:', dataUrl?.length);
|
|
3076
|
+
// console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - dataUrl prefix:', dataUrl?.substring(0, 100));
|
|
2901
3077
|
|
|
2902
3078
|
// If resolution is specified, resize the image
|
|
2903
3079
|
if (settings.maxWidth || settings.maxHeight) {
|
|
2904
|
-
console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - Resizing required, maxWidth:', settings.maxWidth, 'maxHeight:', settings.maxHeight);
|
|
3080
|
+
// console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - Resizing required, maxWidth:', settings.maxWidth, 'maxHeight:', settings.maxHeight);
|
|
2905
3081
|
// Create an image element to get dimensions
|
|
2906
3082
|
const img = new Image();
|
|
2907
3083
|
const canvas = new OffscreenCanvas(1, 1);
|
|
@@ -2941,8 +3117,8 @@ async function captureTabScreenshot(tabId, settings) {
|
|
|
2941
3117
|
});
|
|
2942
3118
|
}
|
|
2943
3119
|
|
|
2944
|
-
console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - No resize needed, returning dataUrl');
|
|
2945
|
-
console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - Final dataUrl length:', dataUrl?.length);
|
|
3120
|
+
// console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - No resize needed, returning dataUrl');
|
|
3121
|
+
// console.log('[SCREENSHOT-DEBUG] captureTabScreenshot - Final dataUrl length:', dataUrl?.length);
|
|
2946
3122
|
return dataUrl;
|
|
2947
3123
|
} catch (error) {
|
|
2948
3124
|
console.error('[SCREENSHOT-DEBUG] captureTabScreenshot - EXCEPTION CAUGHT');
|
|
@@ -2956,7 +3132,7 @@ async function captureTabScreenshot(tabId, settings) {
|
|
|
2956
3132
|
// Start recording
|
|
2957
3133
|
// Detect if server is available (server mode vs browser-only mode)
|
|
2958
3134
|
async function detectServerMode() {
|
|
2959
|
-
console.log('[ServerDetection] Checking server availability...');
|
|
3135
|
+
// console.log('[ServerDetection] Checking server availability...');
|
|
2960
3136
|
|
|
2961
3137
|
for (const port of CONFIG_PORTS) {
|
|
2962
3138
|
try {
|
|
@@ -2970,7 +3146,7 @@ async function detectServerMode() {
|
|
|
2970
3146
|
]);
|
|
2971
3147
|
|
|
2972
3148
|
if (response.ok) {
|
|
2973
|
-
console.log(`[ServerDetection] Server detected on port ${port}`);
|
|
3149
|
+
// console.log(`[ServerDetection] Server detected on port ${port}`);
|
|
2974
3150
|
serverMode = 'server';
|
|
2975
3151
|
return 'server';
|
|
2976
3152
|
}
|
|
@@ -2979,7 +3155,7 @@ async function detectServerMode() {
|
|
|
2979
3155
|
}
|
|
2980
3156
|
}
|
|
2981
3157
|
|
|
2982
|
-
console.log('[ServerDetection] No server detected - using browser-only mode');
|
|
3158
|
+
// console.log('[ServerDetection] No server detected - using browser-only mode');
|
|
2983
3159
|
serverMode = 'browser-only';
|
|
2984
3160
|
return 'browser-only';
|
|
2985
3161
|
}
|
|
@@ -3007,7 +3183,7 @@ async function startRecording(tabId, settings = {}) {
|
|
|
3007
3183
|
try {
|
|
3008
3184
|
// Detect server mode before starting
|
|
3009
3185
|
await detectServerMode();
|
|
3010
|
-
console.log(`[Recording] Mode: ${serverMode}`);
|
|
3186
|
+
// console.log(`[Recording] Mode: ${serverMode}`);
|
|
3011
3187
|
|
|
3012
3188
|
// Check if session manager is available
|
|
3013
3189
|
if (!sessionManager) {
|
|
@@ -3028,12 +3204,12 @@ async function startRecording(tabId, settings = {}) {
|
|
|
3028
3204
|
|
|
3029
3205
|
// Start capturing console logs FIRST, before any other setup
|
|
3030
3206
|
const logsStarted = await startCapturingLogs(tabId);
|
|
3031
|
-
console.log('Console log capture started:', logsStarted);
|
|
3207
|
+
// console.log('Console log capture started:', logsStarted);
|
|
3032
3208
|
|
|
3033
3209
|
// Give console interception time to settle (increased from 100ms to 500ms for reliability)
|
|
3034
3210
|
if (logsStarted) {
|
|
3035
3211
|
await new Promise(resolve => setTimeout(resolve, 500));
|
|
3036
|
-
console.log('[Recording] Console interception ready');
|
|
3212
|
+
// console.log('[Recording] Console interception ready');
|
|
3037
3213
|
} else {
|
|
3038
3214
|
console.warn('[Recording] Console capture unavailable for this page - recording will proceed without console logs');
|
|
3039
3215
|
}
|
|
@@ -3046,7 +3222,7 @@ async function startRecording(tabId, settings = {}) {
|
|
|
3046
3222
|
targetTabId: tabId
|
|
3047
3223
|
});
|
|
3048
3224
|
|
|
3049
|
-
console.log('Got stream ID:', streamId);
|
|
3225
|
+
// console.log('Got stream ID:', streamId);
|
|
3050
3226
|
|
|
3051
3227
|
// Create session with session manager
|
|
3052
3228
|
const sessionConfig = {
|
|
@@ -3079,7 +3255,7 @@ async function startRecording(tabId, settings = {}) {
|
|
|
3079
3255
|
|
|
3080
3256
|
// STEP 4: Initialize browser-only recording if in browser-only mode
|
|
3081
3257
|
if (serverMode === 'browser-only' && browserRecordingManager) {
|
|
3082
|
-
console.log('[Recording] Initializing browser-only recording in IndexedDB');
|
|
3258
|
+
// console.log('[Recording] Initializing browser-only recording in IndexedDB');
|
|
3083
3259
|
const tab = await chrome.tabs.get(tabId);
|
|
3084
3260
|
await browserRecordingManager.startRecording(sessionId, {
|
|
3085
3261
|
tabId: tabId,
|
|
@@ -3112,7 +3288,19 @@ async function startRecording(tabId, settings = {}) {
|
|
|
3112
3288
|
// Update badge
|
|
3113
3289
|
chrome.action.setBadgeText({ text: 'REC' });
|
|
3114
3290
|
chrome.action.setBadgeBackgroundColor({ color: '#FF0000' });
|
|
3115
|
-
|
|
3291
|
+
|
|
3292
|
+
// DON'T start inactivity monitoring here - wait for countdownComplete message
|
|
3293
|
+
// This ensures the 10s timer starts AFTER the 3s visual countdown, not before
|
|
3294
|
+
// Set a fallback timer in case content script doesn't send countdownComplete
|
|
3295
|
+
inactivityMonitoringStarted = false;
|
|
3296
|
+
if (inactivityFallbackTimer) clearTimeout(inactivityFallbackTimer);
|
|
3297
|
+
inactivityFallbackTimer = setTimeout(async () => {
|
|
3298
|
+
// Use isCurrentlyRecording (the actual state variable)
|
|
3299
|
+
if (isCurrentlyRecording && !inactivityMonitoringStarted) {
|
|
3300
|
+
await startInactivityMonitoring(tabId);
|
|
3301
|
+
}
|
|
3302
|
+
}, 5000); // 5s = 3s countdown + 2s buffer
|
|
3303
|
+
|
|
3116
3304
|
// If on a restricted page, notify user
|
|
3117
3305
|
const tab = await chrome.tabs.get(tabId);
|
|
3118
3306
|
if (tab.url && (tab.url.startsWith('chrome://') || tab.url.startsWith('chrome-extension://'))) {
|
|
@@ -3133,12 +3321,12 @@ async function startRecording(tabId, settings = {}) {
|
|
|
3133
3321
|
sessionId: sessionId
|
|
3134
3322
|
}).catch(async (error) => {
|
|
3135
3323
|
// Content script might not be injected, try to inject it
|
|
3136
|
-
console.log('Could not notify content script, attempting to inject:', error);
|
|
3324
|
+
// console.log('Could not notify content script, attempting to inject:', error);
|
|
3137
3325
|
|
|
3138
3326
|
// First check if this tab allows content script injection
|
|
3139
3327
|
const tab = await chrome.tabs.get(tabId);
|
|
3140
3328
|
if (!tab.url || tab.url.startsWith('chrome://') || tab.url.startsWith('chrome-extension://') || tab.url.startsWith('moz-extension://')) {
|
|
3141
|
-
console.log('Cannot inject content script into restricted URL:', tab.url);
|
|
3329
|
+
// console.log('Cannot inject content script into restricted URL:', tab.url);
|
|
3142
3330
|
return;
|
|
3143
3331
|
}
|
|
3144
3332
|
|
|
@@ -3174,7 +3362,7 @@ async function startRecording(tabId, settings = {}) {
|
|
|
3174
3362
|
url: tab.url,
|
|
3175
3363
|
title: tab.title
|
|
3176
3364
|
});
|
|
3177
|
-
console.log('[Recording] Browser recording initialized for session:', sessionId);
|
|
3365
|
+
// console.log('[Recording] Browser recording initialized for session:', sessionId);
|
|
3178
3366
|
}
|
|
3179
3367
|
|
|
3180
3368
|
// Send stream ID, session info, and settings to offscreen document for frame capture
|
|
@@ -3194,7 +3382,7 @@ async function startRecording(tabId, settings = {}) {
|
|
|
3194
3382
|
}
|
|
3195
3383
|
});
|
|
3196
3384
|
|
|
3197
|
-
console.log('Recording started in', serverMode, 'mode');
|
|
3385
|
+
// console.log('Recording started in', serverMode, 'mode');
|
|
3198
3386
|
} catch (error) {
|
|
3199
3387
|
console.error('Error in startRecording:', error);
|
|
3200
3388
|
throw error;
|
|
@@ -3213,13 +3401,16 @@ async function stopRecording() {
|
|
|
3213
3401
|
// Check if currently recording via session manager
|
|
3214
3402
|
const currentlyRecording = await isCurrentlyRecordingAsync();
|
|
3215
3403
|
if (!currentlyRecording) {
|
|
3216
|
-
console.log('No active recording session to stop');
|
|
3404
|
+
// console.log('No active recording session to stop');
|
|
3217
3405
|
return { success: false, error: 'No active recording' };
|
|
3218
3406
|
}
|
|
3219
3407
|
|
|
3220
3408
|
// Store sessionId before clearing it
|
|
3221
3409
|
const stoppedSessionId = currentSession?.sessionId;
|
|
3222
3410
|
|
|
3411
|
+
// Stop inactivity monitoring
|
|
3412
|
+
await stopInactivityMonitoring(recordingTabId);
|
|
3413
|
+
|
|
3223
3414
|
// Capture frame count and duration for the response
|
|
3224
3415
|
let recordedFrameCount = 0;
|
|
3225
3416
|
let recordedDuration = 0;
|
|
@@ -3233,11 +3424,11 @@ async function stopRecording() {
|
|
|
3233
3424
|
} else {
|
|
3234
3425
|
recordedFrameCount = stopResult.frameCount || 0;
|
|
3235
3426
|
recordedDuration = stopResult.sessionDuration || 0;
|
|
3236
|
-
console.log(`Recording stopped. Duration: ${recordedDuration}ms, Frames: ${recordedFrameCount}`);
|
|
3427
|
+
// console.log(`Recording stopped. Duration: ${recordedDuration}ms, Frames: ${recordedFrameCount}`);
|
|
3237
3428
|
|
|
3238
3429
|
// Finalize browser-only recording if in browser-only mode
|
|
3239
3430
|
if (serverMode === 'browser-only' && browserRecordingManager) {
|
|
3240
|
-
console.log('[Browser-Only] Finalizing browser recording in IndexedDB');
|
|
3431
|
+
// console.log('[Browser-Only] Finalizing browser recording in IndexedDB');
|
|
3241
3432
|
await browserRecordingManager.stopRecording(currentSession.sessionId);
|
|
3242
3433
|
}
|
|
3243
3434
|
}
|
|
@@ -3248,10 +3439,10 @@ async function stopRecording() {
|
|
|
3248
3439
|
let flushCompleted = false;
|
|
3249
3440
|
if (logBuffer) {
|
|
3250
3441
|
try {
|
|
3251
|
-
console.log('[Background] Flushing all buffered logs before stop...');
|
|
3442
|
+
// console.log('[Background] Flushing all buffered logs before stop...');
|
|
3252
3443
|
await logBuffer.flushAll();
|
|
3253
3444
|
flushCompleted = true;
|
|
3254
|
-
console.log('[Background] Successfully flushed all buffered logs');
|
|
3445
|
+
// console.log('[Background] Successfully flushed all buffered logs');
|
|
3255
3446
|
} catch (flushError) {
|
|
3256
3447
|
console.error('[Background] Failed to flush logs during stop:', flushError);
|
|
3257
3448
|
// Continue with stop process even if flush fails
|
|
@@ -3271,25 +3462,25 @@ async function stopRecording() {
|
|
|
3271
3462
|
|
|
3272
3463
|
// CRITICAL: Store recordingTabId BEFORE clearing it (for cleanup)
|
|
3273
3464
|
const previousRecordingTabId = recordingTabId;
|
|
3274
|
-
console.log('[Background] previousRecordingTabId:', previousRecordingTabId, 'stoppedSessionId:', stoppedSessionId);
|
|
3465
|
+
// console.log('[Background] previousRecordingTabId:', previousRecordingTabId, 'stoppedSessionId:', stoppedSessionId);
|
|
3275
3466
|
|
|
3276
3467
|
// CRITICAL FIX: Send stop-screen-capture-tracking message to recording tab WITH sessionId
|
|
3277
3468
|
// so it can show the completion UI
|
|
3278
3469
|
if (previousRecordingTabId && stoppedSessionId) {
|
|
3279
3470
|
try {
|
|
3280
|
-
console.log('[Background] Sending recording-complete-show-ui message to tab:', previousRecordingTabId, 'with sessionId:', stoppedSessionId);
|
|
3471
|
+
// console.log('[Background] Sending recording-complete-show-ui message to tab:', previousRecordingTabId, 'with sessionId:', stoppedSessionId);
|
|
3281
3472
|
await chrome.tabs.sendMessage(previousRecordingTabId, {
|
|
3282
3473
|
type: 'recording-complete-show-ui',
|
|
3283
3474
|
sessionId: stoppedSessionId
|
|
3284
3475
|
}).catch((err) => {
|
|
3285
|
-
console.log('[Background] Could not send completion UI message to recording tab:', err);
|
|
3476
|
+
// console.log('[Background] Could not send completion UI message to recording tab:', err);
|
|
3286
3477
|
});
|
|
3287
|
-
console.log('[Background] Successfully sent recording-complete-show-ui message');
|
|
3478
|
+
// console.log('[Background] Successfully sent recording-complete-show-ui message');
|
|
3288
3479
|
} catch (error) {
|
|
3289
3480
|
console.error('[Background] Failed to send completion UI message:', error);
|
|
3290
3481
|
}
|
|
3291
3482
|
} else {
|
|
3292
|
-
console.log('[Background] NOT sending recording-complete-show-ui - missing previousRecordingTabId or stoppedSessionId');
|
|
3483
|
+
// console.log('[Background] NOT sending recording-complete-show-ui - missing previousRecordingTabId or stoppedSessionId');
|
|
3293
3484
|
}
|
|
3294
3485
|
|
|
3295
3486
|
// CRITICAL FIX: Send stop-screen-capture-tracking message to ALL content scripts
|
|
@@ -3301,13 +3492,13 @@ async function stopRecording() {
|
|
|
3301
3492
|
type: 'stop-screen-capture-tracking'
|
|
3302
3493
|
}).catch(() => {
|
|
3303
3494
|
// Ignore errors for tabs that don't have content scripts
|
|
3304
|
-
console.log(`[Background] Could not send cleanup message to tab ${tab.id}`);
|
|
3495
|
+
// console.log(`[Background] Could not send cleanup message to tab ${tab.id}`);
|
|
3305
3496
|
});
|
|
3306
3497
|
}
|
|
3307
3498
|
return Promise.resolve();
|
|
3308
3499
|
});
|
|
3309
3500
|
await Promise.all(cleanupPromises);
|
|
3310
|
-
console.log('[Background] Cleanup messages sent to all content scripts');
|
|
3501
|
+
// console.log('[Background] Cleanup messages sent to all content scripts');
|
|
3311
3502
|
} catch (error) {
|
|
3312
3503
|
console.error('[Background] Failed to send cleanup messages to content scripts:', error);
|
|
3313
3504
|
}
|
|
@@ -3315,7 +3506,7 @@ async function stopRecording() {
|
|
|
3315
3506
|
// CRITICAL FIX: Restore original console methods and remove event listeners
|
|
3316
3507
|
if (previousRecordingTabId) {
|
|
3317
3508
|
try {
|
|
3318
|
-
console.log('[Background] Stopping console log capture for tab:', previousRecordingTabId);
|
|
3509
|
+
// console.log('[Background] Stopping console log capture for tab:', previousRecordingTabId);
|
|
3319
3510
|
await stopCapturingLogs(previousRecordingTabId);
|
|
3320
3511
|
} catch (cleanupError) {
|
|
3321
3512
|
console.error('[Background] Failed to cleanup console interceptor:', cleanupError);
|
|
@@ -3339,11 +3530,11 @@ async function stopRecording() {
|
|
|
3339
3530
|
|
|
3340
3531
|
// CRITICAL: Clear pending frame queue to prevent infinite retry loop
|
|
3341
3532
|
if (stoppedSessionId && pendingFrameQueue.has(stoppedSessionId)) {
|
|
3342
|
-
console.log(`[FrameQueue] Clearing ${pendingFrameQueue.get(stoppedSessionId).length} pending frames for stopped session ${stoppedSessionId}`);
|
|
3533
|
+
// console.log(`[FrameQueue] Clearing ${pendingFrameQueue.get(stoppedSessionId).length} pending frames for stopped session ${stoppedSessionId}`);
|
|
3343
3534
|
pendingFrameQueue.delete(stoppedSessionId);
|
|
3344
3535
|
}
|
|
3345
3536
|
|
|
3346
|
-
console.log('Stop message sent to offscreen document');
|
|
3537
|
+
// console.log('Stop message sent to offscreen document');
|
|
3347
3538
|
|
|
3348
3539
|
// Notify popup to refresh recordings list
|
|
3349
3540
|
chrome.runtime.sendMessage({
|
|
@@ -3351,7 +3542,7 @@ async function stopRecording() {
|
|
|
3351
3542
|
sessionId: stoppedSessionId
|
|
3352
3543
|
}).catch(() => {
|
|
3353
3544
|
// Popup might not be open, that's okay
|
|
3354
|
-
console.log('[Background] Popup not available to notify of recording stop');
|
|
3545
|
+
// console.log('[Background] Popup not available to notify of recording stop');
|
|
3355
3546
|
});
|
|
3356
3547
|
|
|
3357
3548
|
// Format duration as human-readable string (e.g., "1m 30s" or "45s")
|
|
@@ -3380,7 +3571,7 @@ async function stopRecording() {
|
|
|
3380
3571
|
// CRITICAL FIX: Clean up console interceptor even on error
|
|
3381
3572
|
if (errorRecordingTabId) {
|
|
3382
3573
|
try {
|
|
3383
|
-
console.log('[Background] Emergency cleanup of console interceptor for tab:', errorRecordingTabId);
|
|
3574
|
+
// console.log('[Background] Emergency cleanup of console interceptor for tab:', errorRecordingTabId);
|
|
3384
3575
|
await stopCapturingLogs(errorRecordingTabId);
|
|
3385
3576
|
} catch (cleanupError) {
|
|
3386
3577
|
console.error('[Background] Failed to cleanup console interceptor during error handling:', cleanupError);
|
|
@@ -3407,25 +3598,25 @@ async function stopRecording() {
|
|
|
3407
3598
|
// Capture console logs from the recording tab
|
|
3408
3599
|
// REFACTORED: Now uses shared console-interception-library.js
|
|
3409
3600
|
async function startCapturingLogs(tabId) {
|
|
3410
|
-
console.log('[Screen Recording] Starting console interception using shared library');
|
|
3601
|
+
// console.log('[Screen Recording] Starting console interception using shared library');
|
|
3411
3602
|
return await self.ConsoleInterceptionLibrary.startConsoleInterception(tabId, SCREEN_RECORDING_CONSOLE_CONFIG);
|
|
3412
3603
|
}
|
|
3413
3604
|
|
|
3414
3605
|
// REFACTORED: Now uses shared console-interception-library.js via proper namespace
|
|
3415
3606
|
async function stopCapturingLogs(tabId) {
|
|
3416
|
-
console.log('[Screen Recording] Stopping console interception using shared library');
|
|
3607
|
+
// console.log('[Screen Recording] Stopping console interception using shared library');
|
|
3417
3608
|
return await self.ConsoleInterceptionLibrary.stopConsoleInterception(tabId, SCREEN_RECORDING_CONSOLE_CONFIG);
|
|
3418
3609
|
}
|
|
3419
3610
|
|
|
3420
3611
|
// Workflow Recording Functions
|
|
3421
3612
|
async function startWorkflowRecording(tabId, includeLogsInExport, sessionName = null, screenshotSettings = null) {
|
|
3422
3613
|
try {
|
|
3423
|
-
console.log('Starting workflow recording for tab:', tabId);
|
|
3614
|
+
// console.log('Starting workflow recording for tab:', tabId);
|
|
3424
3615
|
|
|
3425
3616
|
// Check if this tab allows content script injection
|
|
3426
3617
|
const tab = await chrome.tabs.get(tabId);
|
|
3427
3618
|
if (!tab.url || tab.url.startsWith('chrome://') || tab.url.startsWith('chrome-extension://') || tab.url.startsWith('moz-extension://')) {
|
|
3428
|
-
console.log('Cannot start workflow recording on restricted URL:', tab.url);
|
|
3619
|
+
// console.log('Cannot start workflow recording on restricted URL:', tab.url);
|
|
3429
3620
|
throw new Error('Cannot record workflows on restricted pages (chrome:// URLs)');
|
|
3430
3621
|
}
|
|
3431
3622
|
|
|
@@ -3446,7 +3637,7 @@ async function startWorkflowRecording(tabId, includeLogsInExport, sessionName =
|
|
|
3446
3637
|
if (includeLogsInExport) {
|
|
3447
3638
|
const buffer = new WorkflowLogBuffer(tabId);
|
|
3448
3639
|
workflowLogBuffers.set(tabId, buffer);
|
|
3449
|
-
console.log(`[Workflow] Initialized WorkflowLogBuffer for tab ${tabId}`);
|
|
3640
|
+
// console.log(`[Workflow] Initialized WorkflowLogBuffer for tab ${tabId}`);
|
|
3450
3641
|
}
|
|
3451
3642
|
|
|
3452
3643
|
// REFACTORED: Use shared console interception library via proper namespace (replaces 150+ lines of duplicate code)
|
|
@@ -3464,7 +3655,7 @@ async function startWorkflowRecording(tabId, includeLogsInExport, sessionName =
|
|
|
3464
3655
|
});
|
|
3465
3656
|
} catch (e) {
|
|
3466
3657
|
// Content script might already be injected
|
|
3467
|
-
console.log('Content script injection attempt:', e.message);
|
|
3658
|
+
// console.log('Content script injection attempt:', e.message);
|
|
3468
3659
|
}
|
|
3469
3660
|
|
|
3470
3661
|
// Tell the content script to start recording
|
|
@@ -3475,7 +3666,7 @@ async function startWorkflowRecording(tabId, includeLogsInExport, sessionName =
|
|
|
3475
3666
|
tabId: tabId
|
|
3476
3667
|
});
|
|
3477
3668
|
|
|
3478
|
-
console.log('Workflow recording started successfully');
|
|
3669
|
+
// console.log('Workflow recording started successfully');
|
|
3479
3670
|
} catch (error) {
|
|
3480
3671
|
console.error('Error starting workflow recording:', error);
|
|
3481
3672
|
throw error;
|
|
@@ -3484,7 +3675,7 @@ async function startWorkflowRecording(tabId, includeLogsInExport, sessionName =
|
|
|
3484
3675
|
|
|
3485
3676
|
async function stopWorkflowRecording(tabId) {
|
|
3486
3677
|
try {
|
|
3487
|
-
console.log('Stopping workflow recording for tab:', tabId);
|
|
3678
|
+
// console.log('Stopping workflow recording for tab:', tabId);
|
|
3488
3679
|
|
|
3489
3680
|
// Check if recording was active
|
|
3490
3681
|
if (!workflowRecordingTabs.has(tabId)) {
|
|
@@ -3503,7 +3694,7 @@ async function stopWorkflowRecording(tabId) {
|
|
|
3503
3694
|
|
|
3504
3695
|
// CRITICAL FIX: Restore original console methods and remove event listeners
|
|
3505
3696
|
try {
|
|
3506
|
-
console.log('[Workflow] Stopping console log capture for tab:', tabId);
|
|
3697
|
+
// console.log('[Workflow] Stopping console log capture for tab:', tabId);
|
|
3507
3698
|
await stopCapturingWorkflowLogs(tabId);
|
|
3508
3699
|
} catch (cleanupError) {
|
|
3509
3700
|
console.error('[Workflow] Failed to cleanup console interceptor:', cleanupError);
|
|
@@ -3515,19 +3706,19 @@ async function stopWorkflowRecording(tabId) {
|
|
|
3515
3706
|
let workflow = Array.isArray(workflowData) ? workflowData : (workflowData.actions || []);
|
|
3516
3707
|
let functionTraces = Array.isArray(workflowData) ? [] : (workflowData.functionTraces || []);
|
|
3517
3708
|
|
|
3518
|
-
console.log(`[Background] Received ${workflow.length} actions and ${functionTraces.length} function traces`);
|
|
3519
|
-
console.log('[SCREENSHOT-DEBUG] background.stopWorkflowRecording - Checking actions for screenshot_data');
|
|
3709
|
+
// console.log(`[Background] Received ${workflow.length} actions and ${functionTraces.length} function traces`);
|
|
3710
|
+
// console.log('[SCREENSHOT-DEBUG] background.stopWorkflowRecording - Checking actions for screenshot_data');
|
|
3520
3711
|
|
|
3521
3712
|
const actionsWithScreenshots = workflow.filter(a => a.screenshot_data);
|
|
3522
|
-
console.log('[SCREENSHOT-DEBUG] background.stopWorkflowRecording - Actions WITH screenshot_data:', actionsWithScreenshots.length);
|
|
3713
|
+
// console.log('[SCREENSHOT-DEBUG] background.stopWorkflowRecording - Actions WITH screenshot_data:', actionsWithScreenshots.length);
|
|
3523
3714
|
|
|
3524
3715
|
workflow.forEach((action, index) => {
|
|
3525
|
-
console.log(`[SCREENSHOT-DEBUG] background.stopWorkflowRecording - Action ${index}:`, {
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
});
|
|
3716
|
+
// console.log(`[SCREENSHOT-DEBUG] background.stopWorkflowRecording - Action ${index}:`, {
|
|
3717
|
+
// type: action.type,
|
|
3718
|
+
// hasScreenshotData: !!action.screenshot_data,
|
|
3719
|
+
// screenshotDataLength: action.screenshot_data?.length,
|
|
3720
|
+
// screenshotPreview: action.screenshot_data?.substring(0, 50)
|
|
3721
|
+
// });
|
|
3531
3722
|
});
|
|
3532
3723
|
|
|
3533
3724
|
// If logs should be included, flush buffer and get them from session storage
|
|
@@ -3536,7 +3727,7 @@ async function stopWorkflowRecording(tabId) {
|
|
|
3536
3727
|
const buffer = workflowLogBuffers.get(tabId);
|
|
3537
3728
|
if (buffer) {
|
|
3538
3729
|
await buffer.flush();
|
|
3539
|
-
console.log(`[Workflow] Flushed buffer before retrieval, stats:`, buffer.getStats());
|
|
3730
|
+
// console.log(`[Workflow] Flushed buffer before retrieval, stats:`, buffer.getStats());
|
|
3540
3731
|
}
|
|
3541
3732
|
|
|
3542
3733
|
const result = await chrome.storage.session.get(`workflow_${tabId}`);
|
|
@@ -3585,7 +3776,7 @@ async function stopWorkflowRecording(tabId) {
|
|
|
3585
3776
|
if (bufferToCleanup) {
|
|
3586
3777
|
await bufferToCleanup.cleanup();
|
|
3587
3778
|
workflowLogBuffers.delete(tabId);
|
|
3588
|
-
console.log(`[Workflow] Cleaned up WorkflowLogBuffer for tab ${tabId}`);
|
|
3779
|
+
// console.log(`[Workflow] Cleaned up WorkflowLogBuffer for tab ${tabId}`);
|
|
3589
3780
|
}
|
|
3590
3781
|
|
|
3591
3782
|
await chrome.storage.session.remove(`workflow_${tabId}`);
|
|
@@ -3597,7 +3788,7 @@ async function stopWorkflowRecording(tabId) {
|
|
|
3597
3788
|
workflowStartTime: null
|
|
3598
3789
|
});
|
|
3599
3790
|
|
|
3600
|
-
console.log('Workflow recording stopped, returning workflow:', workflow);
|
|
3791
|
+
// console.log('Workflow recording stopped, returning workflow:', workflow);
|
|
3601
3792
|
|
|
3602
3793
|
// Try to save to server
|
|
3603
3794
|
try {
|
|
@@ -3610,11 +3801,11 @@ async function stopWorkflowRecording(tabId) {
|
|
|
3610
3801
|
// Retrieve the workflow ID that was generated at start
|
|
3611
3802
|
const storedData = await chrome.storage.local.get(['currentWorkflowId']);
|
|
3612
3803
|
const sessionId = storedData.currentWorkflowId || `workflow_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
3613
|
-
console.log('[Workflow] Using sessionId for save:', sessionId);
|
|
3804
|
+
// console.log('[Workflow] Using sessionId for save:', sessionId);
|
|
3614
3805
|
|
|
3615
3806
|
for (const port of serverPorts) {
|
|
3616
3807
|
try {
|
|
3617
|
-
console.log(`[Workflow] Attempting to save to server on port ${port}...`);
|
|
3808
|
+
// console.log(`[Workflow] Attempting to save to server on port ${port}...`);
|
|
3618
3809
|
|
|
3619
3810
|
const payloadData = {
|
|
3620
3811
|
sessionId: sessionId,
|
|
@@ -3628,19 +3819,19 @@ async function stopWorkflowRecording(tabId) {
|
|
|
3628
3819
|
functionTraces: functionTraces // Include function execution traces
|
|
3629
3820
|
};
|
|
3630
3821
|
|
|
3631
|
-
console.log('[SCREENSHOT-DEBUG] background.stopWorkflowRecording - HTTP POST payload being prepared');
|
|
3632
|
-
console.log('[SCREENSHOT-DEBUG] background.stopWorkflowRecording - Payload actions count:', payloadData.actions.length);
|
|
3822
|
+
// console.log('[SCREENSHOT-DEBUG] background.stopWorkflowRecording - HTTP POST payload being prepared');
|
|
3823
|
+
// console.log('[SCREENSHOT-DEBUG] background.stopWorkflowRecording - Payload actions count:', payloadData.actions.length);
|
|
3633
3824
|
|
|
3634
3825
|
const payloadActionsWithScreenshots = payloadData.actions.filter(a => a.screenshot_data);
|
|
3635
|
-
console.log('[SCREENSHOT-DEBUG] background.stopWorkflowRecording - Payload actions WITH screenshot_data:', payloadActionsWithScreenshots.length);
|
|
3826
|
+
// console.log('[SCREENSHOT-DEBUG] background.stopWorkflowRecording - Payload actions WITH screenshot_data:', payloadActionsWithScreenshots.length);
|
|
3636
3827
|
|
|
3637
3828
|
payloadData.actions.forEach((action, index) => {
|
|
3638
|
-
console.log(`[SCREENSHOT-DEBUG] background.stopWorkflowRecording - Payload Action ${index}:`, {
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3642
|
-
|
|
3643
|
-
});
|
|
3829
|
+
// console.log(`[SCREENSHOT-DEBUG] background.stopWorkflowRecording - Payload Action ${index}:`, {
|
|
3830
|
+
// type: action.type,
|
|
3831
|
+
// hasScreenshotData: !!action.screenshot_data,
|
|
3832
|
+
// screenshotDataLength: action.screenshot_data?.length,
|
|
3833
|
+
// screenshotPreview: action.screenshot_data?.substring(0, 50)
|
|
3834
|
+
// });
|
|
3644
3835
|
});
|
|
3645
3836
|
|
|
3646
3837
|
const response = await fetch(`http://localhost:${port}/chromedebug/workflow-recording`, {
|
|
@@ -3653,15 +3844,15 @@ async function stopWorkflowRecording(tabId) {
|
|
|
3653
3844
|
|
|
3654
3845
|
if (response.ok) {
|
|
3655
3846
|
serverResult = await response.json();
|
|
3656
|
-
console.log(`[Workflow] Successfully saved to server on port ${port}`, serverResult);
|
|
3847
|
+
// console.log(`[Workflow] Successfully saved to server on port ${port}`, serverResult);
|
|
3657
3848
|
break;
|
|
3658
3849
|
} else {
|
|
3659
|
-
console.log(`[Workflow] Failed on port ${port}: ${response.status} ${response.statusText}`);
|
|
3850
|
+
// console.log(`[Workflow] Failed on port ${port}: ${response.status} ${response.statusText}`);
|
|
3660
3851
|
const errorText = await response.text();
|
|
3661
|
-
console.log(`[Workflow] Error response:`, errorText);
|
|
3852
|
+
// console.log(`[Workflow] Error response:`, errorText);
|
|
3662
3853
|
}
|
|
3663
3854
|
} catch (error) {
|
|
3664
|
-
console.log(`Failed to save to server on port ${port}:`, error.message);
|
|
3855
|
+
// console.log(`Failed to save to server on port ${port}:`, error.message);
|
|
3665
3856
|
}
|
|
3666
3857
|
}
|
|
3667
3858
|
|
|
@@ -3725,7 +3916,7 @@ async function stopWorkflowRecording(tabId) {
|
|
|
3725
3916
|
// CRITICAL FIX: Stop workflow console log capture and restore original methods
|
|
3726
3917
|
// REFACTORED: Now uses shared console-interception-library.js via proper namespace
|
|
3727
3918
|
async function stopCapturingWorkflowLogs(tabId) {
|
|
3728
|
-
console.log('[Workflow Recording] Stopping console interception using shared library');
|
|
3919
|
+
// console.log('[Workflow Recording] Stopping console interception using shared library');
|
|
3729
3920
|
return await self.ConsoleInterceptionLibrary.stopConsoleInterception(tabId, WORKFLOW_RECORDING_CONSOLE_CONFIG);
|
|
3730
3921
|
}
|
|
3731
3922
|
|
|
@@ -3764,7 +3955,7 @@ async function deleteRecordingFromServer(recordingId, sendResponse) {
|
|
|
3764
3955
|
|
|
3765
3956
|
if (deleteResult.success) {
|
|
3766
3957
|
deleted = true;
|
|
3767
|
-
console.log('Recording deleted successfully');
|
|
3958
|
+
// console.log('Recording deleted successfully');
|
|
3768
3959
|
sendResponse({ success: true });
|
|
3769
3960
|
return;
|
|
3770
3961
|
} else {
|
|
@@ -3786,11 +3977,11 @@ async function retryPendingFrames(sessionId) {
|
|
|
3786
3977
|
const pending = pendingFrameQueue.get(sessionId);
|
|
3787
3978
|
if (!pending || pending.length === 0) return;
|
|
3788
3979
|
|
|
3789
|
-
console.log(`[FrameQueue] Retrying ${pending.length} pending frame batches for session ${sessionId}`);
|
|
3980
|
+
// console.log(`[FrameQueue] Retrying ${pending.length} pending frame batches for session ${sessionId}`);
|
|
3790
3981
|
|
|
3791
3982
|
// Check if this is still the active recording session
|
|
3792
3983
|
if (currentSession?.sessionId !== sessionId) {
|
|
3793
|
-
console.log(`[FrameQueue] Session ${sessionId} is no longer active, clearing pending frames`);
|
|
3984
|
+
// console.log(`[FrameQueue] Session ${sessionId} is no longer active, clearing pending frames`);
|
|
3794
3985
|
pendingFrameQueue.delete(sessionId);
|
|
3795
3986
|
return;
|
|
3796
3987
|
}
|
|
@@ -3822,12 +4013,12 @@ async function retryPendingFrames(sessionId) {
|
|
|
3822
4013
|
await handleFrameBatch({ sessionId, frames }, true); // skipValidation=true
|
|
3823
4014
|
}
|
|
3824
4015
|
|
|
3825
|
-
console.log(`[FrameQueue] Successfully processed ${batches.length} pending batches`);
|
|
4016
|
+
// console.log(`[FrameQueue] Successfully processed ${batches.length} pending batches`);
|
|
3826
4017
|
}
|
|
3827
4018
|
|
|
3828
4019
|
// Handle frame batches from frame capture
|
|
3829
4020
|
async function handleFrameBatch(batchData, skipValidation = false) {
|
|
3830
|
-
console.log(`Processing frame batch for session ${batchData.sessionId}`);
|
|
4021
|
+
// console.log(`Processing frame batch for session ${batchData.sessionId}`);
|
|
3831
4022
|
|
|
3832
4023
|
try {
|
|
3833
4024
|
const sessionId = batchData.sessionId;
|
|
@@ -3881,7 +4072,7 @@ async function handleFrameBatch(batchData, skipValidation = false) {
|
|
|
3881
4072
|
frameCounter.set(sessionId, currentFrameIndex);
|
|
3882
4073
|
}
|
|
3883
4074
|
|
|
3884
|
-
console.log(`Assigning frame indices ${frameCounter.get(sessionId) - indexedFrames.length} to ${currentFrameIndex - 1}`);
|
|
4075
|
+
// console.log(`Assigning frame indices ${frameCounter.get(sessionId) - indexedFrames.length} to ${currentFrameIndex - 1}`);
|
|
3885
4076
|
|
|
3886
4077
|
// Find available server port using settings
|
|
3887
4078
|
const ports = await getServerPorts();
|
|
@@ -3907,7 +4098,7 @@ async function handleFrameBatch(batchData, skipValidation = false) {
|
|
|
3907
4098
|
|
|
3908
4099
|
if (uploadResponse.ok) {
|
|
3909
4100
|
const result = await uploadResponse.json();
|
|
3910
|
-
console.log(`Frame batch uploaded successfully to port ${port}:`, result);
|
|
4101
|
+
// console.log(`Frame batch uploaded successfully to port ${port}:`, result);
|
|
3911
4102
|
recordingServerPort = port; // Store the successful port
|
|
3912
4103
|
uploadSuccess = true;
|
|
3913
4104
|
|
|
@@ -3923,8 +4114,20 @@ async function handleFrameBatch(batchData, skipValidation = false) {
|
|
|
3923
4114
|
// Append new frames
|
|
3924
4115
|
sessionData.frames = sessionData.frames.concat(batchData.frames);
|
|
3925
4116
|
await chrome.storage.local.set({ [storageKey]: sessionData });
|
|
3926
|
-
console.log(`Saved ${batchData.frames.length} frames to local storage, total: ${sessionData.frames.length}`);
|
|
3927
|
-
|
|
4117
|
+
// console.log(`Saved ${batchData.frames.length} frames to local storage, total: ${sessionData.frames.length}`);
|
|
4118
|
+
|
|
4119
|
+
// Send frame count update to content script
|
|
4120
|
+
if (recordingTabId) {
|
|
4121
|
+
try {
|
|
4122
|
+
await chrome.tabs.sendMessage(recordingTabId, {
|
|
4123
|
+
action: 'updateFrameCount',
|
|
4124
|
+
frameCount: sessionData.frames.length
|
|
4125
|
+
});
|
|
4126
|
+
} catch (e) {
|
|
4127
|
+
// Tab might be closed, ignore
|
|
4128
|
+
}
|
|
4129
|
+
}
|
|
4130
|
+
|
|
3928
4131
|
break;
|
|
3929
4132
|
} else {
|
|
3930
4133
|
const errorText = await uploadResponse.text();
|
|
@@ -3933,16 +4136,16 @@ async function handleFrameBatch(batchData, skipValidation = false) {
|
|
|
3933
4136
|
}
|
|
3934
4137
|
} catch (e) {
|
|
3935
4138
|
lastError = e.message;
|
|
3936
|
-
console.log(`Failed to upload frame batch to port ${port}:`, e.message);
|
|
4139
|
+
// console.log(`Failed to upload frame batch to port ${port}:`, e.message);
|
|
3937
4140
|
}
|
|
3938
4141
|
}
|
|
3939
4142
|
|
|
3940
4143
|
if (!uploadSuccess) {
|
|
3941
|
-
console.log(`No server available - checking if browser-only mode`);
|
|
4144
|
+
// console.log(`No server available - checking if browser-only mode`);
|
|
3942
4145
|
|
|
3943
4146
|
// If in browser-only mode, store frames in IndexedDB
|
|
3944
4147
|
if (serverMode === 'browser-only' && browserRecordingManager) {
|
|
3945
|
-
console.log(`[Browser-Only] Storing ${indexedFrames.length} frames in IndexedDB`);
|
|
4148
|
+
// console.log(`[Browser-Only] Storing ${indexedFrames.length} frames in IndexedDB`);
|
|
3946
4149
|
// Use the browser recording session ID, not the frame capture session ID
|
|
3947
4150
|
const recordingSessionId = currentRecordingSessionId || batchData.sessionId;
|
|
3948
4151
|
for (const frame of indexedFrames) {
|
|
@@ -3959,7 +4162,7 @@ async function handleFrameBatch(batchData, skipValidation = false) {
|
|
|
3959
4162
|
absoluteTimestamp: frame.absoluteTimestamp // Don't use Date.now() fallback - preserve actual capture time
|
|
3960
4163
|
});
|
|
3961
4164
|
}
|
|
3962
|
-
console.log(`[Browser-Only] Frames stored successfully in IndexedDB for session ${recordingSessionId}`);
|
|
4165
|
+
// console.log(`[Browser-Only] Frames stored successfully in IndexedDB for session ${recordingSessionId}`);
|
|
3963
4166
|
} else {
|
|
3964
4167
|
// Server mode but no server available - show error
|
|
3965
4168
|
console.error(`CRITICAL: Failed to upload frame batch to any Chrome Debug server port. Last error: ${lastError}`);
|
|
@@ -3999,7 +4202,7 @@ async function getServerPorts() {
|
|
|
3999
4202
|
// Try to discover the active server port
|
|
4000
4203
|
const discoveredPort = await discoverActiveServerPort();
|
|
4001
4204
|
if (discoveredPort) {
|
|
4002
|
-
console.log(`Discovered Chrome Debug server on port ${discoveredPort}`);
|
|
4205
|
+
// console.log(`Discovered Chrome Debug server on port ${discoveredPort}`);
|
|
4003
4206
|
return [discoveredPort, ...defaultPorts.filter(p => p !== discoveredPort)];
|
|
4004
4207
|
}
|
|
4005
4208
|
|
|
@@ -4037,7 +4240,7 @@ async function discoverActiveServerPort() {
|
|
|
4037
4240
|
|
|
4038
4241
|
// Handle frame capture session completion
|
|
4039
4242
|
async function handleFrameCaptureComplete(sessionData) {
|
|
4040
|
-
console.log(`Frame capture session ${sessionData.sessionId} completed with ${sessionData.totalFrames} frames`);
|
|
4243
|
+
// console.log(`Frame capture session ${sessionData.sessionId} completed with ${sessionData.totalFrames} frames`);
|
|
4041
4244
|
|
|
4042
4245
|
try {
|
|
4043
4246
|
// Store the tab ID and session ID before clearing
|
|
@@ -4055,7 +4258,7 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4055
4258
|
let waitedTime = 0;
|
|
4056
4259
|
let flushCompleted = false;
|
|
4057
4260
|
|
|
4058
|
-
console.log('[Background] Waiting for LogBuffer flush completion...');
|
|
4261
|
+
// console.log('[Background] Waiting for LogBuffer flush completion...');
|
|
4059
4262
|
|
|
4060
4263
|
// Poll for flush completion status
|
|
4061
4264
|
while (waitedTime < maxWaitTime && !flushCompleted) {
|
|
@@ -4069,7 +4272,7 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4069
4272
|
}
|
|
4070
4273
|
|
|
4071
4274
|
if (flushCompleted) {
|
|
4072
|
-
console.log(`[Background] LogBuffer flush completed after ${waitedTime}ms`);
|
|
4275
|
+
// console.log(`[Background] LogBuffer flush completed after ${waitedTime}ms`);
|
|
4073
4276
|
} else {
|
|
4074
4277
|
console.warn(`[Background] LogBuffer flush verification timed out after ${waitedTime}ms`);
|
|
4075
4278
|
}
|
|
@@ -4077,9 +4280,9 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4077
4280
|
// Retrieve buffered logs for this tab
|
|
4078
4281
|
const logsResult = await chrome.storage.session.get(String(tabIdToNotify));
|
|
4079
4282
|
bufferedLogs = logsResult[tabIdToNotify] || [];
|
|
4080
|
-
console.log(`Retrieved ${bufferedLogs.length} buffered logs for post-processing`);
|
|
4283
|
+
// console.log(`Retrieved ${bufferedLogs.length} buffered logs for post-processing`);
|
|
4081
4284
|
if (bufferedLogs.length > 0) {
|
|
4082
|
-
console.log('First log:', bufferedLogs[0]);
|
|
4285
|
+
// console.log('First log:', bufferedLogs[0]);
|
|
4083
4286
|
}
|
|
4084
4287
|
|
|
4085
4288
|
// Clean up flush completion marker
|
|
@@ -4090,7 +4293,7 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4090
4293
|
// Fallback: Try to read logs anyway
|
|
4091
4294
|
const logsResult = await chrome.storage.session.get(String(tabIdToNotify));
|
|
4092
4295
|
bufferedLogs = logsResult[tabIdToNotify] || [];
|
|
4093
|
-
console.log(`Fallback: Retrieved ${bufferedLogs.length} buffered logs`);
|
|
4296
|
+
// console.log(`Fallback: Retrieved ${bufferedLogs.length} buffered logs`);
|
|
4094
4297
|
}
|
|
4095
4298
|
|
|
4096
4299
|
// Clear the buffered logs
|
|
@@ -4099,7 +4302,7 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4099
4302
|
// Send logs to server for association with frames with retry logic
|
|
4100
4303
|
// Skip server communication in browser-only mode (logs already in IndexedDB)
|
|
4101
4304
|
if (bufferedLogs.length > 0 && serverMode !== 'browser-only') {
|
|
4102
|
-
console.log(`[Server Mode] Associating ${bufferedLogs.length} logs with server...`);
|
|
4305
|
+
// console.log(`[Server Mode] Associating ${bufferedLogs.length} logs with server...`);
|
|
4103
4306
|
|
|
4104
4307
|
// Retry logic to handle race conditions
|
|
4105
4308
|
const maxRetries = 3;
|
|
@@ -4107,15 +4310,15 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4107
4310
|
let success = false;
|
|
4108
4311
|
let lastErrorDetails = null;
|
|
4109
4312
|
|
|
4110
|
-
console.log(`[LOG-ASSOC-DEBUG] ========== STARTING LOG ASSOCIATION ==========`);
|
|
4111
|
-
console.log(`[LOG-ASSOC-DEBUG] Session ID: ${sessionIdToUse}`);
|
|
4112
|
-
console.log(`[LOG-ASSOC-DEBUG] Number of logs to associate: ${bufferedLogs.length}`);
|
|
4113
|
-
console.log(`[LOG-ASSOC-DEBUG] Tab ID: ${tabIdToNotify}`);
|
|
4313
|
+
// console.log(`[LOG-ASSOC-DEBUG] ========== STARTING LOG ASSOCIATION ==========`);
|
|
4314
|
+
// console.log(`[LOG-ASSOC-DEBUG] Session ID: ${sessionIdToUse}`);
|
|
4315
|
+
// console.log(`[LOG-ASSOC-DEBUG] Number of logs to associate: ${bufferedLogs.length}`);
|
|
4316
|
+
// console.log(`[LOG-ASSOC-DEBUG] Tab ID: ${tabIdToNotify}`);
|
|
4114
4317
|
|
|
4115
4318
|
// PRE-FLIGHT CHECK: Verify frames exist in database before attempting log association
|
|
4116
4319
|
try {
|
|
4117
4320
|
const ports = await getServerPorts();
|
|
4118
|
-
console.log(`[LOG-ASSOC-DEBUG] PRE-FLIGHT: Checking if frames exist for session ${sessionIdToUse}...`);
|
|
4321
|
+
// console.log(`[LOG-ASSOC-DEBUG] PRE-FLIGHT: Checking if frames exist for session ${sessionIdToUse}...`);
|
|
4119
4322
|
for (const port of ports) {
|
|
4120
4323
|
try {
|
|
4121
4324
|
const checkResponse = await fetch(`http://localhost:${port}/chromedebug/frame-session/${sessionIdToUse}`, {
|
|
@@ -4125,7 +4328,7 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4125
4328
|
if (checkResponse.ok) {
|
|
4126
4329
|
const sessionData = await checkResponse.json();
|
|
4127
4330
|
const frameCount = sessionData.frames?.length || 0;
|
|
4128
|
-
console.log(`[LOG-ASSOC-DEBUG] PRE-FLIGHT: Found ${frameCount} frames on port ${port}`);
|
|
4331
|
+
// console.log(`[LOG-ASSOC-DEBUG] PRE-FLIGHT: Found ${frameCount} frames on port ${port}`);
|
|
4129
4332
|
if (frameCount === 0) {
|
|
4130
4333
|
console.warn(`[LOG-ASSOC-DEBUG] ⚠️ WARNING: Session exists but has 0 frames! This will cause log association to fail.`);
|
|
4131
4334
|
console.warn(`[LOG-ASSOC-DEBUG] Session data:`, sessionData);
|
|
@@ -4133,7 +4336,7 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4133
4336
|
break;
|
|
4134
4337
|
}
|
|
4135
4338
|
} catch (e) {
|
|
4136
|
-
console.log(`[LOG-ASSOC-DEBUG] PRE-FLIGHT: Could not check port ${port}:`, e.message);
|
|
4339
|
+
// console.log(`[LOG-ASSOC-DEBUG] PRE-FLIGHT: Could not check port ${port}:`, e.message);
|
|
4137
4340
|
}
|
|
4138
4341
|
}
|
|
4139
4342
|
} catch (preflightError) {
|
|
@@ -4143,22 +4346,22 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4143
4346
|
while (retryCount < maxRetries && !success) {
|
|
4144
4347
|
try {
|
|
4145
4348
|
const ports = await getServerPorts();
|
|
4146
|
-
console.log(`[LOG-ASSOC-DEBUG] Attempt ${retryCount + 1}/${maxRetries}: Trying ports:`, ports);
|
|
4349
|
+
// console.log(`[LOG-ASSOC-DEBUG] Attempt ${retryCount + 1}/${maxRetries}: Trying ports:`, ports);
|
|
4147
4350
|
|
|
4148
4351
|
for (const port of ports) {
|
|
4149
4352
|
try {
|
|
4150
|
-
console.log(`[LOG-ASSOC-DEBUG] Attempting port ${port}...`);
|
|
4353
|
+
// console.log(`[LOG-ASSOC-DEBUG] Attempting port ${port}...`);
|
|
4151
4354
|
const requestBody = {
|
|
4152
4355
|
sessionId: sessionIdToUse,
|
|
4153
4356
|
logs: bufferedLogs
|
|
4154
4357
|
};
|
|
4155
|
-
console.log(`[LOG-ASSOC-DEBUG] Request payload: sessionId=${sessionIdToUse}, logs.length=${bufferedLogs.length}`);
|
|
4358
|
+
// console.log(`[LOG-ASSOC-DEBUG] Request payload: sessionId=${sessionIdToUse}, logs.length=${bufferedLogs.length}`);
|
|
4156
4359
|
if (bufferedLogs.length > 0) {
|
|
4157
|
-
console.log(`[LOG-ASSOC-DEBUG] First log sample:`, {
|
|
4158
|
-
|
|
4159
|
-
|
|
4160
|
-
|
|
4161
|
-
});
|
|
4360
|
+
// console.log(`[LOG-ASSOC-DEBUG] First log sample:`, {
|
|
4361
|
+
// timestamp: bufferedLogs[0].timestamp,
|
|
4362
|
+
// level: bufferedLogs[0].level,
|
|
4363
|
+
// message: bufferedLogs[0].message?.substring(0, 100)
|
|
4364
|
+
// });
|
|
4162
4365
|
}
|
|
4163
4366
|
|
|
4164
4367
|
const response = await fetch(`http://localhost:${port}/chromedebug/associate-logs`, {
|
|
@@ -4169,12 +4372,12 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4169
4372
|
body: JSON.stringify(requestBody)
|
|
4170
4373
|
});
|
|
4171
4374
|
|
|
4172
|
-
console.log(`[LOG-ASSOC-DEBUG] Port ${port} response status: ${response.status} ${response.statusText}`);
|
|
4375
|
+
// console.log(`[LOG-ASSOC-DEBUG] Port ${port} response status: ${response.status} ${response.statusText}`);
|
|
4173
4376
|
|
|
4174
4377
|
if (response.ok) {
|
|
4175
4378
|
const result = await response.json();
|
|
4176
|
-
console.log(`[LOG-ASSOC-DEBUG] ✅ SUCCESS on port ${port}:`, result);
|
|
4177
|
-
console.log(`Logs associated successfully on port ${port}:`, result);
|
|
4379
|
+
// console.log(`[LOG-ASSOC-DEBUG] ✅ SUCCESS on port ${port}:`, result);
|
|
4380
|
+
// console.log(`Logs associated successfully on port ${port}:`, result);
|
|
4178
4381
|
success = true;
|
|
4179
4382
|
|
|
4180
4383
|
// Fetch the updated session data with logs from server
|
|
@@ -4182,14 +4385,14 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4182
4385
|
const sessionResponse = await fetch(`http://localhost:${port}/chromedebug/frame-session/${sessionIdToUse}`);
|
|
4183
4386
|
if (sessionResponse.ok) {
|
|
4184
4387
|
const updatedSession = await sessionResponse.json();
|
|
4185
|
-
console.log(`[LOG-ASSOC-DEBUG] Fetched updated session: ${updatedSession.frames?.length || 0} frames`);
|
|
4186
|
-
console.log(`Fetched updated session with ${updatedSession.frames ? updatedSession.frames.length : 0} frames`);
|
|
4388
|
+
// console.log(`[LOG-ASSOC-DEBUG] Fetched updated session: ${updatedSession.frames?.length || 0} frames`);
|
|
4389
|
+
// console.log(`Fetched updated session with ${updatedSession.frames ? updatedSession.frames.length : 0} frames`);
|
|
4187
4390
|
|
|
4188
4391
|
// Update Chrome local storage with the frames that now have logs
|
|
4189
4392
|
const storageKey = sessionIdToUse;
|
|
4190
4393
|
await chrome.storage.local.set({ [storageKey]: updatedSession });
|
|
4191
|
-
console.log('[LOG-ASSOC-DEBUG] Updated local storage with frames containing logs');
|
|
4192
|
-
console.log('Updated local storage with frames containing logs');
|
|
4394
|
+
// console.log('[LOG-ASSOC-DEBUG] Updated local storage with frames containing logs');
|
|
4395
|
+
// console.log('Updated local storage with frames containing logs');
|
|
4193
4396
|
} else {
|
|
4194
4397
|
console.error(`[LOG-ASSOC-DEBUG] Failed to fetch updated session: ${sessionResponse.status}`);
|
|
4195
4398
|
console.error('Failed to fetch updated session data');
|
|
@@ -4225,15 +4428,15 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4225
4428
|
attempt: retryCount + 1
|
|
4226
4429
|
};
|
|
4227
4430
|
console.error(`[LOG-ASSOC-DEBUG] ❌ Port ${port} exception:`, e);
|
|
4228
|
-
console.log(`Failed to associate logs on port ${port}:`, e.message);
|
|
4431
|
+
// console.log(`Failed to associate logs on port ${port}:`, e.message);
|
|
4229
4432
|
}
|
|
4230
4433
|
}
|
|
4231
4434
|
|
|
4232
4435
|
if (!success) {
|
|
4233
4436
|
retryCount++;
|
|
4234
4437
|
if (retryCount < maxRetries) {
|
|
4235
|
-
console.log(`[LOG-ASSOC-DEBUG] Retrying in 1 second (attempt ${retryCount + 1}/${maxRetries})...`);
|
|
4236
|
-
console.log(`Retrying log association (attempt ${retryCount + 1}/${maxRetries})...`);
|
|
4438
|
+
// console.log(`[LOG-ASSOC-DEBUG] Retrying in 1 second (attempt ${retryCount + 1}/${maxRetries})...`);
|
|
4439
|
+
// console.log(`Retrying log association (attempt ${retryCount + 1}/${maxRetries})...`);
|
|
4237
4440
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
4238
4441
|
}
|
|
4239
4442
|
}
|
|
@@ -4247,8 +4450,8 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4247
4450
|
}
|
|
4248
4451
|
}
|
|
4249
4452
|
|
|
4250
|
-
console.log(`[LOG-ASSOC-DEBUG] ========== LOG ASSOCIATION COMPLETE ==========`);
|
|
4251
|
-
console.log(`[LOG-ASSOC-DEBUG] Success: ${success}`);
|
|
4453
|
+
// console.log(`[LOG-ASSOC-DEBUG] ========== LOG ASSOCIATION COMPLETE ==========`);
|
|
4454
|
+
// console.log(`[LOG-ASSOC-DEBUG] Success: ${success}`);
|
|
4252
4455
|
if (!success && lastErrorDetails) {
|
|
4253
4456
|
console.error(`[LOG-ASSOC-DEBUG] Last error details:`, lastErrorDetails);
|
|
4254
4457
|
}
|
|
@@ -4279,12 +4482,12 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4279
4482
|
}
|
|
4280
4483
|
} else if (bufferedLogs.length > 0 && serverMode === 'browser-only') {
|
|
4281
4484
|
// Browser-only mode: Associate logs with frames in IndexedDB
|
|
4282
|
-
console.log(`[Browser-Only] Associating ${bufferedLogs.length} logs with frames in IndexedDB...`);
|
|
4485
|
+
// console.log(`[Browser-Only] Associating ${bufferedLogs.length} logs with frames in IndexedDB...`);
|
|
4283
4486
|
|
|
4284
4487
|
try {
|
|
4285
4488
|
// Get all frames for this session from IndexedDB
|
|
4286
4489
|
const frames = await dataBuffer.getBrowserFrames(sessionIdToUse);
|
|
4287
|
-
console.log(`[Browser-Only] Retrieved ${frames.length} frames from IndexedDB for log association`);
|
|
4490
|
+
// console.log(`[Browser-Only] Retrieved ${frames.length} frames from IndexedDB for log association`);
|
|
4288
4491
|
|
|
4289
4492
|
if (frames.length === 0) {
|
|
4290
4493
|
console.warn('[Browser-Only] No frames found - logs cannot be associated');
|
|
@@ -4328,7 +4531,7 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4328
4531
|
}
|
|
4329
4532
|
}
|
|
4330
4533
|
|
|
4331
|
-
console.log(`[Browser-Only] ✓ Associated logs with ${updatedCount} frames in IndexedDB`);
|
|
4534
|
+
// console.log(`[Browser-Only] ✓ Associated logs with ${updatedCount} frames in IndexedDB`);
|
|
4332
4535
|
}
|
|
4333
4536
|
} catch (error) {
|
|
4334
4537
|
console.error('[Browser-Only] Failed to associate logs with frames:', error);
|
|
@@ -4354,18 +4557,18 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4354
4557
|
// Save screen interactions to database
|
|
4355
4558
|
// Skip server communication in browser-only mode
|
|
4356
4559
|
if (screenInteractions.length > 0 && serverMode !== 'browser-only') {
|
|
4357
|
-
console.log(`[Server Mode] Saving ${screenInteractions.length} screen interactions to database`);
|
|
4560
|
+
// console.log(`[Server Mode] Saving ${screenInteractions.length} screen interactions to database`);
|
|
4358
4561
|
|
|
4359
4562
|
// Use comprehensive error handling for screen interactions save
|
|
4360
4563
|
const saveScreenInteractions = async (data, context) => {
|
|
4361
4564
|
// Diagnostic logging for screen interactions save
|
|
4362
|
-
console.log('[ScreenInteractions] Preparing to save interactions:', {
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
});
|
|
4565
|
+
// console.log('[ScreenInteractions] Preparing to save interactions:', {
|
|
4566
|
+
// sessionId: context.sessionId,
|
|
4567
|
+
// dataType: typeof data,
|
|
4568
|
+
// isArray: Array.isArray(data),
|
|
4569
|
+
// interactionCount: Array.isArray(data) ? data.length : 'N/A',
|
|
4570
|
+
// hasComplexData: Array.isArray(data) && data.some(i => i.element_html && i.element_html.length > 100)
|
|
4571
|
+
// });
|
|
4369
4572
|
|
|
4370
4573
|
let lastError = null;
|
|
4371
4574
|
for (const port of CONFIG_PORTS) {
|
|
@@ -4375,7 +4578,7 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4375
4578
|
try {
|
|
4376
4579
|
// data is already { interactions: screenInteractions } from caller
|
|
4377
4580
|
serializedBody = JSON.stringify(data);
|
|
4378
|
-
console.log('[ScreenInteractions] JSON serialization successful, length:', serializedBody.length);
|
|
4581
|
+
// console.log('[ScreenInteractions] JSON serialization successful, length:', serializedBody.length);
|
|
4379
4582
|
} catch (serError) {
|
|
4380
4583
|
console.error('[ScreenInteractions] JSON serialization failed:', serError);
|
|
4381
4584
|
throw new Error(`JSON serialization failed: ${serError.message}`);
|
|
@@ -4392,7 +4595,7 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4392
4595
|
if (response.ok) {
|
|
4393
4596
|
// Only log if we had to try multiple ports
|
|
4394
4597
|
if (port !== CONFIG_PORTS[0]) {
|
|
4395
|
-
console.log(`[ScreenInteractions] Connected to server on port ${port}`);
|
|
4598
|
+
// console.log(`[ScreenInteractions] Connected to server on port ${port}`);
|
|
4396
4599
|
}
|
|
4397
4600
|
return { success: true, result: { saved: true } };
|
|
4398
4601
|
} else {
|
|
@@ -4416,13 +4619,13 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4416
4619
|
);
|
|
4417
4620
|
|
|
4418
4621
|
if (saveResult.success) {
|
|
4419
|
-
console.log('Screen interactions saved successfully with comprehensive error handling');
|
|
4622
|
+
// console.log('Screen interactions saved successfully with comprehensive error handling');
|
|
4420
4623
|
} else {
|
|
4421
4624
|
console.error('[ErrorHandling] Failed to save screen interactions after comprehensive error handling');
|
|
4422
4625
|
}
|
|
4423
4626
|
} else if (screenInteractions.length > 0 && serverMode === 'browser-only') {
|
|
4424
4627
|
// Browser-only mode: screen interactions not needed
|
|
4425
|
-
console.log(`[Browser-Only] ✓ Skipping screen interactions save (browser-only mode)`);
|
|
4628
|
+
// console.log(`[Browser-Only] ✓ Skipping screen interactions save (browser-only mode)`);
|
|
4426
4629
|
}
|
|
4427
4630
|
|
|
4428
4631
|
// Stop session via session manager if available
|
|
@@ -4430,7 +4633,7 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4430
4633
|
try {
|
|
4431
4634
|
const stopResult = await sessionManager.stopRecording(currentSession.sessionId, currentOwnerId);
|
|
4432
4635
|
if (stopResult.success) {
|
|
4433
|
-
console.log(`Session stopped via session manager. Duration: ${stopResult.sessionDuration}ms, Frames: ${stopResult.frameCount}`);
|
|
4636
|
+
// console.log(`Session stopped via session manager. Duration: ${stopResult.sessionDuration}ms, Frames: ${stopResult.frameCount}`);
|
|
4434
4637
|
} else {
|
|
4435
4638
|
console.warn('Failed to stop session via session manager:', stopResult.error?.message);
|
|
4436
4639
|
}
|
|
@@ -4482,7 +4685,7 @@ async function handleFrameCaptureComplete(sessionData) {
|
|
|
4482
4685
|
serverPort: recordingServerPort
|
|
4483
4686
|
}).catch(() => {});
|
|
4484
4687
|
} else {
|
|
4485
|
-
console.log('[Browser-Only] Skipping frameSessionComplete message - recording is in IndexedDB');
|
|
4688
|
+
// console.log('[Browser-Only] Skipping frameSessionComplete message - recording is in IndexedDB');
|
|
4486
4689
|
}
|
|
4487
4690
|
|
|
4488
4691
|
// Notify content script to hide recording indicator
|