vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1739

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 (202) hide show
  1. package/README.md +240 -0
  2. package/package.json +10 -2
  3. package/src/agents/Agent.js +300 -0
  4. package/src/agents/AgentAdditionService.js +311 -0
  5. package/src/agents/AgentCheckService.js +690 -0
  6. package/src/agents/AgentInstallationService.js +140 -0
  7. package/src/agents/AgentSetupService.js +467 -0
  8. package/src/agents/AgentStatus.js +183 -0
  9. package/src/agents/AgentVerificationService.js +634 -0
  10. package/src/agents/ConfigurationSchemaValidator.js +543 -0
  11. package/src/agents/EnvironmentConfigurationManager.js +602 -0
  12. package/src/agents/InstallationErrorHandler.js +372 -0
  13. package/src/agents/InstallationLog.js +363 -0
  14. package/src/agents/InstallationMethod.js +510 -0
  15. package/src/agents/InstallationOrchestrator.js +352 -0
  16. package/src/agents/InstallationProgressReporter.js +372 -0
  17. package/src/agents/InstallationRetryManager.js +322 -0
  18. package/src/agents/InstallationType.js +254 -0
  19. package/src/agents/OperationTypes.js +310 -0
  20. package/src/agents/PerformanceMetricsCollector.js +493 -0
  21. package/src/agents/SecurityValidationService.js +534 -0
  22. package/src/agents/VerificationTest.js +354 -0
  23. package/src/agents/VerificationType.js +226 -0
  24. package/src/agents/WindowsPermissionHandler.js +518 -0
  25. package/src/agents/config/AgentConfigManager.js +393 -0
  26. package/src/agents/config/AgentDefaultsRegistry.js +373 -0
  27. package/src/agents/config/ConfigValidator.js +281 -0
  28. package/src/agents/discovery/AgentDiscoveryService.js +707 -0
  29. package/src/agents/logging/AgentLogger.js +511 -0
  30. package/src/agents/status/AgentStatusManager.js +481 -0
  31. package/src/agents/storage/FileManager.js +454 -0
  32. package/src/agents/verification/AgentCommunicationTester.js +474 -0
  33. package/src/agents/verification/BaseVerifier.js +430 -0
  34. package/src/agents/verification/CommandVerifier.js +480 -0
  35. package/src/agents/verification/FileOperationVerifier.js +453 -0
  36. package/src/agents/verification/ResultAnalyzer.js +707 -0
  37. package/src/agents/verification/TestRequirementManager.js +495 -0
  38. package/src/agents/verification/VerificationRunner.js +433 -0
  39. package/src/agents/windows/BaseWindowsInstaller.js +441 -0
  40. package/src/agents/windows/ChocolateyInstaller.js +509 -0
  41. package/src/agents/windows/DirectInstaller.js +443 -0
  42. package/src/agents/windows/InstallerFactory.js +391 -0
  43. package/src/agents/windows/NpmInstaller.js +505 -0
  44. package/src/agents/windows/PowerShellInstaller.js +458 -0
  45. package/src/agents/windows/WinGetInstaller.js +390 -0
  46. package/src/analysis/analysis-reporter.js +132 -0
  47. package/src/analysis/boundary-detector.js +712 -0
  48. package/src/analysis/categorizer.js +340 -0
  49. package/src/analysis/codebase-scanner.js +384 -0
  50. package/src/analysis/line-counter.js +513 -0
  51. package/src/analysis/priority-calculator.js +679 -0
  52. package/src/analysis/report/analysis-report.js +250 -0
  53. package/src/analysis/report/package-analyzer.js +278 -0
  54. package/src/analysis/report/recommendation-generator.js +382 -0
  55. package/src/analysis/report/statistics-generator.js +515 -0
  56. package/src/analysis/reports/analysis-report-model.js +101 -0
  57. package/src/analysis/reports/recommendation-generator.js +283 -0
  58. package/src/analysis/reports/report-generators.js +191 -0
  59. package/src/analysis/reports/statistics-calculator.js +231 -0
  60. package/src/analysis/reports/trend-analyzer.js +219 -0
  61. package/src/analysis/strategy-generator.js +814 -0
  62. package/src/auto-mode/AutoModeBusinessLogic.js +836 -0
  63. package/src/config/refactoring-config.js +307 -0
  64. package/src/health-tracking/json-storage.js +38 -2
  65. package/src/ide-integration/applescript-manager-core.js +233 -0
  66. package/src/ide-integration/applescript-manager.cjs +357 -28
  67. package/src/ide-integration/applescript-manager.js +89 -3599
  68. package/src/ide-integration/cdp-manager.js +306 -0
  69. package/src/ide-integration/claude-code-cli-manager.cjs +1 -1
  70. package/src/ide-integration/continuation-handler.js +337 -0
  71. package/src/ide-integration/ide-status-checker.js +292 -0
  72. package/src/ide-integration/macos-ide-manager.js +627 -0
  73. package/src/ide-integration/macos-text-sender.js +528 -0
  74. package/src/ide-integration/response-reader.js +548 -0
  75. package/src/ide-integration/windows-automation-manager.js +121 -0
  76. package/src/ide-integration/windows-ide-manager.js +373 -0
  77. package/src/index.cjs +25 -3
  78. package/src/index.js +15 -1
  79. package/src/llm/direct-llm-manager.cjs +90 -2
  80. package/src/models/compliance-report.js +538 -0
  81. package/src/models/file-analysis.js +681 -0
  82. package/src/models/refactoring-plan.js +770 -0
  83. package/src/monitoring/alert-system.js +834 -0
  84. package/src/monitoring/compliance-progress-tracker.js +437 -0
  85. package/src/monitoring/continuous-scan-notifications.js +661 -0
  86. package/src/monitoring/continuous-scanner.js +279 -0
  87. package/src/monitoring/file-monitor/file-analyzer.js +262 -0
  88. package/src/monitoring/file-monitor/file-monitor.js +237 -0
  89. package/src/monitoring/file-monitor/watcher.js +194 -0
  90. package/src/monitoring/file-monitor.js +17 -0
  91. package/src/monitoring/notification-manager.js +437 -0
  92. package/src/monitoring/scanner-core.js +368 -0
  93. package/src/monitoring/scanner-events.js +214 -0
  94. package/src/monitoring/violation-notification-system.js +515 -0
  95. package/src/refactoring/boundaries/cohesion-analyzer.js +316 -0
  96. package/src/refactoring/boundaries/extraction-result.js +285 -0
  97. package/src/refactoring/boundaries/extraction-strategies.js +392 -0
  98. package/src/refactoring/boundaries/module-boundary.js +209 -0
  99. package/src/refactoring/boundary/boundary-detector.js +741 -0
  100. package/src/refactoring/boundary/boundary-types.js +405 -0
  101. package/src/refactoring/boundary/extraction-strategies.js +554 -0
  102. package/src/refactoring/boundary-extraction-result.js +77 -0
  103. package/src/refactoring/boundary-extraction-strategies.js +330 -0
  104. package/src/refactoring/boundary-extractor.js +384 -0
  105. package/src/refactoring/boundary-types.js +46 -0
  106. package/src/refactoring/circular/circular-dependency.js +88 -0
  107. package/src/refactoring/circular/cycle-detection.js +147 -0
  108. package/src/refactoring/circular/dependency-node.js +82 -0
  109. package/src/refactoring/circular/dependency-result.js +107 -0
  110. package/src/refactoring/circular/dependency-types.js +58 -0
  111. package/src/refactoring/circular/graph-builder.js +213 -0
  112. package/src/refactoring/circular/resolution-strategy.js +72 -0
  113. package/src/refactoring/circular/strategy-generator.js +229 -0
  114. package/src/refactoring/circular-dependency-resolver-original.js +809 -0
  115. package/src/refactoring/circular-dependency-resolver.js +200 -0
  116. package/src/refactoring/code-mover.js +761 -0
  117. package/src/refactoring/file-splitter.js +696 -0
  118. package/src/refactoring/functionality-validator.js +816 -0
  119. package/src/refactoring/import-manager.js +774 -0
  120. package/src/refactoring/module-boundary.js +107 -0
  121. package/src/refactoring/refactoring-executor.js +672 -0
  122. package/src/refactoring/refactoring-rollback.js +614 -0
  123. package/src/refactoring/test-validator.js +631 -0
  124. package/src/requirement-management/default-requirement-manager.js +321 -0
  125. package/src/requirement-management/requirement-file-parser.js +159 -0
  126. package/src/requirement-management/requirement-sequencer.js +221 -0
  127. package/src/rui/commands/AgentCommandParser.js +600 -0
  128. package/src/rui/commands/AgentCommands.js +487 -0
  129. package/src/rui/commands/AgentResponseFormatter.js +832 -0
  130. package/src/scripts/verify-full-compliance.js +269 -0
  131. package/src/sync/sync-engine-core.js +1 -0
  132. package/src/sync/sync-engine-remote-handlers.js +135 -0
  133. package/src/task-generation/automated-task-generator.js +351 -0
  134. package/src/task-generation/prioritizer.js +287 -0
  135. package/src/task-generation/task-list-updater.js +215 -0
  136. package/src/task-generation/task-management-integration.js +480 -0
  137. package/src/task-generation/task-manager-integration.js +270 -0
  138. package/src/task-generation/violation-task-generator.js +474 -0
  139. package/src/task-management/continuous-scan-integration.js +342 -0
  140. package/src/timeout-management/index.js +12 -3
  141. package/src/timeout-management/response-time-tracker.js +167 -0
  142. package/src/timeout-management/timeout-calculator.js +159 -0
  143. package/src/timeout-management/timeout-config-manager.js +172 -0
  144. package/src/utils/ast-analyzer.js +417 -0
  145. package/src/utils/current-requirement-manager.js +276 -0
  146. package/src/utils/current-requirement-operations.js +472 -0
  147. package/src/utils/dependency-mapper.js +456 -0
  148. package/src/utils/download-with-progress.js +4 -2
  149. package/src/utils/electron-update-checker.js +4 -1
  150. package/src/utils/file-size-analyzer.js +272 -0
  151. package/src/utils/import-updater.js +280 -0
  152. package/src/utils/refactoring-tools.js +512 -0
  153. package/src/utils/report-generator.js +569 -0
  154. package/src/utils/reports/report-analysis.js +218 -0
  155. package/src/utils/reports/report-types.js +55 -0
  156. package/src/utils/reports/summary-generators.js +102 -0
  157. package/src/utils/requirement-file-management.js +157 -0
  158. package/src/utils/requirement-helpers/requirement-file-ops.js +392 -0
  159. package/src/utils/requirement-helpers/requirement-mover.js +414 -0
  160. package/src/utils/requirement-helpers/requirement-parser.js +326 -0
  161. package/src/utils/requirement-helpers/requirement-status.js +320 -0
  162. package/src/utils/requirement-helpers-new.js +55 -0
  163. package/src/utils/requirement-helpers-refactored.js +367 -0
  164. package/src/utils/requirement-helpers.js +291 -1191
  165. package/src/utils/requirement-movement-operations.js +450 -0
  166. package/src/utils/requirement-movement.js +312 -0
  167. package/src/utils/requirement-parsing-helpers.js +56 -0
  168. package/src/utils/requirement-statistics.js +200 -0
  169. package/src/utils/requirement-text-utils.js +58 -0
  170. package/src/utils/rollback/rollback-handlers.js +125 -0
  171. package/src/utils/rollback/rollback-operation.js +63 -0
  172. package/src/utils/rollback/rollback-recorder.js +166 -0
  173. package/src/utils/rollback/rollback-state-manager.js +175 -0
  174. package/src/utils/rollback/rollback-types.js +33 -0
  175. package/src/utils/rollback/rollback-utils.js +110 -0
  176. package/src/utils/rollback-manager-original.js +569 -0
  177. package/src/utils/rollback-manager.js +202 -0
  178. package/src/utils/smoke-test-cli.js +362 -0
  179. package/src/utils/smoke-test-gui.js +351 -0
  180. package/src/utils/smoke-test-orchestrator.js +321 -0
  181. package/src/utils/smoke-test-runner.js +60 -0
  182. package/src/utils/smoke-test-web.js +347 -0
  183. package/src/utils/specification-helpers.js +39 -13
  184. package/src/utils/specification-migration.js +97 -0
  185. package/src/utils/test-runner.js +579 -0
  186. package/src/utils/validation-framework.js +518 -0
  187. package/src/validation/compliance-analyzer.js +197 -0
  188. package/src/validation/compliance-report-generator.js +343 -0
  189. package/src/validation/compliance-reporter.js +711 -0
  190. package/src/validation/compliance-rules.js +127 -0
  191. package/src/validation/constitution-validator-new.js +196 -0
  192. package/src/validation/constitution-validator.js +17 -0
  193. package/src/validation/file-validators.js +170 -0
  194. package/src/validation/line-limit/file-analyzer.js +201 -0
  195. package/src/validation/line-limit/line-limit-validator.js +208 -0
  196. package/src/validation/line-limit/validation-result.js +144 -0
  197. package/src/validation/line-limit-core.js +225 -0
  198. package/src/validation/line-limit-reporter.js +134 -0
  199. package/src/validation/line-limit-result.js +125 -0
  200. package/src/validation/line-limit-validator.js +41 -0
  201. package/src/validation/metrics-calculator.js +660 -0
  202. package/src/sync/sync-engine-backup.js +0 -559
