UNPKG

ripple-ai-detector

Version:

🌊 Ripple AI Bug Detector - Built by an AI that knows its flaws. Catch AI-generated bugs before you commit.

206 lines 8.73 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.OutputFormatter = void 0; const logger_1 = require("../utils/logger"); const chalk_1 = __importDefault(require("chalk")); const path_1 = __importDefault(require("path")); class OutputFormatter { format; constructor(format = 'console') { this.format = format; } // Main method to display results async displayResults(results) { if (this.format === 'json') { this.displayJSON(results); } else { this.displayConsole(results); } } // Display results in beautiful console format displayConsole(results) { // AI Detection Header if (results.aiGenerated) { logger_1.logger.newLine(); logger_1.logger.aiDetected('AI-generated changes detected', Math.round(results.confidence * 100)); logger_1.logger.newLine(); } // Display issues if (results.issues.length > 0) { this.displayIssues(results.issues); } else { logger_1.logger.success('No issues detected'); if (!results.aiGenerated) { logger_1.logger.info('AI Detection: Low confidence - likely human-written code'); } } // Display summary this.displaySummary(results); // Display recommendations this.displayRecommendations(results); } // Display issues in console displayIssues(issues) { logger_1.logger.info('Issues found:'); logger_1.logger.newLine(); const errors = issues.filter(i => i.severity === 'error'); const warnings = issues.filter(i => i.severity === 'warning'); // Display errors first for (const issue of errors) { this.displayIssue(issue); logger_1.logger.newLine(); } // Then warnings for (const issue of warnings) { this.displayIssue(issue); logger_1.logger.newLine(); } } // Display individual issue displayIssue(issue) { const icon = issue.severity === 'error' ? '❌' : '⚠️'; const color = issue.severity === 'error' ? 'red' : 'yellow'; // Main issue message console.log(chalk_1.default[color](`${icon} ${issue.message}`)); // File location const relativePath = path_1.default.relative(process.cwd(), issue.file); const location = issue.line ? `${relativePath}:${issue.line}` : relativePath; console.log(chalk_1.default.gray(` File: ${location}`)); // Issue-specific details this.displayIssueDetails(issue); // Affected files (for function signature changes) if (issue.details.affectedFiles && issue.details.affectedFiles.length > 0) { console.log(chalk_1.default.red(' 💥 This will break:')); for (const affected of issue.details.affectedFiles) { const affectedPath = path_1.default.relative(process.cwd(), affected.path); console.log(chalk_1.default.red(` - ${affectedPath}:${affected.line}`)); } } // Suggestions if (issue.suggestions && issue.suggestions.length > 0) { console.log(chalk_1.default.cyan(' 💡 Suggestions:')); for (const suggestion of issue.suggestions) { console.log(chalk_1.default.cyan(` • ${suggestion}`)); } } // Confidence score if (issue.confidence > 0) { const confidencePercent = Math.round(issue.confidence * 100); const confidenceColor = issue.confidence > 0.8 ? 'green' : issue.confidence > 0.6 ? 'yellow' : 'red'; console.log(chalk_1.default[confidenceColor](` Confidence: ${confidencePercent}%`)); } } // Display issue-specific details displayIssueDetails(issue) { switch (issue.type) { case 'function-signature-change': if (issue.details.oldSignature && issue.details.newSignature) { console.log(chalk_1.default.gray(` Function: ${issue.details.oldSignature}${issue.details.newSignature}`)); } break; case 'import-export-mismatch': if (issue.details.importName && issue.details.exportName) { console.log(chalk_1.default.gray(` Import: '${issue.details.importName}' not found`)); if (issue.details.availableExports) { console.log(chalk_1.default.gray(` Available: ${issue.details.availableExports.join(', ')}`)); } } break; case 'ai-pattern-detected': if (issue.details.aiPatterns) { console.log(chalk_1.default.magenta(` 🤖 AI Patterns: ${issue.details.aiPatterns.join(', ')}`)); } break; } } // Display summary displaySummary(results) { logger_1.logger.newLine(); logger_1.logger.separator(); const { errors, warnings, filesAnalyzed, timeMs } = results.summary; // Summary line const summaryParts = []; if (errors > 0) summaryParts.push(chalk_1.default.red(`${errors} error${errors !== 1 ? 's' : ''}`)); if (warnings > 0) summaryParts.push(chalk_1.default.yellow(`${warnings} warning${warnings !== 1 ? 's' : ''}`)); if (summaryParts.length > 0) { console.log(`Summary: ${summaryParts.join(', ')}`); } else { logger_1.logger.success('Summary: No issues found'); } // Analysis details console.log(chalk_1.default.gray(`Files analyzed: ${filesAnalyzed}`)); console.log(chalk_1.default.gray(`Analysis time: ${timeMs}ms`)); if (results.confidence > 0) { const confidencePercent = Math.round(results.confidence * 100); console.log(chalk_1.default.gray(`Confidence: ${confidencePercent}% this analysis is accurate`)); } } // Display recommendations displayRecommendations(results) { logger_1.logger.newLine(); if (results.aiGenerated) { logger_1.logger.tip('Recommendation: Review AI-generated changes carefully before committing'); } if (results.issues.some(i => i.severity === 'error')) { logger_1.logger.error('❌ Not safe to commit - fix errors first'); } else if (results.issues.some(i => i.severity === 'warning')) { logger_1.logger.warning('⚠️ Safe to commit, but consider fixing warnings'); } else { logger_1.logger.success('✅ Safe to commit'); } } // Display results in JSON format displayJSON(results) { const jsonOutput = { success: results.success, confidence: results.confidence, aiGenerated: results.aiGenerated, summary: results.summary, issues: results.issues.map(issue => ({ id: issue.id, type: issue.type, severity: issue.severity, message: issue.message, file: issue.file, line: issue.line, column: issue.column, details: issue.details, suggestions: issue.suggestions, confidence: issue.confidence })), metadata: results.metadata }; console.log(JSON.stringify(jsonOutput, null, 2)); } // Create upgrade prompt message static createUpgradePrompt(current, limit) { const remaining = limit - current; if (remaining <= 0) { return '🚀 Upgrade to Pro for unlimited validations: ripple.dev/pro'; } if (remaining <= 2) { return `⚠️ Only ${remaining} validations left this month. Upgrade: ripple.dev/pro`; } return `💡 ${remaining} validations remaining. Get unlimited: ripple.dev/pro`; } // Create value proposition message static createValueMessage(validationsUsed) { const hoursPerBug = 2; const hoursSaved = validationsUsed * hoursPerBug; const hourlyRate = 75; const valueSaved = hoursSaved * hourlyRate; return `💰 This month: ${validationsUsed} validations = ~${hoursSaved} hours saved = ~$${valueSaved} value!`; } } exports.OutputFormatter = OutputFormatter; //# sourceMappingURL=formatter.js.map