Kraft102's picture
Deploy backend fix v2.1.0
1d28c11
// πŸ”₯ PROMETHEUS ENGINE: Autonomous Evolution
// Point 7: Autonomous Paradigm Discovery
// The system that writes its own code. Handle with care.
import fs from 'fs/promises';
import path from 'path';
import { neuralBus } from './NeuralBus.js';
interface CodeProposal {
id: string;
filePath: string;
description: string;
currentCode: string;
proposedCode?: string;
status: 'PROPOSED' | 'APPROVED' | 'REJECTED' | 'APPLIED';
createdAt: Date;
confidence: number;
}
interface ScanResult {
file: string;
issues: string[];
suggestions: string[];
metrics: {
lines: number;
functions: number;
complexity: number;
};
}
export class PrometheusEngine {
private static instance: PrometheusEngine;
private proposals: Map<string, CodeProposal> = new Map();
private scanResults: ScanResult[] = [];
private isScanning = false;
private godMode = false; // Set to true to allow auto-apply
private constructor() {
console.log('πŸ”₯ [PROMETHEUS] Autonomous Evolution Engine Online');
console.log('πŸ”₯ [PROMETHEUS] God Mode:', this.godMode ? 'ENABLED' : 'DISABLED');
}
public static getInstance(): PrometheusEngine {
if (!PrometheusEngine.instance) {
PrometheusEngine.instance = new PrometheusEngine();
}
return PrometheusEngine.instance;
}
/**
* Scan directory for code improvements
*/
public async scanAndPropose(dirPath: string): Promise<ScanResult[]> {
if (this.isScanning) {
console.log('πŸ”₯ [PROMETHEUS] Scan already in progress');
return [];
}
this.isScanning = true;
this.scanResults = [];
try {
console.log(`πŸ”₯ [PROMETHEUS] Scanning: ${dirPath}`);
await this.scanDirectory(dirPath);
console.log(`πŸ”₯ [PROMETHEUS] Scan complete. Found ${this.scanResults.length} files`);
neuralBus.emitThought('PROMETHEUS', `Code scan complete: ${this.scanResults.length} files analyzed`, {
issues: this.scanResults.reduce((acc, r) => acc + r.issues.length, 0),
suggestions: this.scanResults.reduce((acc, r) => acc + r.suggestions.length, 0)
}, 'INFO');
return this.scanResults;
} finally {
this.isScanning = false;
}
}
private async scanDirectory(dirPath: string, depth: number = 0): Promise<void> {
if (depth > 5) return; // Max depth
try {
const entries = await fs.readdir(dirPath, { withFileTypes: true });
for (const entry of entries) {
const fullPath = path.join(dirPath, entry.name);
// Skip node_modules, dist, etc
if (entry.isDirectory()) {
if (!['node_modules', 'dist', '.git', 'coverage'].includes(entry.name)) {
await this.scanDirectory(fullPath, depth + 1);
}
} else if (entry.isFile() && (entry.name.endsWith('.ts') || entry.name.endsWith('.js'))) {
await this.analyzeFile(fullPath);
}
}
} catch (error) {
// Directory access error
}
}
private async analyzeFile(filePath: string): Promise<void> {
try {
const content = await fs.readFile(filePath, 'utf-8');
const lines = content.split('\n');
const result: ScanResult = {
file: filePath,
issues: [],
suggestions: [],
metrics: {
lines: lines.length,
functions: (content.match(/function\s+\w+|=>\s*{|async\s+\w+/g) || []).length,
complexity: this.calculateComplexity(content)
}
};
// Rule 1: Console.log without metrics
if (content.includes('console.log') && !content.includes('metricsService')) {
result.suggestions.push('Replace console.log with metricsService for production monitoring');
this.createProposal(filePath, 'Replace logging with metrics', content, 0.7);
}
// Rule 2: Hardcoded strings that should be config
const hardcodedUrls = content.match(/['"]https?:\/\/[^'"]+['"]/g) || [];
if (hardcodedUrls.length > 2) {
result.issues.push(`Found ${hardcodedUrls.length} hardcoded URLs - consider using config`);
}
// Rule 3: Missing error handling
if (content.includes('await ') && !content.includes('catch')) {
result.suggestions.push('Add try/catch blocks around async operations');
}
// Rule 4: Long functions
const functionMatches = content.match(/(?:async\s+)?function\s+\w+[^{]*\{[\s\S]*?\n\}/g) || [];
for (const fn of functionMatches) {
if (fn.split('\n').length > 50) {
result.issues.push('Function exceeds 50 lines - consider refactoring');
}
}
// Rule 5: TODO/FIXME comments
const todos = (content.match(/\/\/\s*(TODO|FIXME|HACK|XXX):/gi) || []).length;
if (todos > 0) {
result.issues.push(`Found ${todos} TODO/FIXME comments`);
}
// Rule 6: Magic numbers
const magicNumbers = content.match(/[^a-zA-Z0-9_](\d{4,})[^a-zA-Z0-9_]/g) || [];
if (magicNumbers.length > 3) {
result.suggestions.push('Consider extracting magic numbers to named constants');
}
// Rule 7: Unused imports (simplified check)
const importMatches = content.match(/import\s+{?\s*([^}]+)\s*}?\s+from/g) || [];
for (const imp of importMatches) {
const imported = imp.match(/import\s+{?\s*([^}]+)\s*}?\s+from/)?.[1] || '';
const names = imported.split(',').map(n => n.trim().split(' as ')[0].trim());
for (const name of names) {
if (name && !content.slice(content.indexOf(imp) + imp.length).includes(name)) {
result.suggestions.push(`Potentially unused import: ${name}`);
}
}
}
if (result.issues.length > 0 || result.suggestions.length > 0) {
this.scanResults.push(result);
}
} catch (error) {
// File read error
}
}
private calculateComplexity(content: string): number {
// Simplified cyclomatic complexity
let complexity = 1;
complexity += (content.match(/if\s*\(/g) || []).length;
complexity += (content.match(/else\s*{/g) || []).length;
complexity += (content.match(/for\s*\(/g) || []).length;
complexity += (content.match(/while\s*\(/g) || []).length;
complexity += (content.match(/case\s+/g) || []).length;
complexity += (content.match(/\?\s*[^:]+:/g) || []).length; // Ternary
return complexity;
}
private createProposal(filePath: string, description: string, currentCode: string, confidence: number): void {
const id = `proposal_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
const proposal: CodeProposal = {
id,
filePath,
description,
currentCode: currentCode.substring(0, 500), // Preview only
status: 'PROPOSED',
createdAt: new Date(),
confidence
};
this.proposals.set(id, proposal);
console.log(`πŸ”₯ [PROMETHEUS] Proposal Created: ${description} (${path.basename(filePath)})`);
neuralBus.emitThought('PROMETHEUS', `New code proposal: ${description}`, {
proposalId: id,
file: path.basename(filePath),
confidence
}, 'WARNING');
}
/**
* Apply a proposal (God Mode only)
*/
public async applyProposal(proposalId: string): Promise<boolean> {
if (!this.godMode) {
console.warn('πŸ”₯ [PROMETHEUS] God Mode disabled - cannot apply proposals');
return false;
}
const proposal = this.proposals.get(proposalId);
if (!proposal || proposal.status !== 'PROPOSED') {
return false;
}
// In a real implementation, this would:
// 1. Generate improved code via LLM
// 2. Create backup
// 3. Apply changes
// 4. Run tests
// 5. Rollback if tests fail
proposal.status = 'APPLIED';
console.log(`πŸ”₯ [PROMETHEUS] Proposal Applied: ${proposalId}`);
return true;
}
public enableGodMode(enabled: boolean): void {
this.godMode = enabled;
console.log(`πŸ”₯ [PROMETHEUS] God Mode: ${enabled ? 'ENABLED' : 'DISABLED'}`);
neuralBus.emitThought('PROMETHEUS', `God Mode ${enabled ? 'enabled' : 'disabled'}`, {},
enabled ? 'WARNING' : 'INFO');
}
// Public getters
public getProposals(): CodeProposal[] {
return Array.from(this.proposals.values());
}
public getScanResults(): ScanResult[] {
return this.scanResults;
}
public getStats() {
return {
isScanning: this.isScanning,
godMode: this.godMode,
proposals: this.proposals.size,
pendingProposals: Array.from(this.proposals.values()).filter(p => p.status === 'PROPOSED').length,
lastScanFiles: this.scanResults.length,
totalIssues: this.scanResults.reduce((acc, r) => acc + r.issues.length, 0),
totalSuggestions: this.scanResults.reduce((acc, r) => acc + r.suggestions.length, 0)
};
}
}
export const prometheus = PrometheusEngine.getInstance();