baseguard 1.0.3 → 1.0.5

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.
Files changed (169) hide show
  1. package/.baseguardrc.example.json +63 -63
  2. package/.eslintrc.json +24 -24
  3. package/.prettierrc +7 -7
  4. package/CHANGELOG.md +195 -195
  5. package/DEPLOYMENT.md +624 -624
  6. package/DEPLOYMENT_CHECKLIST.md +239 -239
  7. package/DEPLOYMENT_SUMMARY_v1.0.2.md +202 -202
  8. package/QUICK_START.md +134 -134
  9. package/README.md +488 -488
  10. package/RELEASE_NOTES_v1.0.2.md +434 -434
  11. package/bin/base.js +627 -627
  12. package/dist/ai/fix-manager.d.ts.map +1 -1
  13. package/dist/ai/fix-manager.js +1 -1
  14. package/dist/ai/fix-manager.js.map +1 -1
  15. package/dist/ai/gemini-analyzer.d.ts.map +1 -1
  16. package/dist/ai/gemini-analyzer.js +29 -35
  17. package/dist/ai/gemini-analyzer.js.map +1 -1
  18. package/dist/ai/gemini-code-fixer.d.ts.map +1 -1
  19. package/dist/ai/gemini-code-fixer.js +58 -58
  20. package/dist/ai/gemini-code-fixer.js.map +1 -1
  21. package/dist/ai/jules-implementer.d.ts +3 -0
  22. package/dist/ai/jules-implementer.d.ts.map +1 -1
  23. package/dist/ai/jules-implementer.js +63 -32
  24. package/dist/ai/jules-implementer.js.map +1 -1
  25. package/dist/ai/unified-code-fixer.js.map +1 -1
  26. package/dist/commands/check.d.ts.map +1 -1
  27. package/dist/commands/check.js +1 -1
  28. package/dist/commands/check.js.map +1 -1
  29. package/dist/commands/config.js +2 -1
  30. package/dist/commands/config.js.map +1 -1
  31. package/dist/commands/fix.d.ts.map +1 -1
  32. package/dist/commands/fix.js +48 -15
  33. package/dist/commands/fix.js.map +1 -1
  34. package/dist/core/api-key-manager.js +2 -2
  35. package/dist/core/api-key-manager.js.map +1 -1
  36. package/dist/core/baseguard.d.ts +1 -0
  37. package/dist/core/baseguard.d.ts.map +1 -1
  38. package/dist/core/baseguard.js +13 -10
  39. package/dist/core/baseguard.js.map +1 -1
  40. package/dist/core/baseline-checker.d.ts.map +1 -1
  41. package/dist/core/baseline-checker.js +8 -5
  42. package/dist/core/baseline-checker.js.map +1 -1
  43. package/dist/core/configuration-recovery.d.ts.map +1 -1
  44. package/dist/core/configuration-recovery.js +1 -1
  45. package/dist/core/configuration-recovery.js.map +1 -1
  46. package/dist/core/debug-logger.d.ts.map +1 -1
  47. package/dist/core/debug-logger.js +1 -1
  48. package/dist/core/debug-logger.js.map +1 -1
  49. package/dist/core/error-handler.d.ts.map +1 -1
  50. package/dist/core/error-handler.js +2 -1
  51. package/dist/core/error-handler.js.map +1 -1
  52. package/dist/core/gitignore-manager.js +5 -5
  53. package/dist/core/graceful-degradation-manager.d.ts.map +1 -1
  54. package/dist/core/graceful-degradation-manager.js +16 -16
  55. package/dist/core/graceful-degradation-manager.js.map +1 -1
  56. package/dist/core/lazy-loader.d.ts.map +1 -1
  57. package/dist/core/lazy-loader.js +9 -2
  58. package/dist/core/lazy-loader.js.map +1 -1
  59. package/dist/core/memory-manager.d.ts +0 -3
  60. package/dist/core/memory-manager.d.ts.map +1 -1
  61. package/dist/core/memory-manager.js.map +1 -1
  62. package/dist/core/parser-worker.d.ts +2 -0
  63. package/dist/core/parser-worker.d.ts.map +1 -0
  64. package/dist/core/parser-worker.js +19 -0
  65. package/dist/core/parser-worker.js.map +1 -0
  66. package/dist/core/startup-optimizer.d.ts.map +1 -1
  67. package/dist/core/startup-optimizer.js +4 -8
  68. package/dist/core/startup-optimizer.js.map +1 -1
  69. package/dist/core/system-error-handler.d.ts.map +1 -1
  70. package/dist/core/system-error-handler.js.map +1 -1
  71. package/dist/git/automation-engine.d.ts.map +1 -1
  72. package/dist/git/automation-engine.js +5 -4
  73. package/dist/git/automation-engine.js.map +1 -1
  74. package/dist/git/github-manager.d.ts.map +1 -1
  75. package/dist/git/github-manager.js.map +1 -1
  76. package/dist/git/hook-manager.js +5 -5
  77. package/dist/git/hook-manager.js.map +1 -1
  78. package/dist/parsers/parser-manager.d.ts.map +1 -1
  79. package/dist/parsers/parser-manager.js +1 -1
  80. package/dist/parsers/parser-manager.js.map +1 -1
  81. package/dist/parsers/svelte-parser.js +1 -1
  82. package/dist/parsers/svelte-parser.js.map +1 -1
  83. package/dist/parsers/vanilla-parser.d.ts.map +1 -1
  84. package/dist/parsers/vanilla-parser.js.map +1 -1
  85. package/dist/parsers/vue-parser.d.ts.map +1 -1
  86. package/dist/parsers/vue-parser.js.map +1 -1
  87. package/dist/ui/components.d.ts +1 -1
  88. package/dist/ui/components.d.ts.map +1 -1
  89. package/dist/ui/components.js +11 -11
  90. package/dist/ui/components.js.map +1 -1
  91. package/dist/ui/terminal-header.js +14 -14
  92. package/package.json +105 -105
  93. package/src/ai/__tests__/gemini-analyzer.test.ts +180 -180
  94. package/src/ai/agentkit-orchestrator.ts +533 -533
  95. package/src/ai/fix-manager.ts +362 -362
  96. package/src/ai/gemini-analyzer.ts +665 -671
  97. package/src/ai/gemini-code-fixer.ts +539 -540
  98. package/src/ai/index.ts +3 -3
  99. package/src/ai/jules-implementer.ts +504 -460
  100. package/src/ai/unified-code-fixer.ts +347 -347
  101. package/src/commands/automation.ts +343 -343
  102. package/src/commands/check.ts +298 -299
  103. package/src/commands/config.ts +584 -583
  104. package/src/commands/fix.ts +269 -238
  105. package/src/commands/index.ts +6 -6
  106. package/src/commands/init.ts +155 -155
  107. package/src/commands/status.ts +306 -306
  108. package/src/core/api-key-manager.ts +298 -298
  109. package/src/core/baseguard.ts +757 -756
  110. package/src/core/baseline-checker.ts +566 -563
  111. package/src/core/cache-manager.ts +271 -271
  112. package/src/core/configuration-recovery.ts +672 -673
  113. package/src/core/configuration.ts +595 -595
  114. package/src/core/debug-logger.ts +590 -590
  115. package/src/core/directory-filter.ts +420 -420
  116. package/src/core/error-handler.ts +518 -517
  117. package/src/core/file-processor.ts +337 -337
  118. package/src/core/gitignore-manager.ts +168 -168
  119. package/src/core/graceful-degradation-manager.ts +596 -596
  120. package/src/core/index.ts +16 -16
  121. package/src/core/lazy-loader.ts +317 -307
  122. package/src/core/memory-manager.ts +290 -295
  123. package/src/core/parser-worker.ts +33 -0
  124. package/src/core/startup-optimizer.ts +246 -255
  125. package/src/core/system-error-handler.ts +755 -756
  126. package/src/git/automation-engine.ts +361 -361
  127. package/src/git/github-manager.ts +190 -192
  128. package/src/git/hook-manager.ts +210 -210
  129. package/src/git/index.ts +3 -3
  130. package/src/index.ts +7 -7
  131. package/src/parsers/feature-validator.ts +558 -558
  132. package/src/parsers/index.ts +7 -7
  133. package/src/parsers/parser-manager.ts +418 -419
  134. package/src/parsers/parser.ts +25 -25
  135. package/src/parsers/react-parser-optimized.ts +160 -160
  136. package/src/parsers/react-parser.ts +358 -358
  137. package/src/parsers/svelte-parser.ts +510 -510
  138. package/src/parsers/vanilla-parser.ts +685 -686
  139. package/src/parsers/vue-parser.ts +476 -478
  140. package/src/types/index.ts +95 -95
  141. package/src/ui/components.ts +567 -567
  142. package/src/ui/help.ts +192 -192
  143. package/src/ui/index.ts +3 -3
  144. package/src/ui/prompts.ts +680 -680
  145. package/src/ui/terminal-header.ts +58 -58
  146. package/test-build.js +40 -40
  147. package/test-config-commands.js +55 -55
  148. package/test-header-simple.js +32 -32
  149. package/test-terminal-header.js +11 -11
  150. package/test-ui.js +28 -28
  151. package/tests/e2e/baseguard.e2e.test.ts +515 -515
  152. package/tests/e2e/cross-platform.e2e.test.ts +419 -419
  153. package/tests/e2e/git-integration.e2e.test.ts +486 -486
  154. package/tests/fixtures/react-project/package.json +13 -13
  155. package/tests/fixtures/react-project/src/App.css +75 -75
  156. package/tests/fixtures/react-project/src/App.tsx +76 -76
  157. package/tests/fixtures/svelte-project/package.json +10 -10
  158. package/tests/fixtures/svelte-project/src/App.svelte +368 -368
  159. package/tests/fixtures/vanilla-project/index.html +75 -75
  160. package/tests/fixtures/vanilla-project/script.js +330 -330
  161. package/tests/fixtures/vanilla-project/styles.css +358 -358
  162. package/tests/fixtures/vue-project/package.json +11 -11
  163. package/tests/fixtures/vue-project/src/App.vue +215 -215
  164. package/tmp-smoke/.baseguard/backups/config-2026-02-19T12-04-11-067Z-auto.json +30 -0
  165. package/tmp-smoke/src/bad.css +3 -0
  166. package/tsconfig.json +34 -34
  167. package/vitest.config.ts +11 -11
  168. package/dist/terminal-header.d.ts +0 -12
  169. package/dist/terminal-header.js +0 -45