@@ -0,0 +1,660 @@
1
+ /**
2
+ * Compliance Metrics Calculator
3
+ *
4
+ * Calculates and analyzes various compliance metrics for the codebase,
5
+ * providing insights into file size compliance, code quality, and trends.
6
+ */
7
+
8
+ const { COMPLIANCE_STATUS, COMPLIANCE_CATEGORIES } = require('../models/compliance-report');
9
+
10
+ /**
11
+ * Metrics calculator class
12
+ */
13
+ class MetricsCalculator {
14
+ constructor(options = {}) {
15
+ this.options = {
16
+ maxFileSize: options.maxFileSize || 555,
17
+ warningThreshold: options.warningThreshold || 500,
18
+ criticalThreshold: options.criticalThreshold || 800,
19
+ ...options
20
+ };
21
+ }
22
+
23
+ /**
24
+ * Calculate comprehensive compliance metrics
25
+ */
26
+ calculateMetrics(complianceReport) {
27
+ const metrics = {
28
+ overview: this.calculateOverviewMetrics(complianceReport),
29
+ fileMetrics: this.calculateFileMetrics(complianceReport),
30
+ sizeMetrics: this.calculateSizeMetrics(complianceReport),
31
+ categoryMetrics: this.calculateCategoryMetrics(complianceReport),
32
+ severityMetrics: this.calculateSeverityMetrics(complianceReport),
33
+ trendMetrics: this.calculateTrendMetrics(complianceReport),
34
+ performanceMetrics: this.calculatePerformanceMetrics(complianceReport),
35
+ qualityMetrics: this.calculateQualityMetrics(complianceReport)
36
+ };
37
+
38
+ return {
39
+ ...metrics,
40
+ summary: this.calculateMetricsSummary(metrics),
41
+ recommendations: this.generateMetricsRecommendations(metrics),
42
+ calculatedAt: new Date().toISOString()
43
+ };
44
+ }
45
+
46
+ /**
47
+ * Calculate overview metrics
48
+ */
49
+ calculateOverviewMetrics(report) {
50
+ const totalFiles = report.summary.totalFiles;
51
+ const compliantFiles = report.summary.compliantFiles;
52
+ const totalIssues = report.summary.totalIssues;
53
+
54
+ return {
55
+ totalFiles,
56
+ compliantFiles,
57
+ nonCompliantFiles: totalFiles - compliantFiles,
58
+ totalIssues,
59
+ overallComplianceScore: report.summary.overallComplianceScore,
60
+ complianceRate: totalFiles > 0 ? (compliantFiles / totalFiles * 100) : 100,
61
+ averageIssuesPerFile: totalFiles > 0 ? (totalIssues / totalFiles) : 0,
62
+ healthStatus: this.getHealthStatus(report.summary.overallComplianceScore)
63
+ };
64
+ }
65
+
66
+ /**
67
+ * Calculate file-specific metrics
68
+ */
69
+ calculateFileMetrics(report) {
70
+ const fileSummaries = report.fileSummaries;
71
+
72
+ // Sort files by various criteria
73
+ const filesBySize = [...fileSummaries].sort((a, b) => b.lineCount - a.lineCount);
74
+ const filesByCompliance = [...fileSummaries].sort((a, b) => a.complianceScore - b.complianceScore);
75
+ const filesByIssues = [...fileSummaries].sort((a, b) => b.totalIssues - a.totalIssues);
76
+
77
+ return {
78
+ largestFiles: filesBySize.slice(0, 10).map(f => ({
79
+ filePath: f.filePath,
80
+ lineCount: f.lineCount,
81
+ status: f.status,
82
+ complianceScore: f.complianceScore
83
+ })),
84
+ smallestFiles: filesBySize.slice(-10).reverse().map(f => ({
85
+ filePath: f.filePath,
86
+ lineCount: f.lineCount,
87
+ status: f.status,
88
+ complianceScore: f.complianceScore
89
+ })),
90
+ leastCompliantFiles: filesByCompliance.slice(0, 10).map(f => ({
91
+ filePath: f.filePath,
92
+ complianceScore: f.complianceScore,
93
+ status: f.status,
94
+ totalIssues: f.totalIssues
95
+ })),
96
+ mostProblematicFiles: filesByIssues.slice(0, 10).map(f => ({
97
+ filePath: f.filePath,
98
+ totalIssues: f.totalIssues,
99
+ status: f.status,
100
+ complianceScore: f.complianceScore
101
+ })),
102
+ averageFileSize: fileSummaries.length > 0 ?
103
+ fileSummaries.reduce((sum, f) => sum + f.lineCount, 0) / fileSummaries.length : 0,
104
+ medianFileSize: this.calculateMedian(fileSummaries.map(f => f.lineCount)),
105
+ fileSizeDistribution: this.calculateSizeDistribution(fileSummaries)
106
+ };
107
+ }
108
+
109
+ /**
110
+ * Calculate size-specific metrics
111
+ */
112
+ calculateSizeMetrics(report) {
113
+ const fileSummaries = report.fileSummaries;
114
+ const maxLimit = this.options.maxFileSize;
115
+ const warningThreshold = this.options.warningThreshold;
116
+ const criticalThreshold = this.options.criticalThreshold;
117
+
118
+ const sizeCategories = {
119
+ small: fileSummaries.filter(f => f.lineCount <= warningThreshold * 0.5).length,
120
+ medium: fileSummaries.filter(f => f.lineCount > warningThreshold * 0.5 && f.lineCount <= warningThreshold).length,
121
+ large: fileSummaries.filter(f => f.lineCount > warningThreshold && f.lineCount <= maxLimit).length,
122
+ oversized: fileSummaries.filter(f => f.lineCount > maxLimit && f.lineCount <= criticalThreshold).length,
123
+ critical: fileSummaries.filter(f => f.lineCount > criticalThreshold).length
124
+ };
125
+
126
+ const totalLines = fileSummaries.reduce((sum, f) => sum + f.lineCount, 0);
127
+ const excessLines = fileSummaries
128
+ .filter(f => f.lineCount > maxLimit)
129
+ .reduce((sum, f) => sum + (f.lineCount - maxLimit), 0);
130
+
131
+ return {
132
+ sizeCategories,
133
+ totalLines,
134
+ excessLines,
135
+ averageExcessPerOversizedFile: sizeCategories.oversized > 0 ?
136
+ excessLines / (sizeCategories.oversized + sizeCategories.critical) : 0,
137
+ sizeComplianceRate: ((sizeCategories.small + sizeCategories.medium + sizeCategories.large) / fileSummaries.length * 100),
138
+ criticalSizeFiles: sizeCategories.critical,
139
+ oversizedFiles: sizeCategories.oversized,
140
+ sizeRiskScore: this.calculateSizeRiskScore(sizeCategories, fileSummaries.length)
141
+ };
142
+ }
143
+
144
+ /**
145
+ * Calculate category-specific metrics
146
+ */
147
+ calculateCategoryMetrics(report) {
148
+ const categories = {};
149
+ const totalIssues = report.summary.totalIssues;
150
+
151
+ // Calculate metrics for each category
152
+ for (const [category, issueCount] of Object.entries(report.issuesByCategory)) {
153
+ if (issueCount > 0) {
154
+ const categoryFiles = report.fileSummaries.filter(f =>
155
+ f.issues.some(issue => issue.category === category)
156
+ );
157
+
158
+ categories[category] = {
159
+ issueCount,
160
+ percentage: totalIssues > 0 ? (issueCount / totalIssues * 100) : 0,
161
+ affectedFiles: categoryFiles.length,
162
+ averageIssuesPerAffectedFile: categoryFiles.length > 0 ?
163
+ (issueCount / categoryFiles.length) : 0,
164
+ severity: this.getCategorySeverity(category, issueCount, report.summary.totalFiles)
165
+ };
166
+ }
167
+ }
168
+
169
+ return {
170
+ categories,
171
+ mostProblematicCategory: this.getMostProblematicCategory(categories),
172
+ categoryDistribution: this.calculateCategoryDistribution(categories)
173
+ };
174
+ }
175
+
176
+ /**
177
+ * Calculate severity-specific metrics
178
+ */
179
+ calculateSeverityMetrics(report) {
180
+ const summary = report.summary;
181
+ const totalIssues = report.summary.totalIssues;
182
+
183
+ const severities = {
184
+ critical: {
185
+ count: summary.criticalFiles,
186
+ issues: report.fileSummaries.reduce((sum, f) => sum + f.criticalIssues, 0),
187
+ percentage: totalIssues > 0 ? (summary.criticalFiles / summary.totalFiles * 100) : 0
188
+ },
189
+ error: {
190
+ count: summary.violationFiles,
191
+ issues: report.fileSummaries.reduce((sum, f) => sum + f.violationIssues, 0),
192
+ percentage: totalIssues > 0 ? (summary.violationFiles / summary.totalFiles * 100) : 0
193
+ },
194
+ warning: {
195
+ count: summary.warningFiles,
196
+ issues: report.fileSummaries.reduce((sum, f) => sum + f.warningIssues, 0),
197
+ percentage: totalIssues > 0 ? (summary.warningFiles / summary.totalFiles * 100) : 0
198
+ },
199
+ info: {
200
+ count: summary.compliantFiles,
201
+ issues: report.fileSummaries.reduce((sum, f) => sum + f.compliantIssues, 0),
202
+ percentage: totalIssues > 0 ? (summary.compliantFiles / summary.totalFiles * 100) : 0
203
+ }
204
+ };
205
+
206
+ return {
207
+ severities,
208
+ severityRiskScore: this.calculateSeverityRiskScore(severities),
209
+ escalationRisk: this.calculateEscalationRisk(severities)
210
+ };
211
+ }
212
+
213
+ /**
214
+ * Calculate trend metrics (if historical data available)
215
+ */
216
+ calculateTrendMetrics(report) {
217
+ // This would typically compare with previous reports
218
+ // For now, return placeholder metrics
219
+ return {
220
+ trendDirection: 'stable', // 'improving', 'degrading', 'stable'
221
+ complianceScoreChange: 0,
222
+ issueCountChange: 0,
223
+ fileCountChange: 0,
224
+ trendPeriod: 'unknown',
225
+ trendData: []
226
+ };
227
+ }
228
+
229
+ /**
230
+ * Calculate performance metrics
231
+ */
232
+ calculatePerformanceMetrics(report) {
233
+ const fileSummaries = report.fileSummaries;
234
+
235
+ return {
236
+ averageAnalysisTime: 0, // Would be populated by actual timing data
237
+ totalAnalysisTime: 0,
238
+ filesPerSecond: 0,
239
+ memoryUsage: {
240
+ estimated: this.estimateMemoryUsage(fileSummaries),
241
+ peak: 0
242
+ },
243
+ efficiency: {
244
+ issuesDetectedPerMinute: 0,
245
+ filesProcessedPerMinute: 0
246
+ }
247
+ };
248
+ }
249
+
250
+ /**
251
+ * Calculate quality metrics
252
+ */
253
+ calculateQualityMetrics(report) {
254
+ const fileSummaries = report.fileSummaries;
255
+
256
+ return {
257
+ codeQualityScore: this.calculateCodeQualityScore(fileSummaries),
258
+ maintainabilityIndex: this.calculateMaintainabilityIndex(fileSummaries),
259
+ technicalDebt: this.calculateTechnicalDebt(fileSummaries),
260
+ complexityMetrics: this.calculateComplexityMetrics(fileSummaries),
261
+ documentationCoverage: this.calculateDocumentationCoverage(fileSummaries)
262
+ };
263
+ }
264
+
265
+ /**
266
+ * Calculate overall metrics summary
267
+ */
268
+ calculateMetricsSummary(metrics) {
269
+ return {
270
+ overallScore: this.calculateOverallScore(metrics),
271
+ riskLevel: this.assessRiskLevel(metrics),
272
+ healthGrade: this.assignHealthGrade(metrics),
273
+ keyInsights: this.extractKeyInsights(metrics),
274
+ priorityActions: this.identifyPriorityActions(metrics)
275
+ };
276
+ }
277
+
278
+ /**
279
+ * Generate metrics-based recommendations
280
+ */
281
+ generateMetricsRecommendations(metrics) {
282
+ const recommendations = [];
283
+
284
+ // Size-related recommendations
285
+ if (metrics.sizeMetrics.criticalSizeFiles > 0) {
286
+ recommendations.push({
287
+ type: 'critical',
288
+ category: 'file_size',
289
+ title: 'Address Critical File Size Violations',
290
+ description: `${metrics.sizeMetrics.criticalSizeFiles} files exceed critical size threshold.`,
291
+ impact: 'high',
292
+ effort: 'high',
293
+ priority: 1
294
+ });
295
+ }
296
+
297
+ // Compliance-related recommendations
298
+ if (metrics.overview.complianceRate < 80) {
299
+ recommendations.push({
300
+ type: 'high',
301
+ category: 'compliance',
302
+ title: 'Improve Overall Compliance',
303
+ description: `Compliance rate is ${metrics.overview.complianceRate.toFixed(1)}%. Target is >90%.`,
304
+ impact: 'high',
305
+ effort: 'medium',
306
+ priority: 2
307
+ });
308
+ }
309
+
310
+ // Category-specific recommendations
311
+ const mostProblematic = metrics.categoryMetrics.mostProblematicCategory;
312
+ if (mostProblematic && mostProblematic.issueCount > 0) {
313
+ recommendations.push({
314
+ type: 'medium',
315
+ category: mostProblematic.category,
316
+ title: `Address ${mostProblematic.category} Issues`,
317
+ description: `${mostProblematic.issueCount} issues in ${mostProblematic.category} category.`,
318
+ impact: 'medium',
319
+ effort: 'medium',
320
+ priority: 3
321
+ });
322
+ }
323
+
324
+ return recommendations.sort((a, b) => a.priority - b.priority);
325
+ }
326
+
327
+ /**
328
+ * Helper methods
329
+ */
330
+ getHealthStatus(complianceScore) {
331
+ if (complianceScore >= 95) return 'excellent';
332
+ if (complianceScore >= 85) return 'good';
333
+ if (complianceScore >= 70) return 'fair';
334
+ if (complianceScore >= 50) return 'poor';
335
+ return 'critical';
336
+ }
337
+
338
+ calculateMedian(values) {
339
+ const sorted = [...values].sort((a, b) => a - b);
340
+ const mid = Math.floor(sorted.length / 2);
341
+ return sorted.length % 2 === 0 ?
342
+ (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
343
+ }
344
+
345
+ calculateSizeDistribution(fileSummaries) {
346
+ const sizes = fileSummaries.map(f => f.lineCount);
347
+ const max = Math.max(...sizes);
348
+ const min = Math.min(...sizes);
349
+ const ranges = 10;
350
+ const rangeSize = Math.ceil((max - min) / ranges);
351
+
352
+ const distribution = [];
353
+ for (let i = 0; i < ranges; i++) {
354
+ const lower = min + (i * rangeSize);
355
+ const upper = lower + rangeSize;
356
+ const count = sizes.filter(s => s >= lower && s < upper).length;
357
+
358
+ distribution.push({
359
+ range: `${lower}-${upper}`,
360
+ count,
361
+ percentage: (count / fileSummaries.length * 100).toFixed(1)
362
+ });
363
+ }
364
+
365
+ return distribution;
366
+ }
367
+
368
+ calculateSizeRiskScore(sizeCategories, totalFiles) {
369
+ const weights = {
370
+ small: 0,
371
+ medium: 0,
372
+ large: 1,
373
+ oversized: 5,
374
+ critical: 10
375
+ };
376
+
377
+ let riskScore = 0;
378
+ for (const [category, count] of Object.entries(sizeCategories)) {
379
+ riskScore += weights[category] * count;
380
+ }
381
+
382
+ return totalFiles > 0 ? (riskScore / totalFiles) : 0;
383
+ }
384
+
385
+ getCategorySeverity(category, issueCount, totalFiles) {
386
+ const severityRatio = issueCount / totalFiles;
387
+ if (severityRatio > 0.1) return 'high';
388
+ if (severityRatio > 0.05) return 'medium';
389
+ return 'low';
390
+ }
391
+
392
+ getMostProblematicCategory(categories) {
393
+ return Object.entries(categories)
394
+ .sort(([,a], [,b]) => b.issueCount - a.issueCount)[0]?.[1];
395
+ }
396
+
397
+ calculateCategoryDistribution(categories) {
398
+ const total = Object.values(categories).reduce((sum, cat) => sum + cat.issueCount, 0);
399
+ const distribution = {};
400
+
401
+ for (const [name, category] of Object.entries(categories)) {
402
+ distribution[name] = {
403
+ count: category.issueCount,
404
+ percentage: total > 0 ? (category.issueCount / total * 100) : 0
405
+ };
406
+ }
407
+
408
+ return distribution;
409
+ }
410
+
411
+ calculateSeverityRiskScore(severities) {
412
+ const weights = {
413
+ critical: 10,
414
+ error: 5,
415
+ warning: 2,
416
+ info: 0
417
+ };
418
+
419
+ let riskScore = 0;
420
+ for (const [severity, data] of Object.entries(severities)) {
421
+ riskScore += weights[severity] * data.count;
422
+ }
423
+
424
+ return riskScore;
425
+ }
426
+
427
+ calculateEscalationRisk(severities) {
428
+ // Risk of warnings escalating to errors, errors to critical
429
+ const warningToErrorRatio = severities.warning.count > 0 ?
430
+ severities.error.count / severities.warning.count : 0;
431
+ const errorToCriticalRatio = severities.error.count > 0 ?
432
+ severities.critical.count / severities.error.count : 0;
433
+
434
+ return {
435
+ warningEscalationRisk: Math.min(warningToErrorRatio * 100, 100),
436
+ errorEscalationRisk: Math.min(errorToCriticalRatio * 100, 100),
437
+ overallEscalationRisk: (warningToErrorRatio + errorToCriticalRatio) / 2 * 100
438
+ };
439
+ }
440
+
441
+ estimateMemoryUsage(fileSummaries) {
442
+ // Rough estimation based on file sizes and issue counts
443
+ const baseMemory = 50 * 1024 * 1024; // 50MB base
444
+ const perFileMemory = 1024; // 1KB per file
445
+ const perIssueMemory = 512; // 512 bytes per issue
446
+
447
+ const totalIssues = fileSummaries.reduce((sum, f) => sum + f.totalIssues, 0);
448
+
449
+ return baseMemory + (fileSummaries.length * perFileMemory) + (totalIssues * perIssueMemory);
450
+ }
451
+
452
+ calculateCodeQualityScore(fileSummaries) {
453
+ const totalFiles = fileSummaries.length;
454
+ const compliantFiles = fileSummaries.filter(f => f.status === COMPLIANCE_STATUS.COMPLIANT).length;
455
+ const totalIssues = fileSummaries.reduce((sum, f) => sum + f.totalIssues, 0);
456
+
457
+ // Base score from compliance
458
+ let score = (compliantFiles / totalFiles) * 100;
459
+
460
+ // Penalize for high issue density
461
+ const avgIssuesPerFile = totalIssues / totalFiles;
462
+ score -= Math.min(avgIssuesPerFile * 5, 30);
463
+
464
+ return Math.max(0, Math.min(100, score));
465
+ }
466
+
467
+ calculateMaintainabilityIndex(fileSummaries) {
468
+ // Simplified maintainability index based on file sizes and issues
469
+ let totalIndex = 0;
470
+
471
+ for (const file of fileSummaries) {
472
+ let fileIndex = 100;
473
+
474
+ // Reduce based on file size
475
+ if (file.lineCount > 555) {
476
+ fileIndex -= ((file.lineCount - 555) / 555) * 30;
477
+ }
478
+
479
+ // Reduce based on issues
480
+ fileIndex -= file.totalIssues * 2;
481
+
482
+ totalIndex += Math.max(0, fileIndex);
483
+ }
484
+
485
+ return fileSummaries.length > 0 ? totalIndex / fileSummaries.length : 100;
486
+ }
487
+
488
+ calculateTechnicalDebt(fileSummaries) {
489
+ // Estimate technical debt in hours based on violations
490
+ let totalDebt = 0;
491
+
492
+ for (const file of fileSummaries) {
493
+ // Base debt per file
494
+ let fileDebt = 0;
495
+
496
+ // Size-related debt
497
+ if (file.lineCount > 555) {
498
+ fileDebt += (file.lineCount - 555) * 0.1; // 6 minutes per excess line
499
+ }
500
+
501
+ // Issue-related debt
502
+ fileDebt += file.criticalIssues * 4; // 4 hours per critical issue
503
+ fileDebt += file.violationIssues * 2; // 2 hours per violation
504
+ fileDebt += file.warningIssues * 0.5; // 30 minutes per warning
505
+
506
+ totalDebt += fileDebt;
507
+ }
508
+
509
+ return {
510
+ totalHours: totalDebt,
511
+ totalDays: totalDebt / 8,
512
+ estimatedCost: totalDebt * 100, // $100/hour assumption
513
+ priorityFiles: fileSummaries
514
+ .filter(f => f.lineCount > 555 || f.totalIssues > 5)
515
+ .map(f => ({
516
+ filePath: f.filePath,
517
+ estimatedHours: (f.lineCount > 555 ? (f.lineCount - 555) * 0.1 : 0) +
518
+ (f.criticalIssues * 4) +
519
+ (f.violationIssues * 2) +
520
+ (f.warningIssues * 0.5)
521
+ }))
522
+ .sort((a, b) => b.estimatedHours - a.estimatedHours)
523
+ .slice(0, 10)
524
+ };
525
+ }
526
+
527
+ calculateComplexityMetrics(fileSummaries) {
528
+ return {
529
+ averageComplexity: fileSummaries.length > 0 ?
530
+ fileSummaries.reduce((sum, f) => sum + (f.lineCount / 100), 0) / fileSummaries.length : 0,
531
+ highComplexityFiles: fileSummaries.filter(f => f.lineCount > 500).length,
532
+ complexityDistribution: this.calculateComplexityDistribution(fileSummaries)
533
+ };
534
+ }
535
+
536
+ calculateComplexityDistribution(fileSummaries) {
537
+ const complexity = fileSummaries.map(f => f.lineCount / 100);
538
+ const distribution = {
539
+ low: complexity.filter(c => c < 2).length,
540
+ medium: complexity.filter(c => c >= 2 && c < 5).length,
541
+ high: complexity.filter(c => c >= 5 && c < 10).length,
542
+ veryHigh: complexity.filter(c => c >= 10).length
543
+ };
544
+
545
+ return distribution;
546
+ }
547
+
548
+ calculateDocumentationCoverage(fileSummaries) {
549
+ const totalFiles = fileSummaries.length;
550
+ const documentedFiles = fileSummaries.filter(f =>
551
+ f.issues.some(issue => issue.category === COMPLIANCE_CATEGORIES.DOCUMENTATION)
552
+ ).length;
553
+
554
+ return {
555
+ coveragePercentage: totalFiles > 0 ? (documentedFiles / totalFiles * 100) : 100,
556
+ documentedFiles,
557
+ undocumentedFiles: totalFiles - documentedFiles
558
+ };
559
+ }
560
+
561
+ calculateOverallScore(metrics) {
562
+ const weights = {
563
+ compliance: 0.3,
564
+ size: 0.25,
565
+ severity: 0.2,
566
+ quality: 0.15,
567
+ category: 0.1
568
+ };
569
+
570
+ const scores = {
571
+ compliance: metrics.overview.complianceRate,
572
+ size: Math.max(0, 100 - metrics.sizeMetrics.sizeRiskScore * 10),
573
+ severity: Math.max(0, 100 - metrics.severityMetrics.severityRiskScore),
574
+ quality: metrics.qualityMetrics.codeQualityScore,
575
+ category: 100 - (metrics.categoryMetrics.mostProblematicCategory?.issueCount || 0) * 5
576
+ };
577
+
578
+ let overallScore = 0;
579
+ for (const [metric, weight] of Object.entries(weights)) {
580
+ overallScore += scores[metric] * weight;
581
+ }
582
+
583
+ return Math.max(0, Math.min(100, overallScore));
584
+ }
585
+
586
+ assessRiskLevel(metrics) {
587
+ const overallScore = this.calculateOverallScore(metrics);
588
+ if (overallScore >= 90) return 'low';
589
+ if (overallScore >= 70) return 'medium';
590
+ if (overallScore >= 50) return 'high';
591
+ return 'critical';
592
+ }
593
+
594
+ assignHealthGrade(metrics) {
595
+ const overallScore = this.calculateOverallScore(metrics);
596
+ if (overallScore >= 95) return 'A+';
597
+ if (overallScore >= 90) return 'A';
598
+ if (overallScore >= 85) return 'B+';
599
+ if (overallScore >= 80) return 'B';
600
+ if (overallScore >= 75) return 'C+';
601
+ if (overallScore >= 70) return 'C';
602
+ if (overallScore >= 60) return 'D';
603
+ return 'F';
604
+ }
605
+
606
+ extractKeyInsights(metrics) {
607
+ const insights = [];
608
+
609
+ if (metrics.overview.complianceRate < 80) {
610
+ insights.push('Compliance rate below target - requires immediate attention');
611
+ }
612
+
613
+ if (metrics.sizeMetrics.criticalSizeFiles > 0) {
614
+ insights.push(`${metrics.sizeMetrics.criticalSizeFiles} files require immediate refactoring`);
615
+ }
616
+
617
+ if (metrics.severityMetrics.severities.critical.count > 0) {
618
+ insights.push('Critical violations detected - address immediately');
619
+ }
620
+
621
+ const mostProblematic = metrics.categoryMetrics.mostProblematicCategory;
622
+ if (mostProblematic && mostProblematic.issueCount > 5) {
623
+ insights.push(`${mostProblematic.category} category has highest violation count`);
624
+ }
625
+
626
+ return insights;
627
+ }
628
+
629
+ identifyPriorityActions(metrics) {
630
+ const actions = [];
631
+
632
+ if (metrics.sizeMetrics.criticalSizeFiles > 0) {
633
+ actions.push({
634
+ action: 'Refactor critical files',
635
+ priority: 1,
636
+ description: 'Address files exceeding critical size threshold'
637
+ });
638
+ }
639
+
640
+ if (metrics.severityMetrics.severities.critical.count > 0) {
641
+ actions.push({
642
+ action: 'Fix critical violations',
643
+ priority: 2,
644
+ description: 'Resolve all critical compliance issues'
645
+ });
646
+ }
647
+
648
+ if (metrics.overview.complianceRate < 80) {
649
+ actions.push({
650
+ action: 'Improve compliance rate',
651
+ priority: 3,
652
+ description: 'Focus on improving overall compliance to >90%'
653
+ });
654
+ }
655
+
656
+ return actions;
657
+ }
658
+ }
659
+
660
+ module.exports = MetricsCalculator;