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
JavaScript
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