UNPKG

codecrucible-synth

Version:

Production-Ready AI Development Platform with Multi-Voice Synthesis, Smithery MCP Integration, Enterprise Security, and Zero-Timeout Reliability

1,243 lines (1,102 loc) 34.4 kB
/** * Project Intelligence System - Enhanced Context Awareness * Iteration 3: Add enhanced context awareness and project intelligence */ import { EventEmitter } from 'events'; import { readdir, readFile, stat, access } from 'fs/promises'; import { join, relative, extname, dirname, basename } from 'path'; import { Logger } from '../logger.js'; import { unifiedCache } from '../cache/unified-cache-system.js'; import { ProjectContext } from '../types.js'; export interface ProjectIntelligence { structure: ProjectStructure; insights: ProjectInsights; dependencies: DependencyGraph; patterns: ArchitecturePatterns; metadata: ProjectMetadata; recommendations: IntelligentRecommendations; } export interface ProjectStructure { rootPath: string; directories: DirectoryNode[]; files: FileNode[]; packageFiles: PackageFile[]; configFiles: ConfigFile[]; documentationFiles: DocumentationFile[]; testFiles: TestFile[]; buildFiles: BuildFile[]; totalFiles: number; totalDirectories: number; codebaseSize: number; } export interface DirectoryNode { path: string; name: string; depth: number; fileCount: number; childDirectories: string[]; purpose: DirectoryPurpose; importance: 'high' | 'medium' | 'low'; } export interface FileNode { path: string; name: string; extension: string; language: string; size: number; linesOfCode: number; complexity: CodeComplexity; dependencies: string[]; exports: string[]; imports: string[]; functions: FunctionSignature[]; classes: ClassSignature[]; interfaces: InterfaceSignature[]; purpose: FilePurpose; lastModified: Date; importance: 'critical' | 'high' | 'medium' | 'low'; } export interface ProjectInsights { primaryLanguage: string; languageDistribution: Record<string, number>; frameworksDetected: FrameworkInfo[]; architecturePattern: ArchitecturePattern; projectType: ProjectType; maturityLevel: 'prototype' | 'development' | 'production' | 'legacy'; codeQuality: CodeQualityMetrics; technicalDebt: TechnicalDebtAnalysis; securityConcerns: SecurityConcern[]; performanceIndicators: PerformanceIndicator[]; } export interface DependencyGraph { nodes: DependencyNode[]; edges: DependencyEdge[]; cycles: CircularDependency[]; criticalPath: string[]; modularity: ModularityMetrics; externalDependencies: ExternalDependency[]; internalDependencies: InternalDependency[]; } export interface ArchitecturePatterns { primaryPattern: string; secondaryPatterns: string[]; designPrinciples: string[]; antiPatterns: AntiPattern[]; refactoringOpportunities: RefactoringOpportunity[]; } export interface IntelligentRecommendations { codeImprovement: CodeRecommendation[]; architecture: ArchitectureRecommendation[]; performance: PerformanceRecommendation[]; security: SecurityRecommendation[]; testing: TestingRecommendation[]; documentation: DocumentationRecommendation[]; maintenance: MaintenanceRecommendation[]; } // Supporting interfaces export type DirectoryPurpose = | 'source' | 'tests' | 'build' | 'config' | 'docs' | 'assets' | 'dependencies' | 'other'; export type FilePurpose = | 'core' | 'utility' | 'test' | 'config' | 'documentation' | 'build' | 'assets' | 'entry'; export type ProjectType = 'library' | 'application' | 'service' | 'tool' | 'framework' | 'unknown'; export type ArchitecturePattern = | 'mvc' | 'microservices' | 'layered' | 'hexagonal' | 'modular' | 'monolithic' | 'unknown'; export interface FrameworkInfo { name: string; version?: string; confidence: number; evidence: string[]; } export interface CodeComplexity { cyclomaticComplexity: number; cognitiveComplexity: number; nestingDepth: number; functionCount: number; classCount: number; } export interface FunctionSignature { name: string; parameters: string[]; returnType?: string; complexity: number; lineNumber: number; } export interface ClassSignature { name: string; methods: string[]; properties: string[]; inheritance: string[]; lineNumber: number; } export interface InterfaceSignature { name: string; methods: string[]; properties: string[]; lineNumber: number; } export interface CodeQualityMetrics { maintainabilityIndex: number; duplication: number; testCoverage: number; commentDensity: number; naming: QualityScore; structure: QualityScore; consistency: QualityScore; } export interface TechnicalDebtAnalysis { totalDebt: number; debtItems: DebtItem[]; debtRatio: number; prioritizedFixes: PrioritizedFix[]; } export interface SecurityConcern { type: string; severity: 'critical' | 'high' | 'medium' | 'low'; description: string; file: string; lineNumber?: number; recommendation: string; } export interface PerformanceIndicator { metric: string; value: number; target: number; status: 'good' | 'warning' | 'critical'; recommendation: string; } export interface PackageFile { path: string; type: 'package.json' | 'requirements.txt' | 'Cargo.toml' | 'pom.xml' | 'other'; dependencies: string[]; devDependencies: string[]; scripts: Record<string, string>; } export interface ConfigFile { path: string; type: string; purpose: string; settings: Record<string, any>; } export interface DocumentationFile { path: string; type: 'readme' | 'api' | 'tutorial' | 'changelog' | 'other'; quality: 'excellent' | 'good' | 'fair' | 'poor'; coverage: string[]; } export interface TestFile { path: string; type: 'unit' | 'integration' | 'e2e' | 'other'; framework: string; coverage: string[]; } export interface BuildFile { path: string; type: string; commands: string[]; targets: string[]; } export interface QualityScore { score: number; issues: string[]; suggestions: string[]; } export interface DebtItem { type: string; severity: number; effort: number; description: string; location: string; } export interface PrioritizedFix { priority: number; impact: 'high' | 'medium' | 'low'; effort: 'small' | 'medium' | 'large'; description: string; files: string[]; } export interface DependencyNode { id: string; name: string; type: 'internal' | 'external'; version?: string; importance: number; } export interface DependencyEdge { from: string; to: string; type: 'import' | 'require' | 'dependency'; strength: number; } export interface CircularDependency { cycle: string[]; severity: 'high' | 'medium' | 'low'; recommendation: string; } export interface ModularityMetrics { cohesion: number; coupling: number; modularity: number; instability: number; } export interface ExternalDependency { name: string; version: string; type: 'production' | 'development' | 'optional'; usage: string[]; risk: 'high' | 'medium' | 'low'; } export interface InternalDependency { from: string; to: string; relationship: 'depends-on' | 'extends' | 'implements' | 'uses'; strength: number; } export interface AntiPattern { name: string; description: string; locations: string[]; severity: 'high' | 'medium' | 'low'; solution: string; } export interface RefactoringOpportunity { type: string; description: string; files: string[]; effort: 'small' | 'medium' | 'large'; benefit: 'high' | 'medium' | 'low'; priority: number; } export interface CodeRecommendation { category: 'refactoring' | 'optimization' | 'modernization' | 'cleanup'; priority: 'high' | 'medium' | 'low'; description: string; files: string[]; effort: string; benefit: string; } export interface ArchitectureRecommendation { type: 'structural' | 'pattern' | 'design'; description: string; rationale: string; impact: 'high' | 'medium' | 'low'; effort: 'small' | 'medium' | 'large'; } export interface PerformanceRecommendation { metric: string; current: number; target: number; improvement: string; implementation: string; } export interface SecurityRecommendation { category: string; priority: 'critical' | 'high' | 'medium' | 'low'; description: string; solution: string; resources: string[]; } export interface TestingRecommendation { type: 'coverage' | 'strategy' | 'framework'; current: string; recommended: string; rationale: string; implementation: string; } export interface DocumentationRecommendation { type: 'api' | 'user' | 'developer' | 'architecture'; priority: 'high' | 'medium' | 'low'; description: string; template?: string; } export interface MaintenanceRecommendation { category: 'updates' | 'monitoring' | 'automation' | 'tooling'; description: string; frequency: string; automation: boolean; tools: string[]; } export interface ProjectMetadata { name: string; version?: string; description?: string; author?: string; license?: string; repository?: string; homepage?: string; keywords?: string[]; createdDate?: Date; lastModified: Date; contributors?: string[]; stats: ProjectStats; } export interface ProjectStats { totalFiles: number; totalLines: number; codeLines: number; commentLines: number; blankLines: number; testFiles: number; configFiles: number; documentFiles: number; } export class ProjectIntelligenceSystem extends EventEmitter { private logger: Logger; private analysisInProgress: Set<string> = new Set(); constructor() { super(); this.logger = new Logger('ProjectIntelligenceSystem'); } /** * Analyze project and generate comprehensive intelligence */ async analyzeProject( rootPath: string, options: AnalysisOptions = {} ): Promise<ProjectIntelligence> { const normalizedPath = join(rootPath); // Check if analysis is already in progress if (this.analysisInProgress.has(normalizedPath)) { throw new Error(`Analysis already in progress for ${normalizedPath}`); } // Check cache first const cacheKey = `project-intel:${normalizedPath}`; if (!options.force) { const cacheResult = await unifiedCache.get<ProjectIntelligence>(cacheKey); if (cacheResult?.hit) { this.logger.info(`Using cached analysis for ${normalizedPath}`); return cacheResult.value; } } this.analysisInProgress.add(normalizedPath); this.logger.info(`Starting comprehensive project analysis for ${normalizedPath}`); try { const startTime = Date.now(); // Phase 1: Structural Analysis this.emit('analysis:phase', { phase: 'structure', progress: 0 }); const structure = await this.analyzeProjectStructure(rootPath, options); // Phase 2: Code Analysis this.emit('analysis:phase', { phase: 'code', progress: 20 }); const insights = await this.generateProjectInsights(structure, options); // Phase 3: Dependency Analysis this.emit('analysis:phase', { phase: 'dependencies', progress: 40 }); const dependencies = await this.analyzeDependencies(structure, options); // Phase 4: Architecture Analysis this.emit('analysis:phase', { phase: 'architecture', progress: 60 }); const patterns = await this.identifyArchitecturePatterns(structure, insights, dependencies); // Phase 5: Metadata Extraction this.emit('analysis:phase', { phase: 'metadata', progress: 80 }); const metadata = await this.extractProjectMetadata(structure, options); // Phase 6: Generate Recommendations this.emit('analysis:phase', { phase: 'recommendations', progress: 90 }); const recommendations = await this.generateRecommendations( structure, insights, dependencies, patterns, metadata ); const intelligence: ProjectIntelligence = { structure, insights, dependencies, patterns, metadata, recommendations, }; // Cache the results with 1 hour TTL and project intelligence tags await unifiedCache.set(cacheKey, intelligence, { ttl: 3600000, // 1 hour tags: ['project-intelligence', 'analysis'], metadata: { path: normalizedPath, analysisTime: Date.now() - startTime }, }); const analysisTime = Date.now() - startTime; this.logger.info(`Project analysis completed in ${analysisTime}ms`); this.emit('analysis:complete', { path: normalizedPath, intelligence, time: analysisTime }); return intelligence; } finally { this.analysisInProgress.delete(normalizedPath); } } /** * Analyze project structure and file organization */ private async analyzeProjectStructure( rootPath: string, options: AnalysisOptions ): Promise<ProjectStructure> { const files: FileNode[] = []; const directories: DirectoryNode[] = []; const packageFiles: PackageFile[] = []; const configFiles: ConfigFile[] = []; const documentationFiles: DocumentationFile[] = []; const testFiles: TestFile[] = []; const buildFiles: BuildFile[] = []; let totalSize = 0; const scanDirectory = async (dirPath: string, depth = 0): Promise<void> => { try { const entries = await readdir(dirPath, { withFileTypes: true }); for (const entry of entries) { const fullPath = join(dirPath, entry.name); const relativePath = relative(rootPath, fullPath); // Skip common ignore patterns if (this.shouldIgnoreFile(relativePath)) continue; if (entry.isDirectory()) { const dirNode: DirectoryNode = { path: relativePath, name: entry.name, depth, fileCount: 0, childDirectories: [], purpose: this.determineDirectoryPurpose(entry.name, relativePath), importance: this.assessDirectoryImportance(entry.name, relativePath), }; directories.push(dirNode); // Recursively scan subdirectories if (depth < (options.maxDepth || 10)) { await scanDirectory(fullPath, depth + 1); } } else if (entry.isFile()) { const stats = await stat(fullPath); const fileNode = await this.analyzeFile(fullPath, relativePath, stats); files.push(fileNode); totalSize += stats.size; // Categorize special files this.categorizeSpecialFile( fileNode, packageFiles, configFiles, documentationFiles, testFiles, buildFiles ); } } } catch (error) { this.logger.warn(`Error scanning directory ${dirPath}:`, error); } }; await scanDirectory(rootPath); // Update directory file counts this.updateDirectoryFileCounts(directories, files); return { rootPath, directories, files, packageFiles, configFiles, documentationFiles, testFiles, buildFiles, totalFiles: files.length, totalDirectories: directories.length, codebaseSize: totalSize, }; } /** * Generate comprehensive project insights */ private async generateProjectInsights( structure: ProjectStructure, options: AnalysisOptions ): Promise<ProjectInsights> { // Analyze languages const languageStats = this.analyzeLanguageDistribution(structure.files); const primaryLanguage = Object.keys(languageStats).reduce( (a, b) => (languageStats[a] > languageStats[b] ? a : b), '' ); // Detect frameworks const frameworksDetected = await this.detectFrameworks(structure); // Determine project type and architecture const projectType = this.determineProjectType(structure, frameworksDetected); const architecturePattern = this.identifyPrimaryArchitecture(structure, frameworksDetected); // Assess maturity and quality const maturityLevel = this.assessProjectMaturity(structure); const codeQuality = await this.assessCodeQuality(structure); const technicalDebt = await this.analyzeTechnicalDebt(structure); // Security and performance analysis const securityConcerns = await this.identifySecurityConcerns(structure); const performanceIndicators = await this.analyzePerformanceIndicators(structure); return { primaryLanguage, languageDistribution: languageStats, frameworksDetected, architecturePattern, projectType, maturityLevel, codeQuality, technicalDebt, securityConcerns, performanceIndicators, }; } /** * Analyze project dependencies and relationships */ private async analyzeDependencies( structure: ProjectStructure, options: AnalysisOptions ): Promise<DependencyGraph> { // This is a simplified implementation - in practice, this would involve // parsing import statements, package files, etc. const nodes: DependencyNode[] = []; const edges: DependencyEdge[] = []; const externalDependencies: ExternalDependency[] = []; const internalDependencies: InternalDependency[] = []; // Analyze package files for external dependencies for (const pkg of structure.packageFiles) { for (const dep of pkg.dependencies) { externalDependencies.push({ name: dep, version: 'unknown', type: 'production', usage: [], risk: 'low', }); } } // Analyze internal file dependencies (simplified) for (const file of structure.files) { nodes.push({ id: file.path, name: file.name, type: 'internal', importance: file.importance === 'critical' ? 1 : file.importance === 'high' ? 0.8 : 0.5, }); } return { nodes, edges, cycles: [], criticalPath: [], modularity: { cohesion: 0.7, coupling: 0.3, modularity: 0.8, instability: 0.4, }, externalDependencies, internalDependencies, }; } /** * Identify architecture patterns and design principles */ private async identifyArchitecturePatterns( structure: ProjectStructure, insights: ProjectInsights, dependencies: DependencyGraph ): Promise<ArchitecturePatterns> { // Simplified pattern detection const primaryPattern = insights.architecturePattern || 'modular'; return { primaryPattern, secondaryPatterns: ['layered'], designPrinciples: ['separation of concerns', 'single responsibility'], antiPatterns: [], refactoringOpportunities: [], }; } /** * Extract project metadata */ private async extractProjectMetadata( structure: ProjectStructure, options: AnalysisOptions ): Promise<ProjectMetadata> { let metadata: Partial<ProjectMetadata> = { name: basename(structure.rootPath), lastModified: new Date(), }; // Try to extract from package.json or similar for (const pkg of structure.packageFiles) { if (pkg.path.endsWith('package.json')) { try { const content = await readFile(join(structure.rootPath, pkg.path), 'utf8'); const packageInfo = JSON.parse(content); metadata = { ...metadata, name: packageInfo.name || metadata.name, version: packageInfo.version, description: packageInfo.description, author: typeof packageInfo.author === 'string' ? packageInfo.author : packageInfo.author?.name, license: packageInfo.license, repository: typeof packageInfo.repository === 'string' ? packageInfo.repository : packageInfo.repository?.url, homepage: packageInfo.homepage, keywords: packageInfo.keywords, }; break; } catch (error) { this.logger.warn(`Error parsing ${pkg.path}:`, error); } } } // Calculate project statistics const stats = this.calculateProjectStats(structure); return { name: metadata.name || 'Unknown Project', version: metadata.version, description: metadata.description, author: metadata.author, license: metadata.license, repository: metadata.repository, homepage: metadata.homepage, keywords: metadata.keywords, lastModified: metadata.lastModified!, stats, }; } /** * Generate intelligent recommendations */ private async generateRecommendations( structure: ProjectStructure, insights: ProjectInsights, dependencies: DependencyGraph, patterns: ArchitecturePatterns, metadata: ProjectMetadata ): Promise<IntelligentRecommendations> { return { codeImprovement: [], architecture: [], performance: [], security: [], testing: [], documentation: [], maintenance: [], }; } // Helper methods (simplified implementations) private shouldIgnoreFile(path: string): boolean { const ignorePatterns = [ 'node_modules', '.git', '.vscode', '.idea', 'dist', 'build', 'coverage', '.nyc_output', '.DS_Store', 'Thumbs.db', '*.log', ]; return ignorePatterns.some(pattern => path.includes(pattern)); } private determineDirectoryPurpose(name: string, path: string): DirectoryPurpose { const purposeMap: Record<string, DirectoryPurpose> = { src: 'source', source: 'source', lib: 'source', test: 'tests', tests: 'tests', __tests__: 'tests', spec: 'tests', build: 'build', dist: 'build', config: 'config', docs: 'docs', doc: 'docs', assets: 'assets', static: 'assets', node_modules: 'dependencies', }; return purposeMap[name.toLowerCase()] || 'other'; } private assessDirectoryImportance(name: string, path: string): 'high' | 'medium' | 'low' { if (['src', 'source', 'lib'].includes(name.toLowerCase())) return 'high'; if (['test', 'tests', 'config', 'docs'].includes(name.toLowerCase())) return 'medium'; return 'low'; } private async analyzeFile(fullPath: string, relativePath: string, stats: any): Promise<FileNode> { const ext = extname(relativePath); const name = basename(relativePath); const language = this.detectLanguage(ext); let linesOfCode = 0; let complexity: CodeComplexity = { cyclomaticComplexity: 0, cognitiveComplexity: 0, nestingDepth: 0, functionCount: 0, classCount: 0, }; // Read and analyze file content for code files if (this.isCodeFile(ext)) { try { const content = await readFile(fullPath, 'utf8'); linesOfCode = content.split('\n').length; complexity = this.analyzeCodeComplexity(content, language); } catch (error) { this.logger.warn(`Error reading file ${fullPath}:`, error); } } return { path: relativePath, name, extension: ext, language, size: stats.size, linesOfCode, complexity, dependencies: [], exports: [], imports: [], functions: [], classes: [], interfaces: [], purpose: this.determineFilePurpose(name, relativePath), lastModified: stats.mtime, importance: this.assessFileImportance(name, relativePath), }; } private detectLanguage(extension: string): string { const languageMap: Record<string, string> = { '.js': 'JavaScript', '.ts': 'TypeScript', '.jsx': 'JavaScript', '.tsx': 'TypeScript', '.py': 'Python', '.java': 'Java', '.cs': 'C#', '.cpp': 'C++', '.c': 'C', '.go': 'Go', '.rs': 'Rust', '.php': 'PHP', '.rb': 'Ruby', '.swift': 'Swift', '.kt': 'Kotlin', }; return languageMap[extension.toLowerCase()] || 'Unknown'; } private isCodeFile(extension: string): boolean { const codeExtensions = [ '.js', '.ts', '.jsx', '.tsx', '.py', '.java', '.cs', '.cpp', '.c', '.go', '.rs', '.php', '.rb', '.swift', '.kt', '.scala', '.r', '.m', ]; return codeExtensions.includes(extension.toLowerCase()); } private determineFilePurpose(name: string, path: string): FilePurpose { if ( name.toLowerCase().includes('test') || path.includes('/test/') || path.includes('/__tests__/') ) return 'test'; if (name.toLowerCase().includes('config') || name.includes('.config.')) return 'config'; if ( ['index.js', 'index.ts', 'main.js', 'main.ts', 'app.js', 'app.ts'].includes( name.toLowerCase() ) ) return 'entry'; if (name.toLowerCase().includes('util') || name.toLowerCase().includes('helper')) return 'utility'; if (['readme.md', 'readme.txt', 'changelog.md'].includes(name.toLowerCase())) return 'documentation'; return 'core'; } private assessFileImportance(name: string, path: string): 'critical' | 'high' | 'medium' | 'low' { if ( ['index.js', 'index.ts', 'main.js', 'main.ts', 'app.js', 'app.ts'].includes( name.toLowerCase() ) ) return 'critical'; if (path.startsWith('src/') && !path.includes('/test/')) return 'high'; if (name.toLowerCase().includes('test')) return 'medium'; return 'low'; } private analyzeCodeComplexity(content: string, language: string): CodeComplexity { // Simplified complexity analysis const lines = content.split('\n'); const functionMatches = content.match(/function\s+\w+|def\s+\w+|class\s+\w+/gi) || []; const classMatches = content.match(/class\s+\w+/gi) || []; return { cyclomaticComplexity: Math.min(functionMatches.length * 2, 50), cognitiveComplexity: Math.min(functionMatches.length * 1.5, 40), nestingDepth: Math.min( lines.filter(line => line.trim().startsWith('if') || line.trim().startsWith('for')).length, 10 ), functionCount: functionMatches.length, classCount: classMatches.length, }; } private categorizeSpecialFile( file: FileNode, packageFiles: PackageFile[], configFiles: ConfigFile[], documentationFiles: DocumentationFile[], testFiles: TestFile[], buildFiles: BuildFile[] ): void { const name = file.name.toLowerCase(); if ( name === 'package.json' || name === 'requirements.txt' || name === 'cargo.toml' || name === 'pom.xml' ) { packageFiles.push({ path: file.path, type: name.includes('.json') ? 'package.json' : 'other', dependencies: [], devDependencies: [], scripts: {}, } as PackageFile); } if (name.includes('config') || name.includes('.config.') || name.includes('.env')) { configFiles.push({ path: file.path, type: file.extension, purpose: 'configuration', settings: {}, }); } if (name.includes('readme') || name.includes('doc') || file.extension === '.md') { documentationFiles.push({ path: file.path, type: name.includes('readme') ? 'readme' : 'other', quality: 'fair', coverage: [], }); } if (file.purpose === 'test') { testFiles.push({ path: file.path, type: 'unit', framework: 'unknown', coverage: [], }); } if ( name.includes('build') || name.includes('webpack') || name.includes('rollup') || name.includes('gulp') ) { buildFiles.push({ path: file.path, type: file.extension, commands: [], targets: [], }); } } private updateDirectoryFileCounts(directories: DirectoryNode[], files: FileNode[]): void { for (const dir of directories) { dir.fileCount = files.filter(file => file.path.startsWith(dir.path + '/')).length; dir.childDirectories = directories .filter(d => d.path.startsWith(dir.path + '/') && d.depth === dir.depth + 1) .map(d => d.path); } } private analyzeLanguageDistribution(files: FileNode[]): Record<string, number> { const distribution: Record<string, number> = {}; for (const file of files) { if (this.isCodeFile(file.extension)) { distribution[file.language] = (distribution[file.language] || 0) + file.linesOfCode; } } return distribution; } private async detectFrameworks(structure: ProjectStructure): Promise<FrameworkInfo[]> { const frameworks: FrameworkInfo[] = []; // Check package files for framework dependencies for (const pkg of structure.packageFiles) { if (pkg.dependencies.includes('react')) { frameworks.push({ name: 'React', confidence: 0.9, evidence: ['package dependency'] }); } if (pkg.dependencies.includes('vue')) { frameworks.push({ name: 'Vue', confidence: 0.9, evidence: ['package dependency'] }); } if (pkg.dependencies.includes('angular')) { frameworks.push({ name: 'Angular', confidence: 0.9, evidence: ['package dependency'] }); } if (pkg.dependencies.includes('express')) { frameworks.push({ name: 'Express', confidence: 0.9, evidence: ['package dependency'] }); } } return frameworks; } private determineProjectType( structure: ProjectStructure, frameworks: FrameworkInfo[] ): ProjectType { // Check for library indicators if (structure.packageFiles.some(pkg => pkg.path.includes('package.json'))) { return 'library'; } // Check for application indicators if (frameworks.some(f => ['React', 'Vue', 'Angular'].includes(f.name))) { return 'application'; } // Check for service indicators if (frameworks.some(f => f.name === 'Express')) { return 'service'; } return 'unknown'; } private identifyPrimaryArchitecture( structure: ProjectStructure, frameworks: FrameworkInfo[] ): ArchitecturePattern { // Simple architecture detection based on directory structure const hasControllers = structure.directories.some(d => d.name.toLowerCase().includes('controller') ); const hasModels = structure.directories.some(d => d.name.toLowerCase().includes('model')); const hasViews = structure.directories.some(d => d.name.toLowerCase().includes('view')); if (hasControllers && hasModels && hasViews) { return 'mvc'; } if (structure.directories.some(d => d.name.toLowerCase().includes('service'))) { return 'microservices'; } return 'modular'; } private assessProjectMaturity( structure: ProjectStructure ): 'prototype' | 'development' | 'production' | 'legacy' { const hasTests = structure.testFiles.length > 0; const hasDocumentation = structure.documentationFiles.length > 0; const hasConfig = structure.configFiles.length > 0; const hasBuildSystem = structure.buildFiles.length > 0; const maturityScore = [hasTests, hasDocumentation, hasConfig, hasBuildSystem].filter( Boolean ).length; if (maturityScore >= 3) return 'production'; if (maturityScore >= 2) return 'development'; return 'prototype'; } private async assessCodeQuality(structure: ProjectStructure): Promise<CodeQualityMetrics> { // Simplified quality assessment const totalFiles = structure.files.filter(f => this.isCodeFile(f.extension)).length; const testFiles = structure.testFiles.length; return { maintainabilityIndex: 75, duplication: 0.1, testCoverage: totalFiles > 0 ? (testFiles / totalFiles) * 100 : 0, commentDensity: 0.15, naming: { score: 0.8, issues: [], suggestions: [] }, structure: { score: 0.75, issues: [], suggestions: [] }, consistency: { score: 0.85, issues: [], suggestions: [] }, }; } private async analyzeTechnicalDebt(structure: ProjectStructure): Promise<TechnicalDebtAnalysis> { // Simplified debt analysis return { totalDebt: 5, debtItems: [], debtRatio: 0.1, prioritizedFixes: [], }; } private async identifySecurityConcerns(structure: ProjectStructure): Promise<SecurityConcern[]> { // Simplified security analysis return []; } private async analyzePerformanceIndicators( structure: ProjectStructure ): Promise<PerformanceIndicator[]> { // Simplified performance analysis return []; } private calculateProjectStats(structure: ProjectStructure): ProjectStats { const codeFiles = structure.files.filter(f => this.isCodeFile(f.extension)); const totalLines = codeFiles.reduce((sum, file) => sum + file.linesOfCode, 0); return { totalFiles: structure.files.length, totalLines, codeLines: Math.floor(totalLines * 0.8), // Estimate commentLines: Math.floor(totalLines * 0.15), // Estimate blankLines: Math.floor(totalLines * 0.05), // Estimate testFiles: structure.testFiles.length, configFiles: structure.configFiles.length, documentFiles: structure.documentationFiles.length, }; } /** * Get cached analysis if available */ async getCachedAnalysis(path: string): Promise<ProjectIntelligence | null> { const cacheKey = `project-intel:${join(path)}`; const cacheResult = await unifiedCache.get<ProjectIntelligence>(cacheKey); return cacheResult?.value || null; } /** * Clear analysis cache */ async clearCache(path?: string): Promise<void> { if (path) { const cacheKey = `project-intel:${join(path)}`; await unifiedCache.delete(cacheKey); } else { await unifiedCache.clearByTags(['project-intelligence']); } } /** * Get system metrics */ async getSystemMetrics(): Promise<any> { const cacheStats = await unifiedCache.getStats(); return { cachedAnalyses: cacheStats.size || 0, activeAnalyses: this.analysisInProgress.size, memoryUsage: process.memoryUsage(), }; } } export interface AnalysisOptions { force?: boolean; maxDepth?: number; includeTests?: boolean; includeNodeModules?: boolean; languages?: string[]; skipLargeFiles?: boolean; maxFileSize?: number; } export default ProjectIntelligenceSystem;