ai-debug-local-mcp
Version:
🎯 ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh
153 lines • 6.01 kB
JavaScript
export class EventMonitor {
eventCollector;
databaseTraceEngine;
constructor(eventCollector, databaseTraceEngine) {
this.eventCollector = eventCollector;
this.databaseTraceEngine = databaseTraceEngine;
}
/**
* Monitor events on a page for a specified duration
*/
async monitorEvents(page, duration) {
const startTime = Date.now();
const events = [];
// Clear any existing data at start
this.clearDatabaseQueries();
// Collect events for the specified duration
while (Date.now() - startTime < duration * 1000) {
// Collect basic page events
const pageEvents = await page.evaluate(() => {
const aiDebug = window.__AI_DEBUG__;
if (!aiDebug)
return [];
const currentEvents = [...aiDebug.events];
aiDebug.events = []; // Clear collected events
return currentEvents;
});
if (pageEvents && Array.isArray(pageEvents)) {
events.push(...pageEvents);
}
// Collect network requests
const networkRequests = this.getNetworkRequests() || [];
// console.log('[DEBUG] Getting network requests in monitorEvents, count:', networkRequests.length);
networkRequests.forEach(req => {
if (!events.some(e => e.type === 'networkRequest' && e.data.url === req.url && e.timestamp === req.timestamp.toISOString())) {
events.push({
type: 'networkRequest',
data: {
url: req.url,
method: req.method,
status: req.responseStatus,
duration: req.duration,
size: req.responseSize,
hasBody: !!req.responseBody
},
timestamp: req.timestamp.toISOString()
});
}
});
// Check for DOM mutations
const domChanged = await page.evaluate(() => {
return window.__DOM_CHANGED__ || false;
});
if (domChanged) {
events.push({
type: 'domMutation',
data: { changed: true },
timestamp: new Date().toISOString()
});
await page.evaluate(() => {
window.__DOM_CHANGED__ = false;
});
}
await page.waitForTimeout(1000); // Check every second
}
// Capture database queries during the monitoring period
if (this.databaseTraceEngine) {
try {
await this.databaseTraceEngine.captureQueries(100); // Quick capture
}
catch (error) {
// Handle database trace errors gracefully - don't let them break monitoring
console.warn('Database trace capture failed:', error);
}
}
return events;
}
/**
* Perform basic analysis on collected events
*/
basicAnalysis(events) {
const analysis = {
mostActiveElement: null,
performanceScore: 100,
errorRate: 0
};
// Find most clicked element
const clickCounts = {};
events.filter(e => e.type === 'click').forEach(e => {
const selector = e.data?.selector;
if (selector) {
clickCounts[selector] = (clickCounts[selector] || 0) + 1;
}
});
if (Object.keys(clickCounts).length > 0) {
analysis.mostActiveElement = Object.entries(clickCounts)
.sort(([, a], [, b]) => b - a)[0][0];
}
// Calculate error rate
const errorCount = events.filter(e => e.type === 'console.error' || e.type === 'error').length;
analysis.errorRate = events.length > 0 ? Math.round((errorCount / events.length) * 100) : 0;
// Adjust performance score based on errors
analysis.performanceScore = Math.max(0, 100 - (analysis.errorRate * 2));
return analysis;
}
/**
* Capture recent events from a page
*/
async captureRecentEvents(page, duration) {
await page.waitForTimeout(duration);
return await page.evaluate(() => {
const aiDebug = window.__AI_DEBUG__;
if (!aiDebug)
return [];
return [...aiDebug.events];
});
}
/**
* Generate a basic report from a debugging session
*/
generateBasicReport(session) {
const errorEvents = session.events.filter((e) => e.type === 'error' || e.type === 'console.error');
const clickEvents = session.events.filter((e) => e.type === 'click');
const networkEvents = session.events.filter((e) => e.type === 'networkRequest');
const findings = [];
if (errorEvents.length > 0) {
findings.push(`Found ${errorEvents.length} errors during session`);
}
if (clickEvents.length > 10) {
findings.push(`High user interaction detected (${clickEvents.length} clicks)`);
}
if (networkEvents.length > 50) {
findings.push(`Heavy network activity (${networkEvents.length} requests)`);
}
if (findings.length === 0) {
findings.push('Session completed without significant issues');
}
return { findings };
}
/**
* Get network requests from the event collector
*/
getNetworkRequests(filter) {
// Delegate to EventCollector
return this.eventCollector.getNetworkRequests(filter);
}
/**
* Clear database queries from the trace engine
*/
clearDatabaseQueries() {
this.databaseTraceEngine.clearQueries();
}
}
//# sourceMappingURL=event-monitor.js.map