UNPKG

gitdb-database

Version:

A production-ready CLI tool for managing a NoSQL database using GitHub repositories as storage

441 lines (440 loc) 15.9 kB
import { Octokit } from '@octokit/rest'; export class AIDiagnostics { octokit; owner; repo; token; constructor(token, owner, repo) { this.octokit = new Octokit({ auth: token }); this.owner = owner; this.repo = repo; this.token = token; } /** * Run comprehensive health check */ async runHealthCheck() { const checks = [ { name: 'GitHub API Connection', description: 'Verify GitHub API connectivity and authentication', check: () => this.checkGitHubConnection() }, { name: 'Repository Access', description: 'Check repository access and permissions', check: () => this.checkRepositoryAccess() }, { name: 'Token Permissions', description: 'Verify token has required permissions', check: () => this.checkTokenPermissions() }, { name: 'Rate Limit Status', description: 'Check GitHub API rate limit usage', check: () => this.checkRateLimits() }, { name: 'Data Integrity', description: 'Verify data consistency and structure', check: () => this.checkDataIntegrity() }, { name: 'Performance Metrics', description: 'Analyze performance and optimization opportunities', check: () => this.checkPerformance() } ]; const results = []; for (const check of checks) { try { const result = await check.check(); results.push(result); } catch (error) { results.push({ status: 'error', category: check.name, message: `Check failed: ${error.message}`, severity: 'critical' }); } } return results; } /** * Check GitHub API connection */ async checkGitHubConnection() { try { await this.octokit.rest.meta.get(); return { status: 'healthy', category: 'GitHub API Connection', message: '✅ Successfully connected to GitHub API', severity: 'low' }; } catch (error) { return { status: 'error', category: 'GitHub API Connection', message: `❌ Failed to connect to GitHub API: ${error.message}`, recommendation: 'Check your internet connection and GitHub API status', severity: 'critical' }; } } /** * Check repository access */ async checkRepositoryAccess() { try { await this.octokit.repos.get({ owner: this.owner, repo: this.repo }); return { status: 'healthy', category: 'Repository Access', message: `✅ Successfully accessed repository: ${this.owner}/${this.repo}`, severity: 'low' }; } catch (error) { const errorMessage = error.message; if (errorMessage.includes('Not Found')) { return { status: 'error', category: 'Repository Access', message: `❌ Repository not found: ${this.owner}/${this.repo}`, recommendation: 'Verify repository name and owner, ensure repository exists', severity: 'critical' }; } else if (errorMessage.includes('Forbidden')) { return { status: 'error', category: 'Repository Access', message: `❌ Access denied to repository: ${this.owner}/${this.repo}`, recommendation: 'Check token permissions and repository visibility settings', severity: 'critical' }; } else { return { status: 'error', category: 'Repository Access', message: `❌ Repository access error: ${errorMessage}`, severity: 'high' }; } } } /** * Check token permissions */ async checkTokenPermissions() { try { // Test write permission by attempting to get content await this.octokit.repos.getContent({ owner: this.owner, repo: this.repo, path: 'collections' }); return { status: 'healthy', category: 'Token Permissions', message: '✅ Token has required read/write permissions', severity: 'low' }; } catch (error) { const errorMessage = error.message; if (errorMessage.includes('Forbidden')) { return { status: 'error', category: 'Token Permissions', message: '❌ Token lacks required permissions', recommendation: 'Ensure token has repo scope permissions', severity: 'critical' }; } else if (errorMessage.includes('Not Found')) { // This might be normal for empty databases return { status: 'warning', category: 'Token Permissions', message: `⚠️ Permission check warning: ${errorMessage}`, recommendation: 'Database appears to be empty (no collections directory found)', severity: 'low' }; } else { return { status: 'warning', category: 'Token Permissions', message: `⚠️ Permission check warning: ${errorMessage}`, severity: 'medium' }; } } } /** * Check rate limits */ async checkRateLimits() { try { const rateLimit = await this.octokit.rest.rateLimit.get(); const remaining = rateLimit.data.resources.core.remaining; const limit = rateLimit.data.resources.core.limit; const resetTime = new Date(rateLimit.data.resources.core.reset * 1000); const usagePercentage = ((limit - remaining) / limit) * 100; if (usagePercentage > 90) { return { status: 'error', category: 'Rate Limit Status', message: `❌ Rate limit nearly exceeded: ${remaining}/${limit} remaining`, recommendation: `Rate limit resets at ${resetTime.toLocaleString()}. Consider optimizing API usage.`, severity: 'high' }; } else if (usagePercentage > 70) { return { status: 'warning', category: 'Rate Limit Status', message: `⚠️ Rate limit usage high: ${remaining}/${limit} remaining`, recommendation: 'Monitor API usage to avoid rate limiting', severity: 'medium' }; } else { return { status: 'healthy', category: 'Rate Limit Status', message: `✅ Rate limit healthy: ${remaining}/${limit} remaining`, severity: 'low' }; } } catch (error) { return { status: 'warning', category: 'Rate Limit Status', message: `⚠️ Could not check rate limits: ${error.message}`, severity: 'medium' }; } } /** * Check data integrity */ async checkDataIntegrity() { try { const collections = await this.getCollections(); let issues = 0; const problems = []; for (const collection of collections) { try { const data = await this.getCollectionData(collection); // Check if data is valid JSON if (typeof data !== 'object' || data === null) { issues++; problems.push(`${collection}: Invalid data structure`); } // Check for empty collections if (Array.isArray(data) && data.length === 0) { problems.push(`${collection}: Empty collection`); } } catch (error) { issues++; problems.push(`${collection}: ${error.message}`); } } if (issues === 0) { return { status: 'healthy', category: 'Data Integrity', message: `✅ All ${collections.length} collections have valid data structure`, severity: 'low' }; } else { return { status: 'warning', category: 'Data Integrity', message: `⚠️ Found ${issues} data integrity issues`, recommendation: `Issues: ${problems.join(', ')}. Consider running data repair.`, severity: 'medium' }; } } catch (error) { return { status: 'error', category: 'Data Integrity', message: `❌ Data integrity check failed: ${error.message}`, severity: 'high' }; } } /** * Check performance metrics */ async checkPerformance() { try { const collections = await this.getCollections(); const totalDocuments = await this.getTotalDocuments(collections); let recommendations = []; let warnings = 0; // Check for large collections if (totalDocuments > 1000) { warnings++; recommendations.push('Consider enabling SuperMode for better performance'); } // Check for many collections if (collections.length > 10) { warnings++; recommendations.push('Consider consolidating collections for better organization'); } // Check for potential optimization opportunities const largeCollections = collections.filter(c => { try { const data = this.getCollectionData(c); return Array.isArray(data) && data.length > 100; } catch { return false; } }); if (largeCollections.length > 3) { warnings++; recommendations.push('Multiple large collections detected - consider indexing strategies'); } if (warnings === 0) { return { status: 'healthy', category: 'Performance Metrics', message: `✅ Performance is optimal (${totalDocuments} documents across ${collections.length} collections)`, severity: 'low' }; } else { return { status: 'warning', category: 'Performance Metrics', message: `⚠️ ${warnings} performance optimization opportunities detected`, recommendation: recommendations.join('. '), severity: 'medium' }; } } catch (error) { return { status: 'error', category: 'Performance Metrics', message: `❌ Performance check failed: ${error.message}`, severity: 'high' }; } } /** * Get list of collections */ async getCollections() { try { const response = await this.octokit.repos.getContent({ owner: this.owner, repo: this.repo, path: 'collections' }); if (!Array.isArray(response.data)) { return []; } return response.data .filter(item => item.type === 'dir') .map(item => item.name); } catch (error) { return []; } } /** * Get collection data */ async getCollectionData(collectionName) { try { const response = await this.octokit.repos.getContent({ owner: this.owner, repo: this.repo, path: `collections/${collectionName}/data.json` }); if ('content' in response.data) { const content = Buffer.from(response.data.content, 'base64').toString(); return JSON.parse(content); } return null; } catch (error) { throw new Error(`Failed to get collection data: ${error.message}`); } } /** * Get total document count */ async getTotalDocuments(collections) { let total = 0; for (const collection of collections) { try { const data = await this.getCollectionData(collection); if (Array.isArray(data)) { total += data.length; } } catch (error) { // Skip collections that can't be read continue; } } return total; } /** * Generate diagnostic report */ async generateReport() { const results = await this.runHealthCheck(); const healthy = results.filter(r => r.status === 'healthy').length; const warnings = results.filter(r => r.status === 'warning').length; const errors = results.filter(r => r.status === 'error').length; let report = `🔍 GitDB Diagnostic Report ===================================== 📊 Summary: ✅ Healthy: ${healthy} ⚠️ Warnings: ${warnings} ❌ Errors: ${errors} 📈 Overall Status: ${errors > 0 ? '❌ Needs Attention' : warnings > 0 ? '⚠️ Good with Warnings' : '✅ Excellent'} 📋 Detailed Results: `; for (const result of results) { const icon = result.status === 'healthy' ? '✅' : result.status === 'warning' ? '⚠️' : '❌'; report += `${icon} ${result.category}: ${result.message}\n`; if (result.recommendation) { report += ` 💡 Recommendation: ${result.recommendation}\n`; } report += '\n'; } if (errors === 0 && warnings === 0) { report += '🎉 All systems are healthy! Your GitDB instance is running optimally.'; } else if (errors > 0) { report += '🚨 Critical issues detected. Please address the errors above before continuing.'; } else { report += '📝 Consider addressing the warnings above for optimal performance.'; } return report; } } //# sourceMappingURL=diagnostics.js.map