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
278 lines (236 loc) • 7.82 kB
text/typescript
import fetch from 'node-fetch';
import { DebugState } from '../types';
export interface AIAnalysis {
rootCause: string;
suggestedFixes: string[];
relatedPatterns: string[];
confidence: number;
explanation: string;
}
export interface PerformanceInsight {
bottlenecks: Array<{
component: string;
metric: string;
value: number;
severity: 'low' | 'medium' | 'high';
}>;
recommendations: string[];
benchmarks: Record<string, number>;
}
export class CloudAIService {
private apiEndpoint: string;
private apiKey?: string;
constructor(apiEndpoint?: string) {
this.apiEndpoint = apiEndpoint || process.env.AI_DEBUG_API_ENDPOINT || 'https://api.ai-debug.com/v1';
}
setApiKey(apiKey: string): void {
this.apiKey = apiKey;
}
async analyzeRootCause(
error: Error,
state: DebugState,
context: Record<string, any>
): Promise<AIAnalysis> {
if (!this.apiKey) {
throw new Error('API key required for AI analysis');
}
const response = await fetch(`${this.apiEndpoint}/analyze/root-cause`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
},
body: JSON.stringify({
error: {
message: error.message,
stack: error.stack,
name: error.name
},
state: this.sanitizeState(state),
context,
timestamp: new Date().toISOString()
})
});
if (!response.ok) {
throw new Error(`AI analysis failed: ${response.statusText}`);
}
return await response.json() as AIAnalysis;
}
async detectPatterns(
events: Array<{ type: string; data: any; timestamp: Date }>,
state: DebugState
): Promise<Array<{ pattern: string; occurrences: number; significance: string }>> {
if (!this.apiKey) {
throw new Error('API key required for pattern detection');
}
const response = await fetch(`${this.apiEndpoint}/analyze/patterns`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
},
body: JSON.stringify({
events: events.slice(-1000), // Last 1000 events
state: this.sanitizeState(state),
windowSize: '5m'
})
});
if (!response.ok) {
throw new Error(`Pattern detection failed: ${response.statusText}`);
}
return await response.json() as Array<{ pattern: string; occurrences: number; significance: string }>;
}
async analyzePerformance(
metrics: Record<string, number>,
componentTree: any,
renderTimes: Array<{ component: string; duration: number }>
): Promise<PerformanceInsight> {
if (!this.apiKey) {
throw new Error('API key required for performance analysis');
}
const response = await fetch(`${this.apiEndpoint}/analyze/performance`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
},
body: JSON.stringify({
metrics,
componentTree,
renderTimes,
timestamp: new Date().toISOString()
})
});
if (!response.ok) {
throw new Error(`Performance analysis failed: ${response.statusText}`);
}
return await response.json() as PerformanceInsight;
}
async suggestFixes(
issue: string,
codeContext: string,
stackTrace?: string
): Promise<Array<{ fix: string; confidence: number; explanation: string }>> {
if (!this.apiKey) {
throw new Error('API key required for fix suggestions');
}
const response = await fetch(`${this.apiEndpoint}/suggest/fixes`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
},
body: JSON.stringify({
issue,
codeContext,
stackTrace,
language: 'typescript', // Could be detected
framework: 'phoenix-liveview' // Could be detected
})
});
if (!response.ok) {
throw new Error(`Fix suggestion failed: ${response.statusText}`);
}
return await response.json() as Array<{ fix: string; confidence: number; explanation: string }>;
}
private sanitizeState(state: DebugState): any {
// Remove sensitive data before sending to cloud
const sanitized = { ...state };
// Remove potential secrets
const sensitiveKeys = ['password', 'token', 'secret', 'key', 'auth'];
const removeSensitive = (obj: any): any => {
if (typeof obj !== 'object' || obj === null) return obj;
const cleaned: any = Array.isArray(obj) ? [] : {};
for (const [key, value] of Object.entries(obj)) {
if (sensitiveKeys.some(sensitive => key.toLowerCase().includes(sensitive))) {
cleaned[key] = '[REDACTED]';
} else if (typeof value === 'object') {
cleaned[key] = removeSensitive(value);
} else {
cleaned[key] = value;
}
}
return cleaned;
};
return removeSensitive(sanitized);
}
async analyzeEvents(events: any[]): Promise<any> {
if (!this.apiKey) {
throw new Error('API key required for event analysis');
}
const response = await fetch(`${this.apiEndpoint}/analyze/events`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
},
body: JSON.stringify({
events: events.slice(-100), // Last 100 events
timestamp: new Date().toISOString()
})
});
if (!response.ok) {
throw new Error(`Event analysis failed: ${response.statusText}`);
}
return await response.json();
}
async comprehensiveAnalysis(
events: any[],
pageState: any,
analysisType: string
): Promise<any> {
if (!this.apiKey) {
throw new Error('API key required for comprehensive analysis');
}
const response = await fetch(`${this.apiEndpoint}/analyze/comprehensive`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
},
body: JSON.stringify({
events: events.slice(-500), // Last 500 events
pageState: this.sanitizePageState(pageState),
analysisType,
timestamp: new Date().toISOString()
})
});
if (!response.ok) {
throw new Error(`Comprehensive analysis failed: ${response.statusText}`);
}
return await response.json();
}
async enhanceReport(basicReport: any, events: any[]): Promise<any> {
if (!this.apiKey) {
throw new Error('API key required for report enhancement');
}
const response = await fetch(`${this.apiEndpoint}/enhance/report`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.apiKey}`
},
body: JSON.stringify({
basicReport,
events: events.slice(-200), // Last 200 events
timestamp: new Date().toISOString()
})
});
if (!response.ok) {
throw new Error(`Report enhancement failed: ${response.statusText}`);
}
return await response.json();
}
private sanitizePageState(pageState: any): any {
const { localStorage, sessionStorage, cookies, ...rest } = pageState;
return {
...rest,
localStorage: this.sanitizeState({ localStorage } as any).localStorage,
sessionStorage: this.sanitizeState({ sessionStorage } as any).sessionStorage,
cookies: cookies.map((cookie: any) => ({
...cookie,
value: '[REDACTED]'
}))
};
}
}