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
230 lines • 9.73 kB
JavaScript
/**
* Analysis Module
* Handles analysis and auditing of meta-framework performance and patterns
*/
export class MetaFrameworkAnalysis {
dataCollection;
constructor(dataCollection) {
this.dataCollection = dataCollection;
}
/**
* Analyze Remix loader performance and patterns
*/
async analyzeRemixLoaders(page) {
const loaderData = await this.dataCollection.getRemixLoaderData(page);
const routeModules = await this.dataCollection.getRemixRouteModules(page);
if (loaderData.length === 0) {
return {
totalLoaders: 0,
slowLoaders: 0,
averageLoadTime: 0,
recommendations: ['No loader data available - ensure monitoring is active']
};
}
const totalLoaders = loaderData.length;
const slowLoaders = loaderData.filter(loader => loader.duration > 1000).length;
const averageLoadTime = loaderData.reduce((sum, loader) => sum + loader.duration, 0) / totalLoaders;
const cachedLoaders = loaderData.filter(loader => loader.cached).length;
const recommendations = [];
if (slowLoaders > 0) {
recommendations.push(`${slowLoaders} slow loaders detected (>1s). Consider caching or optimization.`);
}
if (cachedLoaders / totalLoaders < 0.3) {
recommendations.push('Low cache hit rate. Consider implementing better caching strategies.');
}
if (averageLoadTime > 500) {
recommendations.push('High average load time. Consider parallel data fetching.');
}
// Analyze route complexity
const routeComplexity = Object.values(routeModules).filter((route) => route.hasLoader && route.hasAction).length;
if (routeComplexity > totalLoaders * 0.8) {
recommendations.push('Many routes have both loaders and actions. Consider separation of concerns.');
}
return {
totalLoaders,
slowLoaders,
averageLoadTime: Math.round(averageLoadTime),
cachedLoaders,
cacheHitRate: Math.round((cachedLoaders / totalLoaders) * 100),
routeComplexity,
recommendations,
routes: Object.keys(routeModules)
};
}
/**
* Audit Astro island hydration patterns
*/
async auditAstroIslands(page) {
const islands = await this.dataCollection.getAstroIslands(page);
if (islands.length === 0) {
return {
totalIslands: 0,
heavyIslands: 0,
hydrationStrategy: 'none',
recommendations: ['No islands detected - static site or monitoring not active']
};
}
const totalIslands = islands.length;
const heavyIslands = islands.filter(island => island.hydrationDirective === 'load' && island.loading === 'eager').length;
const hydrationStrategies = islands.reduce((acc, island) => {
acc[island.hydrationDirective || 'load'] = (acc[island.hydrationDirective || 'load'] || 0) + 1;
return acc;
}, {});
const recommendations = [];
if (heavyIslands > totalIslands * 0.5) {
recommendations.push('Many islands use eager loading. Consider lazy hydration for better performance.');
}
if (hydrationStrategies.load > totalIslands * 0.7) {
recommendations.push('Most islands use immediate hydration. Consider client:idle or client:visible.');
}
if (!hydrationStrategies.visible && totalIslands > 5) {
recommendations.push('Consider using client:visible for below-the-fold components.');
}
const hydrationStrategy = heavyIslands < totalIslands * 0.3 ? 'optimal' :
heavyIslands < totalIslands * 0.7 ? 'moderate' : 'aggressive';
return {
totalIslands,
heavyIslands,
hydrationStrategy,
hydrationStrategies,
recommendations,
components: islands.map(i => i.component)
};
}
/**
* Analyze Nuxt payload and performance
*/
async analyzeNuxtPayload(page) {
const nuxtData = await this.dataCollection.getNuxtPayload(page);
const payloadSize = JSON.stringify(nuxtData.payload).length;
const routeCount = nuxtData.routes.length;
const navigationCount = nuxtData.navigationTimes.length;
const recommendations = [];
if (payloadSize > 100000) { // 100KB
recommendations.push('Large payload detected. Consider reducing initial data or using lazy loading.');
}
if (navigationCount > 0) {
const avgNavigationTime = nuxtData.navigationTimes.reduce((sum, nav) => sum + (nav.timestamp || 0), 0) / navigationCount;
if (avgNavigationTime > 1000) {
recommendations.push('Slow navigation detected. Consider route-level code splitting.');
}
}
return {
payloadSize,
routeCount,
navigationCount,
serverRendered: nuxtData.payload.serverRendered,
version: nuxtData.version,
recommendations
};
}
/**
* Check Qwik resumability performance
*/
async checkQwikResumability(page) {
const qwikData = await this.dataCollection.getQwikResumability(page);
if (!qwikData) {
return {
resumable: false,
recommendations: ['Qwik resumability not detected or monitoring not active']
};
}
const recommendations = [];
if (qwikData.serializedState > 1000) {
recommendations.push('Large serialized state. Consider optimizing state management.');
}
if (qwikData.qrlCount > 500) {
recommendations.push('Many QRL functions detected. Monitor bundle impact.');
}
if (qwikData.resumeTime > 100) {
recommendations.push('Slow resume time. Check for blocking operations in resumability.');
}
const resumabilityScore = Math.max(0, 100 -
Math.floor(qwikData.resumeTime / 10) -
Math.floor(qwikData.serializedState / 100));
return {
resumable: true,
serializedState: qwikData.serializedState,
qrlCount: qwikData.qrlCount,
symbolsLoaded: qwikData.symbolsLoaded,
resumeTime: qwikData.resumeTime,
resumabilityScore,
recommendations
};
}
/**
* Monitor Vite HMR performance
*/
async monitorViteHMR(page) {
const hmrEvents = await this.dataCollection.getViteHMREvents(page);
if (hmrEvents.length === 0) {
return {
active: false,
recommendations: ['No HMR events detected - check Vite development server']
};
}
const updateEvents = hmrEvents.filter(event => event.type === 'update');
const errorEvents = hmrEvents.filter(event => event.type === 'error');
const reloadEvents = hmrEvents.filter(event => event.type === 'full-reload');
const recommendations = [];
if (errorEvents.length > updateEvents.length * 0.1) {
recommendations.push('High HMR error rate. Check for syntax or type errors.');
}
if (reloadEvents.length > updateEvents.length * 0.2) {
recommendations.push('Frequent full reloads. Check HMR boundary configuration.');
}
const errorRate = updateEvents.length > 0 ? (errorEvents.length / updateEvents.length) * 100 : 0;
const reloadRate = updateEvents.length > 0 ? (reloadEvents.length / updateEvents.length) * 100 : 0;
return {
active: true,
totalEvents: hmrEvents.length,
updateEvents: updateEvents.length,
errorEvents: errorEvents.length,
reloadEvents: reloadEvents.length,
errorRate: Math.round(errorRate),
reloadRate: Math.round(reloadRate),
recommendations
};
}
/**
* General framework performance analysis
*/
async analyzeFrameworkPerformance(page, framework) {
const info = await this.dataCollection.getMetaFrameworkInfo(page);
const analysis = {
framework,
timestamp: info.timestamp,
url: info.url,
performance: {},
recommendations: []
};
// Framework-specific performance analysis
switch (framework) {
case 'remix':
analysis.performance = await this.analyzeRemixLoaders(page);
break;
case 'astro':
analysis.performance = await this.auditAstroIslands(page);
break;
case 'nuxt':
analysis.performance = await this.analyzeNuxtPayload(page);
break;
case 'qwik':
analysis.performance = await this.checkQwikResumability(page);
break;
default:
analysis.performance = { message: `No specific analysis available for ${framework}` };
}
// General recommendations
if (info[framework]) {
const frameworkInfo = info[framework];
if (frameworkInfo.version) {
analysis.version = frameworkInfo.version;
}
// Add framework-specific recommendations
analysis.recommendations.push(`Consider monitoring ${framework} specific metrics for better insights.`);
}
return analysis;
}
}
//# sourceMappingURL=meta-framework-analysis.js.map