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
204 lines • 8.88 kB
JavaScript
/**
* Project-Aware Lazy Handler Wrapper
* Extends the existing LazyHandlerWrapper with project-aware loading intelligence
* Integrates with FrameworkDetector to optimize loading based on detected project stack
*/
import { LazyHandlerWrapper } from '../handlers/lazy-handler-wrapper.js';
import { AdaptiveProjectAwareStrategy } from './project-aware-loading-strategy.js';
export class ProjectAwareLazyHandlerWrapper extends LazyHandlerWrapper {
projectStrategy;
frameworkDetected = false;
pendingTools = new Set();
constructor(handler) {
super(handler);
this.projectStrategy = new AdaptiveProjectAwareStrategy();
}
/**
* Initialize project-aware loading based on framework detection
* Called when inject_debugging detects the framework
*/
async initializeProjectAwareLoading(frameworkResult) {
if (this.frameworkDetected)
return; // Already initialized
console.log(`🎯 Framework detected: ${frameworkResult.framework}`);
// Determine optimal loading strategy for this project
const strategy = this.projectStrategy.determineStrategy(frameworkResult);
console.log(`📊 Project-aware loading strategy:`);
console.log(` Framework: ${strategy.framework}`);
console.log(` Immediate tools: ${strategy.immediateTools.length}`);
console.log(` Lazy tools: ${strategy.lazyTools.length}`);
console.log(` Est. memory savings: ${strategy.estimatedMemorySavingsMB}MB`);
console.log(` Reasoning: ${strategy.reasoning}`);
this.frameworkDetected = true;
// Preload tools that should be immediate for this project
await this.preloadProjectTools(strategy.immediateTools);
}
/**
* Preload tools that should be immediately available for the detected project
*/
async preloadProjectTools(immediateTools) {
const toolsToPreload = immediateTools.filter(toolName => this.wrappedHandler.tools.some(tool => tool.name === toolName));
if (toolsToPreload.length === 0)
return;
console.log(`⚡ Preloading ${toolsToPreload.length} project-relevant tools...`);
const preloadPromises = toolsToPreload.map(async (toolName) => {
try {
// Trigger dependency loading for this tool without actually calling it
await this.preloadToolDependencies(toolName);
}
catch (error) {
console.warn(`⚠️ Failed to preload dependencies for ${toolName}:`, error);
}
});
await Promise.all(preloadPromises);
console.log(`✅ Project tools preloaded successfully`);
}
/**
* Preload dependencies for a specific tool without executing it
*/
async preloadToolDependencies(toolName) {
// Use the parent class's dependency loading logic
const { requiresExternalDependencies } = await import('./comprehensive-tool-dependencies.js');
if (requiresExternalDependencies(toolName)) {
// Check if already loading or loaded
if (this.isLoadingDeps.has(toolName) || this.loadedDependencies.has(toolName)) {
return;
}
// Start loading dependencies (same as parent class)
const loadPromise = this.loadDependencies(toolName);
this.isLoadingDeps.set(toolName, loadPromise);
try {
await loadPromise;
}
finally {
this.isLoadingDeps.delete(toolName);
}
}
}
/**
* Enhanced handle method with project-aware prioritization
*/
async handle(toolName, args, sessions) {
// Track tool usage for adaptive learning
this.projectStrategy.trackToolUsage(toolName);
// If framework not detected yet, check if this is inject_debugging
if (!this.frameworkDetected && toolName === 'inject_debugging') {
// Let inject_debugging complete first, then it will call our framework detection
const result = await super.handle(toolName, args, sessions);
// Framework detection happens inside inject_debugging
// The CoreHandler will call our initializeProjectAwareLoading method
return result;
}
// Check if this tool should be prioritized for the current project
if (this.frameworkDetected && this.projectStrategy.shouldLoadImmediately(toolName)) {
// This tool should already be preloaded, so it should be fast
console.log(`⚡ Using preloaded project tool: ${toolName}`);
}
else if (this.frameworkDetected && this.projectStrategy.shouldStayLazy(toolName)) {
// This tool is intentionally lazy for this project type
console.log(`📦 Loading on-demand tool: ${toolName} (not relevant for ${this.projectStrategy.getCurrentStrategy()?.framework})`);
}
// Use parent class handling with all our optimizations
return super.handle(toolName, args, sessions);
}
/**
* Get project-aware loading statistics
*/
getProjectAwareStats() {
const loadingStats = this.projectStrategy.getLoadingStats();
const memoryStats = this.getMemoryStats();
return {
frameworkDetected: this.frameworkDetected,
framework: loadingStats.framework,
immediateToolCount: loadingStats.immediateToolCount,
lazyToolCount: loadingStats.lazyToolCount,
memorySavingsMB: loadingStats.memorySavingsMB,
reasoning: loadingStats.reasoning,
loadedTools: memoryStats.loadedTools,
pendingTools: Array.from(this.pendingTools)
};
}
/**
* Adapt strategy based on usage patterns
* Called periodically to optimize loading based on actual usage
*/
adaptToUsagePatterns() {
if (!this.frameworkDetected)
return;
this.projectStrategy.adaptStrategy();
// Log adapted strategy
const stats = this.getProjectAwareStats();
console.log(`🧠 Adapted loading strategy for ${stats.framework}:`);
console.log(` Immediate tools: ${stats.immediateToolCount}`);
console.log(` Memory savings: ${stats.memorySavingsMB}MB`);
}
/**
* Manual framework override for testing or special cases
*/
overrideFramework(framework) {
const mockFrameworkResult = { framework, engines: {} };
this.frameworkDetected = false;
this.initializeProjectAwareLoading(mockFrameworkResult);
}
}
/**
* Create a project-aware lazy-loaded version of a handler
*/
export function createProjectAwareLazyHandler(handler) {
return new ProjectAwareLazyHandlerWrapper(handler);
}
/**
* Helper to integrate framework detection with project-aware loading
* Used by CoreHandler when inject_debugging detects framework
*/
export class ProjectAwareLoadingCoordinator {
static wrappers = new Map();
/**
* Register a project-aware wrapper for coordination
*/
static registerWrapper(handlerName, wrapper) {
this.wrappers.set(handlerName, wrapper);
}
/**
* Notify all wrappers about framework detection
* Called by CoreHandler after framework is detected
*/
static async notifyFrameworkDetected(frameworkResult) {
console.log(`🌍 Broadcasting framework detection: ${frameworkResult.framework}`);
const notifications = Array.from(this.wrappers.values()).map(wrapper => wrapper.initializeProjectAwareLoading(frameworkResult));
await Promise.all(notifications);
console.log(`📡 Framework detection broadcast complete`);
}
/**
* Get aggregated project-aware statistics from all wrappers
*/
static getAggregatedStats() {
const wrappers = Array.from(this.wrappers.values());
if (wrappers.length === 0) {
return {
totalWrappers: 0,
frameworkDetected: false,
totalMemorySavingsMB: 0,
totalLoadedTools: 0
};
}
const firstWrapper = wrappers[0];
const stats = firstWrapper.getProjectAwareStats();
return {
totalWrappers: wrappers.length,
frameworkDetected: stats.frameworkDetected,
framework: stats.framework,
totalMemorySavingsMB: stats.memorySavingsMB,
totalLoadedTools: wrappers.reduce((total, wrapper) => total + wrapper.getMemoryStats().loadedTools.length, 0)
};
}
/**
* Trigger adaptation for all wrappers
*/
static adaptAllToUsagePatterns() {
for (const wrapper of this.wrappers.values()) {
wrapper.adaptToUsagePatterns();
}
}
}
//# sourceMappingURL=project-aware-lazy-handler-wrapper.js.map