UNPKG

jay-code

Version:

Streamlined AI CLI orchestration engine with mathematical rigor and enterprise-grade reliability

641 lines (544 loc) 19.6 kB
/** * Jay-Code Initialization System * Loads development rules, investigates projects, and generates master documents */ import { readFileSync, writeFileSync, existsSync, readdirSync, statSync } from 'fs'; import { join, extname, dirname } from 'path'; import { DevelopmentRulesEngine } from './development-rules-engine.js'; export interface ProjectContext { projectPath: string; projectName: string; language: string; architecture: string[]; fileCount: number; codebaseSize: number; complexity: number; timestamp: Date; } export interface MasterDocument { id: string; timestamp: Date; projectContext: ProjectContext; architecturalAnalysis: ArchitecturalAnalysis; codebaseMapping: CodebaseMapping; developmentRules: any; recommendations: string[]; transformationPlan: TransformationPlan; } export interface ArchitecturalAnalysis { patterns: string[]; frameworks: string[]; dependencies: string[]; complexity: string; sophisticationLevel: string; qualityScore: number; mathematicalRigor: number; } export interface CodebaseMapping { directories: DirectoryInfo[]; keyFiles: FileAnalysis[]; totalFiles: number; languages: Record<string, number>; architecture: string; } export interface DirectoryInfo { path: string; fileCount: number; purpose: string; importance: 'critical' | 'important' | 'supporting' | 'optional'; } export interface FileAnalysis { path: string; size: number; language: string; purpose: string; complexity: number; importance: 'critical' | 'important' | 'supporting'; } export interface TransformationPlan { phases: TransformationPhase[]; estimatedDuration: string; complexityLevel: string; riskFactors: string[]; successCriteria: string[]; } export interface TransformationPhase { name: string; description: string; tasks: string[]; estimatedHours: number; dependencies: string[]; validation: string[]; } export class JayInitializationSystem { private rulesEngine: DevelopmentRulesEngine; private projectPath: string; constructor(projectPath: string = process.cwd()) { this.projectPath = projectPath; this.rulesEngine = new DevelopmentRulesEngine(); } /** * Initialize Jay-Code session with rules and project analysis */ async initialize(): Promise<MasterDocument> { console.log('Jay-Code Initialization: Loading development philosophy...'); // Step 1: Load and validate rules const rulesValid = this.validateRulesEngine(); if (!rulesValid) { throw new Error('Development rules validation failed'); } console.log('Development rules loaded successfully'); console.log('Investigating project directory...'); // Step 2: Investigate project const projectContext = await this.investigateProject(); console.log(`Project analysis complete: ${projectContext.projectName}`); // Step 3: Analyze architecture const architecturalAnalysis = await this.analyzeArchitecture(); console.log(`Architecture complexity: ${architecturalAnalysis.sophisticationLevel}`); // Step 4: Map codebase const codebaseMapping = await this.mapCodebase(); console.log(`Codebase mapped: ${codebaseMapping.totalFiles} files analyzed`); // Step 5: Generate transformation plan const transformationPlan = this.generateTransformationPlan( projectContext, architecturalAnalysis, codebaseMapping ); // Step 6: Create master document const masterDocument: MasterDocument = { id: `master_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, timestamp: new Date(), projectContext, architecturalAnalysis, codebaseMapping, developmentRules: this.rulesEngine.getCodeGenerationDirectives(), recommendations: this.generateRecommendations(architecturalAnalysis), transformationPlan }; // Step 7: Save master document await this.saveMasterDocument(masterDocument); console.log('Session master document generated and saved'); return masterDocument; } private validateRulesEngine(): boolean { try { const guidance = this.rulesEngine.generateCodeGuidance({}); return guidance.includes('Mathematical Precision'); } catch (error) { console.error('Rules engine validation failed:', error.message); return false; } } private async investigateProject(): Promise<ProjectContext> { const projectName = this.detectProjectName(); const language = this.detectPrimaryLanguage(); const architecture = this.detectArchitecturalPatterns(); const { fileCount, codebaseSize } = this.calculateProjectMetrics(); const complexity = this.calculateProjectComplexity(); return { projectPath: this.projectPath, projectName, language, architecture, fileCount, codebaseSize, complexity, timestamp: new Date() }; } private detectProjectName(): string { // Try package.json first const packageJsonPath = join(this.projectPath, 'package.json'); if (existsSync(packageJsonPath)) { try { const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')); return packageJson.name || 'unknown-project'; } catch (error) { // Fall through to directory name } } // Use directory name return this.projectPath.split('/').pop() || 'unknown-project'; } private detectPrimaryLanguage(): string { const extensions = new Map<string, number>(); this.walkDirectory(this.projectPath, (filePath) => { const ext = extname(filePath).toLowerCase(); if (['.ts', '.js', '.py', '.java', '.cpp', '.go', '.rs'].includes(ext)) { extensions.set(ext, (extensions.get(ext) || 0) + 1); } }); let maxCount = 0; let primaryExt = '.js'; for (const [ext, count] of extensions) { if (count > maxCount) { maxCount = count; primaryExt = ext; } } const languageMap: Record<string, string> = { '.ts': 'TypeScript', '.js': 'JavaScript', '.py': 'Python', '.java': 'Java', '.cpp': 'C++', '.go': 'Go', '.rs': 'Rust' }; return languageMap[primaryExt] || 'Unknown'; } private detectArchitecturalPatterns(): string[] { const patterns: string[] = []; const architecturalIndicators = { 'MVC': ['controller', 'model', 'view'], 'Microservices': ['service', 'api', 'gateway'], 'Layered': ['domain', 'application', 'infrastructure'], 'Event-Driven': ['event', 'handler', 'subscriber'], 'CQRS': ['command', 'query', 'handler'], 'Clean Architecture': ['entity', 'usecase', 'adapter'], 'Hexagonal': ['port', 'adapter', 'domain'] }; this.walkDirectory(this.projectPath, (filePath) => { const content = this.readFileContent(filePath); const fileName = filePath.toLowerCase(); for (const [pattern, indicators] of Object.entries(architecturalIndicators)) { const matches = indicators.some(indicator => fileName.includes(indicator) || content.toLowerCase().includes(indicator) ); if (matches && !patterns.includes(pattern)) { patterns.push(pattern); } } }); return patterns.length > 0 ? patterns : ['Unknown']; } private calculateProjectMetrics(): { fileCount: number; codebaseSize: number } { let fileCount = 0; let codebaseSize = 0; this.walkDirectory(this.projectPath, (filePath) => { const stats = statSync(filePath); fileCount++; codebaseSize += stats.size; }); return { fileCount, codebaseSize }; } private calculateProjectComplexity(): number { // Mathematical complexity calculation based on multiple factors let totalLines = 0; let functionCount = 0; let classCount = 0; let fileCount = 0; this.walkDirectory(this.projectPath, (filePath) => { if (['.ts', '.js', '.py'].includes(extname(filePath))) { const content = this.readFileContent(filePath); const lines = content.split('\n').filter(line => line.trim()).length; totalLines += lines; fileCount++; const functions = (content.match(/function|=>|def\s+\w+/g) || []).length; const classes = (content.match(/class\s+\w+/g) || []).length; functionCount += functions; classCount += classes; } }); // Mathematical complexity formula const avgLinesPerFile = fileCount > 0 ? totalLines / fileCount : 0; const avgFunctionsPerFile = fileCount > 0 ? functionCount / fileCount : 0; const avgClassesPerFile = fileCount > 0 ? classCount / fileCount : 0; const complexity = Math.min(1, ( avgLinesPerFile / 1000 * 0.4 + avgFunctionsPerFile / 20 * 0.3 + avgClassesPerFile / 5 * 0.3 )); return complexity; } private async analyzeArchitecture(): Promise<ArchitecturalAnalysis> { const patterns = this.detectArchitecturalPatterns(); const frameworks = this.detectFrameworks(); const dependencies = this.analyzeDependencies(); const complexity = this.determineArchitecturalComplexity(patterns, frameworks, dependencies); const sophisticationLevel = this.determineSophisticationLevel(complexity); const qualityScore = this.calculateArchitecturalQuality(); const mathematicalRigor = this.assessMathematicalRigor(); return { patterns, frameworks, dependencies, complexity, sophisticationLevel, qualityScore, mathematicalRigor }; } private detectFrameworks(): string[] { const frameworks: string[] = []; const packageJsonPath = join(this.projectPath, 'package.json'); if (existsSync(packageJsonPath)) { try { const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')); const deps = { ...packageJson.dependencies, ...packageJson.devDependencies }; const frameworkMap: Record<string, string> = { 'express': 'Express.js', 'react': 'React', 'vue': 'Vue.js', 'angular': 'Angular', 'nestjs': 'NestJS', 'fastify': 'Fastify', 'koa': 'Koa.js', 'next': 'Next.js' }; for (const [dep, framework] of Object.entries(frameworkMap)) { if (deps[dep]) { frameworks.push(framework); } } } catch (error) { // Continue without package.json analysis } } return frameworks; } private analyzeDependencies(): string[] { const packageJsonPath = join(this.projectPath, 'package.json'); if (!existsSync(packageJsonPath)) return []; try { const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8')); const deps = Object.keys({ ...packageJson.dependencies, ...packageJson.devDependencies }); return deps.slice(0, 20); // Top 20 dependencies } catch (error) { return []; } } private determineArchitecturalComplexity(patterns: string[], frameworks: string[], dependencies: string[]): string { const score = patterns.length * 0.4 + frameworks.length * 0.3 + Math.min(dependencies.length / 10, 1) * 0.3; if (score >= 2) return 'Enterprise'; if (score >= 1.5) return 'Advanced'; if (score >= 1) return 'Intermediate'; return 'Basic'; } private determineSophisticationLevel(complexity: string): string { const mapping: Record<string, string> = { 'Enterprise': 'Top 2% Mathematical', 'Advanced': 'Advanced Mathematical', 'Intermediate': 'Intermediate', 'Basic': 'Basic' }; return mapping[complexity] || 'Basic'; } private calculateArchitecturalQuality(): number { // Implement quality scoring algorithm return 0.75; // Placeholder } private assessMathematicalRigor(): number { let rigorScore = 0; let totalFiles = 0; this.walkDirectory(this.projectPath, (filePath) => { if (['.ts', '.js'].includes(extname(filePath))) { const content = this.readFileContent(filePath); totalFiles++; if (/complexity|algorithm|mathematical|statistical/i.test(content)) { rigorScore++; } } }); return totalFiles > 0 ? rigorScore / totalFiles : 0; } private async mapCodebase(): Promise<CodebaseMapping> { const directories: DirectoryInfo[] = []; const keyFiles: FileAnalysis[] = []; const languages: Record<string, number> = {}; let totalFiles = 0; // Analyze directories this.analyzeDirectories(this.projectPath, directories); // Analyze key files this.walkDirectory(this.projectPath, (filePath) => { const ext = extname(filePath); const stats = statSync(filePath); languages[ext] = (languages[ext] || 0) + 1; totalFiles++; // Identify key files if (this.isKeyFile(filePath)) { keyFiles.push({ path: filePath, size: stats.size, language: this.getLanguageFromExtension(ext), purpose: this.determineFilePurpose(filePath), complexity: this.calculateFileComplexity(filePath), importance: this.determineFileImportance(filePath) }); } }); return { directories, keyFiles, totalFiles, languages, architecture: this.detectArchitecturalPatterns()[0] || 'Unknown' }; } private generateTransformationPlan( context: ProjectContext, analysis: ArchitecturalAnalysis, mapping: CodebaseMapping ): TransformationPlan { const phases: TransformationPhase[] = []; // Phase 1: Analysis and Planning phases.push({ name: 'Analysis and Planning', description: 'Comprehensive codebase analysis and transformation strategy', tasks: [ 'Load development rules and validate against project', 'Analyze current architecture and identify improvement areas', 'Create mathematical sophistication roadmap', 'Plan quality validation checkpoints' ], estimatedHours: 8, dependencies: [], validation: ['Rules compliance check', 'Architecture analysis completion'] }); // Phase 2: Core Transformation phases.push({ name: 'Core Transformation', description: 'Implement mathematical rigor and architectural sophistication', tasks: [ 'Apply mathematical precision requirements', 'Implement deterministic algorithms', 'Add statistical validation frameworks', 'Enhance architectural patterns' ], estimatedHours: 24, dependencies: ['Analysis and Planning'], validation: ['97%+ quality threshold', 'Mathematical correctness verification'] }); // Phase 3: Quality Assurance phases.push({ name: 'Quality Assurance', description: 'Validate transformation against Jay-Code standards', tasks: [ 'Run comprehensive quality validation', 'Verify mathematical rigor compliance', 'Test deterministic behavior', 'Performance benchmark validation' ], estimatedHours: 12, dependencies: ['Core Transformation'], validation: ['All quality gates passed', 'Performance benchmarks met'] }); return { phases, estimatedDuration: '5-7 days', complexityLevel: analysis.sophisticationLevel, riskFactors: this.identifyRiskFactors(analysis), successCriteria: [ '97%+ quality validation score', 'Mathematical rigor compliance', 'Deterministic behavior verification', 'Performance benchmarks achieved' ] }; } private generateRecommendations(analysis: ArchitecturalAnalysis): string[] { const recommendations: string[] = []; if (analysis.mathematicalRigor < 0.5) { recommendations.push('Implement mathematical algorithms with complexity analysis'); } if (analysis.qualityScore < 0.8) { recommendations.push('Enhance code quality with statistical validation'); } if (!analysis.patterns.includes('Circuit Breaker')) { recommendations.push('Add circuit breaker patterns for reliability'); } return recommendations; } private identifyRiskFactors(analysis: ArchitecturalAnalysis): string[] { const risks: string[] = []; if (analysis.mathematicalRigor < 0.3) { risks.push('Low mathematical rigor may require significant refactoring'); } if (analysis.qualityScore < 0.6) { risks.push('Quality improvements may require architectural changes'); } return risks; } private async saveMasterDocument(master: MasterDocument): Promise<void> { const masterDir = join(this.projectPath, '.jay-code', 'masters'); const masterFile = join(masterDir, `${master.id}.json`); try { // Ensure directory exists const fs = await import('fs/promises'); await fs.mkdir(masterDir, { recursive: true }); // Save master document await fs.writeFile(masterFile, JSON.stringify(master, null, 2)); console.log(`Master document saved: ${masterFile}`); } catch (error) { console.error('Failed to save master document:', error.message); } } // Helper methods private walkDirectory(dir: string, callback: (filePath: string) => void): void { try { const items = readdirSync(dir); for (const item of items) { if (item.startsWith('.')) continue; // Skip hidden files const fullPath = join(dir, item); const stats = statSync(fullPath); if (stats.isDirectory()) { this.walkDirectory(fullPath, callback); } else { callback(fullPath); } } } catch (error) { // Skip directories we can't read } } private readFileContent(filePath: string): string { try { return readFileSync(filePath, 'utf8'); } catch (error) { return ''; } } private analyzeDirectories(basePath: string, directories: DirectoryInfo[]): void { // Implementation for directory analysis } private isKeyFile(filePath: string): boolean { const keyPatterns = [ /package\.json$/, /tsconfig\.json$/, /README\.md$/, /index\.[jt]s$/, /main\.[jt]s$/, /app\.[jt]s$/, /server\.[jt]s$/ ]; return keyPatterns.some(pattern => pattern.test(filePath)); } private getLanguageFromExtension(ext: string): string { const map: Record<string, string> = { '.ts': 'TypeScript', '.js': 'JavaScript', '.py': 'Python', '.json': 'JSON' }; return map[ext] || 'Unknown'; } private determineFilePurpose(filePath: string): string { if (filePath.includes('config')) return 'Configuration'; if (filePath.includes('test')) return 'Testing'; if (filePath.includes('component')) return 'Component'; if (filePath.includes('service')) return 'Service'; if (filePath.includes('model')) return 'Model'; return 'Application Logic'; } private calculateFileComplexity(filePath: string): number { const content = this.readFileContent(filePath); const lines = content.split('\n').length; const functions = (content.match(/function|=>/g) || []).length; return Math.min(1, (lines / 100) * 0.7 + (functions / 10) * 0.3); } private determineFileImportance(filePath: string): 'critical' | 'important' | 'supporting' { if (/package\.json|main\.|index\.|app\./i.test(filePath)) return 'critical'; if (/config|service|model/i.test(filePath)) return 'important'; return 'supporting'; } }