Skip to main content
Glama

In Memoria

debug-tools.ts•17.3 kB
import { SQLiteDatabase } from '../storage/sqlite-db.js'; import { SemanticVectorDB } from '../storage/vector-db.js'; import { SemanticEngine } from '../engines/semantic-engine.js'; import { PatternEngine } from '../engines/pattern-engine.js'; import { existsSync, statSync } from 'fs'; import { join } from 'path'; export interface DebugOptions { verbose: boolean; checkDatabase: boolean; checkIntelligence: boolean; checkFileSystem: boolean; validateData: boolean; performance: boolean; } export class DebugTools { private verbose: boolean = false; constructor(private options: DebugOptions = { verbose: false, checkDatabase: true, checkIntelligence: true, checkFileSystem: true, validateData: false, performance: false }) { this.verbose = options.verbose; } async runDiagnostics(projectPath: string = process.cwd()): Promise<void> { console.log('šŸ” In Memoria Debug & Diagnostics'); console.log(`šŸ“ Project: ${projectPath}`); console.log(`⚔ Verbose: ${this.verbose ? 'ON' : 'OFF'}\n`); const results = { passed: 0, warnings: 0, errors: 0, suggestions: [] as string[] }; // System Information console.log('šŸ“Š SYSTEM INFORMATION'); console.log('━'.repeat(50)); this.checkSystemInfo(); console.log(); // Database Diagnostics if (this.options.checkDatabase) { console.log('šŸ—„ļø DATABASE DIAGNOSTICS'); console.log('━'.repeat(50)); const dbResults = await this.checkDatabase(projectPath); this.mergeResults(results, dbResults); console.log(); } // Intelligence Diagnostics if (this.options.checkIntelligence) { console.log('🧠 INTELLIGENCE DIAGNOSTICS'); console.log('━'.repeat(50)); const intResults = await this.checkIntelligence(projectPath); this.mergeResults(results, intResults); console.log(); } // File System Diagnostics if (this.options.checkFileSystem) { console.log('šŸ“ FILE SYSTEM DIAGNOSTICS'); console.log('━'.repeat(50)); const fsResults = await this.checkFileSystem(projectPath); this.mergeResults(results, fsResults); console.log(); } // Data Validation if (this.options.validateData) { console.log('āœ… DATA VALIDATION'); console.log('━'.repeat(50)); const validationResults = await this.validateIntelligenceData(projectPath); this.mergeResults(results, validationResults); console.log(); } // Performance Analysis if (this.options.performance) { console.log('⚔ PERFORMANCE ANALYSIS'); console.log('━'.repeat(50)); const perfResults = await this.analyzePerformance(projectPath); this.mergeResults(results, perfResults); console.log(); } // Summary this.printSummary(results); } private checkSystemInfo(): void { const nodeVersion = process.version; const platform = process.platform; const arch = process.arch; const memory = process.memoryUsage(); console.log(` Node.js Version: ${nodeVersion}`); console.log(` Platform: ${platform}-${arch}`); console.log(` Memory Usage: ${Math.round(memory.rss / 1024 / 1024)}MB RSS, ${Math.round(memory.heapUsed / 1024 / 1024)}MB Heap`); const majorVersion = parseInt(nodeVersion.substring(1)); if (majorVersion < 18) { console.log(' āŒ Node.js version is too old. Minimum required: 18'); } else { console.log(' āœ… Node.js version is compatible'); } } private async checkDatabase(projectPath: string): Promise<any> { const results = { passed: 0, warnings: 0, errors: 0, suggestions: [] as string[] }; try { const dbPath = join(projectPath, 'in-memoria.db'); // Check if database exists if (!existsSync(dbPath)) { console.log(' āŒ Database file not found'); console.log(` Expected: ${dbPath}`); results.errors++; results.suggestions.push('Run `in-memoria init` or `in-memoria setup --interactive` to initialize'); return results; } // Check database file size and permissions const stats = statSync(dbPath); console.log(` šŸ“„ Database file: ${dbPath}`); console.log(` šŸ’¾ Size: ${Math.round(stats.size / 1024)}KB`); console.log(` šŸ“… Modified: ${stats.mtime.toISOString()}`); if (stats.size === 0) { console.log(' āš ļø Database file is empty'); results.warnings++; } else { console.log(' āœ… Database file exists and has content'); results.passed++; } // Test database connection try { const db = new SQLiteDatabase(dbPath); console.log(' āœ… Database connection successful'); // Check migrations const migrator = db.getMigrator(); const currentVersion = migrator.getCurrentVersion(); const latestVersion = migrator.getLatestVersion(); console.log(` šŸ“Š Schema version: ${currentVersion}/${latestVersion}`); if (currentVersion < latestVersion) { console.log(' āš ļø Database schema needs migration'); results.warnings++; results.suggestions.push('Run database migrations will be applied automatically on next start'); } else { console.log(' āœ… Database schema is up-to-date'); results.passed++; } // Check table counts const concepts = db.getSemanticConcepts(); const patterns = db.getDeveloperPatterns(); console.log(` šŸ“ˆ Stored concepts: ${concepts.length}`); console.log(` šŸ” Stored patterns: ${patterns.length}`); if (concepts.length === 0 && patterns.length === 0) { console.log(' āš ļø No intelligence data found'); results.warnings++; results.suggestions.push('Run `in-memoria learn` to analyze your codebase'); } db.close(); results.passed++; } catch (error: unknown) { console.log(` āŒ Database connection failed: ${error instanceof Error ? error.message : String(error)}`); results.errors++; if (this.verbose) { console.log(` Details: ${error instanceof Error ? error.stack : 'No stack trace available'}`); } } } catch (error: unknown) { console.log(` āŒ Database check failed: ${error instanceof Error ? error.message : String(error)}`); results.errors++; } return results; } private async checkIntelligence(projectPath: string): Promise<any> { const results = { passed: 0, warnings: 0, errors: 0, suggestions: [] as string[] }; try { // Check if we can initialize intelligence components const dbPath = join(projectPath, 'in-memoria.db'); if (!existsSync(dbPath)) { console.log(' āŒ No database found for intelligence check'); results.errors++; return results; } const database = new SQLiteDatabase(dbPath); const vectorDB = new SemanticVectorDB(process.env.OPENAI_API_KEY); const semanticEngine = new SemanticEngine(database, vectorDB); const patternEngine = new PatternEngine(database); console.log(' āœ… Intelligence components initialized successfully'); results.passed++; // Test basic functionality try { const concepts = database.getSemanticConcepts(); const patterns = database.getDeveloperPatterns(); console.log(` šŸ“Š Available concepts: ${concepts.length}`); console.log(` šŸ” Available patterns: ${patterns.length}`); if (concepts.length === 0) { console.log(' āš ļø No semantic concepts found'); results.warnings++; results.suggestions.push('Run learning to build semantic understanding'); } if (patterns.length === 0) { console.log(' āš ļø No development patterns found'); results.warnings++; results.suggestions.push('Run learning to identify coding patterns'); } // Check OpenAI integration if (process.env.OPENAI_API_KEY) { console.log(' šŸ”‘ OpenAI API key detected'); console.log(' āœ… Enhanced embeddings available'); results.passed++; } else { console.log(' āš ļø No OpenAI API key found'); console.log(' šŸ“ Using local embeddings only'); results.warnings++; results.suggestions.push('Set OPENAI_API_KEY environment variable for enhanced features'); } } catch (error: unknown) { console.log(` āŒ Intelligence data access failed: ${error instanceof Error ? error.message : String(error)}`); results.errors++; } database.close(); } catch (error: unknown) { console.log(` āŒ Intelligence initialization failed: ${error instanceof Error ? error.message : String(error)}`); results.errors++; if (this.verbose) { console.log(` Details: ${error instanceof Error ? error.stack : 'No stack trace available'}`); } } return results; } private async checkFileSystem(projectPath: string): Promise<any> { const results = { passed: 0, warnings: 0, errors: 0, suggestions: [] as string[] }; try { // Check project directory if (!existsSync(projectPath)) { console.log(` āŒ Project directory does not exist: ${projectPath}`); results.errors++; return results; } console.log(` šŸ“ Project directory: ${projectPath}`); console.log(' āœ… Project directory exists'); results.passed++; // Check for .in-memoria directory const configDir = join(projectPath, '.in-memoria'); if (existsSync(configDir)) { console.log(' šŸ“‚ Configuration directory found'); // Check config file const configFile = join(configDir, 'config.json'); if (existsSync(configFile)) { console.log(' āš™ļø Configuration file exists'); try { const configContent = await import(`file://${configFile}`); console.log(' āœ… Configuration file is valid JSON'); results.passed++; } catch (error) { console.log(' āŒ Configuration file is invalid JSON'); results.errors++; } } else { console.log(' āš ļø No configuration file found'); results.warnings++; results.suggestions.push('Run `in-memoria setup --interactive` to create configuration'); } } else { console.log(' āš ļø No .in-memoria configuration directory'); results.warnings++; results.suggestions.push('Run `in-memoria init` to create basic configuration'); } // Check for common files const packageJson = join(projectPath, 'package.json'); const gitDir = join(projectPath, '.git'); if (existsSync(packageJson)) { console.log(' šŸ“¦ Node.js project detected (package.json)'); results.passed++; } if (existsSync(gitDir)) { console.log(' šŸ—‚ļø Git repository detected'); results.passed++; } // Check .gitignore const gitignore = join(projectPath, '.gitignore'); if (existsSync(gitignore)) { const fs = await import('fs'); const content = fs.readFileSync(gitignore, 'utf-8'); if (content.includes('in-memoria.db')) { console.log(' āœ… In Memoria entries found in .gitignore'); results.passed++; } else { console.log(' āš ļø In Memoria not in .gitignore'); results.warnings++; results.suggestions.push('Add in-memoria.db to .gitignore to avoid committing database'); } } } catch (error: unknown) { console.log(` āŒ File system check failed: ${error instanceof Error ? error.message : String(error)}`); results.errors++; } return results; } private async validateIntelligenceData(projectPath: string): Promise<any> { const results = { passed: 0, warnings: 0, errors: 0, suggestions: [] as string[] }; console.log(' šŸ” Validating intelligence data consistency...'); try { const dbPath = join(projectPath, 'in-memoria.db'); if (!existsSync(dbPath)) { console.log(' āŒ No database to validate'); results.errors++; return results; } const database = new SQLiteDatabase(dbPath); const concepts = database.getSemanticConcepts(); const patterns = database.getDeveloperPatterns(); // Validate concepts let validConcepts = 0; let invalidConcepts = 0; for (const concept of concepts) { if (concept.conceptName && concept.conceptType && concept.confidenceScore >= 0) { validConcepts++; } else { invalidConcepts++; if (this.verbose) { console.log(` āš ļø Invalid concept: ${concept.id}`); } } } console.log(` šŸ“Š Concepts: ${validConcepts} valid, ${invalidConcepts} invalid`); if (invalidConcepts > 0) { results.warnings++; results.suggestions.push('Some concept data may be corrupted - consider re-learning'); } else { results.passed++; } // Validate patterns let validPatterns = 0; let invalidPatterns = 0; for (const pattern of patterns) { if (pattern.patternType && pattern.frequency >= 0) { validPatterns++; } else { invalidPatterns++; if (this.verbose) { console.log(` āš ļø Invalid pattern: ${pattern.patternId}`); } } } console.log(` šŸ” Patterns: ${validPatterns} valid, ${invalidPatterns} invalid`); if (invalidPatterns > 0) { results.warnings++; results.suggestions.push('Some pattern data may be corrupted - consider re-learning'); } else { results.passed++; } database.close(); } catch (error: unknown) { console.log(` āŒ Validation failed: ${error instanceof Error ? error.message : String(error)}`); results.errors++; } return results; } private async analyzePerformance(projectPath: string): Promise<any> { const results = { passed: 0, warnings: 0, errors: 0, suggestions: [] as string[] }; console.log(' ⚔ Analyzing performance characteristics...'); try { const dbPath = join(projectPath, 'in-memoria.db'); if (!existsSync(dbPath)) { console.log(' āŒ No database for performance analysis'); results.errors++; return results; } const stats = statSync(dbPath); const dbSizeMB = stats.size / (1024 * 1024); console.log(` šŸ’¾ Database size: ${dbSizeMB.toFixed(2)}MB`); if (dbSizeMB > 100) { console.log(' āš ļø Large database size detected'); results.warnings++; results.suggestions.push('Consider archiving old intelligence data for better performance'); } else { console.log(' āœ… Database size is reasonable'); results.passed++; } // Test query performance const startTime = Date.now(); const database = new SQLiteDatabase(dbPath); const concepts = database.getSemanticConcepts(); const queryTime = Date.now() - startTime; console.log(` šŸ• Query time: ${queryTime}ms for ${concepts.length} concepts`); if (queryTime > 1000) { console.log(' āš ļø Slow query performance detected'); results.warnings++; results.suggestions.push('Database may benefit from optimization or indexing'); } else { console.log(' āœ… Query performance is good'); results.passed++; } database.close(); } catch (error: unknown) { console.log(` āŒ Performance analysis failed: ${error instanceof Error ? error.message : String(error)}`); results.errors++; } return results; } private mergeResults(target: any, source: any): void { target.passed += source.passed; target.warnings += source.warnings; target.errors += source.errors; target.suggestions.push(...source.suggestions); } private printSummary(results: any): void { console.log('šŸ“‹ DIAGNOSTIC SUMMARY'); console.log('━'.repeat(50)); console.log(`āœ… Passed: ${results.passed}`); console.log(`āš ļø Warnings: ${results.warnings}`); console.log(`āŒ Errors: ${results.errors}`); if (results.suggestions.length > 0) { console.log('\nšŸ’” SUGGESTIONS:'); results.suggestions.forEach((suggestion: string, index: number) => { console.log(`${index + 1}. ${suggestion}`); }); } console.log('\nšŸŽÆ OVERALL STATUS:'); if (results.errors === 0 && results.warnings === 0) { console.log('🟢 All systems operational'); } else if (results.errors === 0) { console.log('🟔 Functional with minor issues'); } else { console.log('šŸ”“ Issues detected - intervention required'); } } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/pi22by7/In-Memoria'

If you have feedback or need assistance with the MCP directory API, please join our Discord server