incize
Version:
AI Commit Copilot for Power Developers
201 lines (200 loc) • 8.48 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.MockAIAnalyzer = void 0;
class MockAIAnalyzer {
/**
* Analyze diff using mock AI (offline mode)
*/
async analyze(_prompt) {
// Simulate API delay
await this.simulateDelay(1000 + Math.random() * 2000);
// Mock analyzer doesn't need the full context, just simulate analysis
const diff = { files: [], summary: { additions: 0, deletions: 0, totalChanges: 0 } };
const commit = { hash: 'mock', author: 'mock', date: 'mock', message: 'mock', branch: 'mock' };
// Generate mock analysis based on diff characteristics
const analysis = this.generateMockAnalysis(diff, commit);
return analysis;
}
/**
* Generate realistic mock analysis
*/
generateMockAnalysis(diff, commit) {
const languages = [...new Set(diff.files.map((f) => f.language).filter(Boolean))];
// Calculate risk score based on changes
const riskScore = this.calculateRiskScore(diff);
const riskLevel = this.getRiskLevel(riskScore);
// Generate summary based on change characteristics
const summary = this.generateSummary(diff, commit);
// Generate suggestions based on file types and changes
const suggestions = this.generateSuggestions(diff, languages);
// Generate changelog entry
const changelog = this.generateChangelog(diff, commit);
// Generate test suggestions
const testSuggestions = this.generateTestSuggestions(diff, languages);
// Calculate confidence based on analysis quality
const confidence = this.calculateConfidence(diff);
return {
summary,
riskScore,
riskLevel,
suggestions,
changelog,
testSuggestions,
confidence
};
}
/**
* Calculate risk score based on diff characteristics
*/
calculateRiskScore(diff) {
const { additions, deletions, totalChanges } = diff.summary;
const fileCount = diff.files.length;
const languages = diff.files.map((f) => f.language).filter(Boolean);
let riskScore = 0;
// High risk factors
if (totalChanges > 500)
riskScore += 30;
if (fileCount > 10)
riskScore += 20;
if (languages.includes('JavaScript') || languages.includes('TypeScript'))
riskScore += 10;
if (languages.includes('Python'))
riskScore += 5;
if (languages.includes('Go') || languages.includes('Rust'))
riskScore -= 5;
// Check for sensitive files
const sensitivePatterns = ['config', 'secret', 'password', 'key', 'token', 'auth'];
const hasSensitiveFiles = diff.files.some((f) => sensitivePatterns.some(pattern => f.path.toLowerCase().includes(pattern)));
if (hasSensitiveFiles)
riskScore += 25;
// Check for large deletions
if (deletions > additions * 2)
riskScore += 15;
return Math.min(100, Math.max(0, riskScore));
}
/**
* Get risk level from score
*/
getRiskLevel(score) {
if (score < 20)
return 'low';
if (score < 50)
return 'medium';
if (score < 80)
return 'high';
return 'critical';
}
/**
* Generate summary based on changes
*/
generateSummary(diff, _commit) {
const { additions, deletions, totalChanges } = diff.summary;
const fileCount = diff.files.length;
const languages = [...new Set(diff.files.map((f) => f.language).filter(Boolean))];
if (fileCount === 0) {
return 'No changes detected in this commit.';
}
const changeType = additions > deletions ? 'additions' : 'modifications';
const languageText = languages.length > 0 ? ` in ${languages.join(', ')}` : '';
return `Updated ${fileCount} file(s) with ${totalChanges} line changes (${changeType})${languageText}.`;
}
/**
* Generate suggestions based on file types and changes
*/
generateSuggestions(diff, languages) {
const suggestions = [];
// Language-specific suggestions
if (languages.includes('JavaScript') || languages.includes('TypeScript')) {
suggestions.push('Consider adding TypeScript types for better type safety');
suggestions.push('Review for potential null/undefined access patterns');
}
if (languages.includes('Python')) {
suggestions.push('Consider adding type hints for better code documentation');
suggestions.push('Review for proper exception handling');
}
if (languages.includes('Go')) {
suggestions.push('Ensure proper error handling for all function calls');
suggestions.push('Consider adding unit tests for new functions');
}
// General suggestions based on change volume
const { totalChanges } = diff.summary;
if (totalChanges > 100) {
suggestions.push('Large change detected - consider breaking into smaller commits');
}
if (diff.files.length > 5) {
suggestions.push('Multiple files changed - ensure changes are logically grouped');
}
// Security suggestions
const hasConfigFiles = diff.files.some((f) => f.path.includes('config') || f.path.includes('secret'));
if (hasConfigFiles) {
suggestions.push('Review configuration changes for sensitive data exposure');
}
return suggestions.slice(0, 3); // Limit to 3 suggestions
}
/**
* Generate changelog entry
*/
generateChangelog(diff, commit) {
const { additions, deletions } = diff.summary;
const fileCount = diff.files.length;
const languages = [...new Set(diff.files.map((f) => f.language).filter(Boolean))];
const changeType = additions > deletions ? 'Added' : 'Modified';
const languageText = languages.length > 0 ? ` (${languages.join(', ')})` : '';
return `${changeType} ${fileCount} file(s)${languageText} - ${commit.message}`;
}
/**
* Generate test suggestions
*/
generateTestSuggestions(diff, languages) {
const suggestions = [];
// Language-specific test suggestions
if (languages.includes('JavaScript') || languages.includes('TypeScript')) {
suggestions.push('Add Jest unit tests for new functions');
suggestions.push('Consider integration tests for API endpoints');
}
if (languages.includes('Python')) {
suggestions.push('Add pytest unit tests for new modules');
suggestions.push('Consider adding doctests for documentation');
}
if (languages.includes('Go')) {
suggestions.push('Add Go test files for new packages');
suggestions.push('Consider table-driven tests for edge cases');
}
// General test suggestions
const { totalChanges } = diff.summary;
if (totalChanges > 50) {
suggestions.push('Large changes detected - ensure comprehensive test coverage');
}
return suggestions.slice(0, 2); // Limit to 2 suggestions
}
/**
* Calculate confidence based on analysis quality
*/
calculateConfidence(diff) {
const { totalChanges } = diff.summary;
const fileCount = diff.files.length;
const languages = diff.files.map((f) => f.language).filter(Boolean);
let confidence = 0.7; // Base confidence
// Higher confidence for smaller, focused changes
if (totalChanges < 50)
confidence += 0.1;
if (fileCount < 3)
confidence += 0.1;
// Higher confidence for well-known languages
const knownLanguages = ['JavaScript', 'TypeScript', 'Python', 'Go', 'Rust'];
const hasKnownLanguages = languages.some((lang) => knownLanguages.includes(lang));
if (hasKnownLanguages)
confidence += 0.1;
// Lower confidence for very large changes
if (totalChanges > 200)
confidence -= 0.2;
return Math.min(1.0, Math.max(0.0, confidence));
}
/**
* Simulate API delay
*/
async simulateDelay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
}
exports.MockAIAnalyzer = MockAIAnalyzer;