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');
}
}
}