baseguard 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/base.js +115 -1
- package/package.json +2 -2
- package/src/commands/config.ts +92 -0
- package/src/commands/index.ts +2 -1
- package/src/commands/status.ts +307 -0
- package/src/core/baseguard.ts +36 -22
- package/src/core/configuration-recovery.ts +3 -6
- package/src/core/system-error-handler.ts +9 -5
package/bin/base.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import chalk from 'chalk';
|
|
5
|
-
import { init, check, fix, config, automation } from '../dist/commands/index.js';
|
|
5
|
+
import { init, check, fix, config, automation, status, diagnostics } from '../dist/commands/index.js';
|
|
6
6
|
import { showTerminalHeader, showVersionInfo, showGlobalHelp } from '../dist/ui/index.js';
|
|
7
7
|
import { StartupOptimizer } from '../dist/core/startup-optimizer.js';
|
|
8
8
|
|
|
@@ -84,6 +84,8 @@ program
|
|
|
84
84
|
.option('--strict', 'Exit with error code if violations are found (useful for CI/CD)')
|
|
85
85
|
.option('--files <pattern>', 'File pattern to check using glob syntax', '**/*.{js,jsx,ts,tsx,vue,svelte,css,html}')
|
|
86
86
|
.option('--format <format>', 'Output format for results', 'table')
|
|
87
|
+
.option('--debug', 'Enable debug logging for troubleshooting')
|
|
88
|
+
.option('--offline', 'Run in offline mode (no network requests)')
|
|
87
89
|
.addHelpText('after', `
|
|
88
90
|
${chalk.cyan('Output Formats:')}
|
|
89
91
|
${chalk.white('table')} Human-readable table format (default)
|
|
@@ -280,6 +282,39 @@ ${chalk.cyan('Automation Settings:')}
|
|
|
280
282
|
`)
|
|
281
283
|
.action(() => config('automation'));
|
|
282
284
|
|
|
285
|
+
configCmd
|
|
286
|
+
.command('recover')
|
|
287
|
+
.description('Attempt automatic recovery of corrupted configuration')
|
|
288
|
+
.option('--backup', 'Create backup before recovery')
|
|
289
|
+
.option('--interactive', 'Run interactive recovery wizard')
|
|
290
|
+
.addHelpText('after', `
|
|
291
|
+
${chalk.cyan('Recovery Features:')}
|
|
292
|
+
• Automatic detection of configuration issues
|
|
293
|
+
• Repair of corrupted JSON syntax
|
|
294
|
+
• Migration from older configuration versions
|
|
295
|
+
• Validation and structure repair
|
|
296
|
+
• Backup creation before changes
|
|
297
|
+
|
|
298
|
+
${chalk.cyan('Recovery Process:')}
|
|
299
|
+
1. Validates current configuration
|
|
300
|
+
2. Creates backup if requested
|
|
301
|
+
3. Attempts automatic repair
|
|
302
|
+
4. Migrates to current version
|
|
303
|
+
5. Validates final result
|
|
304
|
+
|
|
305
|
+
${chalk.cyan('Examples:')}
|
|
306
|
+
${chalk.dim('
|
|
307
|
+
</content>
|
|
308
|
+
</file>)} base config recover ${chalk.gray('# Automatic recovery')}
|
|
309
|
+
${chalk.dim('
|
|
310
|
+
</content>
|
|
311
|
+
</file>)} base config recover --backup ${chalk.gray('# Create backup first')}
|
|
312
|
+
${chalk.dim('
|
|
313
|
+
</content>
|
|
314
|
+
</file>)} base config recover --interactive ${chalk.gray('# Interactive wizard')}
|
|
315
|
+
`)
|
|
316
|
+
.action((options) => config('recover', options));
|
|
317
|
+
|
|
283
318
|
// Automation and git hooks
|
|
284
319
|
const autoCmd = program
|
|
285
320
|
.command('automation')
|
|
@@ -421,6 +456,85 @@ ${chalk.cyan('Examples:')}
|
|
|
421
456
|
`)
|
|
422
457
|
.action((options) => config('list', options));
|
|
423
458
|
|
|
459
|
+
// System status and health
|
|
460
|
+
program
|
|
461
|
+
.command('status')
|
|
462
|
+
.description('Show BaseGuard system status and health information')
|
|
463
|
+
.option('--verbose', 'Show detailed status information')
|
|
464
|
+
.option('--services', 'Check external service availability')
|
|
465
|
+
.option('--config', 'Show configuration status and validation')
|
|
466
|
+
.option('--errors', 'Show error summary and recent issues')
|
|
467
|
+
.addHelpText('after', `
|
|
468
|
+
${chalk.cyan('Status Information:')}
|
|
469
|
+
• Overall system health (healthy/degraded/critical)
|
|
470
|
+
• Component status (configuration, services, errors)
|
|
471
|
+
• Current degradation mode and limitations
|
|
472
|
+
• Service availability (network, APIs)
|
|
473
|
+
• Configuration validation results
|
|
474
|
+
• Error summary and recent issues
|
|
475
|
+
• Performance information
|
|
476
|
+
• Recovery recommendations
|
|
477
|
+
|
|
478
|
+
${chalk.cyan('Examples:')}
|
|
479
|
+
${chalk.dim('
|
|
480
|
+
</content>
|
|
481
|
+
</file>)} base status ${chalk.gray('# Show basic system status')}
|
|
482
|
+
${chalk.dim('
|
|
483
|
+
</content>
|
|
484
|
+
</file>)} base status --verbose ${chalk.gray('# Show detailed information')}
|
|
485
|
+
${chalk.dim('
|
|
486
|
+
</content>
|
|
487
|
+
</file>)} base status --services ${chalk.gray('# Check service availability')}
|
|
488
|
+
${chalk.dim('
|
|
489
|
+
</content>
|
|
490
|
+
</file>)} base status --config ${chalk.gray('# Show configuration status')}
|
|
491
|
+
${chalk.dim('
|
|
492
|
+
</content>
|
|
493
|
+
</file>)} base status --errors ${chalk.gray('# Show error information')}
|
|
494
|
+
|
|
495
|
+
${chalk.cyan('Health Levels:')}
|
|
496
|
+
${chalk.green('✅ Healthy')} All systems operational
|
|
497
|
+
${chalk.yellow('⚠️ Degraded')} Some features limited
|
|
498
|
+
${chalk.red('❌ Critical')} Major issues detected
|
|
499
|
+
`)
|
|
500
|
+
.action(async (options) => {
|
|
501
|
+
await startupPromise;
|
|
502
|
+
return status(options);
|
|
503
|
+
});
|
|
504
|
+
|
|
505
|
+
// System diagnostics
|
|
506
|
+
program
|
|
507
|
+
.command('diagnostics')
|
|
508
|
+
.alias('diag')
|
|
509
|
+
.description('Run comprehensive system diagnostics and recovery')
|
|
510
|
+
.addHelpText('after', `
|
|
511
|
+
${chalk.cyan('Diagnostic Features:')}
|
|
512
|
+
• Generate detailed debug report
|
|
513
|
+
• Run configuration recovery wizard
|
|
514
|
+
• Check service availability
|
|
515
|
+
• Show error log summary
|
|
516
|
+
• Clean up old files and caches
|
|
517
|
+
• Provide recovery recommendations
|
|
518
|
+
|
|
519
|
+
${chalk.cyan('What this does:')}
|
|
520
|
+
1. Creates comprehensive debug report
|
|
521
|
+
2. Attempts automatic configuration recovery
|
|
522
|
+
3. Checks all external services
|
|
523
|
+
4. Analyzes error logs for patterns
|
|
524
|
+
5. Cleans up temporary files
|
|
525
|
+
6. Provides actionable recommendations
|
|
526
|
+
|
|
527
|
+
${chalk.cyan('Use when:')}
|
|
528
|
+
• BaseGuard is not working correctly
|
|
529
|
+
• You're experiencing frequent errors
|
|
530
|
+
• Need to troubleshoot issues
|
|
531
|
+
• Want to optimize performance
|
|
532
|
+
`)
|
|
533
|
+
.action(async () => {
|
|
534
|
+
await startupPromise;
|
|
535
|
+
return diagnostics();
|
|
536
|
+
});
|
|
537
|
+
|
|
424
538
|
// Add version command with detailed info
|
|
425
539
|
program
|
|
426
540
|
.command('version')
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "baseguard",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "BaseGuard - Never ship incompatible code again. Intelligent browser compatibility enforcement with AI-powered analysis and autonomous fixing.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -77,4 +77,4 @@
|
|
|
77
77
|
"url": "https://github.com/ebuka1017/baseguard/issues"
|
|
78
78
|
},
|
|
79
79
|
"homepage": "https://github.com/ebuka1017/baseguard#readme"
|
|
80
|
-
}
|
|
80
|
+
}
|
package/src/commands/config.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { UIComponents, Prompts } from '../ui/index.js';
|
|
2
2
|
import { ConfigurationManager, ApiKeyManager, GitignoreManager } from '../core/index.js';
|
|
3
|
+
import { ConfigurationRecovery } from '../core/configuration-recovery.js';
|
|
3
4
|
import { ErrorHandler } from '../core/error-handler.js';
|
|
5
|
+
import chalk from 'chalk';
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Manage BaseGuard configuration
|
|
@@ -11,6 +13,8 @@ export async function config(action: string, options?: {
|
|
|
11
13
|
preset?: string;
|
|
12
14
|
file?: string;
|
|
13
15
|
format?: string;
|
|
16
|
+
backup?: boolean;
|
|
17
|
+
interactive?: boolean;
|
|
14
18
|
}): Promise<void> {
|
|
15
19
|
try {
|
|
16
20
|
switch (action) {
|
|
@@ -44,6 +48,9 @@ export async function config(action: string, options?: {
|
|
|
44
48
|
case 'restore':
|
|
45
49
|
await restoreConfiguration(options?.file);
|
|
46
50
|
break;
|
|
51
|
+
case 'recover':
|
|
52
|
+
await recoverConfiguration(options);
|
|
53
|
+
break;
|
|
47
54
|
default:
|
|
48
55
|
UIComponents.showErrorBox(`Unknown config action: ${action}`);
|
|
49
56
|
showConfigHelp();
|
|
@@ -339,6 +346,89 @@ async function restoreConfiguration(backupFile?: string): Promise<void> {
|
|
|
339
346
|
}
|
|
340
347
|
}
|
|
341
348
|
|
|
349
|
+
async function recoverConfiguration(options?: { backup?: boolean; interactive?: boolean }): Promise<void> {
|
|
350
|
+
try {
|
|
351
|
+
console.log(chalk.cyan('🔧 BaseGuard Configuration Recovery\n'));
|
|
352
|
+
|
|
353
|
+
if (options?.interactive) {
|
|
354
|
+
// Run interactive recovery wizard
|
|
355
|
+
await ConfigurationRecovery.runRecoveryWizard();
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// Automatic recovery
|
|
360
|
+
console.log(chalk.cyan('Attempting automatic configuration recovery...'));
|
|
361
|
+
|
|
362
|
+
const recoveryResult = await ConfigurationRecovery.recoverConfiguration({
|
|
363
|
+
createBackup: options?.backup ?? true,
|
|
364
|
+
validateConfig: true,
|
|
365
|
+
migrateVersion: true,
|
|
366
|
+
repairCorruption: true,
|
|
367
|
+
useDefaults: true
|
|
368
|
+
});
|
|
369
|
+
|
|
370
|
+
if (recoveryResult.success) {
|
|
371
|
+
UIComponents.showSuccessBox('Configuration recovered successfully');
|
|
372
|
+
|
|
373
|
+
if (recoveryResult.backupCreated) {
|
|
374
|
+
console.log(chalk.dim(`Backup created: ${recoveryResult.backupCreated}`));
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if (recoveryResult.warnings.length > 0) {
|
|
378
|
+
console.log(chalk.yellow('\n⚠️ Recovery warnings:'));
|
|
379
|
+
recoveryResult.warnings.forEach(warning => {
|
|
380
|
+
console.log(chalk.yellow(` • ${warning}`));
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// Show recovered configuration
|
|
385
|
+
console.log(chalk.cyan('\n📋 Recovered Configuration:'));
|
|
386
|
+
if (recoveryResult.config) {
|
|
387
|
+
console.log(` Version: ${recoveryResult.config.version}`);
|
|
388
|
+
console.log(` Targets: ${recoveryResult.config.targets.length} browser(s)`);
|
|
389
|
+
console.log(` API Keys: Jules ${recoveryResult.config.apiKeys.jules ? '✓' : '✗'}, Gemini ${recoveryResult.config.apiKeys.gemini ? '✓' : '✗'}`);
|
|
390
|
+
console.log(` Automation: ${recoveryResult.config.automation.enabled ? 'Enabled' : 'Disabled'}`);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
} else {
|
|
394
|
+
UIComponents.showErrorBox('Configuration recovery failed');
|
|
395
|
+
|
|
396
|
+
console.log(chalk.red('\n❌ Recovery errors:'));
|
|
397
|
+
recoveryResult.errors.forEach(error => {
|
|
398
|
+
console.log(chalk.red(` • ${error}`));
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
console.log(chalk.cyan('\n💡 Manual recovery options:'));
|
|
402
|
+
console.log(chalk.cyan(' • Run "base config recover --interactive" for guided recovery'));
|
|
403
|
+
console.log(chalk.cyan(' • Run "base init" to create a fresh configuration'));
|
|
404
|
+
console.log(chalk.cyan(' • Manually edit .baseguardrc.json file'));
|
|
405
|
+
console.log(chalk.cyan(' • Restore from backup if available'));
|
|
406
|
+
|
|
407
|
+
// Show available backups
|
|
408
|
+
const backups = await ConfigurationRecovery.listBackups();
|
|
409
|
+
if (backups.length > 0) {
|
|
410
|
+
console.log(chalk.cyan('\n📦 Available backups:'));
|
|
411
|
+
backups.slice(0, 3).forEach(backup => {
|
|
412
|
+
console.log(chalk.cyan(` • ${backup.timestamp.toLocaleString()} (${backup.source})`));
|
|
413
|
+
});
|
|
414
|
+
console.log(chalk.cyan('\n Use "base config restore --file <backup-file>" to restore'));
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
process.exit(1);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
} catch (error) {
|
|
421
|
+
UIComponents.showErrorBox(`Recovery process failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
422
|
+
|
|
423
|
+
console.log(chalk.cyan('\n🆘 Emergency recovery options:'));
|
|
424
|
+
console.log(chalk.cyan(' • Delete .baseguardrc.json and run "base init"'));
|
|
425
|
+
console.log(chalk.cyan(' • Check file permissions in your project directory'));
|
|
426
|
+
console.log(chalk.cyan(' • Run "base diagnostics" for comprehensive troubleshooting'));
|
|
427
|
+
|
|
428
|
+
process.exit(1);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
342
432
|
function showConfigHelp(): void {
|
|
343
433
|
UIComponents.showSectionHeader('Configuration Commands');
|
|
344
434
|
UIComponents.showList([
|
|
@@ -356,6 +446,8 @@ function showConfigHelp(): void {
|
|
|
356
446
|
'base config security - Check configuration security',
|
|
357
447
|
'base config backup - Create configuration backup',
|
|
358
448
|
'base config restore --file <backup> - Restore from backup',
|
|
449
|
+
'base config recover - Attempt automatic configuration recovery',
|
|
450
|
+
'base config recover --interactive - Run interactive recovery wizard',
|
|
359
451
|
'',
|
|
360
452
|
'Shorthand commands:',
|
|
361
453
|
'base add "chrome 100" - Add browser target',
|
package/src/commands/index.ts
CHANGED
package/src/commands/status.ts
CHANGED
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { BaseGuard } from '../core/baseguard.js';
|
|
2
|
+
import { ConfigurationManager } from '../core/configuration.js';
|
|
3
|
+
import { ConfigurationRecovery } from '../core/configuration-recovery.js';
|
|
4
|
+
import { GracefulDegradationManager } from '../core/graceful-degradation-manager.js';
|
|
5
|
+
import { SystemErrorHandler } from '../core/system-error-handler.js';
|
|
6
|
+
import { logger } from '../core/debug-logger.js';
|
|
7
|
+
import { UIComponents } from '../ui/components.js';
|
|
8
|
+
import chalk from 'chalk';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Show BaseGuard system status and health
|
|
12
|
+
*/
|
|
13
|
+
export async function status(options: {
|
|
14
|
+
verbose?: boolean;
|
|
15
|
+
services?: boolean;
|
|
16
|
+
config?: boolean;
|
|
17
|
+
errors?: boolean;
|
|
18
|
+
}): Promise<void> {
|
|
19
|
+
const categoryLogger = logger.createCategoryLogger('status-command');
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
UIComponents.showHeader();
|
|
23
|
+
console.log(chalk.cyan('🔍 BaseGuard System Status\n'));
|
|
24
|
+
|
|
25
|
+
// Load configuration with recovery if needed
|
|
26
|
+
let config;
|
|
27
|
+
try {
|
|
28
|
+
config = await ConfigurationManager.load();
|
|
29
|
+
} catch (error) {
|
|
30
|
+
console.log(chalk.red('❌ Configuration Error'));
|
|
31
|
+
console.log(chalk.dim(` ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
32
|
+
|
|
33
|
+
if (options.config) {
|
|
34
|
+
console.log(chalk.cyan('\n🔧 Configuration Recovery Options:'));
|
|
35
|
+
console.log(chalk.cyan(' • Run "base config recover" to attempt automatic recovery'));
|
|
36
|
+
console.log(chalk.cyan(' • Run "base init" to create a new configuration'));
|
|
37
|
+
console.log(chalk.cyan(' • Check .baseguardrc.json file manually'));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Initialize BaseGuard
|
|
44
|
+
const baseGuard = new BaseGuard(config);
|
|
45
|
+
|
|
46
|
+
// Show system health
|
|
47
|
+
const health = await baseGuard.getHealthStatus();
|
|
48
|
+
|
|
49
|
+
// Overall status
|
|
50
|
+
const statusIcon = health.overall === 'healthy' ? '✅' : health.overall === 'degraded' ? '⚠️' : '❌';
|
|
51
|
+
const statusColor = health.overall === 'healthy' ? chalk.green : health.overall === 'degraded' ? chalk.yellow : chalk.red;
|
|
52
|
+
|
|
53
|
+
console.log(statusColor(`${statusIcon} Overall Status: ${health.overall.toUpperCase()}`));
|
|
54
|
+
console.log(chalk.dim(` Degradation Mode: ${health.degradationMode}`));
|
|
55
|
+
|
|
56
|
+
// Component status
|
|
57
|
+
console.log(chalk.cyan('\n📊 Component Status:'));
|
|
58
|
+
for (const [component, status] of Object.entries(health.components)) {
|
|
59
|
+
const componentIcon = status.status === 'healthy' ? '✅' : status.status === 'degraded' ? '⚠️' : '❌';
|
|
60
|
+
console.log(` ${componentIcon} ${component}: ${status.status}`);
|
|
61
|
+
|
|
62
|
+
if (options.verbose && status.details) {
|
|
63
|
+
if (status.details.errors?.length > 0) {
|
|
64
|
+
console.log(chalk.dim(` Errors: ${status.details.errors.slice(0, 3).join(', ')}`));
|
|
65
|
+
}
|
|
66
|
+
if (status.details.error) {
|
|
67
|
+
console.log(chalk.dim(` Error: ${status.details.error}`));
|
|
68
|
+
}
|
|
69
|
+
if (status.details.lastCheck) {
|
|
70
|
+
const age = Math.round((Date.now() - status.details.lastCheck) / 1000);
|
|
71
|
+
console.log(chalk.dim(` Last Check: ${age}s ago`));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Service status (if requested)
|
|
77
|
+
if (options.services) {
|
|
78
|
+
console.log(chalk.cyan('\n🌐 Service Status:'));
|
|
79
|
+
const serviceStatus = GracefulDegradationManager.getServiceStatus();
|
|
80
|
+
|
|
81
|
+
for (const [service, info] of serviceStatus) {
|
|
82
|
+
const serviceIcon = info.available ? '✅' : '❌';
|
|
83
|
+
const age = Math.round((Date.now() - info.lastCheck) / 1000);
|
|
84
|
+
console.log(` ${serviceIcon} ${service}: ${info.available ? 'Available' : 'Unavailable'} (${age}s ago)`);
|
|
85
|
+
|
|
86
|
+
if (!info.available && info.error && options.verbose) {
|
|
87
|
+
console.log(chalk.dim(` Error: ${info.error}`));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Refresh service status
|
|
92
|
+
console.log(chalk.dim('\n🔄 Refreshing service status...'));
|
|
93
|
+
await GracefulDegradationManager.refreshServiceStatus();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Configuration status (if requested)
|
|
97
|
+
if (options.config) {
|
|
98
|
+
console.log(chalk.cyan('\n⚙️ Configuration Status:'));
|
|
99
|
+
|
|
100
|
+
const configIntegrity = await ConfigurationRecovery.validateIntegrity();
|
|
101
|
+
const configIcon = configIntegrity.valid ? '✅' : '❌';
|
|
102
|
+
console.log(` ${configIcon} Configuration File: ${configIntegrity.valid ? 'Valid' : 'Invalid'}`);
|
|
103
|
+
|
|
104
|
+
if (!configIntegrity.valid) {
|
|
105
|
+
console.log(chalk.red(' Errors:'));
|
|
106
|
+
configIntegrity.errors.forEach(error => {
|
|
107
|
+
console.log(chalk.red(` • ${error}`));
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
console.log(chalk.cyan(' Suggestions:'));
|
|
111
|
+
configIntegrity.suggestions.forEach(suggestion => {
|
|
112
|
+
console.log(chalk.cyan(` • ${suggestion}`));
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Show configuration details
|
|
117
|
+
if (options.verbose) {
|
|
118
|
+
console.log(chalk.dim('\n Configuration Details:'));
|
|
119
|
+
console.log(chalk.dim(` Version: ${config.version}`));
|
|
120
|
+
console.log(chalk.dim(` Targets: ${config.targets.length} browser(s)`));
|
|
121
|
+
console.log(chalk.dim(` API Keys: Jules ${config.apiKeys.jules ? '✓' : '✗'}, Gemini ${config.apiKeys.gemini ? '✓' : '✗'}`));
|
|
122
|
+
console.log(chalk.dim(` Automation: ${config.automation.enabled ? 'Enabled' : 'Disabled'}`));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Show available backups
|
|
126
|
+
const backups = await ConfigurationRecovery.listBackups();
|
|
127
|
+
if (backups.length > 0) {
|
|
128
|
+
console.log(chalk.dim(`\n Available Backups: ${backups.length}`));
|
|
129
|
+
if (options.verbose) {
|
|
130
|
+
backups.slice(0, 3).forEach(backup => {
|
|
131
|
+
console.log(chalk.dim(` • ${backup.timestamp.toLocaleString()} (${backup.source})`));
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Error summary (if requested)
|
|
138
|
+
if (options.errors) {
|
|
139
|
+
console.log(chalk.cyan('\n🚨 Error Summary:'));
|
|
140
|
+
|
|
141
|
+
const errorSummary = logger.getErrorSummary();
|
|
142
|
+
console.log(` Total Errors: ${errorSummary.totalErrors}`);
|
|
143
|
+
console.log(` Total Warnings: ${errorSummary.totalWarnings}`);
|
|
144
|
+
|
|
145
|
+
if (errorSummary.totalErrors > 0) {
|
|
146
|
+
console.log(chalk.red('\n Error Categories:'));
|
|
147
|
+
for (const [category, count] of Object.entries(errorSummary.errorsByCategory)) {
|
|
148
|
+
console.log(chalk.red(` ${category}: ${count}`));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (options.verbose && errorSummary.recentErrors.length > 0) {
|
|
152
|
+
console.log(chalk.red('\n Recent Errors:'));
|
|
153
|
+
errorSummary.recentErrors.slice(0, 3).forEach(error => {
|
|
154
|
+
console.log(chalk.red(` • ${error.message} (${error.category})`));
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// System error handler status
|
|
160
|
+
const systemErrorSummary = SystemErrorHandler.getErrorSummary();
|
|
161
|
+
if (systemErrorSummary.total > 0) {
|
|
162
|
+
console.log(chalk.yellow('\n System Errors:'));
|
|
163
|
+
console.log(` Total: ${systemErrorSummary.total}`);
|
|
164
|
+
console.log(` Critical: ${systemErrorSummary.critical}`);
|
|
165
|
+
console.log(` Recoverable: ${systemErrorSummary.recoverable}`);
|
|
166
|
+
|
|
167
|
+
if (options.verbose) {
|
|
168
|
+
console.log(chalk.yellow('\n By Severity:'));
|
|
169
|
+
for (const [severity, count] of Object.entries(systemErrorSummary.bySeverity)) {
|
|
170
|
+
if (count > 0) {
|
|
171
|
+
console.log(` ${severity}: ${count}`);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Recommendations
|
|
179
|
+
if (health.recommendations.length > 0) {
|
|
180
|
+
console.log(chalk.cyan('\n💡 Recommendations:'));
|
|
181
|
+
health.recommendations.forEach(rec => {
|
|
182
|
+
console.log(chalk.cyan(` • ${rec}`));
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Show degradation mode details
|
|
187
|
+
const mode = GracefulDegradationManager.getCurrentMode();
|
|
188
|
+
if (mode && mode.name !== 'Full Functionality') {
|
|
189
|
+
console.log(chalk.yellow(`\n⚠️ Currently in ${mode.name} Mode`));
|
|
190
|
+
console.log(chalk.dim(` ${mode.description}`));
|
|
191
|
+
|
|
192
|
+
if (mode.limitations.length > 0) {
|
|
193
|
+
console.log(chalk.yellow('\n Limitations:'));
|
|
194
|
+
mode.limitations.forEach(limitation => {
|
|
195
|
+
console.log(chalk.yellow(` • ${limitation}`));
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
console.log(chalk.cyan('\n Available Features:'));
|
|
200
|
+
if (mode.capabilities.baselineChecking) {
|
|
201
|
+
console.log(chalk.green(' ✅ Baseline compatibility checking'));
|
|
202
|
+
}
|
|
203
|
+
if (mode.capabilities.caching) {
|
|
204
|
+
console.log(chalk.green(' ✅ Result caching'));
|
|
205
|
+
}
|
|
206
|
+
if (!mode.capabilities.aiAnalysis) {
|
|
207
|
+
console.log(chalk.yellow(' ⚠️ AI analysis disabled'));
|
|
208
|
+
}
|
|
209
|
+
if (!mode.capabilities.autoFix) {
|
|
210
|
+
console.log(chalk.yellow(' ⚠️ Auto-fixing disabled'));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// Performance info
|
|
215
|
+
if (options.verbose) {
|
|
216
|
+
const memoryUsage = process.memoryUsage();
|
|
217
|
+
const uptime = process.uptime();
|
|
218
|
+
|
|
219
|
+
console.log(chalk.cyan('\n📈 Performance Info:'));
|
|
220
|
+
console.log(` Uptime: ${Math.round(uptime)}s`);
|
|
221
|
+
console.log(` Memory: ${Math.round(memoryUsage.heapUsed / 1024 / 1024)}MB used / ${Math.round(memoryUsage.heapTotal / 1024 / 1024)}MB total`);
|
|
222
|
+
console.log(` Platform: ${process.platform} ${process.arch}`);
|
|
223
|
+
console.log(` Node.js: ${process.version}`);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Quick actions
|
|
227
|
+
console.log(chalk.cyan('\n🔧 Quick Actions:'));
|
|
228
|
+
const actions = [];
|
|
229
|
+
|
|
230
|
+
if (health.overall !== 'healthy') {
|
|
231
|
+
actions.push('Run "base config recover" to attempt automatic recovery');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
if (!mode?.capabilities.aiAnalysis) {
|
|
235
|
+
actions.push('Check network connectivity to restore AI features');
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const errorSummary = logger.getErrorSummary();
|
|
239
|
+
if (errorSummary.totalErrors > 5) {
|
|
240
|
+
actions.push('Run with --errors flag to see detailed error information');
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
actions.push('Run "base check" to scan for compatibility issues');
|
|
244
|
+
actions.push('Run "base status --verbose" for detailed information');
|
|
245
|
+
|
|
246
|
+
actions.forEach(action => {
|
|
247
|
+
console.log(chalk.cyan(` • ${action}`));
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
} catch (error) {
|
|
251
|
+
categoryLogger.error('Status command failed', { error });
|
|
252
|
+
|
|
253
|
+
console.log(chalk.red('\n❌ Failed to get system status'));
|
|
254
|
+
console.log(chalk.red(` Error: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
255
|
+
|
|
256
|
+
console.log(chalk.cyan('\n🔧 Recovery Options:'));
|
|
257
|
+
console.log(chalk.cyan(' • Run "base init" to reinitialize BaseGuard'));
|
|
258
|
+
console.log(chalk.cyan(' • Check file permissions in your project directory'));
|
|
259
|
+
console.log(chalk.cyan(' • Verify BaseGuard installation: npm list baseguard'));
|
|
260
|
+
|
|
261
|
+
process.exit(1);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Show detailed system diagnostics
|
|
267
|
+
*/
|
|
268
|
+
export async function diagnostics(): Promise<void> {
|
|
269
|
+
const categoryLogger = logger.createCategoryLogger('diagnostics');
|
|
270
|
+
|
|
271
|
+
try {
|
|
272
|
+
console.log(chalk.cyan('🔬 BaseGuard System Diagnostics\n'));
|
|
273
|
+
|
|
274
|
+
// Generate comprehensive debug report
|
|
275
|
+
const reportFile = await logger.generateDebugReport();
|
|
276
|
+
console.log(chalk.green(`✅ Debug report generated: ${reportFile}`));
|
|
277
|
+
|
|
278
|
+
// Show configuration recovery wizard
|
|
279
|
+
console.log(chalk.cyan('\n🔧 Running Configuration Recovery Wizard...'));
|
|
280
|
+
await ConfigurationRecovery.runRecoveryWizard();
|
|
281
|
+
|
|
282
|
+
// Show service status
|
|
283
|
+
console.log(chalk.cyan('\n🌐 Checking Service Availability...'));
|
|
284
|
+
await GracefulDegradationManager.refreshServiceStatus();
|
|
285
|
+
|
|
286
|
+
// Show error log summary
|
|
287
|
+
const loggerErrorSummary = logger.getErrorSummary();
|
|
288
|
+
if (loggerErrorSummary.totalErrors > 0) {
|
|
289
|
+
console.log(chalk.yellow(`\n⚠️ Found ${loggerErrorSummary.totalErrors} errors in logs`));
|
|
290
|
+
console.log(chalk.cyan('Recent errors:'));
|
|
291
|
+
loggerErrorSummary.recentErrors.slice(0, 5).forEach(error => {
|
|
292
|
+
console.log(chalk.red(` • ${error.message} (${error.category})`));
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Cleanup old files
|
|
297
|
+
console.log(chalk.cyan('\n🧹 Cleaning up old files...'));
|
|
298
|
+
await logger.cleanupOldLogs();
|
|
299
|
+
await GracefulDegradationManager.cleanupCache();
|
|
300
|
+
|
|
301
|
+
console.log(chalk.green('\n✅ Diagnostics completed'));
|
|
302
|
+
|
|
303
|
+
} catch (error) {
|
|
304
|
+
categoryLogger.error('Diagnostics failed', { error });
|
|
305
|
+
console.log(chalk.red(`\n❌ Diagnostics failed: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
306
|
+
}
|
|
307
|
+
}
|
package/src/core/baseguard.ts
CHANGED
|
@@ -16,11 +16,11 @@ import chalk from 'chalk';
|
|
|
16
16
|
*/
|
|
17
17
|
export class BaseGuard {
|
|
18
18
|
private config: Configuration;
|
|
19
|
-
private parserManager
|
|
20
|
-
private baselineChecker
|
|
21
|
-
private fileProcessor
|
|
22
|
-
private directoryFilter
|
|
23
|
-
private cacheManager
|
|
19
|
+
private parserManager!: ParserManager;
|
|
20
|
+
private baselineChecker!: BaselineChecker;
|
|
21
|
+
private fileProcessor!: FileProcessor;
|
|
22
|
+
private directoryFilter!: DirectoryFilter;
|
|
23
|
+
private cacheManager!: CacheManager;
|
|
24
24
|
private categoryLogger: ReturnType<typeof logger.createCategoryLogger>;
|
|
25
25
|
private initialized = false;
|
|
26
26
|
|
|
@@ -28,8 +28,10 @@ export class BaseGuard {
|
|
|
28
28
|
this.config = config;
|
|
29
29
|
this.categoryLogger = logger.createCategoryLogger('baseguard');
|
|
30
30
|
|
|
31
|
-
// Initialize with error handling
|
|
32
|
-
this.initializeComponents()
|
|
31
|
+
// Initialize with error handling (async initialization)
|
|
32
|
+
this.initializeComponents().catch(error => {
|
|
33
|
+
this.categoryLogger.error('Failed to initialize BaseGuard', { error });
|
|
34
|
+
});
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
/**
|
|
@@ -43,9 +45,9 @@ export class BaseGuard {
|
|
|
43
45
|
await GracefulDegradationManager.initialize();
|
|
44
46
|
|
|
45
47
|
// Initialize components with error handling
|
|
46
|
-
await SystemErrorHandler.handleGracefully(
|
|
48
|
+
this.cacheManager = await SystemErrorHandler.handleGracefully(
|
|
47
49
|
async () => {
|
|
48
|
-
|
|
50
|
+
return new CacheManager({
|
|
49
51
|
maxCacheSize: parseInt(process.env.BASEGUARD_CACHE_SIZE || '2000'),
|
|
50
52
|
cacheValidityMs: 10 * 60 * 1000 // 10 minutes
|
|
51
53
|
});
|
|
@@ -54,17 +56,17 @@ export class BaseGuard {
|
|
|
54
56
|
{ operation: 'cache_manager_init' }
|
|
55
57
|
);
|
|
56
58
|
|
|
57
|
-
await SystemErrorHandler.handleGracefully(
|
|
59
|
+
this.parserManager = await SystemErrorHandler.handleGracefully(
|
|
58
60
|
async () => {
|
|
59
|
-
|
|
61
|
+
return new ParserManager();
|
|
60
62
|
},
|
|
61
63
|
new ParserManager(),
|
|
62
64
|
{ operation: 'parser_manager_init' }
|
|
63
65
|
);
|
|
64
66
|
|
|
65
|
-
await SystemErrorHandler.handleGracefully(
|
|
67
|
+
this.baselineChecker = await SystemErrorHandler.handleGracefully(
|
|
66
68
|
async () => {
|
|
67
|
-
|
|
69
|
+
return new BaselineChecker();
|
|
68
70
|
},
|
|
69
71
|
new BaselineChecker(),
|
|
70
72
|
{ operation: 'baseline_checker_init' }
|
|
@@ -73,9 +75,9 @@ export class BaseGuard {
|
|
|
73
75
|
const maxWorkers = parseInt(process.env.BASEGUARD_MAX_WORKERS || '8');
|
|
74
76
|
const maxFiles = parseInt(process.env.BASEGUARD_MAX_FILES || '5000');
|
|
75
77
|
|
|
76
|
-
await SystemErrorHandler.handleGracefully(
|
|
78
|
+
this.fileProcessor = await SystemErrorHandler.handleGracefully(
|
|
77
79
|
async () => {
|
|
78
|
-
|
|
80
|
+
return new FileProcessor({
|
|
79
81
|
maxWorkers,
|
|
80
82
|
cacheManager: this.cacheManager
|
|
81
83
|
});
|
|
@@ -84,9 +86,9 @@ export class BaseGuard {
|
|
|
84
86
|
{ operation: 'file_processor_init' }
|
|
85
87
|
);
|
|
86
88
|
|
|
87
|
-
await SystemErrorHandler.handleGracefully(
|
|
89
|
+
this.directoryFilter = await SystemErrorHandler.handleGracefully(
|
|
88
90
|
async () => {
|
|
89
|
-
|
|
91
|
+
return new DirectoryFilter({
|
|
90
92
|
maxDepth: 8,
|
|
91
93
|
maxFiles
|
|
92
94
|
});
|
|
@@ -167,7 +169,7 @@ export class BaseGuard {
|
|
|
167
169
|
try {
|
|
168
170
|
const compatibilityResult = await SystemErrorHandler.handleGracefully(
|
|
169
171
|
() => this.baselineChecker.checkCompatibility(feature, this.config.targets),
|
|
170
|
-
{ violations: [] }, // fallback result
|
|
172
|
+
{ violations: [], featureData: null }, // fallback result
|
|
171
173
|
{
|
|
172
174
|
operation: 'check_compatibility',
|
|
173
175
|
file: feature.file,
|
|
@@ -340,7 +342,10 @@ export class BaseGuard {
|
|
|
340
342
|
try {
|
|
341
343
|
// Cleanup file processor
|
|
342
344
|
await SystemErrorHandler.handleGracefully(
|
|
343
|
-
() =>
|
|
345
|
+
async () => {
|
|
346
|
+
await this.fileProcessor.cleanup();
|
|
347
|
+
return undefined;
|
|
348
|
+
},
|
|
344
349
|
undefined,
|
|
345
350
|
{ operation: 'file_processor_cleanup' },
|
|
346
351
|
{ logError: false, showWarning: false }
|
|
@@ -348,7 +353,10 @@ export class BaseGuard {
|
|
|
348
353
|
|
|
349
354
|
// Clear caches
|
|
350
355
|
await SystemErrorHandler.handleGracefully(
|
|
351
|
-
() =>
|
|
356
|
+
async () => {
|
|
357
|
+
this.cacheManager.clearAll();
|
|
358
|
+
return undefined;
|
|
359
|
+
},
|
|
352
360
|
undefined,
|
|
353
361
|
{ operation: 'cache_cleanup' },
|
|
354
362
|
{ logError: false, showWarning: false }
|
|
@@ -356,7 +364,10 @@ export class BaseGuard {
|
|
|
356
364
|
|
|
357
365
|
// Cleanup graceful degradation manager
|
|
358
366
|
await SystemErrorHandler.handleGracefully(
|
|
359
|
-
() =>
|
|
367
|
+
async () => {
|
|
368
|
+
await GracefulDegradationManager.cleanupCache();
|
|
369
|
+
return undefined;
|
|
370
|
+
},
|
|
360
371
|
undefined,
|
|
361
372
|
{ operation: 'degradation_cleanup' },
|
|
362
373
|
{ logError: false, showWarning: false }
|
|
@@ -364,7 +375,10 @@ export class BaseGuard {
|
|
|
364
375
|
|
|
365
376
|
// Cleanup old logs
|
|
366
377
|
await SystemErrorHandler.handleGracefully(
|
|
367
|
-
() =>
|
|
378
|
+
async () => {
|
|
379
|
+
await logger.cleanupOldLogs();
|
|
380
|
+
return undefined;
|
|
381
|
+
},
|
|
368
382
|
undefined,
|
|
369
383
|
{ operation: 'log_cleanup' },
|
|
370
384
|
{ logError: false, showWarning: false }
|
|
@@ -131,9 +131,8 @@ export class ConfigurationRecovery {
|
|
|
131
131
|
// Step 6: Final validation and save
|
|
132
132
|
if (currentConfig) {
|
|
133
133
|
try {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
currentConfig as Configuration;
|
|
134
|
+
// Use the public migrateConfiguration method instead
|
|
135
|
+
const finalConfig = ConfigurationManager.migrateConfiguration(currentConfig);
|
|
137
136
|
|
|
138
137
|
await ConfigurationManager.save(finalConfig);
|
|
139
138
|
result.config = finalConfig;
|
|
@@ -454,9 +453,7 @@ export class ConfigurationRecovery {
|
|
|
454
453
|
}
|
|
455
454
|
|
|
456
455
|
// Perform migration
|
|
457
|
-
const migratedConfig = ConfigurationManager.migrateConfiguration
|
|
458
|
-
ConfigurationManager.migrateConfiguration(config) :
|
|
459
|
-
config;
|
|
456
|
+
const migratedConfig = ConfigurationManager.migrateConfiguration(config);
|
|
460
457
|
|
|
461
458
|
return {
|
|
462
459
|
migrated: true,
|
|
@@ -30,8 +30,12 @@ export class SystemError extends Error {
|
|
|
30
30
|
super(message);
|
|
31
31
|
this.name = 'SystemError';
|
|
32
32
|
this.context = {
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
operation: context?.operation || 'unknown',
|
|
34
|
+
file: context?.file,
|
|
35
|
+
line: context?.line,
|
|
36
|
+
details: context?.details,
|
|
37
|
+
timestamp: new Date(),
|
|
38
|
+
userId: context?.userId
|
|
35
39
|
};
|
|
36
40
|
}
|
|
37
41
|
}
|
|
@@ -110,7 +114,7 @@ export class SystemErrorHandler {
|
|
|
110
114
|
}
|
|
111
115
|
|
|
112
116
|
if (showWarning) {
|
|
113
|
-
console.warn(chalk.yellow(`⚠️ ${context.operation} failed: ${error.message}`));
|
|
117
|
+
console.warn(chalk.yellow(`⚠️ ${context.operation} failed: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
114
118
|
}
|
|
115
119
|
|
|
116
120
|
// Attempt recovery if enabled
|
|
@@ -254,7 +258,7 @@ export class SystemErrorHandler {
|
|
|
254
258
|
return true;
|
|
255
259
|
}
|
|
256
260
|
} catch (recoveryError) {
|
|
257
|
-
console.log(chalk.dim(` Recovery failed: ${recoveryError.message}`));
|
|
261
|
+
console.log(chalk.dim(` Recovery failed: ${recoveryError instanceof Error ? recoveryError.message : 'Unknown error'}`));
|
|
258
262
|
}
|
|
259
263
|
}
|
|
260
264
|
|
|
@@ -414,7 +418,7 @@ export class SystemErrorHandler {
|
|
|
414
418
|
await fs.writeFile(logPath, JSON.stringify(logData, null, 2));
|
|
415
419
|
console.log(chalk.dim(`Error log saved to: ${logPath}`));
|
|
416
420
|
} catch (writeError) {
|
|
417
|
-
console.warn(chalk.yellow(`Failed to save error log: ${writeError.message}`));
|
|
421
|
+
console.warn(chalk.yellow(`Failed to save error log: ${writeError instanceof Error ? writeError.message : 'Unknown error'}`));
|
|
418
422
|
}
|
|
419
423
|
}
|
|
420
424
|
|