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,679 @@
1
+ /**
2
+ * Priority Calculator
3
+ *
4
+ * Calculates refactoring priorities based on multiple factors.
5
+ * Provides consistent, data-driven priority assessment.
6
+ */
7
+
8
+ const RefactoringConfig = require('../config/refactoring-config');
9
+
10
+ /**
11
+ * Priority levels
12
+ */
13
+ const PRIORITY_LEVELS = {
14
+ CRITICAL: 'critical',
15
+ HIGH: 'high',
16
+ MEDIUM: 'medium',
17
+ LOW: 'low',
18
+ NONE: 'none'
19
+ };
20
+
21
+ /**
22
+ * Priority factors
23
+ */
24
+ const PRIORITY_FACTORS = {
25
+ SIZE_VIOLATION: 'size_violation',
26
+ COMPLEXITY: 'complexity',
27
+ DEPENDENCY_COUNT: 'dependency_count',
28
+ CHANGE_FREQUENCY: 'change_frequency',
29
+ PACKAGE_IMPORTANCE: 'package_importance',
30
+ TEST_COVERAGE: 'test_coverage',
31
+ BUSINESS_IMPACT: 'business_impact'
32
+ };
33
+
34
+ /**
35
+ * Priority calculation result class
36
+ */
37
+ class PriorityResult {
38
+ constructor(filePath) {
39
+ this.filePath = filePath;
40
+ this.priority = PRIORITY_LEVELS.NONE;
41
+ this.score = 0;
42
+ this.factors = {};
43
+ this.reasons = [];
44
+ this.recommendations = [];
45
+ this.metadata = {
46
+ calculatedAt: new Date().toISOString(),
47
+ version: '1.0.0'
48
+ };
49
+ }
50
+
51
+ addFactor(factorName, score, weight, details = {}) {
52
+ this.factors[factorName] = {
53
+ score,
54
+ weight,
55
+ weightedScore: score * weight,
56
+ details
57
+ };
58
+ }
59
+
60
+ addReason(reason) {
61
+ this.reasons.push(reason);
62
+ }
63
+
64
+ addRecommendation(recommendation) {
65
+ this.recommendations.push(recommendation);
66
+ }
67
+
68
+ setPriority(priority, score) {
69
+ this.priority = priority;
70
+ this.score = score;
71
+ }
72
+
73
+ getFactorScore(factorName) {
74
+ return this.factors[factorName]?.weightedScore || 0;
75
+ }
76
+
77
+ getTotalWeightedScore() {
78
+ return Object.values(this.factors)
79
+ .reduce((sum, factor) => sum + factor.weightedScore, 0);
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Priority calculator class
85
+ */
86
+ class PriorityCalculator {
87
+ constructor(config = RefactoringConfig) {
88
+ this.config = config;
89
+ this.weights = this.getDefaultWeights();
90
+ this.thresholds = this.getDefaultThresholds();
91
+ }
92
+
93
+ /**
94
+ * Get default factor weights
95
+ */
96
+ getDefaultWeights() {
97
+ return {
98
+ [PRIORITY_FACTORS.SIZE_VIOLATION]: 0.4,
99
+ [PRIORITY_FACTORS.COMPLEXITY]: 0.25,
100
+ [PRIORITY_FACTORS.DEPENDENCY_COUNT]: 0.15,
101
+ [PRIORITY_FACTORS.PACKAGE_IMPORTANCE]: 0.1,
102
+ [PRIORITY_FACTORS.CHANGE_FREQUENCY]: 0.05,
103
+ [PRIORITY_FACTORS.TEST_COVERAGE]: 0.03,
104
+ [PRIORITY_FACTORS.BUSINESS_IMPACT]: 0.02
105
+ };
106
+ }
107
+
108
+ /**
109
+ * Get default priority thresholds
110
+ */
111
+ getDefaultThresholds() {
112
+ return {
113
+ [PRIORITY_LEVELS.CRITICAL]: 0.8,
114
+ [PRIORITY_LEVELS.HIGH]: 0.6,
115
+ [PRIORITY_LEVELS.MEDIUM]: 0.4,
116
+ [PRIORITY_LEVELS.LOW]: 0.2,
117
+ [PRIORITY_LEVELS.NONE]: 0
118
+ };
119
+ }
120
+
121
+ /**
122
+ * Calculate priority for a file analysis
123
+ */
124
+ calculatePriority(fileAnalysis) {
125
+ const result = new PriorityResult(fileAnalysis.filePath);
126
+
127
+ // Calculate each factor
128
+ this.calculateSizeViolationFactor(fileAnalysis, result);
129
+ this.calculateComplexityFactor(fileAnalysis, result);
130
+ this.calculateDependencyFactor(fileAnalysis, result);
131
+ this.calculatePackageImportanceFactor(fileAnalysis, result);
132
+ this.calculateChangeFrequencyFactor(fileAnalysis, result);
133
+ this.calculateTestCoverageFactor(fileAnalysis, result);
134
+ this.calculateBusinessImpactFactor(fileAnalysis, result);
135
+
136
+ // Calculate total weighted score
137
+ const totalScore = result.getTotalWeightedScore();
138
+
139
+ // Determine priority based on thresholds
140
+ const priority = this.determinePriority(totalScore);
141
+
142
+ result.setPriority(priority, totalScore);
143
+ this.generateReasonsAndRecommendations(fileAnalysis, result);
144
+
145
+ return result;
146
+ }
147
+
148
+ /**
149
+ * Calculate size violation factor
150
+ */
151
+ calculateSizeViolationFactor(fileAnalysis, result) {
152
+ const limits = this.config.limits;
153
+ let score = 0;
154
+ let details = {};
155
+
156
+ if (fileAnalysis.lineCount > limits.criticalThreshold) {
157
+ score = 1.0;
158
+ details.violation = 'critical';
159
+ details.excessLines = fileAnalysis.lineCount - limits.maxFileSize;
160
+ details.severity = 'critical';
161
+ } else if (fileAnalysis.lineCount > limits.maxFileSize) {
162
+ score = 0.8;
163
+ details.violation = 'major';
164
+ details.excessLines = fileAnalysis.lineCount - limits.maxFileSize;
165
+ details.severity = 'major';
166
+ } else if (fileAnalysis.lineCount > limits.warningThreshold) {
167
+ score = 0.6;
168
+ details.violation = 'minor';
169
+ details.excessLines = fileAnalysis.lineCount - limits.warningThreshold;
170
+ details.severity = 'minor';
171
+ } else if (fileAnalysis.lineCount > limits.mediumFileMax) {
172
+ score = 0.3;
173
+ details.violation = 'approaching';
174
+ details.excessLines = 0;
175
+ details.severity = 'low';
176
+ } else {
177
+ score = 0.0;
178
+ details.violation = 'none';
179
+ details.excessLines = 0;
180
+ details.severity = 'none';
181
+ }
182
+
183
+ details.lineCount = fileAnalysis.lineCount;
184
+ details.limit = limits.maxFileSize;
185
+ details.warningThreshold = limits.warningThreshold;
186
+
187
+ result.addFactor(PRIORITY_FACTORS.SIZE_VIOLATION, score, this.weights[PRIORITY_FACTORS.SIZE_VIOLATION], details);
188
+ }
189
+
190
+ /**
191
+ * Calculate complexity factor
192
+ */
193
+ calculateComplexityFactor(fileAnalysis, result) {
194
+ let score = 0;
195
+ let details = {};
196
+
197
+ // Use complexity score if available, otherwise calculate
198
+ const complexityScore = fileAnalysis.getComplexityScore ?
199
+ fileAnalysis.getComplexityScore() :
200
+ this.calculateComplexityScore(fileAnalysis);
201
+
202
+ if (complexityScore >= 80) {
203
+ score = 1.0;
204
+ details.level = 'very_high';
205
+ } else if (complexityScore >= 60) {
206
+ score = 0.8;
207
+ details.level = 'high';
208
+ } else if (complexityScore >= 40) {
209
+ score = 0.6;
210
+ details.level = 'medium';
211
+ } else if (complexityScore >= 20) {
212
+ score = 0.3;
213
+ details.level = 'low';
214
+ } else {
215
+ score = 0.0;
216
+ details.level = 'very_low';
217
+ }
218
+
219
+ details.complexityScore = complexityScore;
220
+ details.cyclomaticComplexity = fileAnalysis.cyclomaticComplexity || 0;
221
+ details.nestingDepth = fileAnalysis.nestingDepth || 0;
222
+ details.functionCount = fileAnalysis.functionCount || 0;
223
+ details.classCount = fileAnalysis.classCount || 0;
224
+
225
+ result.addFactor(PRIORITY_FACTORS.COMPLEXITY, score, this.weights[PRIORITY_FACTORS.COMPLEXITY], details);
226
+ }
227
+
228
+ /**
229
+ * Calculate dependency factor
230
+ */
231
+ calculateDependencyFactor(fileAnalysis, result) {
232
+ let score = 0;
233
+ let details = {};
234
+
235
+ const dependencyCount = fileAnalysis.dependencyCount || fileAnalysis.imports?.length || 0;
236
+ const dependentCount = fileAnalysis.dependents?.length || 0;
237
+
238
+ // Score based on total dependencies (incoming + outgoing)
239
+ const totalDependencies = dependencyCount + dependentCount;
240
+
241
+ if (totalDependencies > 20) {
242
+ score = 1.0;
243
+ details.level = 'very_high';
244
+ } else if (totalDependencies > 15) {
245
+ score = 0.8;
246
+ details.level = 'high';
247
+ } else if (totalDependencies > 10) {
248
+ score = 0.6;
249
+ details.level = 'medium';
250
+ } else if (totalDependencies > 5) {
251
+ score = 0.3;
252
+ details.level = 'low';
253
+ } else {
254
+ score = 0.0;
255
+ details.level = 'very_low';
256
+ }
257
+
258
+ details.dependencyCount = dependencyCount;
259
+ details.dependentCount = dependentCount;
260
+ details.totalDependencies = totalDependencies;
261
+ details.couplingRisk = this.assessCouplingRisk(totalDependencies);
262
+
263
+ result.addFactor(PRIORITY_FACTORS.DEPENDENCY_COUNT, score, this.weights[PRIORITY_FACTORS.DEPENDENCY_COUNT], details);
264
+ }
265
+
266
+ /**
267
+ * Calculate package importance factor
268
+ */
269
+ calculatePackageImportanceFactor(fileAnalysis, result) {
270
+ let score = 0;
271
+ let details = {};
272
+
273
+ const packageName = fileAnalysis.package || 'root';
274
+
275
+ // Package importance scoring
276
+ const packageImportance = {
277
+ 'core': 1.0,
278
+ 'cli': 0.8,
279
+ 'electron-app': 0.7,
280
+ 'web': 0.6,
281
+ 'api-server': 0.6,
282
+ 'chrome-extension': 0.5,
283
+ 'mobile': 0.5,
284
+ 'vscode-extension': 0.4,
285
+ 'admin': 0.3,
286
+ 'root': 0.2
287
+ };
288
+
289
+ score = packageImportance[packageName] || 0.2;
290
+
291
+ details.packageName = packageName;
292
+ details.importance = score >= 0.8 ? 'critical' :
293
+ score >= 0.6 ? 'high' :
294
+ score >= 0.4 ? 'medium' : 'low';
295
+ details.isCorePackage = packageName === 'core';
296
+
297
+ result.addFactor(PRIORITY_FACTORS.PACKAGE_IMPORTANCE, score, this.weights[PRIORITY_FACTORS.PACKAGE_IMPORTANCE], details);
298
+ }
299
+
300
+ /**
301
+ * Calculate change frequency factor
302
+ */
303
+ calculateChangeFrequencyFactor(fileAnalysis, result) {
304
+ let score = 0;
305
+ let details = {};
306
+
307
+ // For now, use a simple heuristic based on file type and location
308
+ // In a real implementation, this would use git history or other metrics
309
+ const filePath = fileAnalysis.filePath;
310
+
311
+ // Files that tend to change frequently
312
+ const highFrequencyPatterns = [
313
+ /config\//,
314
+ /\/bin\//,
315
+ /\/src\/main\//,
316
+ /package\.json$/,
317
+ /README\.md$/,
318
+ /\.config\./
319
+ ];
320
+
321
+ const mediumFrequencyPatterns = [
322
+ /\/src\/utils\//,
323
+ /\/src\/helpers\//,
324
+ /\/src\/services\//
325
+ ];
326
+
327
+ if (highFrequencyPatterns.some(pattern => pattern.test(filePath))) {
328
+ score = 0.8;
329
+ details.frequency = 'high';
330
+ } else if (mediumFrequencyPatterns.some(pattern => pattern.test(filePath))) {
331
+ score = 0.5;
332
+ details.frequency = 'medium';
333
+ } else {
334
+ score = 0.2;
335
+ details.frequency = 'low';
336
+ }
337
+
338
+ details.filePath = filePath;
339
+ details.lastModified = fileAnalysis.lastModified;
340
+
341
+ // If we have last modified, use it to adjust score
342
+ if (fileAnalysis.lastModified) {
343
+ const daysSinceModified = (Date.now() - new Date(fileAnalysis.lastModified)) / (1000 * 60 * 60 * 24);
344
+ if (daysSinceModified < 7) {
345
+ score = Math.min(1.0, score + 0.2);
346
+ details.recentlyModified = true;
347
+ } else if (daysSinceModified < 30) {
348
+ score = Math.min(1.0, score + 0.1);
349
+ details.recentlyModified = false;
350
+ }
351
+ }
352
+
353
+ result.addFactor(PRIORITY_FACTORS.CHANGE_FREQUENCY, score, this.weights[PRIORITY_FACTORS.CHANGE_FREQUENCY], details);
354
+ }
355
+
356
+ /**
357
+ * Calculate test coverage factor
358
+ */
359
+ calculateTestCoverageFactor(fileAnalysis, result) {
360
+ let score = 0;
361
+ let details = {};
362
+
363
+ // Simple heuristic based on file type and naming
364
+ const filePath = fileAnalysis.filePath;
365
+ const isTestFile = fileAnalysis.isTestFile || /test|spec/.test(filePath);
366
+
367
+ if (isTestFile) {
368
+ score = 0.0; // Test files themselves don't need refactoring priority
369
+ details.coverage = 'test_file';
370
+ } else {
371
+ // Look for corresponding test files
372
+ const hasTestFile = this.hasCorrespondingTestFile(filePath);
373
+
374
+ if (hasTestFile) {
375
+ score = 0.2; // Lower priority if well tested
376
+ details.coverage = 'good';
377
+ details.testFile = this.findTestFile(filePath);
378
+ } else {
379
+ score = 0.6; // Higher priority if no tests
380
+ details.coverage = 'poor';
381
+ details.testFile = null;
382
+ }
383
+ }
384
+
385
+ details.filePath = filePath;
386
+ details.isTestFile = isTestFile;
387
+ details.impact = score > 0.4 ? 'high_risk' : 'low_risk';
388
+
389
+ result.addFactor(PRIORITY_FACTORS.TEST_COVERAGE, score, this.weights[PRIORITY_FACTORS.TEST_COVERAGE], details);
390
+ }
391
+
392
+ /**
393
+ * Calculate business impact factor
394
+ */
395
+ calculateBusinessImpactFactor(fileAnalysis, result) {
396
+ let score = 0;
397
+ let details = {};
398
+
399
+ const filePath = fileAnalysis.filePath;
400
+
401
+ // Business critical file patterns
402
+ const criticalPatterns = [
403
+ /\/bin\//,
404
+ /\/src\/main\//,
405
+ /\/src\/app\//,
406
+ /\/src\/index\./,
407
+ /\/server\./,
408
+ /\/app\./
409
+ ];
410
+
411
+ // Important but not critical patterns
412
+ const importantPatterns = [
413
+ /\/src\/api\//,
414
+ /\/src\/controllers\//,
415
+ /\/src\/services\//,
416
+ /\/src\/models\//
417
+ ];
418
+
419
+ if (criticalPatterns.some(pattern => pattern.test(filePath))) {
420
+ score = 0.8;
421
+ details.impact = 'critical';
422
+ } else if (importantPatterns.some(pattern => pattern.test(filePath))) {
423
+ score = 0.5;
424
+ details.impact = 'important';
425
+ } else {
426
+ score = 0.2;
427
+ details.impact = 'standard';
428
+ }
429
+
430
+ details.filePath = filePath;
431
+ details.isBusinessCritical = score >= 0.8;
432
+
433
+ result.addFactor(PRIORITY_FACTORS.BUSINESS_IMPACT, score, this.weights[PRIORITY_FACTORS.BUSINESS_IMPACT], details);
434
+ }
435
+
436
+ /**
437
+ * Determine priority from score
438
+ */
439
+ determinePriority(score) {
440
+ if (score >= this.thresholds[PRIORITY_LEVELS.CRITICAL]) {
441
+ return PRIORITY_LEVELS.CRITICAL;
442
+ } else if (score >= this.thresholds[PRIORITY_LEVELS.HIGH]) {
443
+ return PRIORITY_LEVELS.HIGH;
444
+ } else if (score >= this.thresholds[PRIORITY_LEVELS.MEDIUM]) {
445
+ return PRIORITY_LEVELS.MEDIUM;
446
+ } else if (score >= this.thresholds[PRIORITY_LEVELS.LOW]) {
447
+ return PRIORITY_LEVELS.LOW;
448
+ }
449
+ return PRIORITY_LEVELS.NONE;
450
+ }
451
+
452
+ /**
453
+ * Generate reasons and recommendations
454
+ */
455
+ generateReasonsAndRecommendations(fileAnalysis, result) {
456
+ const reasons = [];
457
+ const recommendations = [];
458
+
459
+ // Size-related reasons
460
+ const sizeFactor = result.factors[PRIORITY_FACTORS.SIZE_VIOLATION];
461
+ if (sizeFactor && sizeFactor.score > 0.6) {
462
+ reasons.push(`File has ${sizeFactor.details.excessLines} excess lines beyond limit`);
463
+ recommendations.push('Consider splitting large functions or extracting modules');
464
+ }
465
+
466
+ // Complexity-related reasons
467
+ const complexityFactor = result.factors[PRIORITY_FACTORS.COMPLEXITY];
468
+ if (complexityFactor && complexityFactor.score > 0.6) {
469
+ reasons.push(`File has ${complexityFactor.details.level} complexity`);
470
+ recommendations.push('Reduce complexity through better organization and smaller functions');
471
+ }
472
+
473
+ // Dependency-related reasons
474
+ const dependencyFactor = result.factors[PRIORITY_FACTORS.DEPENDENCY_COUNT];
475
+ if (dependencyFactor && dependencyFactor.score > 0.6) {
476
+ reasons.push(`File has ${dependencyFactor.details.totalDependencies} total dependencies`);
477
+ recommendations.push('Consider reducing dependencies through better separation of concerns');
478
+ }
479
+
480
+ // Package importance reasons
481
+ const packageFactor = result.factors[PRIORITY_FACTORS.PACKAGE_IMPORTANCE];
482
+ if (packageFactor && packageFactor.score > 0.8) {
483
+ reasons.push(`File is in ${packageFactor.details.importance} package (${packageFactor.details.packageName})`);
484
+ recommendations.push('Ensure high code quality for critical package files');
485
+ }
486
+
487
+ // Test coverage reasons
488
+ const testFactor = result.factors[PRIORITY_FACTORS.TEST_COVERAGE];
489
+ if (testFactor && testFactor.score > 0.4) {
490
+ reasons.push('File has poor or no test coverage');
491
+ recommendations.push('Add test coverage before refactoring to ensure safety');
492
+ }
493
+
494
+ // Business impact reasons
495
+ const businessFactor = result.factors[PRIORITY_FACTORS.BUSINESS_IMPACT];
496
+ if (businessFactor && businessFactor.score > 0.6) {
497
+ reasons.push(`File has ${businessFactor.details.impact} business impact`);
498
+ recommendations.push('Exercise extra caution when refactoring business-critical code');
499
+ }
500
+
501
+ result.reasons = reasons;
502
+ result.recommendations = recommendations;
503
+ }
504
+
505
+ /**
506
+ * Calculate complexity score for a file
507
+ */
508
+ calculateComplexityScore(fileAnalysis) {
509
+ let score = 0;
510
+
511
+ // Line count contribution
512
+ if (fileAnalysis.lineCount > 1000) score += 30;
513
+ else if (fileAnalysis.lineCount > 555) score += 25;
514
+ else if (fileAnalysis.lineCount > 300) score += 15;
515
+ else if (fileAnalysis.lineCount > 100) score += 5;
516
+
517
+ // Function count contribution
518
+ const functionCount = fileAnalysis.functionCount || 0;
519
+ if (functionCount > 20) score += 20;
520
+ else if (functionCount > 10) score += 15;
521
+ else if (functionCount > 5) score += 10;
522
+ else if (functionCount > 2) score += 5;
523
+
524
+ // Class count contribution
525
+ const classCount = fileAnalysis.classCount || 0;
526
+ if (classCount > 5) score += 15;
527
+ else if (classCount > 3) score += 10;
528
+ else if (classCount > 1) score += 5;
529
+
530
+ // Nesting depth contribution
531
+ const nestingDepth = fileAnalysis.nestingDepth || 0;
532
+ if (nestingDepth > 8) score += 15;
533
+ else if (nestingDepth > 5) score += 10;
534
+ else if (nestingDepth > 3) score += 5;
535
+
536
+ // Dependency count contribution
537
+ const dependencyCount = fileAnalysis.dependencyCount || 0;
538
+ if (dependencyCount > 20) score += 20;
539
+ else if (dependencyCount > 10) score += 15;
540
+ else if (dependencyCount > 5) score += 10;
541
+ else if (dependencyCount > 2) score += 5;
542
+
543
+ return Math.min(score, 100);
544
+ }
545
+
546
+ /**
547
+ * Assess coupling risk
548
+ */
549
+ assessCouplingRisk(dependencyCount) {
550
+ if (dependencyCount > 20) return 'very_high';
551
+ if (dependencyCount > 15) return 'high';
552
+ if (dependencyCount > 10) return 'medium';
553
+ if (dependencyCount > 5) return 'low';
554
+ return 'very_low';
555
+ }
556
+
557
+ /**
558
+ * Check if file has corresponding test file
559
+ */
560
+ hasCorrespondingTestFile(filePath) {
561
+ const testFile = this.findTestFile(filePath);
562
+ return testFile !== null;
563
+ }
564
+
565
+ /**
566
+ * Find test file for a given source file
567
+ */
568
+ findTestFile(filePath) {
569
+ const fs = require('fs');
570
+ const path = require('path');
571
+
572
+ const dir = path.dirname(filePath);
573
+ const basename = path.basename(filePath, path.extname(filePath));
574
+
575
+ const testPatterns = [
576
+ path.join(dir, `${basename}.test.js`),
577
+ path.join(dir, `${basename}.spec.js`),
578
+ path.join(dir, `${basename}.test.ts`),
579
+ path.join(dir, `${basename}.spec.ts`),
580
+ path.join(dir, '__tests__', `${basename}.js`),
581
+ path.join(dir, '__tests__', `${basename}.ts`),
582
+ path.join(dir, 'test', `${basename}.js`),
583
+ path.join(dir, 'test', `${basename}.ts`),
584
+ path.join(dir, 'tests', `${basename}.js`),
585
+ path.join(dir, 'tests', `${basename}.ts`)
586
+ ];
587
+
588
+ for (const testPath of testPatterns) {
589
+ if (fs.existsSync(testPath)) {
590
+ return testPath;
591
+ }
592
+ }
593
+
594
+ return null;
595
+ }
596
+
597
+ /**
598
+ * Calculate priorities for multiple files
599
+ */
600
+ calculatePriorities(fileAnalyses) {
601
+ const results = [];
602
+
603
+ for (const fileAnalysis of fileAnalyses) {
604
+ const result = this.calculatePriority(fileAnalysis);
605
+ results.push(result);
606
+ }
607
+
608
+ return results;
609
+ }
610
+
611
+ /**
612
+ * Get priority summary
613
+ */
614
+ getPrioritySummary(priorityResults) {
615
+ const summary = {
616
+ total: priorityResults.length,
617
+ byPriority: {
618
+ [PRIORITY_LEVELS.CRITICAL]: 0,
619
+ [PRIORITY_LEVELS.HIGH]: 0,
620
+ [PRIORITY_LEVELS.MEDIUM]: 0,
621
+ [PRIORITY_LEVELS.LOW]: 0,
622
+ [PRIORITY_LEVELS.NONE]: 0
623
+ },
624
+ averageScore: 0,
625
+ highestScore: 0,
626
+ lowestScore: 100
627
+ };
628
+
629
+ let totalScore = 0;
630
+
631
+ for (const result of priorityResults) {
632
+ summary.byPriority[result.priority]++;
633
+ totalScore += result.score;
634
+ summary.highestScore = Math.max(summary.highestScore, result.score);
635
+ summary.lowestScore = Math.min(summary.lowestScore, result.score);
636
+ }
637
+
638
+ summary.averageScore = summary.total > 0 ? totalScore / summary.total : 0;
639
+
640
+ return summary;
641
+ }
642
+
643
+ /**
644
+ * Sort files by priority
645
+ */
646
+ sortByPriority(priorityResults, descending = true) {
647
+ const priorityOrder = {
648
+ [PRIORITY_LEVELS.CRITICAL]: 0,
649
+ [PRIORITY_LEVELS.HIGH]: 1,
650
+ [PRIORITY_LEVELS.MEDIUM]: 2,
651
+ [PRIORITY_LEVELS.LOW]: 3,
652
+ [PRIORITY_LEVELS.NONE]: 4
653
+ };
654
+
655
+ return [...priorityResults].sort((a, b) => {
656
+ const priorityDiff = priorityOrder[a.priority] - priorityOrder[b.priority];
657
+ if (priorityDiff !== 0) {
658
+ return priorityDiff;
659
+ }
660
+
661
+ // If same priority, sort by score
662
+ return descending ? b.score - a.score : a.score - b.score;
663
+ });
664
+ }
665
+
666
+ /**
667
+ * Get files by priority level
668
+ */
669
+ getFilesByPriority(priorityResults, priorityLevel) {
670
+ return priorityResults.filter(result => result.priority === priorityLevel);
671
+ }
672
+ }
673
+
674
+ module.exports = {
675
+ PriorityCalculator,
676
+ PriorityResult,
677
+ PRIORITY_LEVELS,
678
+ PRIORITY_FACTORS
679
+ };