gitdb-database
Version:
A production-ready CLI tool for managing a NoSQL database using GitHub repositories as storage
333 lines • 12.4 kB
JavaScript
import { promises as fs } from 'fs';
import path from 'path';
export class AutoFix {
fixPatterns = new Map();
constructor() {
this.initializeFixPatterns();
}
/**
* Initialize common fix patterns
*/
initializeFixPatterns() {
// Versioning test fixes
this.fixPatterns.set('version', [
{
type: 'error',
message: 'Version test expects v1.0.0 but gets commit hash',
fix: 'Update test to expect commit-based versioning instead of semantic versioning',
confidence: 0.9,
category: 'logic'
},
{
type: 'warning',
message: 'Version rollback test may fail due to missing collection',
fix: 'Ensure collection exists before testing rollback functionality',
confidence: 0.8,
category: 'logic'
}
]);
// Query syntax fixes
this.fixPatterns.set('query', [
{
type: 'error',
message: 'Invalid JSON query syntax',
fix: 'Use proper JSON format: {"field": "value"} or {"field": {"$gte": 25}}',
confidence: 0.9,
category: 'syntax'
},
{
type: 'warning',
message: 'Query may be inefficient for large datasets',
fix: 'Add indexes or use SuperMode for better performance',
confidence: 0.7,
category: 'performance'
}
]);
// Collection fixes
this.fixPatterns.set('collection', [
{
type: 'error',
message: 'Collection not selected',
fix: 'Use "use <collection>" before running commands',
confidence: 0.9,
category: 'logic'
},
{
type: 'warning',
message: 'Collection does not exist',
fix: 'Create collection first with "create-collection <name>"',
confidence: 0.8,
category: 'logic'
}
]);
// Connection fixes
this.fixPatterns.set('connection', [
{
type: 'error',
message: 'Not connected to database',
fix: 'Use "connect" to establish database connection',
confidence: 0.9,
category: 'logic'
},
{
type: 'warning',
message: 'Token may be invalid or expired',
fix: 'Check token permissions and regenerate if needed',
confidence: 0.7,
category: 'security'
}
]);
// Performance fixes
this.fixPatterns.set('performance', [
{
type: 'info',
message: 'Large dataset detected',
fix: 'Enable SuperMode with "supermode enable" for better performance',
confidence: 0.8,
category: 'performance'
},
{
type: 'warning',
message: 'Multiple queries detected',
fix: 'Use batch operations or enable caching',
confidence: 0.7,
category: 'performance'
}
]);
}
/**
* Analyze error and suggest fixes
*/
async analyzeError(error, context) {
const suggestions = [];
const normalizedError = error.toLowerCase();
// Check for version-related errors
if (normalizedError.includes('version') || normalizedError.includes('v1.0.0')) {
suggestions.push(...this.fixPatterns.get('version') || []);
}
// Check for query syntax errors
if (normalizedError.includes('json') || normalizedError.includes('syntax') || normalizedError.includes('parse')) {
suggestions.push(...this.fixPatterns.get('query') || []);
}
// Check for collection errors
if (normalizedError.includes('collection') || normalizedError.includes('use')) {
suggestions.push(...this.fixPatterns.get('collection') || []);
}
// Check for connection errors
if (normalizedError.includes('connect') || normalizedError.includes('token') || normalizedError.includes('auth')) {
suggestions.push(...this.fixPatterns.get('connection') || []);
}
// Check for performance issues
if (normalizedError.includes('slow') || normalizedError.includes('timeout') || normalizedError.includes('performance')) {
suggestions.push(...this.fixPatterns.get('performance') || []);
}
// Add context-specific suggestions
if (context) {
suggestions.push(...this.generateContextSpecificFixes(error, context));
}
return suggestions.sort((a, b) => b.confidence - a.confidence);
}
/**
* Generate context-specific fixes
*/
generateContextSpecificFixes(error, context) {
const suggestions = [];
// Check if user is trying to use AI commands
if (error.includes('ai') && context.lastCommand?.includes('ai')) {
suggestions.push({
type: 'info',
message: 'AI command needs more specific parameters',
fix: 'Try: ai "show me all users" or ai "find users over 25"',
confidence: 0.8,
category: 'syntax'
});
}
// Check for missing parameters in common commands
if (error.includes('usage') && context.lastCommand) {
const command = context.lastCommand.split(' ')[0];
suggestions.push({
type: 'error',
message: `Missing parameters for ${command}`,
fix: this.getUsageExample(command),
confidence: 0.9,
category: 'syntax'
});
}
// Check for empty database issues
if (error.includes('404') || error.includes('not found')) {
suggestions.push({
type: 'info',
message: 'Database appears to be empty',
fix: 'Create collections and add documents to get started',
confidence: 0.8,
category: 'logic'
});
}
return suggestions;
}
/**
* Get usage example for command
*/
getUsageExample(command) {
const examples = {
'use': 'use <collection> - Example: use users',
'insert': 'insert <json> - Example: insert {"name":"John","age":25}',
'findone': 'findone <json-query> - Example: findone {"name":"John"}',
'update': 'update <id> <json> - Example: update abc123 {"age":26}',
'delete': 'delete <id> - Example: delete abc123',
'count': 'count [json-query] - Example: count {"age":{"$gte":25}}',
'create-collection': 'create-collection <name> - Example: create-collection users',
'rollback': 'rollback <collection> - Example: rollback users',
'ai': 'ai "natural language query" - Example: ai "show me all users"'
};
return examples[command] || `Check "help" for ${command} usage`;
}
/**
* Auto-fix test failures
*/
async fixTestFailure(testResult) {
const fixes = [];
if (!testResult.passed && testResult.error) {
const suggestions = await this.analyzeError(testResult.error, {
testName: testResult.testName
});
for (const suggestion of suggestions) {
if (suggestion.confidence > 0.7) {
fixes.push(`${suggestion.message}\n💡 Fix: ${suggestion.fix}`);
}
}
}
return fixes;
}
/**
* Suggest performance improvements
*/
async suggestPerformanceImprovements(metrics) {
const suggestions = [];
// Check query performance
if (metrics.averageQueryTime > 100) {
suggestions.push({
type: 'warning',
message: 'Slow query performance detected',
fix: 'Enable SuperMode or add indexes for frequently queried fields',
confidence: 0.8,
category: 'performance'
});
}
// Check cache hit rate
if (metrics.cacheHitRate < 0.5) {
suggestions.push({
type: 'info',
message: 'Low cache hit rate',
fix: 'Enable caching or optimize query patterns',
confidence: 0.7,
category: 'performance'
});
}
// Check storage efficiency
if (metrics.storageEfficiency < 0.8) {
suggestions.push({
type: 'info',
message: 'Storage efficiency can be improved',
fix: 'Enable compression or clean up unused data',
confidence: 0.6,
category: 'performance'
});
}
return suggestions;
}
/**
* Suggest security improvements
*/
async suggestSecurityImprovements() {
return [
{
type: 'warning',
message: 'Token permissions should be reviewed',
fix: 'Ensure token has minimal required permissions (repo scope)',
confidence: 0.8,
category: 'security'
},
{
type: 'info',
message: 'Consider using environment variables for tokens',
fix: 'Store tokens in .env file or use gitdb set token <token>',
confidence: 0.7,
category: 'security'
}
];
}
/**
* Generate command from natural language
*/
async generateCommand(prompt, context) {
const normalizedPrompt = prompt.toLowerCase();
// Simple command mapping
const commandMap = {
'show all': 'show docs',
'list all': 'show docs',
'find users': 'findone {"name":"user"}',
'add user': 'insert {"name":"user","age":25}',
'update user': 'update <id> {"field":"value"}',
'delete user': 'delete <id>',
'count users': 'count',
'show collections': 'show collections',
'use users': 'use users',
'create users': 'create-collection users',
'rollback': 'rollback <collection>',
'enable performance': 'supermode enable',
'generate summary': 'summarize',
'check health': 'doctor'
};
for (const [key, command] of Object.entries(commandMap)) {
if (normalizedPrompt.includes(key)) {
return command;
}
}
return 'help';
}
/**
* Learn from user corrections
*/
async learnFromCorrection(originalQuery, userCorrection) {
try {
const learningPath = path.join(process.env.HOME || process.env.USERPROFILE || '', '.gitdb', 'ai-learning.json');
const learningData = await this.loadLearningData(learningPath);
learningData.corrections.push({
original: originalQuery,
correction: userCorrection,
timestamp: new Date().toISOString()
});
await this.saveLearningData(learningPath, learningData);
}
catch (error) {
console.warn('Failed to save learning data:', error);
}
}
/**
* Load learning data
*/
async loadLearningData(path) {
try {
const data = await fs.readFile(path, 'utf8');
return JSON.parse(data);
}
catch (error) {
return { corrections: [] };
}
}
/**
* Save learning data
*/
async saveLearningData(filePath, data) {
try {
const dir = path.dirname(filePath);
await fs.mkdir(dir, { recursive: true });
await fs.writeFile(filePath, JSON.stringify(data, null, 2));
}
catch (error) {
console.warn('Failed to save learning data:', error);
}
}
}
//# sourceMappingURL=auto-fix.js.map