vibecodingmachine-core 2026.2.20-438 → 2026.2.26-1642

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,515 @@
1
+ /**
2
+ * Statistics and Trends Generator for Analysis Reports
3
+ */
4
+
5
+ /**
6
+ * Generate comprehensive statistics and trend analysis
7
+ */
8
+ class StatisticsGenerator {
9
+ constructor() {
10
+ this.trendData = new Map();
11
+ }
12
+
13
+ /**
14
+ * Generate comprehensive statistics
15
+ * @param {Object} analysisData - Complete analysis data
16
+ * @returns {Object} Statistics object
17
+ */
18
+ generateStatistics(analysisData) {
19
+ const files = analysisData.files || [];
20
+
21
+ return {
22
+ overview: this.generateOverviewStats(files),
23
+ sizeDistribution: this.generateSizeDistribution(files),
24
+ complexityDistribution: this.generateComplexityDistribution(files),
25
+ complianceMetrics: this.generateComplianceMetrics(files),
26
+ packageMetrics: this.generatePackageMetrics(files),
27
+ violationMetrics: this.generateViolationMetrics(files),
28
+ riskMetrics: this.generateRiskMetrics(files),
29
+ effortEstimates: this.generateEffortEstimates(files)
30
+ };
31
+ }
32
+
33
+ /**
34
+ * Generate overview statistics
35
+ * @param {Array} files - Files to analyze
36
+ * @returns {Object} Overview statistics
37
+ */
38
+ generateOverviewStats(files) {
39
+ const totalFiles = files.length;
40
+ const totalLines = files.reduce((sum, f) => sum + f.lineCount, 0);
41
+ const averageLines = totalFiles > 0 ? Math.round(totalLines / totalFiles) : 0;
42
+
43
+ const filesNeedingRefactoring = files.filter(f => f.needsRefactoring).length;
44
+ const urgentFiles = files.filter(f => f.urgentRefactoring).length;
45
+ const complianceRate = totalFiles > 0 ? Math.round(((totalFiles - filesNeedingRefactoring) / totalFiles) * 100) : 0;
46
+
47
+ return {
48
+ totalFiles,
49
+ totalLines,
50
+ averageLines,
51
+ filesNeedingRefactoring,
52
+ urgentFiles,
53
+ complianceRate,
54
+ status: this.getOverallStatus(complianceRate, urgentFiles)
55
+ };
56
+ }
57
+
58
+ /**
59
+ * Generate size distribution statistics
60
+ * @param {Array} files - Files to analyze
61
+ * @returns {Object} Size distribution
62
+ */
63
+ generateSizeDistribution(files) {
64
+ const distribution = {
65
+ SMALL: { count: 0, lines: 0, percentage: 0 },
66
+ MEDIUM: { count: 0, lines: 0, percentage: 0 },
67
+ LARGE: { count: 0, lines: 0, percentage: 0 },
68
+ XLARGE: { count: 0, lines: 0, percentage: 0 }
69
+ };
70
+
71
+ for (const file of files) {
72
+ const category = file.sizeCategory || 'UNKNOWN';
73
+ if (distribution[category]) {
74
+ distribution[category].count += 1;
75
+ distribution[category].lines += file.lineCount;
76
+ }
77
+ }
78
+
79
+ // Calculate percentages
80
+ const totalFiles = files.length;
81
+ for (const category of Object.keys(distribution)) {
82
+ distribution[category].percentage = totalFiles > 0
83
+ ? Math.round((distribution[category].count / totalFiles) * 100)
84
+ : 0;
85
+ }
86
+
87
+ return distribution;
88
+ }
89
+
90
+ /**
91
+ * Generate complexity distribution statistics
92
+ * @param {Array} files - Files to analyze
93
+ * @returns {Object} Complexity distribution
94
+ */
95
+ generateComplexityDistribution(files) {
96
+ const scores = files
97
+ .map(f => f.getComplexityScore ? f.getComplexityScore() : 0)
98
+ .filter(score => score > 0);
99
+
100
+ if (scores.length === 0) {
101
+ return {
102
+ average: 0,
103
+ median: 0,
104
+ min: 0,
105
+ max: 0,
106
+ distribution: {
107
+ LOW: 0,
108
+ MEDIUM: 0,
109
+ HIGH: 0,
110
+ VERY_HIGH: 0
111
+ }
112
+ };
113
+ }
114
+
115
+ scores.sort((a, b) => a - b);
116
+
117
+ const average = Math.round(scores.reduce((sum, score) => sum + score, 0) / scores.length);
118
+ const median = scores[Math.floor(scores.length / 2)];
119
+ const min = scores[0];
120
+ const max = scores[scores.length - 1];
121
+
122
+ const distribution = {
123
+ LOW: scores.filter(s => s <= 25).length,
124
+ MEDIUM: scores.filter(s => s > 25 && s <= 50).length,
125
+ HIGH: scores.filter(s => s > 50 && s <= 75).length,
126
+ VERY_HIGH: scores.filter(s => s > 75).length
127
+ };
128
+
129
+ return {
130
+ average,
131
+ median,
132
+ min,
133
+ max,
134
+ distribution,
135
+ totalFiles: scores.length
136
+ };
137
+ }
138
+
139
+ /**
140
+ * Generate compliance metrics
141
+ * @param {Array} files - Files to analyze
142
+ * @returns {Object} Compliance metrics
143
+ */
144
+ generateComplianceMetrics(files) {
145
+ const totalFiles = files.length;
146
+ const compliantFiles = files.filter(f => !f.needsRefactoring).length;
147
+ const nonCompliantFiles = totalFiles - compliantFiles;
148
+
149
+ const complianceRate = totalFiles > 0 ? Math.round((compliantFiles / totalFiles) * 100) : 0;
150
+
151
+ // Compliance by size category
152
+ const complianceBySize = {};
153
+ const sizeCategories = ['SMALL', 'MEDIUM', 'LARGE', 'XLARGE'];
154
+
155
+ for (const category of sizeCategories) {
156
+ const categoryFiles = files.filter(f => f.sizeCategory === category);
157
+ const categoryCompliant = categoryFiles.filter(f => !f.needsRefactoring).length;
158
+ const categoryTotal = categoryFiles.length;
159
+
160
+ complianceBySize[category] = {
161
+ total: categoryTotal,
162
+ compliant: categoryCompliant,
163
+ nonCompliant: categoryTotal - categoryCompliant,
164
+ complianceRate: categoryTotal > 0 ? Math.round((categoryCompliant / categoryTotal) * 100) : 0
165
+ };
166
+ }
167
+
168
+ return {
169
+ totalFiles,
170
+ compliantFiles,
171
+ nonCompliantFiles,
172
+ complianceRate,
173
+ complianceBySize,
174
+ status: this.getComplianceStatus(complianceRate)
175
+ };
176
+ }
177
+
178
+ /**
179
+ * Generate package metrics
180
+ * @param {Array} files - Files to analyze
181
+ * @returns {Object} Package metrics
182
+ */
183
+ generatePackageMetrics(files) {
184
+ const packageMap = new Map();
185
+
186
+ // Group files by package
187
+ for (const file of files) {
188
+ const packageName = this.extractPackageName(file.filePath);
189
+
190
+ if (!packageMap.has(packageName)) {
191
+ packageMap.set(packageName, {
192
+ packageName,
193
+ totalFiles: 0,
194
+ totalLines: 0,
195
+ compliantFiles: 0,
196
+ urgentFiles: 0,
197
+ averageComplexity: 0,
198
+ complexityScores: []
199
+ });
200
+ }
201
+
202
+ const packageData = packageMap.get(packageName);
203
+ packageData.totalFiles += 1;
204
+ packageData.totalLines += file.lineCount;
205
+
206
+ if (!file.needsRefactoring) {
207
+ packageData.compliantFiles += 1;
208
+ }
209
+
210
+ if (file.urgentRefactoring) {
211
+ packageData.urgentFiles += 1;
212
+ }
213
+
214
+ if (file.getComplexityScore) {
215
+ packageData.complexityScores.push(file.getComplexityScore());
216
+ }
217
+ }
218
+
219
+ // Calculate package metrics
220
+ const packages = {};
221
+ for (const [packageName, data] of packageMap) {
222
+ data.complianceRate = data.totalFiles > 0 ? Math.round((data.compliantFiles / data.totalFiles) * 100) : 0;
223
+ data.averageComplexity = data.complexityScores.length > 0
224
+ ? Math.round(data.complexityScores.reduce((sum, score) => sum + score, 0) / data.complexityScores.length)
225
+ : 0;
226
+ data.status = this.getPackageStatus(data.complianceRate, data.urgentFiles);
227
+
228
+ packages[packageName] = data;
229
+ }
230
+
231
+ return {
232
+ totalPackages: Object.keys(packages).length,
233
+ packages,
234
+ ranking: this.getPackageRanking(packages)
235
+ };
236
+ }
237
+
238
+ /**
239
+ * Generate violation metrics
240
+ * @param {Array} files - Files to analyze
241
+ * @returns {Object} Violation metrics
242
+ */
243
+ generateViolationMetrics(files) {
244
+ const allViolations = [];
245
+ const violationTypes = new Map();
246
+ const violationSeverity = new Map();
247
+
248
+ for (const file of files) {
249
+ if (file.violations) {
250
+ for (const violation of file.violations) {
251
+ allViolations.push(violation);
252
+
253
+ // Count by type
254
+ const type = violation.type || 'UNKNOWN';
255
+ violationTypes.set(type, (violationTypes.get(type) || 0) + 1);
256
+
257
+ // Count by severity
258
+ const severity = violation.severity || 'LOW';
259
+ violationSeverity.set(severity, (violationSeverity.get(severity) || 0) + 1);
260
+ }
261
+ }
262
+ }
263
+
264
+ return {
265
+ totalViolations: allViolations.length,
266
+ filesWithViolations: files.filter(f => f.violations && f.violations.length > 0).length,
267
+ violationTypes: Object.fromEntries(violationTypes),
268
+ violationSeverity: Object.fromEntries(violationSeverity),
269
+ averageViolationsPerFile: files.length > 0 ? Math.round((allViolations.length / files.length) * 10) / 10 : 0
270
+ };
271
+ }
272
+
273
+ /**
274
+ * Generate risk metrics
275
+ * @param {Array} files - Files to analyze
276
+ * @returns {Object} Risk metrics
277
+ */
278
+ generateRiskMetrics(files) {
279
+ const riskScores = files.map(f => this.calculateFileRiskScore(f));
280
+
281
+ const totalRisk = riskScores.reduce((sum, score) => sum + score, 0);
282
+ const averageRisk = files.length > 0 ? Math.round(totalRisk / files.length) : 0;
283
+
284
+ const riskDistribution = {
285
+ LOW: riskScores.filter(s => s <= 25).length,
286
+ MEDIUM: riskScores.filter(s => s > 25 && s <= 50).length,
287
+ HIGH: riskScores.filter(s => s > 50 && s <= 75).length,
288
+ CRITICAL: riskScores.filter(s => s > 75).length
289
+ };
290
+
291
+ const highRiskFiles = files.filter(f => this.calculateFileRiskScore(f) > 50);
292
+
293
+ return {
294
+ totalRisk,
295
+ averageRisk,
296
+ riskDistribution,
297
+ highRiskFiles: highRiskFiles.length,
298
+ riskLevel: this.getOverallRiskLevel(averageRisk)
299
+ };
300
+ }
301
+
302
+ /**
303
+ * Generate effort estimates
304
+ * @param {Array} files - Files to analyze
305
+ * @returns {Object} Effort estimates
306
+ */
307
+ generateEffortEstimates(files) {
308
+ const filesNeedingRefactoring = files.filter(f => f.needsRefactoring);
309
+ const totalLines = filesNeedingRefactoring.reduce((sum, f) => sum + f.lineCount, 0);
310
+
311
+ // Estimate effort in person-hours (rough estimate: 1 hour per 50 lines)
312
+ const baseHours = Math.round(totalLines / 50);
313
+
314
+ // Adjust for complexity
315
+ const complexityMultiplier = 1.5; // Complex files take longer
316
+
317
+ // Adjust for dependencies
318
+ const dependencyMultiplier = 1.2; // Files with many dependencies take longer
319
+
320
+ const adjustedHours = Math.round(baseHours * complexityMultiplier * dependencyMultiplier);
321
+
322
+ return {
323
+ totalFiles: filesNeedingRefactoring.length,
324
+ totalLines,
325
+ estimatedHours: adjustedHours,
326
+ estimatedDays: Math.round(adjustedHours / 8), // Assuming 8-hour work days
327
+ effortLevel: this.getEffortLevel(adjustedHours),
328
+ breakdown: this.getEffortBreakdown(filesNeedingRefactoring)
329
+ };
330
+ }
331
+
332
+ /**
333
+ * Extract package name from file path
334
+ * @param {string} filePath - File path
335
+ * @returns {string} Package name
336
+ */
337
+ extractPackageName(filePath) {
338
+ const parts = filePath.split('/');
339
+ const packagesIndex = parts.findIndex(part => part === 'packages');
340
+
341
+ if (packagesIndex !== -1 && parts.length > packagesIndex + 1) {
342
+ return parts[packagesIndex + 1];
343
+ }
344
+
345
+ return 'unknown';
346
+ }
347
+
348
+ /**
349
+ * Get overall status
350
+ * @param {number} complianceRate - Compliance rate
351
+ * @param {number} urgentFiles - Number of urgent files
352
+ * @returns {string} Overall status
353
+ */
354
+ getOverallStatus(complianceRate, urgentFiles) {
355
+ if (complianceRate === 100 && urgentFiles === 0) {
356
+ return 'COMPLIANT';
357
+ } else if (urgentFiles > 0) {
358
+ return 'URGENT_ATTENTION';
359
+ } else if (complianceRate >= 90) {
360
+ return 'MOSTLY_COMPLIANT';
361
+ } else if (complianceRate >= 70) {
362
+ return 'PARTIALLY_COMPLIANT';
363
+ } else {
364
+ return 'NON_COMPLIANT';
365
+ }
366
+ }
367
+
368
+ /**
369
+ * Get compliance status
370
+ * @param {number} complianceRate - Compliance rate
371
+ * @returns {string} Compliance status
372
+ */
373
+ getComplianceStatus(complianceRate) {
374
+ if (complianceRate === 100) return 'COMPLIANT';
375
+ if (complianceRate >= 90) return 'MOSTLY_COMPLIANT';
376
+ if (complianceRate >= 70) return 'PARTIALLY_COMPLIANT';
377
+ return 'NON_COMPLIANT';
378
+ }
379
+
380
+ /**
381
+ * Get package status
382
+ * @param {number} complianceRate - Compliance rate
383
+ * @param {number} urgentFiles - Number of urgent files
384
+ * @returns {string} Package status
385
+ */
386
+ getPackageStatus(complianceRate, urgentFiles) {
387
+ if (complianceRate === 100 && urgentFiles === 0) {
388
+ return 'COMPLIANT';
389
+ } else if (urgentFiles > 0) {
390
+ return 'URGENT_ATTENTION';
391
+ } else if (complianceRate >= 90) {
392
+ return 'MOSTLY_COMPLIANT';
393
+ } else if (complianceRate >= 70) {
394
+ return 'PARTIALLY_COMPLIANT';
395
+ } else {
396
+ return 'NON_COMPLIANT';
397
+ }
398
+ }
399
+
400
+ /**
401
+ * Get package ranking by priority
402
+ * @param {Object} packages - Package metrics
403
+ * @returns {Array} Sorted packages
404
+ */
405
+ getPackageRanking(packages) {
406
+ return Object.entries(packages)
407
+ .map(([name, data]) => ({
408
+ name,
409
+ ...data,
410
+ priority: this.calculatePackagePriority(data)
411
+ }))
412
+ .sort((a, b) => b.priority - a.priority);
413
+ }
414
+
415
+ /**
416
+ * Calculate package priority
417
+ * @param {Object} packageData - Package data
418
+ * @returns {number} Priority score
419
+ */
420
+ calculatePackagePriority(packageData) {
421
+ let priority = 0;
422
+
423
+ // Priority from urgent files
424
+ priority += packageData.urgentFiles * 50;
425
+
426
+ // Priority from non-compliance
427
+ priority += (100 - packageData.complianceRate) * 2;
428
+
429
+ // Priority from complexity
430
+ priority += packageData.averageComplexity * 0.5;
431
+
432
+ // Priority from size
433
+ priority += Math.log(packageData.totalLines + 1) * 0.1;
434
+
435
+ return Math.round(priority);
436
+ }
437
+
438
+ /**
439
+ * Calculate file risk score
440
+ * @param {Object} file - File analysis
441
+ * @returns {number} Risk score (0-100)
442
+ */
443
+ calculateFileRiskScore(file) {
444
+ let riskScore = 0;
445
+
446
+ // Risk from size
447
+ if (file.sizeCategory === 'XLARGE') riskScore += 40;
448
+ else if (file.sizeCategory === 'LARGE') riskScore += 20;
449
+
450
+ // Risk from urgency
451
+ if (file.urgentRefactoring) riskScore += 30;
452
+
453
+ // Risk from complexity
454
+ const complexity = file.getComplexityScore ? file.getComplexityScore() : 0;
455
+ riskScore += Math.min(complexity * 0.5, 30);
456
+
457
+ // Risk from violations
458
+ if (file.violations) {
459
+ riskScore += Math.min(file.violations.length * 5, 25);
460
+ }
461
+
462
+ return Math.min(100, Math.round(riskScore));
463
+ }
464
+
465
+ /**
466
+ * Get overall risk level
467
+ * @param {number} averageRisk - Average risk score
468
+ * @returns {string} Risk level
469
+ */
470
+ getOverallRiskLevel(averageRisk) {
471
+ if (averageRisk <= 25) return 'LOW';
472
+ if (averageRisk <= 50) return 'MEDIUM';
473
+ if (averageRisk <= 75) return 'HIGH';
474
+ return 'CRITICAL';
475
+ }
476
+
477
+ /**
478
+ * Get effort level
479
+ * @param {number} hours - Estimated hours
480
+ * @returns {string} Effort level
481
+ */
482
+ getEffortLevel(hours) {
483
+ if (hours <= 8) return 'LOW';
484
+ if (hours <= 40) return 'MEDIUM';
485
+ if (hours <= 160) return 'HIGH';
486
+ return 'VERY_HIGH';
487
+ }
488
+
489
+ /**
490
+ * Get effort breakdown
491
+ * @param {Array} files - Files needing refactoring
492
+ * @returns {Object} Effort breakdown
493
+ */
494
+ getEffortBreakdown(files) {
495
+ const breakdown = {
496
+ SMALL: { files: 0, lines: 0, hours: 0 },
497
+ MEDIUM: { files: 0, lines: 0, hours: 0 },
498
+ LARGE: { files: 0, lines: 0, hours: 0 },
499
+ XLARGE: { files: 0, lines: 0, hours: 0 }
500
+ };
501
+
502
+ for (const file of files) {
503
+ const category = file.sizeCategory || 'UNKNOWN';
504
+ if (breakdown[category]) {
505
+ breakdown[category].files += 1;
506
+ breakdown[category].lines += file.lineCount;
507
+ breakdown[category].hours += Math.round(file.lineCount / 50);
508
+ }
509
+ }
510
+
511
+ return breakdown;
512
+ }
513
+ }
514
+
515
+ module.exports = StatisticsGenerator;
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Analysis Report Model
3
+ *
4
+ * Data model for analysis reports with metadata, summary, and file analysis.
5
+ */
6
+
7
+ const RefactoringConfig = require('../../config/refactoring-config');
8
+
9
+ /**
10
+ * Analysis report class
11
+ */
12
+ class AnalysisReport {
13
+ constructor() {
14
+ this.metadata = {
15
+ generatedAt: new Date().toISOString(),
16
+ version: '1.0.0',
17
+ analysisScope: 'full_codebase',
18
+ config: RefactoringConfig.limits
19
+ };
20
+
21
+ this.summary = {
22
+ totalFiles: 0,
23
+ totalLines: 0,
24
+ filesNeedingRefactoring: 0,
25
+ urgentRefactoring: 0,
26
+ complianceRate: 0,
27
+ averageComplexity: 0
28
+ };
29
+
30
+ this.fileAnalysis = [];
31
+ this.packageAnalysis = {};
32
+ this.recommendations = [];
33
+ this.strategies = [];
34
+ this.statistics = {};
35
+ this.violations = [];
36
+ this.trends = {};
37
+ }
38
+
39
+ addFileAnalysis(analysis) {
40
+ this.fileAnalysis.push(analysis);
41
+ this.updateSummary();
42
+ }
43
+
44
+ updateSummary() {
45
+ this.summary.totalFiles = this.fileAnalysis.length;
46
+ this.summary.totalLines = this.fileAnalysis.reduce((sum, f) => sum + f.lineCount, 0);
47
+ this.summary.filesNeedingRefactoring = this.fileAnalysis.filter(f => f.needsRefactoring).length;
48
+ this.summary.urgentRefactoring = this.fileAnalysis.filter(f => f.priority === 'urgent').length;
49
+ this.summary.complianceRate = this.summary.totalFiles > 0 ?
50
+ ((this.summary.totalFiles - this.summary.filesNeedingRefactoring) / this.summary.totalFiles * 100).toFixed(2) : 100;
51
+ this.summary.averageComplexity = this.calculateAverageComplexity();
52
+ }
53
+
54
+ calculateAverageComplexity() {
55
+ if (this.fileAnalysis.length === 0) return 0;
56
+ const totalComplexity = this.fileAnalysis.reduce((sum, f) => {
57
+ return sum + (f.getComplexityScore ? f.getComplexityScore() : 0);
58
+ }, 0);
59
+ return (totalComplexity / this.fileAnalysis.length).toFixed(2);
60
+ }
61
+
62
+ addPackageAnalysis(packageName, analysis) {
63
+ this.packageAnalysis[packageName] = analysis;
64
+ }
65
+
66
+ addRecommendation(recommendation) {
67
+ this.recommendations.push(recommendation);
68
+ }
69
+
70
+ addStrategy(strategy) {
71
+ this.strategies.push(strategy);
72
+ }
73
+
74
+ addViolation(violation) {
75
+ this.violations.push(violation);
76
+ }
77
+
78
+ setStatistics(stats) {
79
+ this.statistics = stats;
80
+ }
81
+
82
+ setTrends(trends) {
83
+ this.trends = trends;
84
+ }
85
+
86
+ toJSON() {
87
+ return {
88
+ metadata: this.metadata,
89
+ summary: this.summary,
90
+ fileAnalysis: this.fileAnalysis,
91
+ packageAnalysis: this.packageAnalysis,
92
+ recommendations: this.recommendations,
93
+ strategies: this.strategies,
94
+ statistics: this.statistics,
95
+ violations: this.violations,
96
+ trends: this.trends
97
+ };
98
+ }
99
+ }
100
+
101
+ module.exports = AnalysisReport;