@@ -1,756 +1,757 @@
1
- import type { Violation, Analysis, Fix, Configuration } from '../types/index.js';
2
- import { ParserManager } from '../parsers/parser-manager.js';
3
- import { BaselineChecker } from './baseline-checker.js';
4
- import { FileProcessor } from './file-processor.js';
5
- import { DirectoryFilter } from './directory-filter.js';
6
- import { CacheManager } from './cache-manager.js';
7
- import { SystemErrorHandler } from './system-error-handler.js';
8
- import { GracefulDegradationManager } from './graceful-degradation-manager.js';
9
- import { ConfigurationRecovery } from './configuration-recovery.js';
10
- import { logger } from './debug-logger.js';
11
- import { ErrorHandler, APIError } from './error-handler.js';
12
- import chalk from 'chalk';
13
-
14
- /**
15
- * Main BaseGuard class that orchestrates compatibility checking and fixing
16
- */
17
- export class BaseGuard {
18
- private config: Configuration;
19
- private parserManager!: ParserManager;
20
- private baselineChecker!: BaselineChecker;
21
- private fileProcessor!: FileProcessor;
22
- private directoryFilter!: DirectoryFilter;
23
- private cacheManager!: CacheManager;
24
- private categoryLogger: ReturnType<typeof logger.createCategoryLogger>;
25
- private initialized = false;
26
-
27
- constructor(config: Configuration) {
28
- this.config = config;
29
- this.categoryLogger = logger.createCategoryLogger('baseguard');
30
-
31
- // Initialize with error handling (async initialization)
32
- this.initializeComponents().catch(error => {
33
- this.categoryLogger.error('Failed to initialize BaseGuard', { error });
34
- });
35
- }
36
-
37
- /**
38
- * Initialize BaseGuard components with error recovery
39
- */
40
- private async initializeComponents(): Promise<void> {
41
- try {
42
- this.categoryLogger.info('Initializing BaseGuard components');
43
-
44
- // Initialize graceful degradation manager
45
- await GracefulDegradationManager.initialize();
46
-
47
- // Initialize components with error handling
48
- this.cacheManager = await SystemErrorHandler.handleGracefully(
49
- async () => {
50
- return new CacheManager({
51
- maxCacheSize: parseInt(process.env.BASEGUARD_CACHE_SIZE || '2000'),
52
- cacheValidityMs: 10 * 60 * 1000 // 10 minutes
53
- });
54
- },
55
- new CacheManager({ maxCacheSize: 1000, cacheValidityMs: 5 * 60 * 1000 }),
56
- { operation: 'cache_manager_init' }
57
- );
58
-
59
- this.parserManager = await SystemErrorHandler.handleGracefully(
60
- async () => {
61
- return new ParserManager();
62
- },
63
- new ParserManager(),
64
- { operation: 'parser_manager_init' }
65
- );
66
-
67
- this.baselineChecker = await SystemErrorHandler.handleGracefully(
68
- async () => {
69
- return new BaselineChecker();
70
- },
71
- new BaselineChecker(),
72
- { operation: 'baseline_checker_init' }
73
- );
74
-
75
- const maxWorkers = parseInt(process.env.BASEGUARD_MAX_WORKERS || '8');
76
- const maxFiles = parseInt(process.env.BASEGUARD_MAX_FILES || '5000');
77
-
78
- this.fileProcessor = await SystemErrorHandler.handleGracefully(
79
- async () => {
80
- return new FileProcessor({
81
- maxWorkers,
82
- cacheManager: this.cacheManager
83
- });
84
- },
85
- new FileProcessor({ maxWorkers: 2, cacheManager: this.cacheManager }),
86
- { operation: 'file_processor_init' }
87
- );
88
-
89
- this.directoryFilter = await SystemErrorHandler.handleGracefully(
90
- async () => {
91
- return new DirectoryFilter({
92
- maxDepth: 8,
93
- maxFiles
94
- });
95
- },
96
- new DirectoryFilter({ maxDepth: 4, maxFiles: 1000 }),
97
- { operation: 'directory_filter_init' }
98
- );
99
-
100
- this.initialized = true;
101
- this.categoryLogger.info('BaseGuard components initialized successfully');
102
-
103
- } catch (error) {
104
- this.categoryLogger.error('Failed to initialize BaseGuard components', { error });
105
- throw new Error(`BaseGuard initialization failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
106
- }
107
- }
108
-
109
- /**
110
- * Ensure BaseGuard is properly initialized
111
- */
112
- private async ensureInitialized(): Promise<void> {
113
- if (!this.initialized) {
114
- await this.initializeComponents();
115
- }
116
- }
117
-
118
- /**
119
- * Check files for compatibility violations with enhanced error recovery
120
- */
121
- async checkViolations(patterns: string[] = []): Promise<Violation[]> {
122
- await this.ensureInitialized();
123
-
124
- const sessionId = logger.startSession('check-violations');
125
- this.categoryLogger.startPerformance('check-violations');
126
-
127
- try {
128
- const violations: Violation[] = [];
129
-
130
- // Find files using smart filtering and caching with error recovery
131
- const allFiles = await SystemErrorHandler.withRetry(
132
- async () => {
133
- return patterns.length > 0
134
- ? await this.directoryFilter.findFilesWithGlob(patterns)
135
- : await this.directoryFilter.findFiles(['src', 'app', 'pages', 'components'], {
136
- includeHidden: false
137
- });
138
- },
139
- { operation: 'find_files', details: { patterns } },
140
- 3 // max retries
141
- );
142
-
143
- if (allFiles.length === 0) {
144
- this.categoryLogger.warn('No supported files found to check', { patterns });
145
- return violations;
146
- }
147
-
148
- this.categoryLogger.info(`Processing ${allFiles.length} files for violations`);
149
-
150
- // Process files concurrently with caching and error recovery
151
- const allFeatures = await SystemErrorHandler.handleGracefully(
152
- () => this.fileProcessor.processFiles(allFiles),
153
- [], // fallback to empty array
154
- { operation: 'process_files', details: { fileCount: allFiles.length } },
155
- {
156
- logError: true,
157
- showWarning: true,
158
- attemptRecovery: true
159
- }
160
- );
161
-
162
- this.categoryLogger.info(`Extracted ${allFeatures.length} features from ${allFiles.length} files`);
163
-
164
- // Check each feature for compatibility violations with error recovery
165
- let processedFeatures = 0;
166
- let failedFeatures = 0;
167
-
168
- for (const feature of allFeatures) {
169
- try {
170
- const compatibilityResult = await SystemErrorHandler.handleGracefully(
171
- () => this.baselineChecker.checkCompatibility(feature, this.config.targets),
172
- { violations: [], featureData: null }, // fallback result
173
- {
174
- operation: 'check_compatibility',
175
- file: feature.file,
176
- details: { feature: feature.feature }
177
- }
178
- );
179
-
180
- // Add violations with file context
181
- for (const violation of compatibilityResult.violations) {
182
- violations.push({
183
- ...violation,
184
- file: feature.file || 'unknown',
185
- line: feature.line,
186
- column: feature.column,
187
- context: feature.context
188
- });
189
- }
190
-
191
- processedFeatures++;
192
- } catch (error) {
193
- failedFeatures++;
194
- this.categoryLogger.warn('Failed to check feature compatibility', {
195
- feature: feature.feature,
196
- file: feature.file,
197
- error: error instanceof Error ? error.message : 'Unknown error'
198
- });
199
-
200
- // Continue processing other features
201
- continue;
202
- }
203
- }
204
-
205
- const duration = this.categoryLogger.endPerformance('check-violations', {
206
- totalFiles: allFiles.length,
207
- processedFeatures,
208
- failedFeatures,
209
- violationsFound: violations.length
210
- });
211
-
212
- this.categoryLogger.info('Violation check completed', {
213
- duration,
214
- totalFiles: allFiles.length,
215
- processedFeatures,
216
- failedFeatures,
217
- violationsFound: violations.length
218
- });
219
-
220
- return violations;
221
-
222
- } catch (error) {
223
- this.categoryLogger.error('Violation check failed', { error });
224
-
225
- // Try graceful degradation
226
- const mode = GracefulDegradationManager.getCurrentMode();
227
- if (mode?.capabilities.baselineChecking) {
228
- this.categoryLogger.info('Attempting graceful degradation for violation checking');
229
-
230
- try {
231
- // Simplified violation checking with minimal features
232
- const basicViolations = await this.performBasicViolationCheck(patterns);
233
- this.categoryLogger.info('Graceful degradation successful', { violationsFound: basicViolations.length });
234
- return basicViolations;
235
- } catch (degradationError) {
236
- this.categoryLogger.error('Graceful degradation also failed', { error: degradationError });
237
- }
238
- }
239
-
240
- throw error;
241
- } finally {
242
- await logger.endSession();
243
- }
244
- }
245
-
246
- /**
247
- * Perform basic violation checking as fallback
248
- */
249
- private async performBasicViolationCheck(patterns: string[]): Promise<Violation[]> {
250
- const violations: Violation[] = [];
251
-
252
- try {
253
- // Use minimal file processing
254
- const basicFiles = patterns.length > 0 ? patterns : ['src/**/*.{js,ts,jsx,tsx,css,vue,svelte}'];
255
-
256
- // Simple file enumeration without complex processing
257
- const { glob } = await import('glob');
258
- const files = await glob(basicFiles.join(','), { ignore: ['node_modules/**', 'dist/**', 'build/**'] });
259
-
260
- this.categoryLogger.info(`Basic violation check on ${files.length} files`);
261
-
262
- // Process a limited number of files to avoid overwhelming the system
263
- const limitedFiles = files.slice(0, 100);
264
-
265
- for (const file of limitedFiles) {
266
- try {
267
- // Basic feature extraction without complex parsing
268
- const basicFeatures = await this.extractBasicFeatures(file);
269
-
270
- for (const feature of basicFeatures) {
271
- const result = await this.baselineChecker.checkCompatibility(feature, this.config.targets);
272
- violations.push(...result.violations);
273
- }
274
- } catch (error) {
275
- // Skip individual file errors in basic mode
276
- this.categoryLogger.debug('Skipped file in basic mode', { file, error: error instanceof Error ? error.message : 'Unknown error' });
277
- }
278
- }
279
-
280
- } catch (error) {
281
- this.categoryLogger.error('Basic violation check failed', { error });
282
- }
283
-
284
- return violations;
285
- }
286
-
287
- /**
288
- * Extract basic features without complex parsing
289
- */
290
- private async extractBasicFeatures(file: string): Promise<any[]> {
291
- // This is a simplified feature extraction for fallback mode
292
- // In a real implementation, this would do basic text pattern matching
293
- return [];
294
- }
295
-
296
- /**
297
- * Get processing statistics
298
- */
299
- async getProcessingStats(directories: string[] = ['src']): Promise<{
300
- directoryStats: any;
301
- processorStats: any;
302
- cacheStats: any;
303
- }> {
304
- const directoryStats = await Promise.all(
305
- directories.map(dir => this.directoryFilter.getDirectoryStats(dir))
306
- );
307
-
308
- return {
309
- directoryStats: directoryStats.reduce((acc, stats) => ({
310
- totalFiles: acc.totalFiles + stats.totalFiles,
311
- supportedFiles: acc.supportedFiles + stats.supportedFiles,
312
- directories: acc.directories + stats.directories,
313
- excludedDirectories: acc.excludedDirectories + stats.excludedDirectories,
314
- largestFiles: [...acc.largestFiles, ...stats.largestFiles]
315
- .sort((a, b) => b.size - a.size)
316
- .slice(0, 10)
317
- }), {
318
- totalFiles: 0,
319
- supportedFiles: 0,
320
- directories: 0,
321
- excludedDirectories: 0,
322
- largestFiles: []
323
- }),
324
- processorStats: this.fileProcessor.getStats(),
325
- cacheStats: this.cacheManager.getStats()
326
- };
327
- }
328
-
329
- /**
330
- * Clear all caches
331
- */
332
- clearCache(): void {
333
- this.cacheManager.clearAll();
334
- }
335
-
336
- /**
337
- * Cleanup resources with error handling
338
- */
339
- async cleanup(): Promise<void> {
340
- this.categoryLogger.info('Starting BaseGuard cleanup');
341
-
342
- try {
343
- // Cleanup file processor
344
- await SystemErrorHandler.handleGracefully(
345
- async () => {
346
- await this.fileProcessor.cleanup();
347
- return undefined;
348
- },
349
- undefined,
350
- { operation: 'file_processor_cleanup' },
351
- { logError: false, showWarning: false }
352
- );
353
-
354
- // Clear caches
355
- await SystemErrorHandler.handleGracefully(
356
- async () => {
357
- this.cacheManager.clearAll();
358
- return undefined;
359
- },
360
- undefined,
361
- { operation: 'cache_cleanup' },
362
- { logError: false, showWarning: false }
363
- );
364
-
365
- // Cleanup graceful degradation manager
366
- await SystemErrorHandler.handleGracefully(
367
- async () => {
368
- await GracefulDegradationManager.cleanupCache();
369
- return undefined;
370
- },
371
- undefined,
372
- { operation: 'degradation_cleanup' },
373
- { logError: false, showWarning: false }
374
- );
375
-
376
- // Cleanup old logs
377
- await SystemErrorHandler.handleGracefully(
378
- async () => {
379
- await logger.cleanupOldLogs();
380
- return undefined;
381
- },
382
- undefined,
383
- { operation: 'log_cleanup' },
384
- { logError: false, showWarning: false }
385
- );
386
-
387
- this.categoryLogger.info('BaseGuard cleanup completed');
388
-
389
- } catch (error) {
390
- this.categoryLogger.warn('Some cleanup operations failed', { error: error instanceof Error ? error.message : 'Unknown error' });
391
- }
392
- }
393
-
394
- /**
395
- * Create auto-backup of configuration
396
- */
397
- async createConfigBackup(): Promise<string | null> {
398
- try {
399
- return await ConfigurationRecovery.createAutoBackup();
400
- } catch (error) {
401
- this.categoryLogger.error('Failed to create config backup', { error });
402
- return null;
403
- }
404
- }
405
-
406
- /**
407
- * Show system status and health
408
- */
409
- async showSystemStatus(): Promise<void> {
410
- console.log(chalk.cyan('🔍 BaseGuard System Status\n'));
411
-
412
- const health = await this.getHealthStatus();
413
-
414
- // Overall status
415
- const statusIcon = health.overall === 'healthy' ? '✅' : health.overall === 'degraded' ? '⚠️' : '❌';
416
- const statusColor = health.overall === 'healthy' ? chalk.green : health.overall === 'degraded' ? chalk.yellow : chalk.red;
417
-
418
- console.log(statusColor(`${statusIcon} Overall Status: ${health.overall.toUpperCase()}`));
419
- console.log(chalk.dim(`Degradation Mode: ${health.degradationMode}\n`));
420
-
421
- // Component status
422
- console.log(chalk.cyan('📊 Component Status:'));
423
- for (const [component, status] of Object.entries(health.components)) {
424
- const componentIcon = status.status === 'healthy' ? '✅' : status.status === 'degraded' ? '⚠️' : '❌';
425
- console.log(` ${componentIcon} ${component}: ${status.status}`);
426
-
427
- if (status.details && status.status !== 'healthy') {
428
- if (status.details.errors?.length > 0) {
429
- console.log(chalk.dim(` Errors: ${status.details.errors.slice(0, 2).join(', ')}`));
430
- }
431
- if (status.details.error) {
432
- console.log(chalk.dim(` Error: ${status.details.error}`));
433
- }
434
- }
435
- }
436
-
437
- // Recommendations
438
- if (health.recommendations.length > 0) {
439
- console.log(chalk.cyan('\n💡 Recommendations:'));
440
- health.recommendations.forEach(rec => {
441
- console.log(chalk.cyan(` • ${rec}`));
442
- });
443
- }
444
-
445
- // Show degradation status
446
- GracefulDegradationManager.showStatus();
447
- }
448
-
449
- /**
450
- * Analyze violations using AI with graceful degradation
451
- */
452
- async analyzeViolations(violations: Violation[]): Promise<Analysis[]> {
453
- await this.ensureInitialized();
454
-
455
- const sessionId = logger.startSession('analyze-violations');
456
- this.categoryLogger.startPerformance('analyze-violations');
457
-
458
- try {
459
- const analyses: Analysis[] = [];
460
- const mode = GracefulDegradationManager.getCurrentMode();
461
-
462
- if (!mode?.capabilities.aiAnalysis) {
463
- this.categoryLogger.info('AI analysis disabled in current mode, using fallback analysis');
464
-
465
- // Create fallback analyses for all violations
466
- for (const violation of violations) {
467
- const fallbackAnalysis = GracefulDegradationManager.createFallbackAnalysis(
468
- violation,
469
- 'AI analysis unavailable in current mode'
470
- );
471
- analyses.push(fallbackAnalysis);
472
- }
473
-
474
- return analyses;
475
- }
476
-
477
- // Try to use cached analyses first
478
- for (const violation of violations) {
479
- const cached = await GracefulDegradationManager.loadCachedAnalysis(violation);
480
- if (cached) {
481
- analyses.push(cached);
482
- } else {
483
- // Will need AI analysis
484
- const fallbackAnalysis = GracefulDegradationManager.createFallbackAnalysis(
485
- violation,
486
- 'AI analysis not yet implemented'
487
- );
488
- analyses.push(fallbackAnalysis);
489
- }
490
- }
491
-
492
- const duration = this.categoryLogger.endPerformance('analyze-violations', {
493
- violationCount: violations.length,
494
- analysesCreated: analyses.length
495
- });
496
-
497
- this.categoryLogger.info('Violation analysis completed', {
498
- duration,
499
- violationCount: violations.length,
500
- analysesCreated: analyses.length
501
- });
502
-
503
- return analyses;
504
-
505
- } catch (error) {
506
- this.categoryLogger.error('Violation analysis failed', { error });
507
-
508
- // Fallback to basic analysis
509
- const fallbackAnalyses = violations.map(violation =>
510
- GracefulDegradationManager.createFallbackAnalysis(violation, 'Analysis failed, using fallback')
511
- );
512
-
513
- return fallbackAnalyses;
514
- } finally {
515
- await logger.endSession();
516
- }
517
- }
518
-
519
- /**
520
- * Generate fixes for violations with graceful degradation
521
- */
522
- async generateFixes(violations: Violation[], analyses: Analysis[]): Promise<Fix[]> {
523
- await this.ensureInitialized();
524
-
525
- const sessionId = logger.startSession('generate-fixes');
526
- this.categoryLogger.startPerformance('generate-fixes');
527
-
528
- try {
529
- const fixes: Fix[] = [];
530
- const mode = GracefulDegradationManager.getCurrentMode();
531
-
532
- if (!mode?.capabilities.autoFix) {
533
- this.categoryLogger.info('Auto-fix disabled in current mode, creating manual fix suggestions');
534
-
535
- // Create manual fix suggestions
536
- for (let i = 0; i < violations.length; i++) {
537
- const violation = violations[i];
538
- const analysis = analyses[i];
539
-
540
- if (violation && analysis) {
541
- const manualFix = GracefulDegradationManager.createBasicFixSuggestion(violation, analysis);
542
- fixes.push(manualFix);
543
- }
544
- }
545
-
546
- return fixes;
547
- }
548
-
549
- // Auto-fix would be implemented here when available
550
- this.categoryLogger.info('Auto-fix not yet implemented, creating manual suggestions');
551
-
552
- for (let i = 0; i < violations.length; i++) {
553
- const violation = violations[i];
554
- const analysis = analyses[i];
555
-
556
- if (violation && analysis) {
557
- const manualFix = GracefulDegradationManager.createBasicFixSuggestion(violation, analysis);
558
- fixes.push(manualFix);
559
- }
560
- }
561
-
562
- const duration = this.categoryLogger.endPerformance('generate-fixes', {
563
- violationCount: violations.length,
564
- fixesGenerated: fixes.length
565
- });
566
-
567
- this.categoryLogger.info('Fix generation completed', {
568
- duration,
569
- violationCount: violations.length,
570
- fixesGenerated: fixes.length
571
- });
572
-
573
- return fixes;
574
-
575
- } catch (error) {
576
- this.categoryLogger.error('Fix generation failed', { error });
577
- throw error;
578
- } finally {
579
- await logger.endSession();
580
- }
581
- }
582
-
583
- /**
584
- * Apply fixes to files with error recovery
585
- */
586
- async applyFixes(fixes: Fix[]): Promise<void> {
587
- await this.ensureInitialized();
588
-
589
- const sessionId = logger.startSession('apply-fixes');
590
- this.categoryLogger.startPerformance('apply-fixes');
591
-
592
- try {
593
- this.categoryLogger.info(`Applying ${fixes.length} fixes`);
594
-
595
- let appliedCount = 0;
596
- let failedCount = 0;
597
-
598
- for (const fix of fixes) {
599
- try {
600
- await SystemErrorHandler.withRetry(
601
- async () => {
602
- // Fix application would be implemented here
603
- this.categoryLogger.debug('Fix application not yet implemented', {
604
- file: fix.filePath,
605
- feature: fix.violation.feature
606
- });
607
-
608
- // For now, just log the fix that would be applied
609
- console.log(chalk.cyan(`Would apply fix for ${fix.violation.feature} in ${fix.filePath}`));
610
- },
611
- {
612
- operation: 'apply_fix',
613
- file: fix.filePath,
614
- details: { feature: fix.violation.feature }
615
- },
616
- 2 // max retries
617
- );
618
-
619
- appliedCount++;
620
- } catch (error) {
621
- failedCount++;
622
- this.categoryLogger.error('Failed to apply fix', {
623
- file: fix.filePath,
624
- feature: fix.violation.feature,
625
- error: error instanceof Error ? error.message : 'Unknown error'
626
- });
627
- }
628
- }
629
-
630
- const duration = this.categoryLogger.endPerformance('apply-fixes', {
631
- totalFixes: fixes.length,
632
- appliedCount,
633
- failedCount
634
- });
635
-
636
- this.categoryLogger.info('Fix application completed', {
637
- duration,
638
- totalFixes: fixes.length,
639
- appliedCount,
640
- failedCount
641
- });
642
-
643
- if (failedCount > 0) {
644
- console.log(chalk.yellow(`⚠️ ${failedCount} fixes failed to apply. Check logs for details.`));
645
- }
646
-
647
- } catch (error) {
648
- this.categoryLogger.error('Fix application process failed', { error });
649
- throw error;
650
- } finally {
651
- await logger.endSession();
652
- }
653
- }
654
-
655
- /**
656
- * Recover from configuration corruption
657
- */
658
- async recoverConfiguration(): Promise<Configuration> {
659
- this.categoryLogger.info('Attempting configuration recovery');
660
-
661
- const recoveryResult = await ConfigurationRecovery.recoverConfiguration({
662
- createBackup: true,
663
- validateConfig: true,
664
- migrateVersion: true,
665
- repairCorruption: true,
666
- useDefaults: true
667
- });
668
-
669
- if (recoveryResult.success && recoveryResult.config) {
670
- this.config = recoveryResult.config;
671
- this.categoryLogger.info('Configuration recovered successfully');
672
-
673
- if (recoveryResult.warnings.length > 0) {
674
- this.categoryLogger.warn('Configuration recovery warnings', { warnings: recoveryResult.warnings });
675
- }
676
-
677
- return this.config;
678
- } else {
679
- const error = new Error(`Configuration recovery failed: ${recoveryResult.errors.join(', ')}`);
680
- this.categoryLogger.error('Configuration recovery failed', { errors: recoveryResult.errors });
681
- throw error;
682
- }
683
- }
684
-
685
- /**
686
- * Get system health status
687
- */
688
- async getHealthStatus(): Promise<{
689
- overall: 'healthy' | 'degraded' | 'critical';
690
- components: Record<string, { status: string; details?: any }>;
691
- degradationMode: string;
692
- recommendations: string[];
693
- }> {
694
- const health = {
695
- overall: 'healthy' as 'healthy' | 'degraded' | 'critical',
696
- components: {} as Record<string, { status: string; details?: any }>,
697
- degradationMode: 'unknown',
698
- recommendations: [] as string[]
699
- };
700
-
701
- try {
702
- // Check configuration health
703
- const configIntegrity = await ConfigurationRecovery.validateIntegrity();
704
- health.components.configuration = {
705
- status: configIntegrity.valid ? 'healthy' : 'degraded',
706
- details: { errors: configIntegrity.errors, suggestions: configIntegrity.suggestions }
707
- };
708
-
709
- // Check degradation mode
710
- const mode = GracefulDegradationManager.getCurrentMode();
711
- health.degradationMode = mode?.name || 'unknown';
712
-
713
- if (mode?.name !== 'Full Functionality') {
714
- health.overall = 'degraded';
715
- health.recommendations.push(`Currently in ${mode?.name} mode`);
716
- health.recommendations.push(...(mode?.limitations || []));
717
- }
718
-
719
- // Check service status
720
- const serviceStatus = GracefulDegradationManager.getServiceStatus();
721
- for (const [service, status] of serviceStatus) {
722
- health.components[service] = {
723
- status: status.available ? 'healthy' : 'degraded',
724
- details: { lastCheck: status.lastCheck, error: status.error }
725
- };
726
-
727
- if (!status.available) {
728
- health.overall = 'degraded';
729
- health.recommendations.push(`${service} service is unavailable`);
730
- }
731
- }
732
-
733
- // Check error summary
734
- const errorSummary = logger.getErrorSummary();
735
- health.components.errors = {
736
- status: errorSummary.totalErrors > 10 ? 'critical' : errorSummary.totalErrors > 0 ? 'degraded' : 'healthy',
737
- details: errorSummary
738
- };
739
-
740
- if (errorSummary.totalErrors > 10) {
741
- health.overall = 'critical';
742
- health.recommendations.push('High error count detected - check logs');
743
- }
744
-
745
- } catch (error) {
746
- health.overall = 'critical';
747
- health.components.healthCheck = {
748
- status: 'failed',
749
- details: { error: error instanceof Error ? error.message : 'Unknown error' }
750
- };
751
- health.recommendations.push('Health check failed - system may be unstable');
752
- }
753
-
754
- return health;
755
- }
756
- }
1
+ import type { Violation, Analysis, Fix, Configuration } from '../types/index.js';
2
+ import { ParserManager } from '../parsers/parser-manager.js';
3
+ import { BaselineChecker } from './baseline-checker.js';
4
+ import { FileProcessor } from './file-processor.js';
5
+ import { DirectoryFilter } from './directory-filter.js';
6
+ import { CacheManager } from './cache-manager.js';
7
+ import { SystemErrorHandler } from './system-error-handler.js';
8
+ import { GracefulDegradationManager } from './graceful-degradation-manager.js';
9
+ import { ConfigurationRecovery } from './configuration-recovery.js';
10
+ import { logger } from './debug-logger.js';
11
+ import chalk from 'chalk';
12
+
13
+ /**
14
+ * Main BaseGuard class that orchestrates compatibility checking and fixing
15
+ */
16
+ export class BaseGuard {
17
+ private config: Configuration;
18
+ private parserManager!: ParserManager;
19
+ private baselineChecker!: BaselineChecker;
20
+ private fileProcessor!: FileProcessor;
21
+ private directoryFilter!: DirectoryFilter;
22
+ private cacheManager!: CacheManager;
23
+ private categoryLogger: ReturnType<typeof logger.createCategoryLogger>;
24
+ private initialized = false;
25
+ private initializationPromise: Promise<void> | null = null;
26
+
27
+ constructor(config: Configuration) {
28
+ this.config = config;
29
+ this.categoryLogger = logger.createCategoryLogger('baseguard');
30
+ }
31
+
32
+ /**
33
+ * Initialize BaseGuard components with error recovery
34
+ */
35
+ private async initializeComponents(): Promise<void> {
36
+ try {
37
+ this.categoryLogger.info('Initializing BaseGuard components');
38
+
39
+ // Initialize graceful degradation manager
40
+ await GracefulDegradationManager.initialize();
41
+
42
+ // Initialize components with error handling
43
+ this.cacheManager = await SystemErrorHandler.handleGracefully(
44
+ async () => {
45
+ return new CacheManager({
46
+ maxCacheSize: parseInt(process.env.BASEGUARD_CACHE_SIZE || '2000'),
47
+ cacheValidityMs: 10 * 60 * 1000 // 10 minutes
48
+ });
49
+ },
50
+ new CacheManager({ maxCacheSize: 1000, cacheValidityMs: 5 * 60 * 1000 }),
51
+ { operation: 'cache_manager_init' }
52
+ );
53
+
54
+ this.parserManager = await SystemErrorHandler.handleGracefully(
55
+ async () => {
56
+ return new ParserManager();
57
+ },
58
+ new ParserManager(),
59
+ { operation: 'parser_manager_init' }
60
+ );
61
+
62
+ this.baselineChecker = await SystemErrorHandler.handleGracefully(
63
+ async () => {
64
+ return new BaselineChecker();
65
+ },
66
+ new BaselineChecker(),
67
+ { operation: 'baseline_checker_init' }
68
+ );
69
+
70
+ const maxWorkers = parseInt(process.env.BASEGUARD_MAX_WORKERS || '8');
71
+ const maxFiles = parseInt(process.env.BASEGUARD_MAX_FILES || '5000');
72
+
73
+ this.fileProcessor = await SystemErrorHandler.handleGracefully(
74
+ async () => {
75
+ return new FileProcessor({
76
+ maxWorkers,
77
+ cacheManager: this.cacheManager
78
+ });
79
+ },
80
+ new FileProcessor({ maxWorkers: 2, cacheManager: this.cacheManager }),
81
+ { operation: 'file_processor_init' }
82
+ );
83
+
84
+ this.directoryFilter = await SystemErrorHandler.handleGracefully(
85
+ async () => {
86
+ return new DirectoryFilter({
87
+ maxDepth: 8,
88
+ maxFiles
89
+ });
90
+ },
91
+ new DirectoryFilter({ maxDepth: 4, maxFiles: 1000 }),
92
+ { operation: 'directory_filter_init' }
93
+ );
94
+
95
+ this.initialized = true;
96
+ this.categoryLogger.info('BaseGuard components initialized successfully');
97
+
98
+ } catch (error) {
99
+ this.categoryLogger.error('Failed to initialize BaseGuard components', { error });
100
+ throw new Error(`BaseGuard initialization failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Ensure BaseGuard is properly initialized
106
+ */
107
+ private async ensureInitialized(): Promise<void> {
108
+ if (!this.initialized) {
109
+ if (!this.initializationPromise) {
110
+ this.initializationPromise = this.initializeComponents().catch(error => {
111
+ this.initializationPromise = null;
112
+ throw error;
113
+ });
114
+ }
115
+ await this.initializationPromise;
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Check files for compatibility violations with enhanced error recovery
121
+ */
122
+ async checkViolations(patterns: string[] = []): Promise<Violation[]> {
123
+ await this.ensureInitialized();
124
+
125
+ logger.startSession('check-violations');
126
+ this.categoryLogger.startPerformance('check-violations');
127
+
128
+ try {
129
+ const violations: Violation[] = [];
130
+
131
+ // Find files using smart filtering and caching with error recovery
132
+ const allFiles = await SystemErrorHandler.withRetry(
133
+ async () => {
134
+ return patterns.length > 0
135
+ ? await this.directoryFilter.findFilesWithGlob(patterns)
136
+ : await this.directoryFilter.findFiles(['src', 'app', 'pages', 'components'], {
137
+ includeHidden: false
138
+ });
139
+ },
140
+ { operation: 'find_files', details: { patterns } },
141
+ 3 // max retries
142
+ );
143
+
144
+ if (allFiles.length === 0) {
145
+ this.categoryLogger.warn('No supported files found to check', { patterns });
146
+ return violations;
147
+ }
148
+
149
+ this.categoryLogger.info(`Processing ${allFiles.length} files for violations`);
150
+
151
+ // Process files concurrently with caching and error recovery
152
+ const allFeatures = await SystemErrorHandler.handleGracefully(
153
+ () => this.fileProcessor.processFiles(allFiles),
154
+ [], // fallback to empty array
155
+ { operation: 'process_files', details: { fileCount: allFiles.length } },
156
+ {
157
+ logError: true,
158
+ showWarning: true,
159
+ attemptRecovery: true
160
+ }
161
+ );
162
+
163
+ this.categoryLogger.info(`Extracted ${allFeatures.length} features from ${allFiles.length} files`);
164
+
165
+ // Check each feature for compatibility violations with error recovery
166
+ let processedFeatures = 0;
167
+ let failedFeatures = 0;
168
+
169
+ for (const feature of allFeatures) {
170
+ try {
171
+ const compatibilityResult = await SystemErrorHandler.handleGracefully(
172
+ () => this.baselineChecker.checkCompatibility(feature, this.config.targets),
173
+ { violations: [], featureData: null }, // fallback result
174
+ {
175
+ operation: 'check_compatibility',
176
+ file: feature.file,
177
+ details: { feature: feature.feature }
178
+ }
179
+ );
180
+
181
+ // Add violations with file context
182
+ for (const violation of compatibilityResult.violations) {
183
+ violations.push({
184
+ ...violation,
185
+ file: feature.file || 'unknown',
186
+ line: feature.line,
187
+ column: feature.column,
188
+ context: feature.context
189
+ });
190
+ }
191
+
192
+ processedFeatures++;
193
+ } catch (error) {
194
+ failedFeatures++;
195
+ this.categoryLogger.warn('Failed to check feature compatibility', {
196
+ feature: feature.feature,
197
+ file: feature.file,
198
+ error: error instanceof Error ? error.message : 'Unknown error'
199
+ });
200
+
201
+ // Continue processing other features
202
+ continue;
203
+ }
204
+ }
205
+
206
+ const duration = this.categoryLogger.endPerformance('check-violations', {
207
+ totalFiles: allFiles.length,
208
+ processedFeatures,
209
+ failedFeatures,
210
+ violationsFound: violations.length
211
+ });
212
+
213
+ this.categoryLogger.info('Violation check completed', {
214
+ duration,
215
+ totalFiles: allFiles.length,
216
+ processedFeatures,
217
+ failedFeatures,
218
+ violationsFound: violations.length
219
+ });
220
+
221
+ return violations;
222
+
223
+ } catch (error) {
224
+ this.categoryLogger.error('Violation check failed', { error });
225
+
226
+ // Try graceful degradation
227
+ const mode = GracefulDegradationManager.getCurrentMode();
228
+ if (mode?.capabilities.baselineChecking) {
229
+ this.categoryLogger.info('Attempting graceful degradation for violation checking');
230
+
231
+ try {
232
+ // Simplified violation checking with minimal features
233
+ const basicViolations = await this.performBasicViolationCheck(patterns);
234
+ this.categoryLogger.info('Graceful degradation successful', { violationsFound: basicViolations.length });
235
+ return basicViolations;
236
+ } catch (degradationError) {
237
+ this.categoryLogger.error('Graceful degradation also failed', { error: degradationError });
238
+ }
239
+ }
240
+
241
+ throw error;
242
+ } finally {
243
+ await logger.endSession();
244
+ }
245
+ }
246
+
247
+ /**
248
+ * Perform basic violation checking as fallback
249
+ */
250
+ private async performBasicViolationCheck(patterns: string[]): Promise<Violation[]> {
251
+ const violations: Violation[] = [];
252
+
253
+ try {
254
+ // Use minimal file processing
255
+ const basicFiles = patterns.length > 0 ? patterns : ['src/**/*.{js,ts,jsx,tsx,css,vue,svelte}'];
256
+
257
+ // Simple file enumeration without complex processing
258
+ const { glob } = await import('glob');
259
+ const files = await glob(basicFiles.join(','), { ignore: ['node_modules/**', 'dist/**', 'build/**'] });
260
+
261
+ this.categoryLogger.info(`Basic violation check on ${files.length} files`);
262
+
263
+ // Process a limited number of files to avoid overwhelming the system
264
+ const limitedFiles = files.slice(0, 100);
265
+
266
+ for (const file of limitedFiles) {
267
+ try {
268
+ // Basic feature extraction without complex parsing
269
+ const basicFeatures = await this.extractBasicFeatures(file);
270
+
271
+ for (const feature of basicFeatures) {
272
+ const result = await this.baselineChecker.checkCompatibility(feature, this.config.targets);
273
+ violations.push(...result.violations);
274
+ }
275
+ } catch (error) {
276
+ // Skip individual file errors in basic mode
277
+ this.categoryLogger.debug('Skipped file in basic mode', { file, error: error instanceof Error ? error.message : 'Unknown error' });
278
+ }
279
+ }
280
+
281
+ } catch (error) {
282
+ this.categoryLogger.error('Basic violation check failed', { error });
283
+ }
284
+
285
+ return violations;
286
+ }
287
+
288
+ /**
289
+ * Extract basic features without complex parsing
290
+ */
291
+ private async extractBasicFeatures(_file: string): Promise<any[]> {
292
+ // This is a simplified feature extraction for fallback mode
293
+ // In a real implementation, this would do basic text pattern matching
294
+ return [];
295
+ }
296
+
297
+ /**
298
+ * Get processing statistics
299
+ */
300
+ async getProcessingStats(directories: string[] = ['src']): Promise<{
301
+ directoryStats: any;
302
+ processorStats: any;
303
+ cacheStats: any;
304
+ }> {
305
+ const directoryStats = await Promise.all(
306
+ directories.map(dir => this.directoryFilter.getDirectoryStats(dir))
307
+ );
308
+
309
+ return {
310
+ directoryStats: directoryStats.reduce((acc, stats) => ({
311
+ totalFiles: acc.totalFiles + stats.totalFiles,
312
+ supportedFiles: acc.supportedFiles + stats.supportedFiles,
313
+ directories: acc.directories + stats.directories,
314
+ excludedDirectories: acc.excludedDirectories + stats.excludedDirectories,
315
+ largestFiles: [...acc.largestFiles, ...stats.largestFiles]
316
+ .sort((a, b) => b.size - a.size)
317
+ .slice(0, 10)
318
+ }), {
319
+ totalFiles: 0,
320
+ supportedFiles: 0,
321
+ directories: 0,
322
+ excludedDirectories: 0,
323
+ largestFiles: []
324
+ }),
325
+ processorStats: this.fileProcessor.getStats(),
326
+ cacheStats: this.cacheManager.getStats()
327
+ };
328
+ }
329
+
330
+ /**
331
+ * Clear all caches
332
+ */
333
+ clearCache(): void {
334
+ this.cacheManager.clearAll();
335
+ }
336
+
337
+ /**
338
+ * Cleanup resources with error handling
339
+ */
340
+ async cleanup(): Promise<void> {
341
+ this.categoryLogger.info('Starting BaseGuard cleanup');
342
+
343
+ try {
344
+ // Cleanup file processor
345
+ await SystemErrorHandler.handleGracefully(
346
+ async () => {
347
+ await this.fileProcessor.cleanup();
348
+ return undefined;
349
+ },
350
+ undefined,
351
+ { operation: 'file_processor_cleanup' },
352
+ { logError: false, showWarning: false }
353
+ );
354
+
355
+ // Clear caches
356
+ await SystemErrorHandler.handleGracefully(
357
+ async () => {
358
+ this.cacheManager.clearAll();
359
+ return undefined;
360
+ },
361
+ undefined,
362
+ { operation: 'cache_cleanup' },
363
+ { logError: false, showWarning: false }
364
+ );
365
+
366
+ // Cleanup graceful degradation manager
367
+ await SystemErrorHandler.handleGracefully(
368
+ async () => {
369
+ await GracefulDegradationManager.cleanupCache();
370
+ return undefined;
371
+ },
372
+ undefined,
373
+ { operation: 'degradation_cleanup' },
374
+ { logError: false, showWarning: false }
375
+ );
376
+
377
+ // Cleanup old logs
378
+ await SystemErrorHandler.handleGracefully(
379
+ async () => {
380
+ await logger.cleanupOldLogs();
381
+ return undefined;
382
+ },
383
+ undefined,
384
+ { operation: 'log_cleanup' },
385
+ { logError: false, showWarning: false }
386
+ );
387
+
388
+ this.categoryLogger.info('BaseGuard cleanup completed');
389
+
390
+ } catch (error) {
391
+ this.categoryLogger.warn('Some cleanup operations failed', { error: error instanceof Error ? error.message : 'Unknown error' });
392
+ }
393
+ }
394
+
395
+ /**
396
+ * Create auto-backup of configuration
397
+ */
398
+ async createConfigBackup(): Promise<string | null> {
399
+ try {
400
+ return await ConfigurationRecovery.createAutoBackup();
401
+ } catch (error) {
402
+ this.categoryLogger.error('Failed to create config backup', { error });
403
+ return null;
404
+ }
405
+ }
406
+
407
+ /**
408
+ * Show system status and health
409
+ */
410
+ async showSystemStatus(): Promise<void> {
411
+ console.log(chalk.cyan('🔍 BaseGuard System Status\n'));
412
+
413
+ const health = await this.getHealthStatus();
414
+
415
+ // Overall status
416
+ const statusIcon = health.overall === 'healthy' ? '✅' : health.overall === 'degraded' ? '⚠️' : '❌';
417
+ const statusColor = health.overall === 'healthy' ? chalk.green : health.overall === 'degraded' ? chalk.yellow : chalk.red;
418
+
419
+ console.log(statusColor(`${statusIcon} Overall Status: ${health.overall.toUpperCase()}`));
420
+ console.log(chalk.dim(`Degradation Mode: ${health.degradationMode}\n`));
421
+
422
+ // Component status
423
+ console.log(chalk.cyan('📊 Component Status:'));
424
+ for (const [component, status] of Object.entries(health.components)) {
425
+ const componentIcon = status.status === 'healthy' ? '✅' : status.status === 'degraded' ? '⚠️' : '❌';
426
+ console.log(` ${componentIcon} ${component}: ${status.status}`);
427
+
428
+ if (status.details && status.status !== 'healthy') {
429
+ if (status.details.errors?.length > 0) {
430
+ console.log(chalk.dim(` Errors: ${status.details.errors.slice(0, 2).join(', ')}`));
431
+ }
432
+ if (status.details.error) {
433
+ console.log(chalk.dim(` Error: ${status.details.error}`));
434
+ }
435
+ }
436
+ }
437
+
438
+ // Recommendations
439
+ if (health.recommendations.length > 0) {
440
+ console.log(chalk.cyan('\n💡 Recommendations:'));
441
+ health.recommendations.forEach(rec => {
442
+ console.log(chalk.cyan(` • ${rec}`));
443
+ });
444
+ }
445
+
446
+ // Show degradation status
447
+ GracefulDegradationManager.showStatus();
448
+ }
449
+
450
+ /**
451
+ * Analyze violations using AI with graceful degradation
452
+ */
453
+ async analyzeViolations(violations: Violation[]): Promise<Analysis[]> {
454
+ await this.ensureInitialized();
455
+
456
+ logger.startSession('analyze-violations');
457
+ this.categoryLogger.startPerformance('analyze-violations');
458
+
459
+ try {
460
+ const analyses: Analysis[] = [];
461
+ const mode = GracefulDegradationManager.getCurrentMode();
462
+
463
+ if (!mode?.capabilities.aiAnalysis) {
464
+ this.categoryLogger.info('AI analysis disabled in current mode, using fallback analysis');
465
+
466
+ // Create fallback analyses for all violations
467
+ for (const violation of violations) {
468
+ const fallbackAnalysis = GracefulDegradationManager.createFallbackAnalysis(
469
+ violation,
470
+ 'AI analysis unavailable in current mode'
471
+ );
472
+ analyses.push(fallbackAnalysis);
473
+ }
474
+
475
+ return analyses;
476
+ }
477
+
478
+ // Try to use cached analyses first
479
+ for (const violation of violations) {
480
+ const cached = await GracefulDegradationManager.loadCachedAnalysis(violation);
481
+ if (cached) {
482
+ analyses.push(cached);
483
+ } else {
484
+ // Will need AI analysis
485
+ const fallbackAnalysis = GracefulDegradationManager.createFallbackAnalysis(
486
+ violation,
487
+ 'AI analysis not yet implemented'
488
+ );
489
+ analyses.push(fallbackAnalysis);
490
+ }
491
+ }
492
+
493
+ const duration = this.categoryLogger.endPerformance('analyze-violations', {
494
+ violationCount: violations.length,
495
+ analysesCreated: analyses.length
496
+ });
497
+
498
+ this.categoryLogger.info('Violation analysis completed', {
499
+ duration,
500
+ violationCount: violations.length,
501
+ analysesCreated: analyses.length
502
+ });
503
+
504
+ return analyses;
505
+
506
+ } catch (error) {
507
+ this.categoryLogger.error('Violation analysis failed', { error });
508
+
509
+ // Fallback to basic analysis
510
+ const fallbackAnalyses = violations.map(violation =>
511
+ GracefulDegradationManager.createFallbackAnalysis(violation, 'Analysis failed, using fallback')
512
+ );
513
+
514
+ return fallbackAnalyses;
515
+ } finally {
516
+ await logger.endSession();
517
+ }
518
+ }
519
+
520
+ /**
521
+ * Generate fixes for violations with graceful degradation
522
+ */
523
+ async generateFixes(violations: Violation[], analyses: Analysis[]): Promise<Fix[]> {
524
+ await this.ensureInitialized();
525
+
526
+ logger.startSession('generate-fixes');
527
+ this.categoryLogger.startPerformance('generate-fixes');
528
+
529
+ try {
530
+ const fixes: Fix[] = [];
531
+ const mode = GracefulDegradationManager.getCurrentMode();
532
+
533
+ if (!mode?.capabilities.autoFix) {
534
+ this.categoryLogger.info('Auto-fix disabled in current mode, creating manual fix suggestions');
535
+
536
+ // Create manual fix suggestions
537
+ for (let i = 0; i < violations.length; i++) {
538
+ const violation = violations[i];
539
+ const analysis = analyses[i];
540
+
541
+ if (violation && analysis) {
542
+ const manualFix = GracefulDegradationManager.createBasicFixSuggestion(violation, analysis);
543
+ fixes.push(manualFix);
544
+ }
545
+ }
546
+
547
+ return fixes;
548
+ }
549
+
550
+ // Auto-fix would be implemented here when available
551
+ this.categoryLogger.info('Auto-fix not yet implemented, creating manual suggestions');
552
+
553
+ for (let i = 0; i < violations.length; i++) {
554
+ const violation = violations[i];
555
+ const analysis = analyses[i];
556
+
557
+ if (violation && analysis) {
558
+ const manualFix = GracefulDegradationManager.createBasicFixSuggestion(violation, analysis);
559
+ fixes.push(manualFix);
560
+ }
561
+ }
562
+
563
+ const duration = this.categoryLogger.endPerformance('generate-fixes', {
564
+ violationCount: violations.length,
565
+ fixesGenerated: fixes.length
566
+ });
567
+
568
+ this.categoryLogger.info('Fix generation completed', {
569
+ duration,
570
+ violationCount: violations.length,
571
+ fixesGenerated: fixes.length
572
+ });
573
+
574
+ return fixes;
575
+
576
+ } catch (error) {
577
+ this.categoryLogger.error('Fix generation failed', { error });
578
+ throw error;
579
+ } finally {
580
+ await logger.endSession();
581
+ }
582
+ }
583
+
584
+ /**
585
+ * Apply fixes to files with error recovery
586
+ */
587
+ async applyFixes(fixes: Fix[]): Promise<void> {
588
+ await this.ensureInitialized();
589
+
590
+ logger.startSession('apply-fixes');
591
+ this.categoryLogger.startPerformance('apply-fixes');
592
+
593
+ try {
594
+ this.categoryLogger.info(`Applying ${fixes.length} fixes`);
595
+
596
+ let appliedCount = 0;
597
+ let failedCount = 0;
598
+
599
+ for (const fix of fixes) {
600
+ try {
601
+ await SystemErrorHandler.withRetry(
602
+ async () => {
603
+ // Fix application would be implemented here
604
+ this.categoryLogger.debug('Fix application not yet implemented', {
605
+ file: fix.filePath,
606
+ feature: fix.violation.feature
607
+ });
608
+
609
+ // For now, just log the fix that would be applied
610
+ console.log(chalk.cyan(`Would apply fix for ${fix.violation.feature} in ${fix.filePath}`));
611
+ },
612
+ {
613
+ operation: 'apply_fix',
614
+ file: fix.filePath,
615
+ details: { feature: fix.violation.feature }
616
+ },
617
+ 2 // max retries
618
+ );
619
+
620
+ appliedCount++;
621
+ } catch (error) {
622
+ failedCount++;
623
+ this.categoryLogger.error('Failed to apply fix', {
624
+ file: fix.filePath,
625
+ feature: fix.violation.feature,
626
+ error: error instanceof Error ? error.message : 'Unknown error'
627
+ });
628
+ }
629
+ }
630
+
631
+ const duration = this.categoryLogger.endPerformance('apply-fixes', {
632
+ totalFixes: fixes.length,
633
+ appliedCount,
634
+ failedCount
635
+ });
636
+
637
+ this.categoryLogger.info('Fix application completed', {
638
+ duration,
639
+ totalFixes: fixes.length,
640
+ appliedCount,
641
+ failedCount
642
+ });
643
+
644
+ if (failedCount > 0) {
645
+ console.log(chalk.yellow(`⚠️ ${failedCount} fixes failed to apply. Check logs for details.`));
646
+ }
647
+
648
+ } catch (error) {
649
+ this.categoryLogger.error('Fix application process failed', { error });
650
+ throw error;
651
+ } finally {
652
+ await logger.endSession();
653
+ }
654
+ }
655
+
656
+ /**
657
+ * Recover from configuration corruption
658
+ */
659
+ async recoverConfiguration(): Promise<Configuration> {
660
+ this.categoryLogger.info('Attempting configuration recovery');
661
+
662
+ const recoveryResult = await ConfigurationRecovery.recoverConfiguration({
663
+ createBackup: true,
664
+ validateConfig: true,
665
+ migrateVersion: true,
666
+ repairCorruption: true,
667
+ useDefaults: true
668
+ });
669
+
670
+ if (recoveryResult.success && recoveryResult.config) {
671
+ this.config = recoveryResult.config;
672
+ this.categoryLogger.info('Configuration recovered successfully');
673
+
674
+ if (recoveryResult.warnings.length > 0) {
675
+ this.categoryLogger.warn('Configuration recovery warnings', { warnings: recoveryResult.warnings });
676
+ }
677
+
678
+ return this.config;
679
+ } else {
680
+ const error = new Error(`Configuration recovery failed: ${recoveryResult.errors.join(', ')}`);
681
+ this.categoryLogger.error('Configuration recovery failed', { errors: recoveryResult.errors });
682
+ throw error;
683
+ }
684
+ }
685
+
686
+ /**
687
+ * Get system health status
688
+ */
689
+ async getHealthStatus(): Promise<{
690
+ overall: 'healthy' | 'degraded' | 'critical';
691
+ components: Record<string, { status: string; details?: any }>;
692
+ degradationMode: string;
693
+ recommendations: string[];
694
+ }> {
695
+ const health = {
696
+ overall: 'healthy' as 'healthy' | 'degraded' | 'critical',
697
+ components: {} as Record<string, { status: string; details?: any }>,
698
+ degradationMode: 'unknown',
699
+ recommendations: [] as string[]
700
+ };
701
+
702
+ try {
703
+ // Check configuration health
704
+ const configIntegrity = await ConfigurationRecovery.validateIntegrity();
705
+ health.components.configuration = {
706
+ status: configIntegrity.valid ? 'healthy' : 'degraded',
707
+ details: { errors: configIntegrity.errors, suggestions: configIntegrity.suggestions }
708
+ };
709
+
710
+ // Check degradation mode
711
+ const mode = GracefulDegradationManager.getCurrentMode();
712
+ health.degradationMode = mode?.name || 'unknown';
713
+
714
+ if (mode?.name !== 'Full Functionality') {
715
+ health.overall = 'degraded';
716
+ health.recommendations.push(`Currently in ${mode?.name} mode`);
717
+ health.recommendations.push(...(mode?.limitations || []));
718
+ }
719
+
720
+ // Check service status
721
+ const serviceStatus = GracefulDegradationManager.getServiceStatus();
722
+ for (const [service, status] of serviceStatus) {
723
+ health.components[service] = {
724
+ status: status.available ? 'healthy' : 'degraded',
725
+ details: { lastCheck: status.lastCheck, error: status.error }
726
+ };
727
+
728
+ if (!status.available) {
729
+ health.overall = 'degraded';
730
+ health.recommendations.push(`${service} service is unavailable`);
731
+ }
732
+ }
733
+
734
+ // Check error summary
735
+ const errorSummary = logger.getErrorSummary();
736
+ health.components.errors = {
737
+ status: errorSummary.totalErrors > 10 ? 'critical' : errorSummary.totalErrors > 0 ? 'degraded' : 'healthy',
738
+ details: errorSummary
739
+ };
740
+
741
+ if (errorSummary.totalErrors > 10) {
742
+ health.overall = 'critical';
743
+ health.recommendations.push('High error count detected - check logs');
744
+ }
745
+
746
+ } catch (error) {
747
+ health.overall = 'critical';
748
+ health.components.healthCheck = {
749
+ status: 'failed',
750
+ details: { error: error instanceof Error ? error.message : 'Unknown error' }
751
+ };
752
+ health.recommendations.push('Health check failed - system may be unstable');
753
+ }
754
+
755
+ return health;
756
+ }
757
+ }