import path from 'path'; import * as fs from 'fs/promises'; import { Logger } from '../utils/logger.js'; import { EventEmitter } from 'events'; export class ViolationManager { private violationsMap = new Map(); private totalViolations = 0; private watchPath: string; private emitter: EventEmitter; constructor(watchPath: string, emitter: EventEmitter) { this.watchPath = watchPath; this.emitter = emitter; } public handleViolations(filePath: string, violations: any[]) { this.totalViolations += violations.length; this.emitter.emit('violation', { file: filePath, violations }); // Update state map this.violationsMap.set(filePath, violations); this.updateViolationReport(); for (const v of violations) { const level = v.severity === 'critical' ? 'error' : v.severity === 'warning' ? 'warn' : 'info'; Logger[level as 'info'](`[${v.severity.toUpperCase()}] ${filePath}: ${v.message}`); } } public clear(filePath: string) { if (this.violationsMap.has(filePath)) { this.violationsMap.delete(filePath); this.updateViolationReport(); } } public getViolationCount(): number { return this.totalViolations; } private async updateViolationReport() { const reportPath = path.join(this.watchPath, '.rigstate', 'ACTIVE_VIOLATIONS.md'); const allViolations = Array.from(this.violationsMap.entries()); const totalCount = allViolations.reduce((acc, [, v]) => acc + v.length, 0); let content = `# 🛡️ Guardian Status: ${totalCount > 0 ? '⚠️ ATTENTION' : '✅ PASS'}\n\n`; content += `*Last check: ${new Date().toLocaleString()}*\n`; content += `*Files with issues: ${allViolations.length}*\n\n`; if (totalCount === 0) { content += "All systems within architectural limits. Frank is satisfied. 🤫\n"; } else { content += "### 🚨 Active Violations\n\n"; for (const [file, fileViolations] of allViolations) { const relPath = path.relative(this.watchPath, file); content += `#### 📄 ${relPath}\n`; for (const v of fileViolations) { content += `- **[${v.severity.toUpperCase()}]**: ${v.message}\n`; } content += '\n'; } content += "\n---\n*Rigstate Daemon is watching. Fix violations to clear this report.*"; } try { await fs.writeFile(reportPath, content, 'utf-8'); } catch (e) { /* ignore */ } } }