arcvision 0.2.14 → 0.2.15

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 (134) hide show
  1. package/ARCVISION_DIRECTORY_STRUCTURE.md +104 -0
  2. package/CLI_STRUCTURE.md +110 -0
  3. package/CONFIGURATION.md +119 -0
  4. package/IMPLEMENTATION_SUMMARY.md +99 -0
  5. package/README.md +149 -89
  6. package/architecture.authority.ledger.json +46 -0
  7. package/arcvision-0.2.3.tgz +0 -0
  8. package/arcvision-0.2.4.tgz +0 -0
  9. package/arcvision-0.2.5.tgz +0 -0
  10. package/arcvision.context.diff.json +2181 -0
  11. package/arcvision.context.json +1021 -0
  12. package/arcvision.context.v1.json +2163 -0
  13. package/arcvision.context.v2.json +2173 -0
  14. package/arcvision_context/README.md +93 -0
  15. package/arcvision_context/architecture.authority.ledger.json +83 -0
  16. package/arcvision_context/arcvision.context.json +6884 -0
  17. package/debug-cycle-detection.js +56 -0
  18. package/dist/index.js +1626 -25
  19. package/docs/ENHANCED_ACCURACY_SAFETY_PROTOCOL.md +172 -0
  20. package/docs/accuracy-enhancement-artifacts/enhanced-validation-config.json +98 -0
  21. package/docs/acig-robustness-guide.md +164 -0
  22. package/docs/authoritative-gate-implementation.md +168 -0
  23. package/docs/cli-strengthening-summary.md +232 -0
  24. package/docs/invariant-system-summary.md +100 -0
  25. package/docs/invariant-system.md +112 -0
  26. package/generate_large_test.js +42 -0
  27. package/large_test_repo.json +1 -0
  28. package/output1.json +2163 -0
  29. package/output2.json +2163 -0
  30. package/package.json +46 -36
  31. package/scan_calcom_report.txt +0 -0
  32. package/scan_leafmint_report.txt +0 -0
  33. package/scan_output.txt +0 -0
  34. package/scan_trigger_report.txt +0 -0
  35. package/schema/arcvision_context_schema_v1.json +136 -1
  36. package/src/arcvision-guard.js +433 -0
  37. package/src/core/authority-core-detector.js +382 -0
  38. package/src/core/authority-ledger.js +300 -0
  39. package/src/core/blastRadius.js +299 -0
  40. package/src/core/call-resolver.js +196 -0
  41. package/src/core/change-evaluator.js +509 -0
  42. package/src/core/change-evaluator.js.backup +424 -0
  43. package/src/core/change-evaluator.ts +285 -0
  44. package/src/core/chunked-uploader.js +180 -0
  45. package/src/core/circular-dependency-detector.js +404 -0
  46. package/src/core/cli-error-handler.js +458 -0
  47. package/src/core/cli-validator.js +458 -0
  48. package/src/core/compression.js +64 -0
  49. package/src/core/context_builder.js +741 -0
  50. package/src/core/dependency-manager.js +134 -0
  51. package/src/core/di-detector.js +202 -0
  52. package/src/core/diff-analyzer.js +76 -0
  53. package/src/core/example-invariants.js +135 -0
  54. package/src/core/failure-mode-synthesizer.js +341 -0
  55. package/src/core/invariant-analyzer.js +294 -0
  56. package/src/core/invariant-detector.js +548 -0
  57. package/src/core/invariant-enforcer.js +171 -0
  58. package/src/core/invariant-evaluation-utils.js +172 -0
  59. package/src/core/invariant-hooks.js +152 -0
  60. package/src/core/invariant-integration-example.js +186 -0
  61. package/src/core/invariant-registry.js +298 -0
  62. package/src/core/invariant-registry.ts +100 -0
  63. package/src/core/invariant-types.js +66 -0
  64. package/src/core/invariants-index.js +88 -0
  65. package/src/core/method-tracker.js +170 -0
  66. package/src/core/override-handler.js +304 -0
  67. package/src/core/ownership-resolver.js +227 -0
  68. package/src/core/parser-enhanced.js +80 -0
  69. package/src/core/parser.js +610 -0
  70. package/src/core/path-resolver.js +240 -0
  71. package/src/core/pattern-matcher.js +246 -0
  72. package/src/core/progress-tracker.js +71 -0
  73. package/src/core/react-nextjs-detector.js +245 -0
  74. package/src/core/readme-generator.js +167 -0
  75. package/src/core/retry-handler.js +57 -0
  76. package/src/core/scanner.js +289 -0
  77. package/src/core/semantic-analyzer.js +204 -0
  78. package/src/core/structural-context-owner.js +442 -0
  79. package/src/core/symbol-indexer.js +164 -0
  80. package/src/core/tsconfig-utils.js +73 -0
  81. package/src/core/type-analyzer.js +272 -0
  82. package/src/core/watcher.js +18 -0
  83. package/src/core/workspace-scanner.js +88 -0
  84. package/src/engine/context_builder.js +280 -0
  85. package/src/engine/context_sorter.js +59 -0
  86. package/src/engine/context_validator.js +200 -0
  87. package/src/engine/id-generator.js +16 -0
  88. package/src/engine/pass1_facts.js +260 -0
  89. package/src/engine/pass2_semantics.js +333 -0
  90. package/src/engine/pass3_lifter.js +99 -0
  91. package/src/engine/pass4_signals.js +201 -0
  92. package/src/index.js +830 -0
  93. package/src/plugins/express-plugin.js +48 -0
  94. package/src/plugins/plugin-manager.js +58 -0
  95. package/src/plugins/react-plugin.js +54 -0
  96. package/temp_original.js +0 -0
  97. package/test/determinism-test.js +83 -0
  98. package/test-authoritative-context.js +53 -0
  99. package/test-real-authoritative-context.js +118 -0
  100. package/test-upload-enhancements.js +111 -0
  101. package/test_repos/allowed-clean-architecture/.arcvision/invariants.json +57 -0
  102. package/test_repos/allowed-clean-architecture/adapters/controllers/UserController.js +95 -0
  103. package/test_repos/allowed-clean-architecture/adapters/http/HttpServer.js +78 -0
  104. package/test_repos/allowed-clean-architecture/application/dtos/CreateUserRequest.js +37 -0
  105. package/test_repos/allowed-clean-architecture/application/services/UserService.js +61 -0
  106. package/test_repos/allowed-clean-architecture/arcvision_context/README.md +93 -0
  107. package/test_repos/allowed-clean-architecture/arcvision_context/arcvision.context.json +2796 -0
  108. package/test_repos/allowed-clean-architecture/domain/interfaces/UserRepository.js +25 -0
  109. package/test_repos/allowed-clean-architecture/domain/models/User.js +39 -0
  110. package/test_repos/allowed-clean-architecture/index.js +45 -0
  111. package/test_repos/allowed-clean-architecture/infrastructure/database/DatabaseConnection.js +56 -0
  112. package/test_repos/allowed-clean-architecture/infrastructure/repositories/InMemoryUserRepository.js +61 -0
  113. package/test_repos/allowed-clean-architecture/package.json +15 -0
  114. package/test_repos/blocked-legacy-monolith/.arcvision/invariants.json +78 -0
  115. package/test_repos/blocked-legacy-monolith/arcvision_context/README.md +93 -0
  116. package/test_repos/blocked-legacy-monolith/arcvision_context/arcvision.context.json +2882 -0
  117. package/test_repos/blocked-legacy-monolith/database/dbConnection.js +35 -0
  118. package/test_repos/blocked-legacy-monolith/index.js +38 -0
  119. package/test_repos/blocked-legacy-monolith/modules/emailService.js +31 -0
  120. package/test_repos/blocked-legacy-monolith/modules/paymentProcessor.js +37 -0
  121. package/test_repos/blocked-legacy-monolith/package.json +15 -0
  122. package/test_repos/blocked-legacy-monolith/shared/utils.js +19 -0
  123. package/test_repos/blocked-legacy-monolith/utils/helpers.js +23 -0
  124. package/test_repos/risky-microservices-concerns/.arcvision/invariants.json +69 -0
  125. package/test_repos/risky-microservices-concerns/arcvision_context/README.md +93 -0
  126. package/test_repos/risky-microservices-concerns/arcvision_context/arcvision.context.json +3070 -0
  127. package/test_repos/risky-microservices-concerns/common/utils.js +77 -0
  128. package/test_repos/risky-microservices-concerns/gateways/apiGateway.js +84 -0
  129. package/test_repos/risky-microservices-concerns/index.js +20 -0
  130. package/test_repos/risky-microservices-concerns/libs/deprecatedHelper.js +36 -0
  131. package/test_repos/risky-microservices-concerns/package.json +15 -0
  132. package/test_repos/risky-microservices-concerns/services/orderService.js +42 -0
  133. package/test_repos/risky-microservices-concerns/services/userService.js +48 -0
  134. package/verify_engine.js +116 -0
