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
164 lines • 5.2 kB
JavaScript
import { globalResourceManager } from '../utils/resource-manager.js';
import { globalSessionResourceManager } from '../utils/session-resource-manager.js';
/**
* Base class with common functionality for tool handlers
*/
export class BaseToolHandler {
/**
* Helper to get a session or throw if not found
*/
getSession(sessionId, sessions) {
const session = sessions.get(sessionId);
if (!session) {
throw new Error(`Debug session ${sessionId} not found`);
}
return session;
}
/**
* Helper to create a text response
*/
createTextResponse(text) {
return {
content: [{
type: 'text',
text
}]
};
}
/**
* Helper to create an error response
*/
createErrorResponse(error) {
const errorMessage = error instanceof Error ? error.message : String(error);
const errorStack = error instanceof Error ? error.stack : undefined;
return {
content: [{
type: 'text',
text: `❌ **Error:** ${errorMessage}${errorStack ? `\n\n\`\`\`\n${errorStack}\n\`\`\`` : ''}`
}],
isError: true
};
}
}
/**
* Enhanced BaseHandler with resource management - solves the audit finding:
* "20+ handlers use sessions.get() but NO handlers call cleanup directly"
*/
export class BaseHandler extends BaseToolHandler {
resourceManager;
sessionResourceManager;
handlerName;
// Abstract methods that concrete handlers must implement
tools = [];
async handle(toolName, args, sessions) {
throw new Error('BaseHandler is abstract - concrete handlers must implement handle method');
}
constructor(options = {}) {
super();
this.resourceManager = options.resourceManager || globalResourceManager;
this.sessionResourceManager = options.sessionResourceManager || globalSessionResourceManager;
this.handlerName = this.constructor.name;
}
/**
* Track a resource for automatic cleanup
*/
trackResource(resourceType, sessionId, resource) {
this.resourceManager.trackHandlerResource(this.handlerName, sessionId, resource);
}
/**
* Get session with resource tracking - replaces the problematic sessions.get() pattern
*/
getSessionWithTracking(sessionId, sessions) {
const session = sessions.get(sessionId);
if (!session) {
throw new Error(`Session ${sessionId} not found`);
}
// Touch session to update last used time
this.sessionResourceManager.touchSession(sessionId);
// Track page resource if it exists
if (session.page) {
this.trackResource('page', sessionId, session.page);
}
// Track browser resource if it exists
if (session.browser) {
this.trackResource('browser', sessionId, session.browser);
}
return session;
}
/**
* Cleanup resources for this handler
*/
async cleanupResources(sessionId) {
if (sessionId) {
await this.sessionResourceManager.cleanupSession(sessionId);
}
else {
await this.resourceManager.cleanupAll();
}
}
/**
* Get resource count for this handler
*/
getResourceCount() {
return this.resourceManager.getResourceCount();
}
/**
* Get resource statistics for this handler
*/
getResourceStats() {
return this.resourceManager.getResourceStats();
}
/**
* Get session resource statistics
*/
getSessionStats() {
return this.sessionResourceManager.getSessionStats();
}
/**
* Check if session is active
*/
isSessionActive(sessionId) {
return this.sessionResourceManager.isSessionActive(sessionId);
}
/**
* Create a new session with resource tracking
*/
async createTrackedSession(sessionId) {
return await this.sessionResourceManager.createSession(sessionId);
}
/**
* Execute with resource cleanup on error
*/
async executeWithCleanup(sessionId, operation, sessions) {
try {
return await operation();
}
catch (error) {
// Cleanup resources on error
await this.cleanupResources(sessionId).catch(cleanupError => {
console.warn(`Cleanup failed for session ${sessionId} after error:`, cleanupError);
});
// Re-throw original error
throw error;
}
}
/**
* Get handler name for debugging
*/
getHandlerName() {
return this.handlerName;
}
/**
* Get resource management status
*/
getResourceManagementStatus() {
return {
handlerName: this.handlerName,
resourceCount: this.getResourceCount(),
sessionCount: this.sessionResourceManager.getActiveSessionIds().length,
resourceStats: this.getResourceStats(),
sessionStats: this.getSessionStats()
};
}
}
//# sourceMappingURL=base-handler.js.map