jay-code
Version:
Streamlined AI CLI orchestration engine with mathematical rigor and enterprise-grade reliability
641 lines (544 loc) • 19.6 kB
text/typescript
/**
* 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';
}
}