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,283 @@
1
+ /**
2
+ * Recommendation Generator
3
+ *
4
+ * Generates refactoring recommendations based on analysis results.
5
+ */
6
+
7
+ /**
8
+ * Recommendation Generator class
9
+ */
10
+ class RecommendationGenerator {
11
+ constructor(report) {
12
+ this.report = report;
13
+ }
14
+
15
+ generateAllRecommendations() {
16
+ const recommendations = [];
17
+
18
+ // File-level recommendations
19
+ recommendations.push(...this.generateFileRecommendations());
20
+
21
+ // Package-level recommendations
22
+ recommendations.push(...this.generatePackageRecommendations());
23
+
24
+ // Strategic recommendations
25
+ recommendations.push(...this.generateStrategicRecommendations());
26
+
27
+ // Priority-based recommendations
28
+ recommendations.push(...this.generatePriorityRecommendations());
29
+
30
+ return recommendations;
31
+ }
32
+
33
+ generateFileRecommendations() {
34
+ const recommendations = [];
35
+ const violatingFiles = this.report.fileAnalysis.filter(f => f.needsRefactoring);
36
+
37
+ // Group files by size category
38
+ const sizeGroups = this.groupFilesBySize(violatingFiles);
39
+
40
+ // Recommendations for extra-large files
41
+ if (sizeGroups.xlarge.length > 0) {
42
+ recommendations.push({
43
+ type: 'urgent',
44
+ category: 'file_size',
45
+ title: `Refactor ${sizeGroups.xlarge.length} extra-large files immediately`,
46
+ description: 'Files over 1000 lines should be split into smaller, focused modules',
47
+ affectedFiles: sizeGroups.xlarge.map(f => f.filePath),
48
+ estimatedEffort: this.calculateEffortForFiles(sizeGroups.xlarge),
49
+ priority: 'urgent'
50
+ });
51
+ }
52
+
53
+ // Recommendations for large files
54
+ if (sizeGroups.large.length > 0) {
55
+ recommendations.push({
56
+ type: 'high',
57
+ category: 'file_size',
58
+ title: `Refactor ${sizeGroups.large.length} large files`,
59
+ description: 'Files between 556-1000 lines should be refactored to improve maintainability',
60
+ affectedFiles: sizeGroups.large.map(f => f.filePath),
61
+ estimatedEffort: this.calculateEffortForFiles(sizeGroups.large),
62
+ priority: 'high'
63
+ });
64
+ }
65
+
66
+ // Complexity-based recommendations
67
+ const highComplexityFiles = violatingFiles.filter(f =>
68
+ f.getComplexityScore && f.getComplexityScore() > 50
69
+ );
70
+
71
+ if (highComplexityFiles.length > 0) {
72
+ recommendations.push({
73
+ type: 'high',
74
+ category: 'complexity',
75
+ title: `Reduce complexity in ${highComplexityFiles.length} files`,
76
+ description: 'High complexity files are difficult to maintain and should be simplified',
77
+ affectedFiles: highComplexityFiles.map(f => f.filePath),
78
+ estimatedEffort: this.calculateEffortForFiles(highComplexityFiles),
79
+ priority: 'high'
80
+ });
81
+ }
82
+
83
+ return recommendations;
84
+ }
85
+
86
+ generatePackageRecommendations() {
87
+ const recommendations = [];
88
+ const packages = this.report.packageAnalysis;
89
+
90
+ // Find packages with many violations
91
+ const problematicPackages = Object.entries(packages)
92
+ .filter(([name, data]) => data.filesNeedingRefactoring > 0)
93
+ .sort(([,a], [,b]) => b.filesNeedingRefactoring - a.filesNeedingRefactoring);
94
+
95
+ for (const [packageName, packageData] of problematicPackages) {
96
+ const violationRate = (packageData.filesNeedingRefactoring / packageData.files.length * 100).toFixed(1);
97
+
98
+ if (violationRate > 50) {
99
+ recommendations.push({
100
+ type: 'high',
101
+ category: 'package_health',
102
+ title: `Comprehensive refactoring needed for ${packageName} package`,
103
+ description: `${violationRate}% of files in this package violate size limits`,
104
+ affectedPackage: packageName,
105
+ violationRate: parseFloat(violationRate),
106
+ estimatedEffort: packageData.filesNeedingRefactoring * 3, // 3 hours per file average
107
+ priority: 'high'
108
+ });
109
+ } else if (violationRate > 25) {
110
+ recommendations.push({
111
+ type: 'medium',
112
+ category: 'package_health',
113
+ title: `Partial refactoring recommended for ${packageName} package`,
114
+ description: `${violationRate}% of files in this package violate size limits`,
115
+ affectedPackage: packageName,
116
+ violationRate: parseFloat(violationRate),
117
+ estimatedEffort: packageData.filesNeedingRefactoring * 2, // 2 hours per file average
118
+ priority: 'medium'
119
+ });
120
+ }
121
+ }
122
+
123
+ return recommendations;
124
+ }
125
+
126
+ generateStrategicRecommendations() {
127
+ const recommendations = [];
128
+ const complianceRate = parseFloat(this.report.summary.complianceRate);
129
+
130
+ // Overall compliance strategy
131
+ if (complianceRate < 70) {
132
+ recommendations.push({
133
+ type: 'strategic',
134
+ category: 'compliance_strategy',
135
+ title: 'Implement comprehensive refactoring initiative',
136
+ description: 'With less than 70% compliance, a systematic approach is needed',
137
+ strategy: 'comprehensive',
138
+ phases: [
139
+ 'Phase 1: Focus on urgent and high-priority files',
140
+ 'Phase 2: Address medium-priority violations',
141
+ 'Phase 3: Handle remaining low-priority files'
142
+ ],
143
+ estimatedTimeline: '8-12 weeks',
144
+ priority: 'urgent'
145
+ });
146
+ } else if (complianceRate < 90) {
147
+ recommendations.push({
148
+ type: 'strategic',
149
+ category: 'compliance_strategy',
150
+ title: 'Targeted refactoring initiative',
151
+ description: 'With good compliance baseline, focus on remaining violations',
152
+ strategy: 'targeted',
153
+ phases: [
154
+ 'Phase 1: Address remaining high-priority files',
155
+ 'Phase 2: Clean up medium and low priority files'
156
+ ],
157
+ estimatedTimeline: '4-6 weeks',
158
+ priority: 'high'
159
+ });
160
+ } else {
161
+ recommendations.push({
162
+ type: 'strategic',
163
+ category: 'compliance_strategy',
164
+ title: 'Final compliance push',
165
+ description: 'Near-complete compliance, focus on remaining edge cases',
166
+ strategy: 'cleanup',
167
+ phases: [
168
+ 'Phase 1: Address final violations',
169
+ 'Phase 2: Implement compliance monitoring'
170
+ ],
171
+ estimatedTimeline: '1-2 weeks',
172
+ priority: 'medium'
173
+ });
174
+ }
175
+
176
+ // Process recommendations
177
+ recommendations.push({
178
+ type: 'process',
179
+ category: 'prevention',
180
+ title: 'Implement size validation in development workflow',
181
+ description: 'Prevent future violations by adding size checks to CI/CD and pre-commit hooks',
182
+ implementation: [
183
+ 'Add pre-commit hook for file size validation',
184
+ 'Integrate size checks into CI pipeline',
185
+ 'Set up automated monitoring for new files',
186
+ 'Establish size limits in code review guidelines'
187
+ ],
188
+ priority: 'medium'
189
+ });
190
+
191
+ return recommendations;
192
+ }
193
+
194
+ generatePriorityRecommendations() {
195
+ const recommendations = [];
196
+ const violatingFiles = this.report.fileAnalysis.filter(f => f.needsRefactoring);
197
+
198
+ // Urgent priority files
199
+ const urgentFiles = violatingFiles.filter(f => f.priority === 'urgent');
200
+ if (urgentFiles.length > 0) {
201
+ recommendations.push({
202
+ type: 'priority_action',
203
+ category: 'immediate',
204
+ title: `Immediate action required for ${urgentFiles.length} urgent files`,
205
+ description: 'These files pose the highest risk and should be addressed first',
206
+ files: urgentFiles.map(f => ({
207
+ path: f.filePath,
208
+ lines: f.lineCount,
209
+ complexity: f.getComplexityScore ? f.getComplexityScore() : 0,
210
+ reason: this.getUrgentReason(f)
211
+ })),
212
+ suggestedOrder: 'largest_first',
213
+ priority: 'urgent'
214
+ });
215
+ }
216
+
217
+ // High priority files
218
+ const highPriorityFiles = violatingFiles.filter(f => f.priority === 'high');
219
+ if (highPriorityFiles.length > 0) {
220
+ recommendations.push({
221
+ type: 'priority_action',
222
+ category: 'short_term',
223
+ title: `Address ${highPriorityFiles.length} high-priority files next`,
224
+ description: 'These files should be addressed after urgent issues are resolved',
225
+ files: highPriorityFiles.map(f => ({
226
+ path: f.filePath,
227
+ lines: f.lineCount,
228
+ complexity: f.getComplexityScore ? f.getComplexityScore() : 0,
229
+ reason: this.getHighPriorityReason(f)
230
+ })),
231
+ suggestedOrder: 'complexity_first',
232
+ priority: 'high'
233
+ });
234
+ }
235
+
236
+ return recommendations;
237
+ }
238
+
239
+ // Helper methods
240
+ groupFilesBySize(files) {
241
+ return {
242
+ small: files.filter(f => f.lineCount < 100),
243
+ medium: files.filter(f => f.lineCount >= 100 && f.lineCount <= 300),
244
+ large: files.filter(f => f.lineCount >= 301 && f.lineCount <= 1000),
245
+ xlarge: files.filter(f => f.lineCount > 1000)
246
+ };
247
+ }
248
+
249
+ calculateEffortForFiles(files) {
250
+ let totalEffort = 0;
251
+ for (const file of files) {
252
+ // Base effort: 1 hour per 100 lines
253
+ const baseEffort = Math.ceil(file.lineCount / 100);
254
+
255
+ // Complexity multiplier
256
+ const complexity = file.getComplexityScore ? file.getComplexityScore() : 0;
257
+ const complexityMultiplier = complexity > 50 ? 2 : (complexity > 20 ? 1.5 : 1);
258
+
259
+ totalEffort += baseEffort * complexityMultiplier;
260
+ }
261
+ return Math.ceil(totalEffort);
262
+ }
263
+
264
+ getUrgentReason(file) {
265
+ if (file.lineCount > 2000) return 'Extremely large file - immediate splitting required';
266
+ if (file.lineCount > 1000) return 'Very large file - high maintenance burden';
267
+ const complexity = file.getComplexityScore ? file.getComplexityScore() : 0;
268
+ if (complexity > 100) return 'Critical complexity - unmanageable code';
269
+ if (complexity > 50) return 'High complexity - difficult to maintain';
270
+ return 'Size and complexity thresholds exceeded';
271
+ }
272
+
273
+ getHighPriorityReason(file) {
274
+ if (file.lineCount > 800) return 'Large file - should be split soon';
275
+ if (file.lineCount > 600) return 'Approaching size limit - plan refactoring';
276
+ const complexity = file.getComplexityScore ? file.getComplexityScore() : 0;
277
+ if (complexity > 30) return 'Moderate-high complexity - simplification needed';
278
+ if (complexity > 20) return 'Moderate complexity - consider refactoring';
279
+ return 'Size limit exceeded - standard refactoring needed';
280
+ }
281
+ }
282
+
283
+ module.exports = RecommendationGenerator;
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Report Generators
3
+ *
4
+ * Handles generation of different report formats (JSON, HTML, CSV).
5
+ */
6
+
7
+ const fs = require('fs');
8
+ const path = require('path');
9
+ const { ReportGenerator } = require('../../utils/report-generator');
10
+
11
+ /**
12
+ * JSON Report Generator
13
+ */
14
+ class JSONReportGenerator {
15
+ constructor(report) {
16
+ this.report = report;
17
+ }
18
+
19
+ generate(outputPath) {
20
+ const jsonContent = JSON.stringify(this.report.toJSON(), null, 2);
21
+
22
+ if (outputPath) {
23
+ fs.writeFileSync(outputPath, jsonContent, 'utf8');
24
+ return { success: true, path: outputPath, format: 'json' };
25
+ }
26
+
27
+ return { success: true, content: jsonContent, format: 'json' };
28
+ }
29
+ }
30
+
31
+ /**
32
+ * HTML Report Generator
33
+ */
34
+ class HTMLReportGenerator {
35
+ constructor(report) {
36
+ this.report = report;
37
+ }
38
+
39
+ generate(outputPath) {
40
+ const html = this.generateHTMLContent();
41
+
42
+ if (outputPath) {
43
+ fs.writeFileSync(outputPath, html, 'utf8');
44
+ return { success: true, path: outputPath, format: 'html' };
45
+ }
46
+
47
+ return { success: true, content: html, format: 'html' };
48
+ }
49
+
50
+ generateHTMLContent() {
51
+ const report = this.report;
52
+
53
+ return `
54
+ <!DOCTYPE html>
55
+ <html>
56
+ <head>
57
+ <title>File Size Analysis Report</title>
58
+ <style>
59
+ body { font-family: Arial, sans-serif; margin: 20px; }
60
+ .summary { background: #f5f5f5; padding: 15px; border-radius: 5px; margin-bottom: 20px; }
61
+ .metric { display: inline-block; margin: 10px; padding: 10px; background: white; border-radius: 3px; }
62
+ .file-item { margin: 5px 0; padding: 8px; border-left: 3px solid #ccc; }
63
+ .urgent { border-left-color: #d32f2f; }
64
+ .high { border-left-color: #f57c00; }
65
+ .medium { border-left-color: #fbc02d; }
66
+ .low { border-left-color: #388e3c; }
67
+ table { width: 100%; border-collapse: collapse; margin: 10px 0; }
68
+ th, td { padding: 8px; text-align: left; border-bottom: 1px solid #ddd; }
69
+ th { background-color: #f2f2f2; }
70
+ </style>
71
+ </head>
72
+ <body>
73
+ <h1>File Size Analysis Report</h1>
74
+
75
+ <div class="summary">
76
+ <h2>Summary</h2>
77
+ <div class="metric">Total Files: ${report.summary.totalFiles}</div>
78
+ <div class="metric">Total Lines: ${report.summary.totalLines.toLocaleString()}</div>
79
+ <div class="metric">Files Needing Refactoring: ${report.summary.filesNeedingRefactoring}</div>
80
+ <div class="metric">Compliance Rate: ${report.summary.complianceRate}%</div>
81
+ <div class="metric">Average Complexity: ${report.summary.averageComplexity}</div>
82
+ </div>
83
+
84
+ <h2>Files Requiring Refactoring</h2>
85
+ <table>
86
+ <thead>
87
+ <tr>
88
+ <th>File</th>
89
+ <th>Lines</th>
90
+ <th>Priority</th>
91
+ <th>Complexity</th>
92
+ <th>Recommendation</th>
93
+ </tr>
94
+ </thead>
95
+ <tbody>
96
+ ${report.fileAnalysis
97
+ .filter(f => f.needsRefactoring)
98
+ .map(f => `
99
+ <tr class="file-item ${f.priority}">
100
+ <td>${f.filePath}</td>
101
+ <td>${f.lineCount}</td>
102
+ <td>${f.priority.toUpperCase()}</td>
103
+ <td>${f.getComplexityScore ? f.getComplexityScore() : 'N/A'}</td>
104
+ <td>${f.recommendation || 'See detailed analysis'}</td>
105
+ </tr>
106
+ `).join('')}
107
+ </tbody>
108
+ </table>
109
+
110
+ <h2>Package Analysis</h2>
111
+ <table>
112
+ <thead>
113
+ <tr>
114
+ <th>Package</th>
115
+ <th>Files</th>
116
+ <th>Total Lines</th>
117
+ <th>Files Needing Refactoring</th>
118
+ <th>Priority</th>
119
+ </tr>
120
+ </thead>
121
+ <tbody>
122
+ ${Object.entries(report.packageAnalysis)
123
+ .map(([name, data]) => `
124
+ <tr>
125
+ <td>${name}</td>
126
+ <td>${data.files.length}</td>
127
+ <td>${data.totalLines.toLocaleString()}</td>
128
+ <td>${data.filesNeedingRefactoring}</td>
129
+ <td>${data.priority.toUpperCase()}</td>
130
+ </tr>
131
+ `).join('')}
132
+ </tbody>
133
+ </table>
134
+
135
+ <h2>Recommendations</h2>
136
+ <ul>
137
+ ${report.recommendations.map(r => `<li>${r}</li>`).join('')}
138
+ </ul>
139
+
140
+ <div style="margin-top: 30px; font-size: 12px; color: #666;">
141
+ Report generated on ${report.metadata.generatedAt}<br>
142
+ Analysis version: ${report.metadata.version}
143
+ </div>
144
+ </body>
145
+ </html>`;
146
+ }
147
+ }
148
+
149
+ /**
150
+ * CSV Report Generator
151
+ */
152
+ class CSVReportGenerator {
153
+ constructor(report) {
154
+ this.report = report;
155
+ }
156
+
157
+ generate(outputPath) {
158
+ const csv = this.generateCSVContent();
159
+
160
+ if (outputPath) {
161
+ fs.writeFileSync(outputPath, csv, 'utf8');
162
+ return { success: true, path: outputPath, format: 'csv' };
163
+ }
164
+
165
+ return { success: true, content: csv, format: 'csv' };
166
+ }
167
+
168
+ generateCSVContent() {
169
+ const headers = ['File Path', 'Lines', 'Priority', 'Complexity', 'Needs Refactoring', 'Recommendation'];
170
+ const rows = this.report.fileAnalysis.map(f => [
171
+ f.filePath,
172
+ f.lineCount,
173
+ f.priority,
174
+ f.getComplexityScore ? f.getComplexityScore() : '',
175
+ f.needsRefactoring ? 'Yes' : 'No',
176
+ f.recommendation || ''
177
+ ]);
178
+
179
+ const csvContent = [headers, ...rows]
180
+ .map(row => row.map(cell => `"${cell}"`).join(','))
181
+ .join('\n');
182
+
183
+ return csvContent;
184
+ }
185
+ }
186
+
187
+ module.exports = {
188
+ JSONReportGenerator,
189
+ HTMLReportGenerator,
190
+ CSVReportGenerator
191
+ };
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Statistics Calculator
3
+ *
4
+ * Calculates various statistics and metrics for analysis reports.
5
+ */
6
+
7
+ /**
8
+ * Statistics Calculator class
9
+ */
10
+ class StatisticsCalculator {
11
+ constructor(report) {
12
+ this.report = report;
13
+ }
14
+
15
+ calculateAllStatistics() {
16
+ return {
17
+ fileStatistics: this.calculateFileStatistics(),
18
+ packageStatistics: this.calculatePackageStatistics(),
19
+ complexityStatistics: this.calculateComplexityStatistics(),
20
+ sizeStatistics: this.calculateSizeStatistics(),
21
+ complianceStatistics: this.calculateComplianceStatistics()
22
+ };
23
+ }
24
+
25
+ calculateFileStatistics() {
26
+ const files = this.report.fileAnalysis;
27
+
28
+ return {
29
+ totalFiles: files.length,
30
+ filesNeedingRefactoring: files.filter(f => f.needsRefactoring).length,
31
+ averageFileSize: this.calculateAverage(files.map(f => f.lineCount)),
32
+ medianFileSize: this.calculateMedian(files.map(f => f.lineCount)),
33
+ largestFile: this.findLargestFile(),
34
+ smallestFile: this.findSmallestFile(),
35
+ sizeDistribution: this.calculateDistribution(files.map(f => f.lineCount))
36
+ };
37
+ }
38
+
39
+ calculatePackageStatistics() {
40
+ const packages = this.report.packageAnalysis;
41
+
42
+ return {
43
+ totalPackages: Object.keys(packages).length,
44
+ packagePriorityDistribution: this.calculatePackagePriorityDistribution(),
45
+ largestPackage: this.findLargestPackage(),
46
+ mostComplexPackage: this.findMostComplexPackage(),
47
+ packagesNeedingRefactoring: Object.values(packages).filter(p => p.filesNeedingRefactoring > 0).length
48
+ };
49
+ }
50
+
51
+ calculateComplexityStatistics() {
52
+ const complexities = this.report.fileAnalysis
53
+ .map(f => f.getComplexityScore ? f.getComplexityScore() : 0)
54
+ .filter(c => c > 0);
55
+
56
+ return {
57
+ averageComplexity: this.calculateAverage(complexities),
58
+ medianComplexity: this.calculateMedian(complexities),
59
+ highestComplexity: Math.max(...complexities, 0),
60
+ lowestComplexity: Math.min(...complexities, 0),
61
+ complexityDistribution: this.calculateDistribution(complexities)
62
+ };
63
+ }
64
+
65
+ calculateSizeStatistics() {
66
+ const totalLines = this.report.summary.totalLines;
67
+ const filesNeedingRefactoring = this.report.summary.filesNeedingRefactoring;
68
+
69
+ return {
70
+ totalLinesOfCode: totalLines,
71
+ linesInViolatingFiles: this.calculateLinesInViolatingFiles(),
72
+ refactoringEffort: this.calculateTotalEffort(),
73
+ potentialLineReduction: this.calculatePotentialLineReduction()
74
+ };
75
+ }
76
+
77
+ calculateComplianceStatistics() {
78
+ const totalFiles = this.report.summary.totalFiles;
79
+ const compliantFiles = totalFiles - this.report.summary.filesNeedingRefactoring;
80
+
81
+ return {
82
+ complianceRate: this.report.summary.complianceRate,
83
+ compliantFiles,
84
+ nonCompliantFiles: this.report.summary.filesNeedingRefactoring,
85
+ urgentFiles: this.report.summary.urgentRefactoring,
86
+ highPriorityFiles: this.report.fileAnalysis.filter(f => f.priority === 'high').length,
87
+ mediumPriorityFiles: this.report.fileAnalysis.filter(f => f.priority === 'medium').length,
88
+ lowPriorityFiles: this.report.fileAnalysis.filter(f => f.priority === 'low').length
89
+ };
90
+ }
91
+
92
+ // Helper methods
93
+ calculateAverage(values) {
94
+ if (values.length === 0) return 0;
95
+ return values.reduce((sum, val) => sum + val, 0) / values.length;
96
+ }
97
+
98
+ calculateMedian(values) {
99
+ if (values.length === 0) return 0;
100
+ const sorted = [...values].sort((a, b) => a - b);
101
+ const mid = Math.floor(sorted.length / 2);
102
+ return sorted.length % 2 === 0 ?
103
+ (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
104
+ }
105
+
106
+ calculateDistribution(values) {
107
+ const distribution = { '0-5': 0, '6-10': 0, '11-20': 0, '21+': 0 };
108
+ for (const value of values) {
109
+ if (value <= 5) distribution['0-5']++;
110
+ else if (value <= 10) distribution['6-10']++;
111
+ else if (value <= 20) distribution['11-20']++;
112
+ else distribution['21+']++;
113
+ }
114
+ return distribution;
115
+ }
116
+
117
+ findLargestFile() {
118
+ let largest = null;
119
+ let maxLines = 0;
120
+
121
+ for (const fileAnalysis of this.report.fileAnalysis) {
122
+ if (fileAnalysis.lineCount > maxLines) {
123
+ maxLines = fileAnalysis.lineCount;
124
+ largest = {
125
+ path: fileAnalysis.filePath,
126
+ lines: fileAnalysis.lineCount,
127
+ priority: fileAnalysis.priority
128
+ };
129
+ }
130
+ }
131
+
132
+ return largest;
133
+ }
134
+
135
+ findSmallestFile() {
136
+ let smallest = null;
137
+ let minLines = Infinity;
138
+
139
+ for (const fileAnalysis of this.report.fileAnalysis) {
140
+ if (fileAnalysis.lineCount < minLines) {
141
+ minLines = fileAnalysis.lineCount;
142
+ smallest = {
143
+ path: fileAnalysis.filePath,
144
+ lines: fileAnalysis.lineCount,
145
+ priority: fileAnalysis.priority
146
+ };
147
+ }
148
+ }
149
+
150
+ return smallest;
151
+ }
152
+
153
+ calculatePackagePriorityDistribution() {
154
+ const distribution = { critical: 0, high: 0, medium: 0, low: 0 };
155
+ for (const packageData of Object.values(this.report.packageAnalysis)) {
156
+ distribution[packageData.priority]++;
157
+ }
158
+ return distribution;
159
+ }
160
+
161
+ findLargestPackage() {
162
+ let largest = null;
163
+ let maxLines = 0;
164
+
165
+ for (const [packageName, packageData] of Object.entries(this.report.packageAnalysis)) {
166
+ if (packageData.totalLines > maxLines) {
167
+ maxLines = packageData.totalLines;
168
+ largest = {
169
+ name: packageName,
170
+ lines: packageData.totalLines,
171
+ files: packageData.files.length
172
+ };
173
+ }
174
+ }
175
+
176
+ return largest;
177
+ }
178
+
179
+ findMostComplexPackage() {
180
+ let mostComplex = null;
181
+ let maxComplexity = 0;
182
+
183
+ for (const [packageName, packageData] of Object.entries(this.report.packageAnalysis)) {
184
+ if (packageData.averageComplexity > maxComplexity) {
185
+ maxComplexity = packageData.averageComplexity;
186
+ mostComplex = {
187
+ name: packageName,
188
+ complexity: packageData.averageComplexity
189
+ };
190
+ }
191
+ }
192
+
193
+ return mostComplex;
194
+ }
195
+
196
+ calculateLinesInViolatingFiles() {
197
+ return this.report.fileAnalysis
198
+ .filter(f => f.needsRefactoring)
199
+ .reduce((sum, f) => sum + f.lineCount, 0);
200
+ }
201
+
202
+ calculateTotalEffort() {
203
+ let totalEffort = 0;
204
+ for (const fileAnalysis of this.report.fileAnalysis) {
205
+ if (fileAnalysis.needsRefactoring) {
206
+ // Simple effort calculation based on line count and complexity
207
+ const lineEffort = Math.ceil(fileAnalysis.lineCount / 100);
208
+ const complexity = fileAnalysis.getComplexityScore ? fileAnalysis.getComplexityScore() : 0;
209
+ const complexityEffort = Math.ceil(complexity / 20);
210
+ totalEffort += lineEffort + complexityEffort;
211
+ }
212
+ }
213
+ return totalEffort;
214
+ }
215
+
216
+ calculatePotentialLineReduction() {
217
+ // Estimate potential line reduction from refactoring
218
+ const violatingFiles = this.report.fileAnalysis.filter(f => f.needsRefactoring);
219
+ let potentialReduction = 0;
220
+
221
+ for (const file of violatingFiles) {
222
+ // Assume 10-30% reduction based on file size and complexity
223
+ const reductionRate = file.lineCount > 1000 ? 0.3 : (file.lineCount > 500 ? 0.2 : 0.1);
224
+ potentialReduction += Math.floor(file.lineCount * reductionRate);
225
+ }
226
+
227
+ return potentialReduction;
228
+ }
229
+ }
230
+
231
+ module.exports = StatisticsCalculator;