@@ -0,0 +1,458 @@
1
+ /**
2
+ * CLI Error Handler - Comprehensive error management for ArcVision CLI
3
+ * Provides authoritative error reporting and recovery mechanisms
4
+ */
5
+
6
+ const chalk = require('chalk');
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+
10
+ class CLIErrorHandler {
11
+ constructor() {
12
+ this.errorCategories = {
13
+ FILE_SYSTEM: 'FILE_SYSTEM',
14
+ NETWORK: 'NETWORK',
15
+ VALIDATION: 'VALIDATION',
16
+ PARSING: 'PARSING',
17
+ CONFIGURATION: 'CONFIGURATION',
18
+ PERMISSION: 'PERMISSION',
19
+ TIMEOUT: 'TIMEOUT',
20
+ UNKNOWN: 'UNKNOWN'
21
+ };
22
+
23
+ this.recoveryStrategies = {
24
+ RETRY: 'RETRY',
25
+ FALLBACK: 'FALLBACK',
26
+ SKIP: 'SKIP',
27
+ ABORT: 'ABORT',
28
+ MANUAL_INTERVENTION: 'MANUAL_INTERVENTION'
29
+ };
30
+ }
31
+
32
+ /**
33
+ * Categorize and handle errors based on type
34
+ */
35
+ handleError(error, context = {}) {
36
+ const categorizedError = this.categorizeError(error);
37
+
38
+ // Log the error with context
39
+ this.logError(categorizedError, context);
40
+
41
+ // Apply recovery strategy
42
+ const recoveryResult = this.applyRecoveryStrategy(categorizedError, context);
43
+
44
+ // Format user-friendly message
45
+ const userMessage = this.formatUserMessage(categorizedError, recoveryResult);
46
+
47
+ return {
48
+ ...categorizedError,
49
+ recovery: recoveryResult,
50
+ userMessage
51
+ };
52
+ }
53
+
54
+ /**
55
+ * Categorize error based on its properties and message
56
+ */
57
+ categorizeError(error) {
58
+ const errorInfo = {
59
+ original: error,
60
+ message: error.message || 'Unknown error',
61
+ code: error.code || null,
62
+ type: error.constructor.name,
63
+ stack: error.stack || null
64
+ };
65
+
66
+ // File system errors
67
+ if (error.code && ['ENOENT', 'EACCES', 'EPERM', 'EISDIR', 'ENOTDIR'].includes(error.code)) {
68
+ errorInfo.category = this.errorCategories.FILE_SYSTEM;
69
+ errorInfo.subtype = this.getFileSubtype(error.code);
70
+ }
71
+ // Network errors
72
+ else if (error.code && ['ENOTFOUND', 'ECONNREFUSED', 'ECONNRESET', 'ETIMEDOUT'].includes(error.code)) {
73
+ errorInfo.category = this.errorCategories.NETWORK;
74
+ errorInfo.subtype = this.getNetworkSubtype(error.code);
75
+ }
76
+ // Validation errors
77
+ else if (error.message && (
78
+ error.message.includes('validation') ||
79
+ error.message.includes('schema') ||
80
+ error.message.includes('invalid')
81
+ )) {
82
+ errorInfo.category = this.errorCategories.VALIDATION;
83
+ }
84
+ // Parsing errors
85
+ else if (error.message && (
86
+ error.message.includes('parse') ||
87
+ error.message.includes('syntax') ||
88
+ error.message.includes('JSON')
89
+ )) {
90
+ errorInfo.category = this.errorCategories.PARSING;
91
+ }
92
+ // Permission errors
93
+ else if (error.message && error.message.includes('permission')) {
94
+ errorInfo.category = this.errorCategories.PERMISSION;
95
+ }
96
+ // Timeout errors
97
+ else if (error.name === 'AbortError' || error.message.includes('timeout')) {
98
+ errorInfo.category = this.errorCategories.TIMEOUT;
99
+ }
100
+ // Configuration errors
101
+ else if (error.message && (
102
+ error.message.includes('config') ||
103
+ error.message.includes('token') ||
104
+ error.message.includes('missing')
105
+ )) {
106
+ errorInfo.category = this.errorCategories.CONFIGURATION;
107
+ }
108
+ // Unknown errors
109
+ else {
110
+ errorInfo.category = this.errorCategories.UNKNOWN;
111
+ }
112
+
113
+ return errorInfo;
114
+ }
115
+
116
+ getFileSubtype(errorCode) {
117
+ const subtypeMap = {
118
+ 'ENOENT': 'FILE_NOT_FOUND',
119
+ 'EACCES': 'ACCESS_DENIED',
120
+ 'EPERM': 'PERMISSION_DENIED',
121
+ 'EISDIR': 'IS_DIRECTORY',
122
+ 'ENOTDIR': 'NOT_DIRECTORY'
123
+ };
124
+ return subtypeMap[errorCode] || 'FILE_SYSTEM_ERROR';
125
+ }
126
+
127
+ getNetworkSubtype(errorCode) {
128
+ const subtypeMap = {
129
+ 'ENOTFOUND': 'HOST_NOT_FOUND',
130
+ 'ECONNREFUSED': 'CONNECTION_REFUSED',
131
+ 'ECONNRESET': 'CONNECTION_RESET',
132
+ 'ETIMEDOUT': 'TIMEOUT'
133
+ };
134
+ return subtypeMap[errorCode] || 'NETWORK_ERROR';
135
+ }
136
+
137
+ /**
138
+ * Log error with detailed context
139
+ */
140
+ logError(errorInfo, context) {
141
+ const timestamp = new Date().toISOString();
142
+ const logEntry = {
143
+ timestamp,
144
+ error: {
145
+ category: errorInfo.category,
146
+ subtype: errorInfo.subtype,
147
+ message: errorInfo.message,
148
+ code: errorInfo.code,
149
+ type: errorInfo.type
150
+ },
151
+ context: {
152
+ operation: context.operation,
153
+ directory: context.directory,
154
+ file: context.file,
155
+ ...context.additional
156
+ },
157
+ stack: errorInfo.stack
158
+ };
159
+
160
+ // Write to error log file
161
+ try {
162
+ const logDir = path.join(process.cwd(), '.arcvision', 'logs');
163
+ if (!fs.existsSync(logDir)) {
164
+ fs.mkdirSync(logDir, { recursive: true });
165
+ }
166
+
167
+ const logFile = path.join(logDir, 'errors.log');
168
+ const logLine = JSON.stringify(logEntry) + '\n';
169
+ fs.appendFileSync(logFile, logLine);
170
+ } catch (logError) {
171
+ // Silently fail if we can't write logs
172
+ console.warn('Could not write error log:', logError.message);
173
+ }
174
+ }
175
+
176
+ /**
177
+ * Apply appropriate recovery strategy based on error type
178
+ */
179
+ applyRecoveryStrategy(errorInfo, context) {
180
+ const strategy = this.determineRecoveryStrategy(errorInfo, context);
181
+
182
+ switch (strategy) {
183
+ case this.recoveryStrategies.RETRY:
184
+ return this.handleRetry(errorInfo, context);
185
+
186
+ case this.recoveryStrategies.FALLBACK:
187
+ return this.handleFallback(errorInfo, context);
188
+
189
+ case this.recoveryStrategies.SKIP:
190
+ return this.handleSkip(errorInfo, context);
191
+
192
+ case this.recoveryStrategies.MANUAL_INTERVENTION:
193
+ return this.handleManualIntervention(errorInfo, context);
194
+
195
+ case this.recoveryStrategies.ABORT:
196
+ default:
197
+ return { strategy: 'ABORT', canContinue: false };
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Determine the best recovery strategy for an error
203
+ */
204
+ determineRecoveryStrategy(errorInfo, context) {
205
+ // Network errors - retry with exponential backoff
206
+ if (errorInfo.category === this.errorCategories.NETWORK) {
207
+ if (context.retryCount && context.retryCount < 3) {
208
+ return this.recoveryStrategies.RETRY;
209
+ }
210
+ return this.recoveryStrategies.FALLBACK;
211
+ }
212
+
213
+ // File not found - abort if critical, skip if optional
214
+ if (errorInfo.subtype === 'FILE_NOT_FOUND') {
215
+ if (context.isCritical) {
216
+ return this.recoveryStrategies.ABORT;
217
+ }
218
+ return this.recoveryStrategies.SKIP;
219
+ }
220
+
221
+ // Permission errors - manual intervention required
222
+ if (errorInfo.category === this.errorCategories.PERMISSION) {
223
+ return this.recoveryStrategies.MANUAL_INTERVENTION;
224
+ }
225
+
226
+ // Parsing errors - skip problematic files
227
+ if (errorInfo.category === this.errorCategories.PARSING) {
228
+ return this.recoveryStrategies.SKIP;
229
+ }
230
+
231
+ // Validation errors - depends on severity
232
+ if (errorInfo.category === this.errorCategories.VALIDATION) {
233
+ if (context.allowInvalid) {
234
+ return this.recoveryStrategies.FALLBACK;
235
+ }
236
+ return this.recoveryStrategies.ABORT;
237
+ }
238
+
239
+ // Timeout errors - retry once
240
+ if (errorInfo.category === this.errorCategories.TIMEOUT) {
241
+ if (context.retryCount && context.retryCount < 1) {
242
+ return this.recoveryStrategies.RETRY;
243
+ }
244
+ return this.recoveryStrategies.ABORT;
245
+ }
246
+
247
+ // Default - abort for unknown errors
248
+ return this.recoveryStrategies.ABORT;
249
+ }
250
+
251
+ /**
252
+ * Handle retry strategy
253
+ */
254
+ handleRetry(errorInfo, context) {
255
+ const retryCount = (context.retryCount || 0) + 1;
256
+ const delay = Math.min(1000 * Math.pow(2, retryCount), 10000); // Max 10s
257
+
258
+ return {
259
+ strategy: 'RETRY',
260
+ canContinue: true,
261
+ retryCount,
262
+ delay,
263
+ message: `Retrying in ${delay}ms... (attempt ${retryCount})`
264
+ };
265
+ }
266
+
267
+ /**
268
+ * Handle fallback strategy
269
+ */
270
+ handleFallback(errorInfo, context) {
271
+ return {
272
+ strategy: 'FALLBACK',
273
+ canContinue: true,
274
+ message: 'Using fallback mechanism to continue operation'
275
+ };
276
+ }
277
+
278
+ /**
279
+ * Handle skip strategy
280
+ */
281
+ handleSkip(errorInfo, context) {
282
+ return {
283
+ strategy: 'SKIP',
284
+ canContinue: true,
285
+ message: `Skipping ${context.file || 'resource'} due to error`
286
+ };
287
+ }
288
+
289
+ /**
290
+ * Handle manual intervention strategy
291
+ */
292
+ handleManualIntervention(errorInfo, context) {
293
+ return {
294
+ strategy: 'MANUAL_INTERVENTION',
295
+ canContinue: false,
296
+ message: 'Manual intervention required - operation cannot continue automatically'
297
+ };
298
+ }
299
+
300
+ /**
301
+ * Format user-friendly error message
302
+ */
303
+ formatUserMessage(errorInfo, recoveryResult) {
304
+ let message = '';
305
+
306
+ // Error category header
307
+ switch (errorInfo.category) {
308
+ case this.errorCategories.FILE_SYSTEM:
309
+ message += chalk.red('šŸ“ File System Error: ');
310
+ break;
311
+ case this.errorCategories.NETWORK:
312
+ message += chalk.red('🌐 Network Error: ');
313
+ break;
314
+ case this.errorCategories.VALIDATION:
315
+ message += chalk.red('āŒ Validation Error: ');
316
+ break;
317
+ case this.errorCategories.PARSING:
318
+ message += chalk.red('šŸ“„ Parsing Error: ');
319
+ break;
320
+ case this.errorCategories.PERMISSION:
321
+ message += chalk.red('šŸ” Permission Error: ');
322
+ break;
323
+ case this.errorCategories.TIMEOUT:
324
+ message += chalk.red('ā° Timeout Error: ');
325
+ break;
326
+ case this.errorCategories.CONFIGURATION:
327
+ message += chalk.red('āš™ļø Configuration Error: ');
328
+ break;
329
+ default:
330
+ message += chalk.red('šŸ’„ Unknown Error: ');
331
+ }
332
+
333
+ // Specific error message
334
+ message += errorInfo.message + '\n';
335
+
336
+ // Recovery information
337
+ if (recoveryResult.canContinue) {
338
+ message += chalk.yellow(`šŸ”„ Recovery: ${recoveryResult.message}\n`);
339
+ } else {
340
+ message += chalk.red(`šŸ›‘ Cannot continue: ${recoveryResult.message}\n`);
341
+ }
342
+
343
+ // Helpful suggestions
344
+ message += this.getSuggestions(errorInfo);
345
+
346
+ return message;
347
+ }
348
+
349
+ /**
350
+ * Get helpful suggestions based on error type
351
+ */
352
+ getSuggestions(errorInfo) {
353
+ const suggestions = [];
354
+
355
+ switch (errorInfo.category) {
356
+ case this.errorCategories.FILE_SYSTEM:
357
+ if (errorInfo.subtype === 'FILE_NOT_FOUND') {
358
+ suggestions.push('• Check if the file path is correct');
359
+ suggestions.push('• Verify the file exists in the specified location');
360
+ } else if (errorInfo.subtype === 'ACCESS_DENIED') {
361
+ suggestions.push('• Check file permissions');
362
+ suggestions.push('• Ensure you have read/write access to the file/directory');
363
+ }
364
+ break;
365
+
366
+ case this.errorCategories.NETWORK:
367
+ suggestions.push('• Check your internet connection');
368
+ suggestions.push('• Verify the API endpoint is accessible');
369
+ suggestions.push('• Try again in a few minutes');
370
+ break;
371
+
372
+ case this.errorCategories.VALIDATION:
373
+ suggestions.push('• Check the structure of your configuration files');
374
+ suggestions.push('• Ensure JSON files are properly formatted');
375
+ suggestions.push('• Refer to documentation for correct schema');
376
+ break;
377
+
378
+ case this.errorCategories.PARSING:
379
+ suggestions.push('• Check for syntax errors in the file');
380
+ suggestions.push('• Verify the file encoding is UTF-8');
381
+ suggestions.push('• Ensure the file contains valid content for its type');
382
+ break;
383
+
384
+ case this.errorCategories.PERMISSION:
385
+ suggestions.push('• Run the command with appropriate permissions');
386
+ suggestions.push('• Check if the file/directory is locked by another process');
387
+ suggestions.push('• Verify your user account has necessary access rights');
388
+ break;
389
+
390
+ case this.errorCategories.TIMEOUT:
391
+ suggestions.push('• Check network connectivity');
392
+ suggestions.push('• Try with a smaller dataset');
393
+ suggestions.push('• Increase timeout settings if available');
394
+ break;
395
+ }
396
+
397
+ return suggestions.length > 0
398
+ ? chalk.dim('\nšŸ’” Suggestions:\n' + suggestions.map(s => ` ${s}`).join('\n') + '\n')
399
+ : '';
400
+ }
401
+
402
+ /**
403
+ * Display error to user with appropriate formatting
404
+ */
405
+ displayError(errorInfo) {
406
+ console.error('\n' + '='.repeat(60));
407
+ console.error(chalk.bold.red('ARCVISION CLI ERROR REPORT'));
408
+ console.error('='.repeat(60));
409
+ console.error('');
410
+ console.error(errorInfo.userMessage);
411
+
412
+ // Show stack trace for debugging in verbose mode
413
+ if (process.env.DEBUG || process.argv.includes('--debug')) {
414
+ console.error(chalk.dim('\nšŸ”§ Debug Information:'));
415
+ console.error(chalk.dim(`Category: ${errorInfo.category}`));
416
+ console.error(chalk.dim(`Type: ${errorInfo.type}`));
417
+ console.error(chalk.dim(`Code: ${errorInfo.code || 'N/A'}`));
418
+ if (errorInfo.stack) {
419
+ console.error(chalk.dim(`Stack:\n${errorInfo.stack}`));
420
+ }
421
+ }
422
+
423
+ console.error('='.repeat(60) + '\n');
424
+ }
425
+
426
+ /**
427
+ * Handle fatal errors that should terminate the process
428
+ */
429
+ handleFatalError(error, context = {}) {
430
+ const errorInfo = this.handleError(error, context);
431
+ this.displayError(errorInfo);
432
+
433
+ // Log additional fatal error information
434
+ console.error(chalk.red.bold('šŸ’€ FATAL ERROR - Terminating process'));
435
+
436
+ process.exit(1);
437
+ }
438
+
439
+ /**
440
+ * Handle recoverable errors that allow continuation
441
+ */
442
+ handleRecoverableError(error, context = {}) {
443
+ const errorInfo = this.handleError(error, context);
444
+
445
+ if (errorInfo.recovery.canContinue) {
446
+ console.warn('\n' + chalk.yellow('āš ļø Recoverable Error:'));
447
+ console.warn(errorInfo.userMessage);
448
+ return true; // Can continue
449
+ } else {
450
+ this.displayError(errorInfo);
451
+ return false; // Cannot continue
452
+ }
453
+ }
454
+ }
455
+
456
+ // Export singleton instance
457
+ const cliErrorHandler = new CLIErrorHandler();
458
+ module.exports = { CLIErrorHandler, cliErrorHandler };